allegro-5.0.10/0000755000175000001440000000000012157230751012411 5ustar tjadenusersallegro-5.0.10/README_cmake.txt0000644000175000001440000000226411405374254015255 0ustar tjadenusersCMake options ------------- Our build system supports many options. Here are some of them: The option `CMAKE_BUILD_TYPE` selects release, debug or profiling configurations. Valid values are: Release, Debug, RelWithDebInfo, MinSizeRel, Profile. The option `SHARED` controls whether libraries are built as shared libraries or static libraries. Shared libraries are built by default. *Note:* For MinGW with gcc < 4, you cannot build a static library because TLS (thread local storage, using __thread) support was not introduced until version 4. There are many options named WANT_*. Unselecting these will prevent the associated addon or feature from being built. HTML and man page documentation will be built by default, but Info and PDF (through pdfLaTeX) can also be selected from the CMake options. deps subdirectory ----------------- As a convenience, you may create a subdirectory called "deps" in the main Allegro directory, or in the build directory. Inside you can place header and library files for dependencies that Allegro will search for. Allegro will search in these locations: deps/include deps/lib deps//include deps//lib allegro-5.0.10/addons/0000755000175000001440000000000012157230736013664 5ustar tjadenusersallegro-5.0.10/addons/primitives/0000755000175000001440000000000012157230736016057 5ustar tjadenusersallegro-5.0.10/addons/primitives/directx_shaders.c0000644000175000001440000005706111451505335021403 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * DirectX dummy shader support. Dummy shader doesn't do anything * except making D3D happy when you pass it vertices with non-FVF * memory layout. * * By Pavel Sountsov. * * Thanks to Michał Cichoń for the pre-compiled shader code. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro_primitives.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/platform/alplatf.h" #ifdef ALLEGRO_CFG_D3D #include "allegro5/allegro_direct3d.h" #include "allegro5/internal/aintern_prim_directx.h" /* * The following pre-compiled shaders are generated using the * nshader.cpp program. See that file for instructions. */ /* POS3 TEX2 COL4 1 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // g_texture_proj c4 2 // vs_1_1 def c6, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 dcl_texcoord1 v2 mad r0, v0.xyzx, c6.xxxy, c6.yyyx dp4 oPos.x, r0, c0 dp4 oPos.y, r0, c1 dp4 oPos.z, r0, c2 dp4 oPos.w, r0, c3 mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oD0, v2 // approximately 9 instruction slots used */ static const uint8_t _al_vs_pos3_tex2_col4_1[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x06, 0x00, 0x40, 0xa0, 0x06, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x02, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS3 TEX2 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // g_texture_proj c4 2 // vs_1_1 def c6, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 mad r0, v0.xyzx, c6.xxxy, c6.yyyx dp4 oPos.x, r0, c0 dp4 oPos.y, r0, c1 dp4 oPos.z, r0, c2 dp4 oPos.w, r0, c3 mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oD0, c6.x // approximately 9 instruction slots used */ static const uint8_t _al_vs_pos3_tex2_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x06, 0x00, 0x40, 0xa0, 0x06, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x06, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 }; /* POS3 TEX0 COL4 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // vs_1_1 def c4, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 mad r0, v0.xyzx, c4.xxxy, c4.yyyx dp4 oPos.x, r0, c0 dp4 oPos.y, r0, c1 dp4 oPos.z, r0, c2 dp4 oPos.w, r0, c3 mov oD0, v1 // approximately 6 instruction slots used */ static const uint8_t _al_vs_pos3_tex0_col4_0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x04, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS3 TEX0 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // vs_1_1 def c4, 1, 0, 0, 0 dcl_position v0 mad r0, v0.xyzx, c4.xxxy, c4.yyyx dp4 oPos.x, r0, c0 dp4 oPos.y, r0, c1 dp4 oPos.z, r0, c2 dp4 oPos.w, r0, c3 mov oD0, c4.x // approximately 6 instruction slots used */ static const uint8_t _al_vs_pos3_tex0_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x04, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x04, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 }; /* POS2 TEX2 COL4 1 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // g_texture_proj c4 2 // vs_1_1 def c6, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 dcl_texcoord1 v2 mad r0.xyz, v0.xyxw, c6.xxyw, c6.yyxw dp3 oPos.x, r0, c0.xyww dp3 oPos.y, r0, c1.xyww dp3 oPos.z, r0, c2.xyww dp3 oPos.w, r0, c3.xyww mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oD0, v2 // approximately 9 instruction slots used */ static const uint8_t _al_vs_pos2_tex2_col4_1[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x02, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS2 TEX2 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // g_texture_proj c4 2 // vs_1_1 def c6, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 mad r0.xyz, v0.xyxw, c6.xxyw, c6.yyxw dp3 oPos.x, r0, c0.xyww dp3 oPos.y, r0, c1.xyww dp3 oPos.z, r0, c2.xyww dp3 oPos.w, r0, c3.xyww mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oD0, c6.x // approximately 9 instruction slots used */ static const uint8_t _al_vs_pos2_tex2_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x06, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 }; /* POS2 TEX0 COL4 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // vs_1_1 def c4, 1, 0, 0, 0 dcl_position v0 dcl_texcoord v1 mad r0.xyz, v0.xyxw, c4.xxyw, c4.yyxw dp3 oPos.x, r0, c0.xyww dp3 oPos.y, r0, c1.xyww dp3 oPos.z, r0, c2.xyww dp3 oPos.w, r0, c3.xyww mov oD0, v1 // approximately 6 instruction slots used */ static const uint8_t _al_vs_pos2_tex0_col4_0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x04, 0x00, 0xd0, 0xa0, 0x04, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS2 TEX0 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_world_view_proj; // // // Registers: // // Name Reg Size // ----------------- ----- ---- // g_world_view_proj c0 4 // vs_1_1 def c4, 1, 0, 0, 0 dcl_position v0 mad r0.xyz, v0.xyxw, c4.xxyw, c4.yyxw dp3 oPos.x, r0, c0.xyww dp3 oPos.y, r0, c1.xyww dp3 oPos.z, r0, c2.xyww dp3 oPos.w, r0, c3.xyww mov oD0, c4.x // approximately 6 instruction slots used */ static const uint8_t _al_vs_pos2_tex0_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x04, 0x00, 0xd0, 0xa0, 0x04, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x04, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 }; /* POS0 TEX2 COL4 1 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // // // Registers: // // Name Reg Size // -------------- ----- ---- // g_texture_proj c4 2 // vs_1_1 def c0, 1, 0, 0, 0 dcl_texcoord v0 dcl_texcoord1 v1 mad r0.xyz, v0.xyxw, c0.xxyw, c0.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oPos, c0.yyyx mov oD0, v1 // approximately 5 instruction slots used */ static const uint8_t _al_vs_pos0_tex2_col4_1[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x00, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x15, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS0 TEX2 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 // // Parameters: // // float4x4 g_texture_proj; // // // Registers: // // Name Reg Size // -------------- ----- ---- // g_texture_proj c4 2 // vs_1_1 def c0, 1, 0, 0, 0 dcl_texcoord v0 mad r0.xyz, v0.xyxw, c0.xxyw, c0.yyxw dp3 oT0.x, r0, c4 dp3 oT0.y, r0, c5 mov oPos, c0.yyyx mov oD0, c0.x // approximately 5 instruction slots used */ static const uint8_t _al_vs_pos0_tex2_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x00, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x15, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 }; /* POS0 TEX0 COL4 0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 vs_1_1 def c0, 0, 1, 0, 0 dcl_texcoord v0 mov oPos, c0.xxxy mov oD0, v0 // approximately 2 instruction slots used */ static const uint8_t _al_vs_pos0_tex0_col4_0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 }; /* POS0 TEX0 COL0 // // Generated by Microsoft (R) HLSL Shader Compiler 9.23.949.2378 vs_1_1 def c0, 0, 1, 0, 0 mov oPos, c0.xxxy mov oD0, c0.y // approximately 2 instruction slots used */ static const uint8_t _al_vs_pos0_tex0_col0[] = { 0x01, 0x01, 0xfe, 0xff, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0x55, 0xa0, 0xff, 0xff, 0x00, 0x00 }; void _al_create_shader(void* dev, ALLEGRO_VERTEX_DECL* decl) { LPDIRECT3DDEVICE9 device = dev; LPDIRECT3DVERTEXSHADER9 ret = 0; ALLEGRO_VERTEX_ELEMENT* e; int position = 0; int texture = 0; int color = 0; const uint8_t* shader = NULL; /*position, texture, color*/ const uint8_t* shaders[3][2][2] = { { {_al_vs_pos0_tex0_col0, _al_vs_pos0_tex0_col4_0}, {_al_vs_pos0_tex2_col0, _al_vs_pos0_tex2_col4_1} }, { {_al_vs_pos2_tex0_col0, _al_vs_pos2_tex0_col4_0}, {_al_vs_pos2_tex2_col0, _al_vs_pos2_tex2_col4_1} }, { {_al_vs_pos3_tex0_col0, _al_vs_pos3_tex0_col4_0}, {_al_vs_pos3_tex2_col0, _al_vs_pos3_tex2_col4_1} } }; e = &decl->elements[ALLEGRO_PRIM_POSITION]; if (e->attribute) { switch(e->storage) { case ALLEGRO_PRIM_SHORT_2: case ALLEGRO_PRIM_FLOAT_2: position = 1; break; case ALLEGRO_PRIM_FLOAT_3: position = 2; break; } } e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; if(!e->attribute) e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; if(e->attribute) { texture = 1; } e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; if(e->attribute) { color = 1; } shader = shaders[position][texture][color]; IDirect3DDevice9_CreateVertexShader(device, (const DWORD*)shader, &ret); decl->d3d_dummy_shader = ret; } void* _al_create_default_shader(void* dev) { LPDIRECT3DDEVICE9 device = dev; LPDIRECT3DVERTEXSHADER9 shader; IDirect3DDevice9_CreateVertexShader(device, (const DWORD*)_al_vs_pos3_tex2_col4_1, &shader); return shader; } static void _al_swap(float* l, float* r) { float temp = *r; *r = *l; *l = temp; } static void _al_transpose_d3d_matrix(D3DMATRIX* m) { int i, j; float* m_ptr = (float*)m; for (i = 1; i < 4; i++) { for (j = 0; j < i; j++) { _al_swap(m_ptr + (i * 4 + j), m_ptr + (j * 4 + i)); } } } static void _al_multiply_d3d_matrix(D3DMATRIX* result, const D3DMATRIX* a, const D3DMATRIX* b) { int i, j, k; float* r_ptr = (float*)result; float* a_ptr = (float*)a; float* b_ptr = (float*)b; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { r_ptr[i * 4 + j] = 0.0f; for (k = 0; k < 4; k++) { r_ptr[i * 4 + j] += a_ptr[i * 4 + k] * b_ptr[k * 4 + j]; } } } } static void _al_multiply_transpose_d3d_matrix(D3DMATRIX* result, const D3DMATRIX* a, const D3DMATRIX* b) { int i, j, k; float* r_ptr = (float*)result; float* a_ptr = (float*)a; float* b_ptr = (float*)b; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { r_ptr[i + 4 * j] = 0.0f; for (k = 0; k < 4; k++) { r_ptr[i + 4 * j] += a_ptr[i * 4 + k] * b_ptr[k * 4 + j]; } } } } /* note: passed matrix may be modified by this function */ void _al_set_texture_matrix(void* dev, float* mat) { _al_transpose_d3d_matrix((D3DMATRIX*)mat); IDirect3DDevice9_SetVertexShaderConstantF((IDirect3DDevice9*)dev, 4, mat, 4); } static void setup_transforms(IDirect3DDevice9* device) { D3DMATRIX matWorld, matView, matProj, matWorldView, matWorldViewProj; IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &matWorld); IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &matView); IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &matProj); _al_multiply_d3d_matrix(&matWorldView, &matWorld, &matView); _al_multiply_transpose_d3d_matrix(&matWorldViewProj, &matWorldView, &matProj); IDirect3DDevice9_SetVertexShaderConstantF(device, 0, (float*)&matWorldViewProj, 4); } void _al_setup_shader(void* dev, const ALLEGRO_VERTEX_DECL* decl) { IDirect3DDevice9* device = (IDirect3DDevice9*)dev; setup_transforms(device); IDirect3DDevice9_SetVertexShader(device, (IDirect3DVertexShader9*)decl->d3d_dummy_shader); } void _al_setup_default_shader(void* dev, void* shader) { IDirect3DDevice9* device = (IDirect3DDevice9*)dev; setup_transforms(device); IDirect3DDevice9_SetVertexShader(device, shader); } #endif /* ALLEGRO_CFG_D3D */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/primitives/point_soft.c0000644000175000001440000000472312101033341020373 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Software point implementation functions. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #define _AL_NO_BLEND_INLINE_FUNC #include "allegro5/allegro.h" #include "allegro5/allegro_primitives.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/internal/aintern_prim_soft.h" #include static int fix_var(float var, int max_var) { const int ivar = (int)floorf(var); const int ret = ivar % max_var; if(ret >= 0) return ret; else return ret + max_var; } void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v) { int shade = 1; int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR vc; int clip_min_x, clip_min_y, clip_max_x, clip_max_y; int x = (int)floorf(v->x); int y = (int)floorf(v->x); al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); clip_max_x += clip_min_x; clip_max_y += clip_min_y; if(x < clip_min_x || x >= clip_max_x || y < clip_min_y || y >= clip_max_y) return; vc = v->color; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { shade = 0; } if (texture) { float U = fix_var(v->u, al_get_bitmap_width(texture)); float V = fix_var(v->v, al_get_bitmap_height(texture)); ALLEGRO_COLOR color = al_get_pixel(texture, U, V); if(vc.r != 1 || vc.g != 1 || vc.b != 1 || vc.a != 1) { color.r *= vc.r; color.g *= vc.g; color.b *= vc.b; color.a *= vc.a; } if (shade) { al_put_blended_pixel(v->x, v->y, color); } else { al_put_pixel(v->x, v->y, color); } } else { ALLEGRO_COLOR color = al_map_rgba_f(vc.r, vc.g, vc.b, vc.a); if (shade) { al_put_blended_pixel(v->x, v->y, color); } else { al_put_pixel(v->x, v->y, color); } } } allegro-5.0.10/addons/primitives/CMakeLists.txt0000644000175000001440000000173612007334371020620 0ustar tjadenusersset(PRIMITIVES_SOURCES high_primitives.c line_soft.c prim_directx.c prim_opengl.c prim_soft.c point_soft.c primitives.c directx_shaders.c ) if(WIN32) # Add this file conditionally. # The Debian folks want to remove it because it contains precompiled code. list(APPEND PRIMITIVES_SOURCES directx_shaders.c) endif(WIN32) set(PRIMITIVES_INCLUDE_FILES allegro5/allegro_primitives.h) set_our_header_properties(${PRIMITIVES_INCLUDE_FILES}) add_our_library(allegro_primitives "${PRIMITIVES_SOURCES};${PRIMITIVES_INCLUDE_FILES}" "-DALLEGRO_PRIMITIVES_SRC" "${ALLEGRO_LINK_WITH}" ) set_our_framework_properties(allegro_primitives AllegroPrimitives-${ALLEGRO_SOVERSION}) install_our_library(allegro_primitives) install_our_headers(${PRIMITIVES_INCLUDE_FILES}) set(PRIMITIVES_LINK_WITH allegro_primitives PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/primitives/nshader.fx0000644000175000001440000001100611451505335020034 0ustar tjadenusers# define CAT(a, b) CAT_I(a, b) # define CAT_I(a, b) CAT_II(a ## b) # define CAT_II(res) res # define JOIN1(a) a # define JOIN2(a, b) CAT(a, b) # define JOIN3(a, b, c) CAT(JOIN2(a, b), c) # define JOIN4(a, b, c, d) CAT(JOIN3(a, b, c), d) # define JOIN5(a, b, c, d, e) CAT(JOIN4(a, b, c, d), e) # define JOIN6(a, b, c, d, e, f) CAT(JOIN5(a, b, c, d, e), f) # define JOIN7(a, b, c, d, e, f, g) CAT(JOIN6(a, b, c, d, e, f), g) # define JOIN8(a, b, c, d, e, f, g, h) CAT(JOIN7(a, b, c, d, e, f, g), h) # define DECL_VS_IN1(v0) struct JOIN2(vs_input_, v0) { _in_##v0 } # define DECL_VS_IN2(v0, v1) struct JOIN4(vs_input_, v0, _, v1) { _in_##v0 _in_##v1 } # define DECL_VS_IN3(v0, v1, v2) struct JOIN6(vs_input_, v0, _, v1, _, v2) { _in_##v0 _in_##v1 _in_##v2 } # define DECL_VS_OUT1(v0) struct JOIN2(vs_output_, v0) { _out_##v0 } # define DECL_VS_OUT2(v0, v1) struct JOIN4(vs_output_, v0, _, v1) { _out_##v0 _out_##v1 } # define DECL_VS_OUT3(v0, v1, v2) struct JOIN6(vs_output_, v0, _, v1, _, v2) { _out_##v0 _out_##v1 _out_##v2 } # define DEF_VS_BODY1(v0) void JOIN2(vs_, v0) (in JOIN2(vs_input_, v0) i, out JOIN2(vs_output_, v0) o) { _op_##v0 } # define DEF_VS_BODY2(v0, v1) void JOIN4(vs_, v0, _, v1) (in JOIN4(vs_input_, v0, _, v1) i, out JOIN4(vs_output_, v0, _) o) { _op_##v0 _op_##v1 } # define DEF_VS_BODY3(v0, v1, v2) void JOIN6(vs_, v0, _, v1, _, v2)(in JOIN6(vs_input_, v0, _, v1, _, v2) i, out JOIN6(vs_output_, v0, _, v1, _, v2) o) { _op_##v0 _op_##v1 _op_##v2 } # define DEF_TECH1(v0) technique JOIN1(v0) { pass { VertexShader = compile vs_1_1 JOIN2(vs_, v0)(); } } # define DEF_TECH2(v0, v1) technique JOIN3(v0, _, v1) { pass { VertexShader = compile vs_1_1 JOIN4(vs_, v0, _, v1)(); } } # define DEF_TECH3(v0, v1, v2) technique JOIN5(v0, _, v1, _, v2) { pass { VertexShader = compile vs_1_1 JOIN6(vs_, v0, _, v1, _, v2)(); } } # define DEF_VS1(v0) DECL_VS_IN1(v0); DECL_VS_OUT1(v0); DEF_VS_BODY1(v0) DEF_TECH1(v0) # define DEF_VS2(v0, v1) DECL_VS_IN2(v0, v1); DECL_VS_OUT2(v0, v1); DEF_VS_BODY2(v0, v1) DEF_TECH2(v0, v1) # define DEF_VS3(v0, v1, v2) DECL_VS_IN3(v0, v1, v2); DECL_VS_OUT3(v0, v1, v2); DEF_VS_BODY3(v0, v1, v2) DEF_TECH3(v0, v1, v2) # define _in_pos0 # define _in_pos2 float2 pos : POSITION; # define _in_pos3 float3 pos : POSITION; # define _in_tex0 # define _in_tex2 float2 tex : TEXCOORD0; # define _in_col0 # define _in_col4_0 float4 col : TEXCOORD0; # define _in_col4_1 float4 col : TEXCOORD1; # define _out_pos0 float4 pos : POSITION; # define _out_pos2 float4 pos : POSITION; # define _out_pos3 float4 pos : POSITION; # define _out_tex0 # define _out_tex2 float2 tex : TEXCOORD0; # define _out_col0 float4 col : COLOR0; # define _out_col4_0 float4 col : COLOR0; # define _out_col4_1 float4 col : COLOR0; # define _op_pos0 o.pos = float4(0.0f, 0.0f, 0.0f, 1.0f); # define _op_pos2 o.pos = mul(float4(i.pos.xy, 0.0f, 1.0f), g_world_view_proj); # define _op_pos3 o.pos = mul(float4(i.pos.xyz, 1.0f), g_world_view_proj); # define _op_tex0 # define _op_tex2 o.tex = mul(float4(i.tex.xy, 1.0f, 0.0f), g_texture_proj).xy; # define _op_col0 o.col = float4(1.0f, 1.0f, 1.0f, 1.0f); # define _op_col4_0 o.col = i.col; # define _op_col4_1 o.col = i.col; float4x4 g_world_view_proj : register(c0); float4x4 g_texture_proj : register(c4); DEF_VS3(pos3, tex2, col4_1); DEF_VS3(pos3, tex2, col0); DEF_VS3(pos3, tex0, col4_0); DEF_VS3(pos3, tex0, col0); DEF_VS3(pos2, tex2, col4_1); DEF_VS3(pos2, tex2, col0); DEF_VS3(pos2, tex0, col4_0); DEF_VS3(pos2, tex0, col0); DEF_VS3(pos0, tex2, col4_1); DEF_VS3(pos0, tex2, col0); DEF_VS3(pos0, tex0, col4_0); DEF_VS3(pos0, tex0, col0); allegro-5.0.10/addons/primitives/prim_directx.c0000644000175000001440000005107312123265510020711 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * DirectX implementation of some of the primitive routines. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_primitives.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_prim_directx.h" #include "allegro5/internal/aintern_prim_soft.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/platform/alplatf.h" #ifdef ALLEGRO_CFG_D3D #include "allegro5/allegro_direct3d.h" #include "allegro5/internal/aintern_direct3d.h" static ALLEGRO_MUTEX *d3d_mutex; /* * In the context of this file, legacy cards pretty much refer to older Intel cards. * They are distinguished by three misfeatures: * 1. They don't support shaders * 2. They don't support custom vertices * 3. DrawIndexedPrimitiveUP is broken * * Since shaders are used 100% of the time, this means that for these cards * the incoming vertices are first converted into the vertex type that these cards * can handle. */ static bool legacy_card = false; static bool know_card_type = false; typedef struct LEGACY_VERTEX { float x, y, z; DWORD color; float u, v; } LEGACY_VERTEX; static LEGACY_VERTEX* legacy_buffer; static int legacy_buffer_size = 0; #define A5V_FVF (D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE4(1)) #define A5V_LEGACY_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) typedef struct SHADER_ENTRY { LPDIRECT3DDEVICE9 device; LPDIRECT3DVERTEXSHADER9 shader; } SHADER_ENTRY; static SHADER_ENTRY* shader_entries; static int num_shader_entries = 0; static void display_invalidated(ALLEGRO_DISPLAY* display) { int ii; LPDIRECT3DDEVICE9 device = al_get_d3d_device(display); /* * If there is no mutex, the addon has been shutdown earlier */ if(!d3d_mutex) return; al_lock_mutex(d3d_mutex); for(ii = 0; ii < num_shader_entries; ii++) { if(shader_entries[ii].device == device) { IDirect3DVertexShader9_Release(shader_entries[ii].shader); shader_entries[ii] = shader_entries[num_shader_entries - 1]; num_shader_entries--; break; } } al_unlock_mutex(d3d_mutex); } static void setup_default_shader(ALLEGRO_DISPLAY* display) { LPDIRECT3DDEVICE9 device = al_get_d3d_device(display); /* * Lock the mutex so that the entries are not messed up by a * display blowing up/being created */ al_lock_mutex(d3d_mutex); if(num_shader_entries == 0) { shader_entries = al_malloc(sizeof(SHADER_ENTRY)); num_shader_entries = 1; shader_entries[0].device = device; shader_entries[0].shader = _al_create_default_shader(device); _al_set_display_invalidated_callback(display, &display_invalidated); } if(shader_entries[0].device != device) { int ii; bool found = false; for(ii = 1; ii < num_shader_entries; ii++) { if(shader_entries[ii].device == device) { /* * Move this entry to the front, so the search goes faster * next time - presumably the al_draw_prim will be called * several times for each display before switching again */ SHADER_ENTRY t = shader_entries[0]; shader_entries[0] = shader_entries[ii]; shader_entries[ii] = t; found = true; break; } } if(!found) { SHADER_ENTRY t = shader_entries[0]; num_shader_entries++; shader_entries = al_realloc(shader_entries, sizeof(SHADER_ENTRY) * num_shader_entries); shader_entries[num_shader_entries - 1] = t; shader_entries[0].device = device; shader_entries[0].shader = _al_create_default_shader(device); _al_set_display_invalidated_callback(display, &display_invalidated); } } _al_setup_default_shader(device, shader_entries[0].shader); al_unlock_mutex(d3d_mutex); } static void destroy_default_shaders(void) { int ii; for(ii = 0; ii < num_shader_entries; ii++) { IDirect3DVertexShader9_Release(shader_entries[ii].shader); } num_shader_entries = 0; al_free(shader_entries); shader_entries = NULL; } #endif bool _al_init_d3d_driver(void) { #ifdef ALLEGRO_CFG_D3D d3d_mutex = al_create_mutex(); #endif return true; } void _al_shutdown_d3d_driver(void) { #ifdef ALLEGRO_CFG_D3D al_destroy_mutex(d3d_mutex); al_free(legacy_buffer); d3d_mutex = NULL; legacy_buffer = NULL; destroy_default_shaders(); legacy_card = false; know_card_type = false; legacy_buffer_size = 0; #endif } #ifdef ALLEGRO_CFG_D3D static void* convert_to_legacy_vertices(const void* vtxs, int num_vertices, const int* indices, bool loop) { const ALLEGRO_VERTEX* vtx = vtxs; int ii; int num_needed_vertices = num_vertices; if(loop) num_needed_vertices++; if(legacy_buffer == 0) { legacy_buffer = al_malloc(num_needed_vertices * sizeof(LEGACY_VERTEX)); legacy_buffer_size = num_needed_vertices; } else if (num_needed_vertices > legacy_buffer_size) { legacy_buffer = al_realloc(legacy_buffer, num_needed_vertices * 1.5 * sizeof(LEGACY_VERTEX)); legacy_buffer_size = num_needed_vertices * 1.5; } for(ii = 0; ii < num_vertices; ii++) { ALLEGRO_VERTEX vertex; if(indices) vertex = vtx[indices[ii]]; else vertex = vtx[ii]; legacy_buffer[ii].x = vertex.x; legacy_buffer[ii].y = vertex.y; legacy_buffer[ii].z = vertex.z; legacy_buffer[ii].u = vertex.u; legacy_buffer[ii].v = vertex.v; legacy_buffer[ii].color = D3DCOLOR_COLORVALUE(vertex.color.r, vertex.color.g, vertex.color.b, vertex.color.a); } if(loop) legacy_buffer[num_vertices] = legacy_buffer[0]; return legacy_buffer; } static int draw_prim_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtx, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) { int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); int num_primitives = 0; LPDIRECT3DDEVICE9 device; LPDIRECT3DBASETEXTURE9 d3d_texture; DWORD old_wrap_state[2]; DWORD old_ttf_state; int min_idx = 0, max_idx = num_vtx - 1; IDirect3DVertexShader9* old_vtx_shader; IDirect3DPixelShader9* old_pix_shader; if (al_is_d3d_device_lost(target->display)) { return 0; } if(indices) { int ii; for(ii = 0; ii < num_vtx; ii++) { int idx = indices[ii]; if(ii == 0) { min_idx = idx; max_idx = idx; } else if (idx < min_idx) { min_idx = idx; } else if (idx > max_idx) { max_idx = idx; } } } device = al_get_d3d_device(target->display); IDirect3DDevice9_GetVertexShader(device, &old_vtx_shader); IDirect3DDevice9_GetPixelShader(device, &old_pix_shader); if(!know_card_type) { D3DCAPS9 caps; IDirect3DDevice9_GetDeviceCaps(device, &caps); if(caps.PixelShaderVersion < D3DPS_VERSION(3, 0)) legacy_card = true; know_card_type = true; } /* Check for early exit */ if((legacy_card && decl) || (decl && decl->d3d_decl == 0)) { if(!indices) return _al_draw_prim_soft(texture, vtx, decl, 0, num_vtx, type); else return _al_draw_prim_indexed_soft(texture, vtx, decl, indices, num_vtx, type); } if(!old_pix_shader) { _al_d3d_set_blender((struct ALLEGRO_DISPLAY_D3D *)target->display); } if(!old_vtx_shader) { /* Prepare the default shader */ if(!legacy_card) { if(decl) _al_setup_shader(device, decl); else setup_default_shader(target->display); } } /* Set the vertex declarations */ if(legacy_card) { IDirect3DDevice9_SetFVF(device, A5V_LEGACY_FVF); stride = sizeof(LEGACY_VERTEX); } else { if(decl) { IDirect3DDevice9_SetVertexDeclaration(device, (IDirect3DVertexDeclaration9*)decl->d3d_decl); } else { IDirect3DDevice9_SetFVF(device, A5V_FVF); } } if(!old_vtx_shader) { /* Set up the texture */ if (texture) { int tex_x, tex_y; D3DSURFACE_DESC desc; float mat[4][4] = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} }; IDirect3DTexture9_GetLevelDesc(al_get_d3d_video_texture(texture), 0, &desc); al_get_d3d_texture_position(texture, &tex_x, &tex_y); if(decl) { if(decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL].attribute) { mat[0][0] = 1.0f / desc.Width; mat[1][1] = 1.0f / desc.Height; } else { mat[0][0] = (float)al_get_bitmap_width(texture) / desc.Width; mat[1][1] = (float)al_get_bitmap_height(texture) / desc.Height; } } else { mat[0][0] = 1.0f / desc.Width; mat[1][1] = 1.0f / desc.Height; } mat[2][0] = (float)tex_x / desc.Width; mat[2][1] = (float)tex_y / desc.Height; if(legacy_card) { IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &old_ttf_state); IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *)&mat); } else { _al_set_texture_matrix(device, mat[0]); } d3d_texture = (LPDIRECT3DBASETEXTURE9)al_get_d3d_video_texture(texture); IDirect3DDevice9_SetTexture(device, 0, d3d_texture); } else { IDirect3DDevice9_SetTexture(device, 0, NULL); } } IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_ADDRESSU, &old_wrap_state[0]); IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_ADDRESSV, &old_wrap_state[1]); IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); if (texture) { if (texture->flags & ALLEGRO_MIN_LINEAR) { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } else { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); } if (texture->flags & ALLEGRO_MAG_LINEAR) { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } else { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); } if (texture->flags & ALLEGRO_MIPMAP) { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } else { IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); } } /* Convert vertices for legacy cards */ if(legacy_card) { al_lock_mutex(d3d_mutex); vtx = convert_to_legacy_vertices(vtx, num_vtx, indices, type == ALLEGRO_PRIM_LINE_LOOP); } if(!indices || legacy_card) { switch (type) { case ALLEGRO_PRIM_LINE_LIST: { num_primitives = num_vtx / 2; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_LINELIST, num_primitives, vtx, stride); break; }; case ALLEGRO_PRIM_LINE_STRIP: { num_primitives = num_vtx - 1; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_LINESTRIP, num_primitives, vtx, stride); break; }; case ALLEGRO_PRIM_LINE_LOOP: { num_primitives = num_vtx - 1; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_LINESTRIP, num_primitives, vtx, stride); if(!legacy_card) { int in[2]; in[0] = 0; in[1] = num_vtx-1; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_LINELIST, 0, num_vtx, 1, in, D3DFMT_INDEX32, vtx, stride); } else { IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_LINELIST, 1, (char*)vtx + stride * (num_vtx - 1), stride); } break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { num_primitives = num_vtx / 3; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, num_primitives, vtx, stride); break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { num_primitives = num_vtx - 2; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, num_primitives, vtx, stride); break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { num_primitives = num_vtx - 2; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLEFAN, num_primitives, vtx, stride); break; }; case ALLEGRO_PRIM_POINT_LIST: { num_primitives = num_vtx; IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, num_primitives, vtx, stride); break; }; } } else { switch (type) { case ALLEGRO_PRIM_LINE_LIST: { num_primitives = num_vtx / 2; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_LINELIST, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_LINE_STRIP: { num_primitives = num_vtx - 1; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_LINESTRIP, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_LINE_LOOP: { int in[2]; num_primitives = num_vtx - 1; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_LINESTRIP, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); in[0] = indices[0]; in[1] = indices[num_vtx-1]; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_LINELIST, min_idx, max_idx + 1, 1, in, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { num_primitives = num_vtx / 3; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { num_primitives = num_vtx - 2; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { num_primitives = num_vtx - 2; IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLEFAN, min_idx, max_idx + 1, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); break; }; case ALLEGRO_PRIM_POINT_LIST: { /* * D3D does not support point lists in indexed mode, so we draw them using the non-indexed mode. To gain at least a semblance * of speed, we detect consecutive runs of vertices and draw them using a single DrawPrimitiveUP call */ int ii = 0; int start_idx = indices[0]; int run_length = 0; for(ii = 0; ii < num_vtx; ii++) { run_length++; if(indices[ii] + 1 != indices[ii + 1] || ii == num_vtx - 1) { IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, run_length, (const char*)vtx + start_idx * stride, stride); if(ii != num_vtx - 1) start_idx = indices[ii + 1]; run_length = 0; } } break; }; } } if(legacy_card) al_unlock_mutex(d3d_mutex); IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, old_wrap_state[0]); IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, old_wrap_state[1]); if(!old_vtx_shader && legacy_card && texture) { IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, old_ttf_state); } if(!old_vtx_shader) IDirect3DDevice9_SetVertexShader(device, 0); return num_primitives; } #endif int _al_draw_prim_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) { #ifdef ALLEGRO_CFG_D3D int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); return draw_prim_raw(target, texture, (const char*)vtxs + start * stride, decl, 0, end - start, type); #else (void)target; (void)texture; (void)vtxs; (void)start; (void)end; (void)type; (void)decl; return 0; #endif } int _al_draw_prim_indexed_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) { #ifdef ALLEGRO_CFG_D3D return draw_prim_raw(target, texture, vtxs, decl, indices, num_vtx, type); #else (void)target; (void)texture; (void)vtxs; (void)indices; (void)num_vtx; (void)type; (void)decl; return 0; #endif } void _al_set_d3d_decl(ALLEGRO_DISPLAY* display, ALLEGRO_VERTEX_DECL* ret) { #ifdef ALLEGRO_CFG_D3D { LPDIRECT3DDEVICE9 device; D3DVERTEXELEMENT9 d3delements[ALLEGRO_PRIM_ATTR_NUM + 1]; int idx = 0; ALLEGRO_VERTEX_ELEMENT* e; D3DCAPS9 caps; device = al_get_d3d_device(display); IDirect3DDevice9_GetDeviceCaps(device, &caps); if(caps.PixelShaderVersion < D3DPS_VERSION(3, 0)) { ret->d3d_decl = 0; } else { int color_idx = 0; e = &ret->elements[ALLEGRO_PRIM_POSITION]; if(e->attribute) { int type = 0; switch(e->storage) { case ALLEGRO_PRIM_FLOAT_2: type = D3DDECLTYPE_FLOAT2; break; case ALLEGRO_PRIM_FLOAT_3: type = D3DDECLTYPE_FLOAT3; break; case ALLEGRO_PRIM_SHORT_2: type = D3DDECLTYPE_SHORT2; break; default: ASSERT(0); } d3delements[idx].Stream = 0; d3delements[idx].Offset = e->offset; d3delements[idx].Type = type; d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; d3delements[idx].Usage = D3DDECLUSAGE_POSITION; d3delements[idx].UsageIndex = 0; idx++; } e = &ret->elements[ALLEGRO_PRIM_TEX_COORD]; if(!e->attribute) e = &ret->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; if(e->attribute) { int type = 0; switch(e->storage) { case ALLEGRO_PRIM_FLOAT_2: type = D3DDECLTYPE_FLOAT2; break; case ALLEGRO_PRIM_SHORT_2: type = D3DDECLTYPE_SHORT2; break; default: ASSERT(0); } d3delements[idx].Stream = 0; d3delements[idx].Offset = e->offset; d3delements[idx].Type = type; d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD; d3delements[idx].UsageIndex = 0; idx++; color_idx++; } e = &ret->elements[ALLEGRO_PRIM_COLOR_ATTR]; if(e->attribute) { d3delements[idx].Stream = 0; d3delements[idx].Offset = e->offset; d3delements[idx].Type = D3DDECLTYPE_FLOAT4; d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD; d3delements[idx].UsageIndex = color_idx; idx++; } d3delements[idx].Stream = 0xFF; d3delements[idx].Offset = 0; d3delements[idx].Type = D3DDECLTYPE_UNUSED; d3delements[idx].Method = 0; d3delements[idx].Usage = 0; d3delements[idx].UsageIndex = 0; IDirect3DDevice9_CreateVertexDeclaration(device, d3delements, (IDirect3DVertexDeclaration9**)&ret->d3d_decl); } _al_create_shader(device, ret); } #else (void)display; ret->d3d_decl = 0; #endif } allegro-5.0.10/addons/primitives/nshader.cpp0000644000175000001440000001674611361227350020217 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * This program is used to pre-compile some dummy shaders from * nshader.fx to be used in directx_shaders.c file. You will need * fxc.exe and vsa.exe to run this program, which can be found in * the April 2008 DirectX SDK (it has been removed in the newer SDK * versions). * * Usage: Just run this program, and copy the output (tables.h) * into the appropriate location in directx_shaders.c. * * Note, that this is not supposed to be compiled into the library. * Compile this manually if needed. * * By Michał Cichoń. * * See readme.txt for copyright information. */ # include # include # include # include # include # include # include # include # include using namespace std; typedef unsigned char byte_t; typedef vector byte_vector_t; struct technique_t { string name; string shader; byte_vector_t binary; }; typedef vector technique_vector_t; int compile(const string& source, const string& dest) { return system(("fxc /nologo /Tfx_2_0 /Op /O3 /Fc " + dest + " " + source + " > nul").c_str()); } int assemble(const string& source, const string& dest) { return system(("vsa /nologo /Fo " + dest + " " + source + " > nul").c_str()); } bool extract_shader(technique_t& technique, istream& stream) { technique.shader.clear(); bool inside = false; bool record = false; string line; while (!getline(stream, line).fail()) { if (!inside && !record) { string::size_type pos = line.find_first_of("asm"); if (pos == string::npos || line.compare(pos, 3, "asm") != 0) continue; // strip everything to including "asm" keyword line = line.substr(pos + 3); inside = true; } if (inside && !record) { string::size_type pos = line.find_first_of("{"); if (pos == string::npos) continue; record = true; continue; } if (inside && record) { string::size_type pos = line.find_first_of("}"); if (pos != string::npos) return true; string::size_type non_white = line.find_first_not_of(" "); if (non_white != string::npos) technique.shader += line.substr(non_white) + "\n"; else technique.shader += "\n"; } } return false; } int extract_techniques(technique_vector_t& techniques, const string& filename) { techniques.clear(); ifstream file(filename.c_str()); if (!file) return 0; technique_t technique; string line; while (!getline(file, line).fail()) { string::size_type pos = line.find_first_of("technique"); if (pos != 0 || line.compare(pos, 9, "technique") != 0) continue; technique.name = line.substr(10); if (technique.name.empty()) { cerr << " Unnamed technique. Skipping..." << endl; continue; } cout << " Found: " << technique.name << endl; if (!extract_shader(technique, file)) { cerr << " Failed! Skipping..." << endl; continue; } techniques.push_back(technique); } return (int)techniques.size(); } int assemble_technique(technique_t& technique) { const string source = "vshader.vs"; const string dest = "vshader.vso"; { ofstream file(source.c_str()); file << technique.shader; } int result = assemble(source, dest); if (result) return result; ifstream file(dest.c_str(), ios::in | ios::binary); if (!file) { _unlink(dest.c_str()); _unlink(source.c_str()); return 1; } file.seekg(0, ios::end); technique.binary.resize(file.tellg()); file.seekg(0, ios::beg); file.read((char*)&technique.binary.front(), technique.binary.size()); file.close(); _unlink(dest.c_str()); _unlink(source.c_str()); return 0; } int assemble_techniques(technique_vector_t& techniques) { int count = 0; technique_vector_t::iterator it, it_end = techniques.end(); for (it = techniques.begin(); it != it_end; ++it) { technique_t& technique = *it; cout << " Processing: " << technique.name << endl; int assembled = assemble_technique(technique); if (assembled) { cerr << " Failed." << endl; continue; } ++count; } return count; } char toupper2(char c) { return toupper(c); } int generate_table(ostream& output, technique_t& technique) { const int bytes_per_line = 16; string::size_type pos = 0; string name = technique.name, line; while ((pos = name.find_first_of('_', pos)) != string::npos) name[pos] = ' '; transform(name.begin(), name.end(), name.begin(), toupper2); output << "/*" << endl; output << " " << name << endl << endl; istringstream shader(technique.shader); while (!getline(shader, line).fail()) output << " " << line << endl; output << "*/" << endl; output << "static const uint8_t _al_vs_" << technique.name << "[] = {" << endl; for (size_t i = 0; i < technique.binary.size(); ++i) { if ((i % bytes_per_line) == 0) output << " "; output << "0x" << setw(2) << setfill('0') << hex << (int)technique.binary[i]; if (i != technique.binary.size() - 1) { if ((i % bytes_per_line) == (bytes_per_line - 1)) output << "," << endl; else output << ", "; } } output << endl; output.unsetf(ios::hex); output << "};" << endl; return 0; } int generate_tables(ostream& output, technique_vector_t& techniques) { int count = 0; technique_vector_t::iterator it, it_end = techniques.end(); for (it = techniques.begin(); it != it_end; ++it) { technique_t& technique = *it; cout << " Processing: " << technique.name << endl; int generated = generate_table(output, technique); if (generated) { cerr << " Failed." << endl; continue; } output << endl; ++count; } return count; } int main() { const string source = "nshader.fx"; const string compiled = "nshader.fxc"; const string output = "tables.h"; cout << "Compiling NULL shader..." << endl; if (int result = compile(source, compiled)) { cout << " Failed!" << endl; return result; } cout << "Done." << endl << endl; cout << "Extracting techniques..." << endl; technique_vector_t techniques; int found = extract_techniques(techniques, compiled); if (found) cout << "Done. " << found << " technique(s) extracted." << endl << endl; else cout << "Done. No techniques extracted." << endl << endl; _unlink(compiled.c_str()); if (found == 0) return 0; cout << "Assembling techniques..." << endl; int assembled = assemble_techniques(techniques); if (assembled) cout << "Done. " << assembled << " technique(s) assembled." << endl << endl; else cout << "Done. No assembled techniques." << endl << endl; if (assembled == 0) return 0; cout << "Generating tables..." << endl; ofstream output_file(output.c_str()); int tables = generate_tables(output_file, techniques); cout << "Done. " << tables << " table(s) generated." << endl << endl; return 0; } allegro-5.0.10/addons/primitives/primitives.c0000644000175000001440000001377612132127543020426 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Core primitive addon functions. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_primitives.h" #include "allegro5/platform/alplatf.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/internal/aintern_prim_directx.h" #include "allegro5/internal/aintern_prim_opengl.h" #include "allegro5/internal/aintern_prim_soft.h" #include #ifdef ALLEGRO_CFG_OPENGL #include "allegro5/allegro_opengl.h" #endif #ifdef ALLEGRO_CFG_D3D #include "allegro5/allegro_direct3d.h" #endif #ifndef ALLEGRO_DIRECT3D #define ALLEGRO_DIRECT3D ALLEGRO_DIRECT3D_INTERNAL #endif ALLEGRO_DEBUG_CHANNEL("primitives") static bool addon_initialized = false; /* Function: al_init_primitives_addon */ bool al_init_primitives_addon(void) { bool ret = true; ret &= _al_init_d3d_driver(); addon_initialized = ret; _al_add_exit_func(al_shutdown_primitives_addon, "primitives_shutdown"); return ret; } /* Function: al_shutdown_primitives_addon */ void al_shutdown_primitives_addon(void) { _al_shutdown_d3d_driver(); addon_initialized = false; } /* Function: al_draw_prim */ int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, int start, int end, int type) { ALLEGRO_BITMAP *target; int ret = 0; ASSERT(addon_initialized); ASSERT(vtxs); ASSERT(end >= start); ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); target = al_get_target_bitmap(); /* In theory, if we ever get a camera concept for this addon, the transformation into * view space should occur here */ if (target->flags & ALLEGRO_MEMORY_BITMAP || (texture && texture->flags & ALLEGRO_MEMORY_BITMAP)) { ret = _al_draw_prim_soft(texture, vtxs, decl, start, end, type); } else { int flags = al_get_display_flags(target->display); if (flags & ALLEGRO_OPENGL) { ret = _al_draw_prim_opengl(target, texture, vtxs, decl, start, end, type); } else if (flags & ALLEGRO_DIRECT3D) { ret = _al_draw_prim_directx(target, texture, vtxs, decl, start, end, type); } } return ret; } /* Function: al_draw_indexed_prim */ int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type) { ALLEGRO_BITMAP *target; int ret = 0; ASSERT(addon_initialized); ASSERT(vtxs); ASSERT(indices); ASSERT(num_vtx > 0); ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); target = al_get_target_bitmap(); /* In theory, if we ever get a camera concept for this addon, the transformation into * view space should occur here */ if (target->flags & ALLEGRO_MEMORY_BITMAP || (texture && texture->flags & ALLEGRO_MEMORY_BITMAP)) { ret = _al_draw_prim_indexed_soft(texture, vtxs, decl, indices, num_vtx, type); } else { int flags = al_get_display_flags(target->display); if (flags & ALLEGRO_OPENGL) { ret = _al_draw_prim_indexed_opengl(target, texture, vtxs, decl, indices, num_vtx, type); } else if (flags & ALLEGRO_DIRECT3D) { ret = _al_draw_prim_indexed_directx(target, texture, vtxs, decl, indices, num_vtx, type); } } return ret; } int _al_bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int w, int h) { ASSERT(bmp); if (!al_is_bitmap_locked(bmp)) return 0; if (x1 + w > bmp->lock_x && y1 + h > bmp->lock_y && x1 < bmp->lock_x + bmp->lock_w && y1 < bmp->lock_y + bmp->lock_h) return 1; return 0; } /* Function: al_get_allegro_primitives_version */ uint32_t al_get_allegro_primitives_version(void) { return ALLEGRO_VERSION_INT; } /* Function: al_create_vertex_decl */ ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride) { ALLEGRO_VERTEX_DECL* ret; ALLEGRO_DISPLAY* display; ALLEGRO_VERTEX_ELEMENT* e; int flags; ASSERT(addon_initialized); ret = al_malloc(sizeof(ALLEGRO_VERTEX_DECL)); ret->elements = al_calloc(1, sizeof(ALLEGRO_VERTEX_ELEMENT) * ALLEGRO_PRIM_ATTR_NUM); while(elements->attribute) { ret->elements[elements->attribute] = *elements; elements++; } e = &ret->elements[ALLEGRO_PRIM_POSITION]; if (e->attribute) { if (e->storage != ALLEGRO_PRIM_FLOAT_2 && e->storage != ALLEGRO_PRIM_FLOAT_3 && e->storage != ALLEGRO_PRIM_SHORT_2) { ALLEGRO_WARN("Invalid storage for ALLEGRO_PRIM_POSITION.\n"); goto fail; } } e = &ret->elements[ALLEGRO_PRIM_TEX_COORD]; if(!e->attribute) e = &ret->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; if (e->attribute) { if (e->storage != ALLEGRO_PRIM_FLOAT_2 && e->storage != ALLEGRO_PRIM_SHORT_2) { ALLEGRO_WARN("Invalid storage for %s.\n", ret->elements[ALLEGRO_PRIM_TEX_COORD].attribute ? "ALLEGRO_PRIM_TEX_COORD" : "ALLEGRO_PRIM_TEX_COORD_PIXEL"); goto fail; } } display = al_get_current_display(); flags = al_get_display_flags(display); if (flags & ALLEGRO_DIRECT3D) { _al_set_d3d_decl(display, ret); } ret->stride = stride; return ret; fail: al_free(ret->elements); al_free(ret); return NULL; } /* Function: al_destroy_vertex_decl */ void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl) { al_free(decl->elements); /* * TODO: Somehow free the d3d_decl */ al_free(decl); } allegro-5.0.10/addons/primitives/prim_soft.c0000644000175000001440000004105411445373511020227 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Software implementation of some of the primitive routines. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/allegro_primitives.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_prim_soft.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/internal/aintern_tri_soft.h" #ifdef ALLEGRO_CFG_D3D #include "allegro5/allegro_direct3d.h" #endif /* The vertex cache allows for bulk transformation of vertices, for faster run speeds */ #define LOCAL_VERTEX_CACHE ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE] static void convert_vtx(ALLEGRO_BITMAP* texture, const char* src, ALLEGRO_VERTEX* dest, const ALLEGRO_VERTEX_DECL* decl) { ALLEGRO_VERTEX_ELEMENT* e; if(!decl) { *dest = *((ALLEGRO_VERTEX*)src); return; } e = &decl->elements[ALLEGRO_PRIM_POSITION]; if(e->attribute) { switch(e->storage) { case ALLEGRO_PRIM_FLOAT_2: case ALLEGRO_PRIM_FLOAT_3: { float *ptr = (float*)(src + e->offset); dest->x = *(ptr); dest->y = *(ptr + 1); break; } case ALLEGRO_PRIM_SHORT_2: { short *ptr = (short*)(src + e->offset); dest->x = (float)*(ptr); dest->y = (float)*(ptr + 1); break; } } } else { dest->x = 0; dest->y = 0; } e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; if(!e->attribute) e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; if(e->attribute) { switch(e->storage) { case ALLEGRO_PRIM_FLOAT_2: case ALLEGRO_PRIM_FLOAT_3: { float *ptr = (float*)(src + e->offset); dest->u = *(ptr); dest->v = *(ptr + 1); break; } case ALLEGRO_PRIM_SHORT_2: { short *ptr = (short*)(src + e->offset); dest->u = (float)*(ptr); dest->v = (float)*(ptr + 1); break; } } if(texture && e->attribute == ALLEGRO_PRIM_TEX_COORD) { dest->u *= (float)al_get_bitmap_width(texture); dest->v *= (float)al_get_bitmap_height(texture); } } else { dest->u = 0; dest->v = 0; } e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; if(e->attribute) { dest->color = *(ALLEGRO_COLOR*)(src + e->offset); } else { dest->color = al_map_rgba_f(1,1,1,1); } } int _al_draw_prim_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) { LOCAL_VERTEX_CACHE; int num_primitives; int num_vtx; int use_cache; int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); const ALLEGRO_TRANSFORM* global_trans = al_get_current_transform(); num_primitives = 0; num_vtx = end - start; use_cache = num_vtx < ALLEGRO_VERTEX_CACHE_SIZE; if (texture) al_lock_bitmap(texture, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); if (use_cache) { int ii; int n = 0; const char* vtxptr = (const char*)vtxs + start * stride; for (ii = 0; ii < num_vtx; ii++) { convert_vtx(texture, vtxptr, &vertex_cache[ii], decl); al_transform_coordinates(global_trans, &vertex_cache[ii].x, &vertex_cache[ii].y); n++; vtxptr += stride; } } #define SET_VERTEX(v, idx) \ convert_vtx(texture, (const char*)vtxs + stride * (idx), &v, decl); \ al_transform_coordinates(global_trans, &v.x, &v.y); \ switch (type) { case ALLEGRO_PRIM_LINE_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx - 1; ii += 2) { _al_line_2d(texture, &vertex_cache[ii], &vertex_cache[ii + 1]); } } else { int ii; for (ii = start; ii < end - 1; ii += 2) { ALLEGRO_VERTEX v1, v2; SET_VERTEX(v1, ii); SET_VERTEX(v2, ii + 1); _al_line_2d(texture, &v1, &v2); } } num_primitives = num_vtx / 2; break; }; case ALLEGRO_PRIM_LINE_STRIP: { if (use_cache) { int ii; for (ii = 1; ii < num_vtx; ii++) { _al_line_2d(texture, &vertex_cache[ii - 1], &vertex_cache[ii]); } } else { int ii; int idx = 1; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(vtx[0], start); for (ii = start + 1; ii < end; ii++) { SET_VERTEX(vtx[idx], ii) _al_line_2d(texture, &vtx[0], &vtx[1]); idx = 1 - idx; } } num_primitives = num_vtx - 1; break; }; case ALLEGRO_PRIM_LINE_LOOP: { if (use_cache) { int ii; for (ii = 1; ii < num_vtx; ii++) { _al_line_2d(texture, &vertex_cache[ii - 1], &vertex_cache[ii]); } _al_line_2d(texture, &vertex_cache[num_vtx - 1], &vertex_cache[0]); } else { int ii; int idx = 1; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(vtx[0], start); for (ii = start + 1; ii < end; ii++) { SET_VERTEX(vtx[idx], ii) _al_line_2d(texture, &vtx[idx], &vtx[1 - idx]); idx = 1 - idx; } SET_VERTEX(vtx[idx], start) _al_line_2d(texture, &vtx[idx], &vtx[1 - idx]); } num_primitives = num_vtx; break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx - 2; ii += 3) { _al_triangle_2d(texture, &vertex_cache[ii], &vertex_cache[ii + 1], &vertex_cache[ii + 2]); } } else { int ii; for (ii = start; ii < end - 2; ii += 3) { ALLEGRO_VERTEX v1, v2, v3; SET_VERTEX(v1, ii); SET_VERTEX(v2, ii + 1); SET_VERTEX(v3, ii + 2); _al_triangle_2d(texture, &v1, &v2, &v3); } } num_primitives = num_vtx / 3; break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { if (use_cache) { int ii; for (ii = 2; ii < num_vtx; ii++) { _al_triangle_2d(texture, &vertex_cache[ii - 2], &vertex_cache[ii - 1], &vertex_cache[ii]); } } else { int ii; int idx = 2; ALLEGRO_VERTEX vtx[3]; SET_VERTEX(vtx[0], start); SET_VERTEX(vtx[1], start + 1); for (ii = start + 2; ii < end; ii++) { SET_VERTEX(vtx[idx], ii); _al_triangle_2d(texture, &vtx[0], &vtx[1], &vtx[2]); idx = (idx + 1) % 3; } } num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { if (use_cache) { int ii; for (ii = 1; ii < num_vtx; ii++) { _al_triangle_2d(texture, &vertex_cache[0], &vertex_cache[ii], &vertex_cache[ii - 1]); } } else { int ii; int idx = 1; ALLEGRO_VERTEX v0; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(v0, start); SET_VERTEX(vtx[0], start + 1); for (ii = start + 1; ii < end; ii++) { SET_VERTEX(vtx[idx], ii) _al_triangle_2d(texture, &v0, &vtx[0], &vtx[1]); idx = 1 - idx; } } num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_POINT_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx; ii++) { _al_point_2d(texture, &vertex_cache[ii]); } } else { int ii; for (ii = start; ii < end; ii++) { ALLEGRO_VERTEX v; SET_VERTEX(v, ii); _al_point_2d(texture, &v); } } num_primitives = num_vtx; break; }; } if(texture) al_unlock_bitmap(texture); return num_primitives; #undef SET_VERTEX } int _al_draw_prim_indexed_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) { LOCAL_VERTEX_CACHE; int num_primitives; int use_cache; int min_idx, max_idx; int ii; int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); const ALLEGRO_TRANSFORM* global_trans = al_get_current_transform(); num_primitives = 0; use_cache = 1; min_idx = indices[0]; max_idx = indices[0]; /* Determine the range we are dealing with */ for (ii = 1; ii < num_vtx; ii++) { int idx = indices[ii]; if (max_idx < idx) max_idx = idx; else if (min_idx > indices[ii]) min_idx = idx; } if (max_idx - min_idx >= ALLEGRO_VERTEX_CACHE_SIZE) { use_cache = 0; } if (texture) al_lock_bitmap(texture, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); if (use_cache) { int ii; for (ii = 0; ii < num_vtx; ii++) { int idx = indices[ii]; convert_vtx(texture, (const char*)vtxs + idx * stride, &vertex_cache[idx - min_idx], decl); al_transform_coordinates(global_trans, &vertex_cache[idx - min_idx].x, &vertex_cache[idx - min_idx].y); } } #define SET_VERTEX(v, idx) \ convert_vtx(texture, (const char*)vtxs + stride * (idx), &v, decl); \ al_transform_coordinates(global_trans, &v.x, &v.y); \ switch (type) { case ALLEGRO_PRIM_LINE_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx - 1; ii += 2) { int idx1 = indices[ii] - min_idx; int idx2 = indices[ii + 1] - min_idx; _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); } } else { int ii; for (ii = 0; ii < num_vtx - 1; ii += 2) { int idx1 = indices[ii]; int idx2 = indices[ii + 1]; ALLEGRO_VERTEX v1, v2; SET_VERTEX(v1, idx1); SET_VERTEX(v2, idx2); _al_line_2d(texture, &v1, &v2); } } num_primitives = num_vtx / 2; break; }; case ALLEGRO_PRIM_LINE_STRIP: { if (use_cache) { int ii; for (ii = 1; ii < num_vtx; ii++) { int idx1 = indices[ii - 1] - min_idx; int idx2 = indices[ii] - min_idx; _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); } } else { int ii; int idx = 1; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(vtx[0], indices[0]); for (ii = 1; ii < num_vtx; ii++) { SET_VERTEX(vtx[idx], indices[ii]) _al_line_2d(texture, &vtx[0], &vtx[1]); idx = 1 - idx; } } num_primitives = num_vtx - 1; break; }; case ALLEGRO_PRIM_LINE_LOOP: { if (use_cache) { int ii; int idx1, idx2; for (ii = 1; ii < num_vtx; ii++) { int idx1 = indices[ii - 1] - min_idx; int idx2 = indices[ii] - min_idx; _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); } idx1 = indices[0] - min_idx; idx2 = indices[num_vtx - 1] - min_idx; _al_line_2d(texture, &vertex_cache[idx2], &vertex_cache[idx1]); } else { int ii; int idx = 1; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(vtx[0], indices[0]); for (ii = 1; ii < num_vtx; ii++) { SET_VERTEX(vtx[idx], indices[ii]) _al_line_2d(texture, &vtx[0], &vtx[1]); idx = 1 - idx; } SET_VERTEX(vtx[idx], indices[0]) _al_line_2d(texture, &vtx[0], &vtx[1]); } num_primitives = num_vtx; break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx - 2; ii += 3) { int idx1 = indices[ii] - min_idx; int idx2 = indices[ii + 1] - min_idx; int idx3 = indices[ii + 2] - min_idx; _al_triangle_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2], &vertex_cache[idx3]); } } else { int ii; for (ii = 0; ii < num_vtx - 2; ii += 3) { int idx1 = indices[ii]; int idx2 = indices[ii + 1]; int idx3 = indices[ii + 2]; ALLEGRO_VERTEX v1, v2, v3; SET_VERTEX(v1, idx1); SET_VERTEX(v2, idx2); SET_VERTEX(v3, idx3); _al_triangle_2d(texture, &v1, &v2, &v3); } } num_primitives = num_vtx / 3; break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { if (use_cache) { int ii; for (ii = 2; ii < num_vtx; ii++) { int idx1 = indices[ii - 2] - min_idx; int idx2 = indices[ii - 1] - min_idx; int idx3 = indices[ii] - min_idx; _al_triangle_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2], &vertex_cache[idx3]); } } else { int ii; int idx = 2; ALLEGRO_VERTEX vtx[3]; SET_VERTEX(vtx[0], indices[0]); SET_VERTEX(vtx[1], indices[1]); for (ii = 2; ii < num_vtx; ii ++) { SET_VERTEX(vtx[idx], indices[ii]); _al_triangle_2d(texture, &vtx[0], &vtx[1], &vtx[2]); idx = (idx + 1) % 3; } } num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { if (use_cache) { int ii; int idx0 = indices[0] - min_idx; for (ii = 1; ii < num_vtx; ii++) { int idx1 = indices[ii] - min_idx; int idx2 = indices[ii - 1] - min_idx; _al_triangle_2d(texture, &vertex_cache[idx0], &vertex_cache[idx1], &vertex_cache[idx2]); } } else { int ii; int idx = 1; ALLEGRO_VERTEX v0; ALLEGRO_VERTEX vtx[2]; SET_VERTEX(v0, indices[0]); SET_VERTEX(vtx[0], indices[1]); for (ii = 2; ii < num_vtx; ii ++) { SET_VERTEX(vtx[idx], indices[ii]) _al_triangle_2d(texture, &v0, &vtx[0], &vtx[1]); idx = 1 - idx; } } num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_POINT_LIST: { if (use_cache) { int ii; for (ii = 0; ii < num_vtx; ii++) { int idx = indices[ii] - min_idx; _al_point_2d(texture, &vertex_cache[idx]); } } else { int ii; for (ii = 0; ii < num_vtx; ii++) { ALLEGRO_VERTEX v; SET_VERTEX(v, indices[ii]); _al_point_2d(texture, &v); } } num_primitives = num_vtx; break; }; } if(texture) al_unlock_bitmap(texture); return num_primitives; #undef SET_VERTEX } /* Function: al_draw_soft_triangle */ void al_draw_soft_triangle( ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*first)(uintptr_t, int, int, int, int), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int, int)) { _al_draw_soft_triangle(v1, v2, v3, state, init, first, step, draw); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/primitives/prim_opengl.c0000644000175000001440000002430412146021714020531 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * OpenGL implementation of some of the primitive routines. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_primitives.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern_prim_opengl.h" #include "allegro5/internal/aintern_prim_soft.h" #include "allegro5/platform/alplatf.h" #include "allegro5/internal/aintern_prim.h" #ifdef ALLEGRO_CFG_OPENGL #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern_opengl.h" static void convert_storage(ALLEGRO_PRIM_STORAGE storage, GLenum* type, int* ncoord, bool* normalized) { switch(storage) { case ALLEGRO_PRIM_FLOAT_2: *type = GL_FLOAT; *ncoord = 2; *normalized = false; break; case ALLEGRO_PRIM_FLOAT_3: *type = GL_FLOAT; *ncoord = 3; *normalized = false; break; case ALLEGRO_PRIM_SHORT_2: *type = GL_SHORT; *ncoord = 2; *normalized = false; break; default: ASSERT(0); } } static void setup_state(const char* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture) { if(decl) { ALLEGRO_VERTEX_ELEMENT* e; e = &decl->elements[ALLEGRO_PRIM_POSITION]; if(e->attribute) { int ncoord = 0; GLenum type = 0; bool normalized; glEnableClientState(GL_VERTEX_ARRAY); convert_storage(e->storage, &type, &ncoord, &normalized); glVertexPointer(ncoord, type, decl->stride, vtxs + e->offset); } else { glDisableClientState(GL_VERTEX_ARRAY); } e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; if(!e->attribute) e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; if(texture && e->attribute) { int ncoord = 0; GLenum type = 0; bool normalized; glEnableClientState(GL_TEXTURE_COORD_ARRAY); convert_storage(e->storage, &type, &ncoord, &normalized); glTexCoordPointer(ncoord, type, decl->stride, vtxs + e->offset); } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; if(e->attribute) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, decl->stride, vtxs + e->offset); } else { glDisableClientState(GL_COLOR_ARRAY); glColor4f(1, 1, 1, 1); } } else { const ALLEGRO_VERTEX* vtx = (const ALLEGRO_VERTEX*)vtxs; glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(ALLEGRO_VERTEX), &vtx[0].x); glColorPointer(4, GL_FLOAT, sizeof(ALLEGRO_VERTEX), &vtx[0].color.r); glTexCoordPointer(2, GL_FLOAT, sizeof(ALLEGRO_VERTEX), &vtx[0].u); } if (texture) { GLuint gl_texture = al_get_opengl_texture(texture); int true_w, true_h; int tex_x, tex_y; GLuint current_texture; float mat[4][4] = { {1, 0, 0, 0}, {0, -1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} }; int height; if (texture->parent) height = texture->parent->h; else height = texture->h; al_get_opengl_texture_size(texture, &true_w, &true_h); al_get_opengl_texture_position(texture, &tex_x, &tex_y); mat[3][0] = (float)tex_x / true_w; mat[3][1] = (float)(height - tex_y) / true_h; if(decl) { if(decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL].attribute) { mat[0][0] = 1.0f / true_w; mat[1][1] = -1.0f / true_h; } else { mat[0][0] = (float)al_get_bitmap_width(texture) / true_w; mat[1][1] = -(float)al_get_bitmap_height(texture) / true_h; } } else { mat[0][0] = 1.0f / true_w; mat[1][1] = -1.0f / true_h; } glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)¤t_texture); if (current_texture != gl_texture) { glBindTexture(GL_TEXTURE_2D, gl_texture); } glMatrixMode(GL_TEXTURE); glLoadMatrixf(mat[0]); glMatrixMode(GL_MODELVIEW); } else { glBindTexture(GL_TEXTURE_2D, 0); } } #endif /* ALLEGRO_CFG_OPENGL */ int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) { #ifdef ALLEGRO_CFG_OPENGL int num_primitives = 0; ALLEGRO_DISPLAY *ogl_disp = target->display; ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target; const void* vtx; int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); int num_vtx; if (target->parent) { ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent; } if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || al_is_bitmap_locked(target)) { return _al_draw_prim_soft(texture, vtxs, decl, start, end, type); } vtx = (const char*)vtxs + start * stride; num_vtx = end - start; _al_opengl_set_blender(ogl_disp); setup_state(vtx, decl, texture); if(texture) { glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } switch (type) { case ALLEGRO_PRIM_LINE_LIST: { glDrawArrays(GL_LINES, 0, num_vtx); num_primitives = num_vtx / 2; break; }; case ALLEGRO_PRIM_LINE_STRIP: { glDrawArrays(GL_LINE_STRIP, 0, num_vtx); num_primitives = num_vtx - 1; break; }; case ALLEGRO_PRIM_LINE_LOOP: { glDrawArrays(GL_LINE_LOOP, 0, num_vtx); num_primitives = num_vtx; break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { glDrawArrays(GL_TRIANGLES, 0, num_vtx); num_primitives = num_vtx / 3; break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { glDrawArrays(GL_TRIANGLE_STRIP, 0, num_vtx); num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { glDrawArrays(GL_TRIANGLE_FAN, 0, num_vtx); num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_POINT_LIST: { glDrawArrays(GL_POINTS, 0, num_vtx); num_primitives = num_vtx; break; }; } if(texture) { glDisable(GL_TEXTURE_2D); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); return num_primitives; #else (void)target; (void)texture; (void)vtxs; (void)decl; (void)start; (void)end; (void)type; return 0; #endif } int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) { #ifdef ALLEGRO_CFG_OPENGL int num_primitives = 0; ALLEGRO_DISPLAY *ogl_disp = target->display; ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target; const void* vtx; const void* idx = indices; GLenum idx_size; #if defined ALLEGRO_GP2XWIZ || defined ALLEGRO_IPHONE GLushort ind[num_vtx]; int ii; #endif if (target->parent) { ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent; } if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || al_is_bitmap_locked(target)) { return _al_draw_prim_indexed_soft(texture, decl, vtxs, indices, num_vtx, type); } vtx = vtxs; _al_opengl_set_blender(ogl_disp); setup_state(vtx, decl, texture); if(texture) { glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } #if defined ALLEGRO_GP2XWIZ || defined ALLEGRO_IPHONE for (ii = 0; ii < num_vtx; ii++) { ind[ii] = (GLushort)indices[ii]; } idx = ind; idx_size = GL_UNSIGNED_SHORT; #else idx_size = GL_UNSIGNED_INT; #endif switch (type) { case ALLEGRO_PRIM_LINE_LIST: { glDrawElements(GL_LINES, num_vtx, idx_size, idx); num_primitives = num_vtx / 2; break; }; case ALLEGRO_PRIM_LINE_STRIP: { glDrawElements(GL_LINE_STRIP, num_vtx, idx_size, idx); num_primitives = num_vtx - 1; break; }; case ALLEGRO_PRIM_LINE_LOOP: { glDrawElements(GL_LINE_LOOP, num_vtx, idx_size, idx); num_primitives = num_vtx; break; }; case ALLEGRO_PRIM_TRIANGLE_LIST: { glDrawElements(GL_TRIANGLES, num_vtx, idx_size, idx); num_primitives = num_vtx / 3; break; }; case ALLEGRO_PRIM_TRIANGLE_STRIP: { glDrawElements(GL_TRIANGLE_STRIP, num_vtx, idx_size, idx); num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_TRIANGLE_FAN: { glDrawElements(GL_TRIANGLE_FAN, num_vtx, idx_size, idx); num_primitives = num_vtx - 2; break; }; case ALLEGRO_PRIM_POINT_LIST: { glDrawElements(GL_POINTS, num_vtx, idx_size, idx); num_primitives = num_vtx; break; }; } if(texture) { glDisable(GL_TEXTURE_2D); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); return num_primitives; #else (void)target; (void)texture; (void)vtxs; (void)decl; (void)indices; (void)num_vtx; (void)type; return 0; #endif } allegro-5.0.10/addons/primitives/allegro5/0000755000175000001440000000000012157230736017571 5ustar tjadenusersallegro-5.0.10/addons/primitives/allegro5/allegro_primitives.h0000644000175000001440000001474011771523426023652 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_primitives_h #define __al_included_allegro5_allegro_primitives_h #include #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_PRIMITIVES_SRC #define _ALLEGRO_PRIM_DLL __declspec(dllexport) #else #define _ALLEGRO_PRIM_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_PRIM_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_PRIM_FUNC(type, name, args) _ALLEGRO_PRIM_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_PRIM_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_PRIM_FUNC(type, name, args) extern _ALLEGRO_PRIM_DLL type name args #else #define ALLEGRO_PRIM_FUNC AL_FUNC #endif #ifdef __cplusplus extern "C" { #endif /* Enum: ALLEGRO_PRIM_TYPE */ typedef enum ALLEGRO_PRIM_TYPE { ALLEGRO_PRIM_LINE_LIST, ALLEGRO_PRIM_LINE_STRIP, ALLEGRO_PRIM_LINE_LOOP, ALLEGRO_PRIM_TRIANGLE_LIST, ALLEGRO_PRIM_TRIANGLE_STRIP, ALLEGRO_PRIM_TRIANGLE_FAN, ALLEGRO_PRIM_POINT_LIST, ALLEGRO_PRIM_NUM_TYPES } ALLEGRO_PRIM_TYPE; /* Enum: ALLEGRO_PRIM_ATTR */ typedef enum ALLEGRO_PRIM_ATTR { ALLEGRO_PRIM_POSITION = 1, ALLEGRO_PRIM_COLOR_ATTR, ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_ATTR_NUM } ALLEGRO_PRIM_ATTR; /* Enum: ALLEGRO_PRIM_STORAGE */ typedef enum ALLEGRO_PRIM_STORAGE { ALLEGRO_PRIM_FLOAT_2, ALLEGRO_PRIM_FLOAT_3, ALLEGRO_PRIM_SHORT_2 } ALLEGRO_PRIM_STORAGE; /* Enum: ALLEGRO_VERTEX_CACHE_SIZE */ #define ALLEGRO_VERTEX_CACHE_SIZE 256 /* Enum: ALLEGRO_PRIM_QUALITY */ #define ALLEGRO_PRIM_QUALITY 10 /* Type: ALLEGRO_VERTEX_ELEMENT */ typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT; struct ALLEGRO_VERTEX_ELEMENT { int attribute; int storage; int offset; }; /* Type: ALLEGRO_VERTEX_DECL */ typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL; /* Duplicated in allegro5/internal/aintern_tri_soft.h */ #ifndef _ALLEGRO_VERTEX_DEFINED #define _ALLEGRO_VERTEX_DEFINED /* Type: ALLEGRO_VERTEX */ typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; struct ALLEGRO_VERTEX { float x, y, z; float u, v; ALLEGRO_COLOR color; }; #endif ALLEGRO_PRIM_FUNC(uint32_t, al_get_allegro_primitives_version, (void)); /* * Primary Functions */ ALLEGRO_PRIM_FUNC(bool, al_init_primitives_addon, (void)); ALLEGRO_PRIM_FUNC(void, al_shutdown_primitives_addon, (void)); ALLEGRO_PRIM_FUNC(int, al_draw_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, int start, int end, int type)); ALLEGRO_PRIM_FUNC(int, al_draw_indexed_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)); ALLEGRO_PRIM_FUNC(ALLEGRO_VERTEX_DECL*, al_create_vertex_decl, (const ALLEGRO_VERTEX_ELEMENT* elements, int stride)); ALLEGRO_PRIM_FUNC(void, al_destroy_vertex_decl, (ALLEGRO_VERTEX_DECL* decl)); /* * Custom primitives */ ALLEGRO_PRIM_FUNC(void, al_draw_soft_triangle, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*first)(uintptr_t, int, int, int, int), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int, int))); ALLEGRO_PRIM_FUNC(void, al_draw_soft_line, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int))); /* *High level primitives */ ALLEGRO_PRIM_FUNC(void, al_draw_line, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_calculate_arc, (float* dest, int stride, float cx, float cy, float rx, float ry, float start_theta, float delta_theta, float thickness, int num_segments)); ALLEGRO_PRIM_FUNC(void, al_draw_circle, (float cx, float cy, float r, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_arc, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_elliptical_arc, (float cx, float cy, float rx, float ry, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_draw_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_calculate_spline, (float* dest, int stride, float points[8], float thickness, int num_segments)); ALLEGRO_PRIM_FUNC(void, al_draw_spline, (float points[8], ALLEGRO_COLOR color, float thickness)); ALLEGRO_PRIM_FUNC(void, al_calculate_ribbon, (float* dest, int dest_stride, const float *points, int points_stride, float thickness, int num_segments)); ALLEGRO_PRIM_FUNC(void, al_draw_ribbon, (const float *points, int points_stride, ALLEGRO_COLOR color, float thickness, int num_segments)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_circle, (float cx, float cy, float r, ALLEGRO_COLOR color)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color)); ALLEGRO_PRIM_FUNC(void, al_draw_filled_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/primitives/allegro5/internal/0000755000175000001440000000000012157230736021405 5ustar tjadenusersallegro-5.0.10/addons/primitives/allegro5/internal/aintern_prim.h0000644000175000001440000000047611426530515024250 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_prim_h #define __al_included_allegro5_aintern_prim_h int _al_bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int x2, int y2); struct ALLEGRO_VERTEX_DECL { ALLEGRO_VERTEX_ELEMENT* elements; int stride; void* d3d_decl; void* d3d_dummy_shader; }; #endif allegro-5.0.10/addons/primitives/allegro5/internal/aintern_prim_opengl.h0000644000175000001440000000075711426530515025616 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_prim_opengl_h #define __al_included_allegro5_aintern_prim_opengl_h struct ALLEGRO_BITMAP; struct ALLEGRO_VERTEX; int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); #endif allegro-5.0.10/addons/primitives/allegro5/internal/aintern_prim_soft.h0000644000175000001440000000111211445373511025271 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_prim_soft_h #define __al_included_allegro5_aintern_prim_soft_h struct ALLEGRO_BITMAP; struct ALLEGRO_VERTEX; int _al_draw_prim_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); int _al_draw_prim_indexed_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); void _al_line_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2); void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v); #endif allegro-5.0.10/addons/primitives/allegro5/internal/aintern_prim_directx.h0000644000175000001440000000163611426530515025771 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_prim_directx_h #define __al_included_allegro5_aintern_prim_directx_h struct ALLEGRO_BITMAP; struct ALLEGRO_VERTEX; int _al_draw_prim_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); int _al_draw_prim_indexed_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); void _al_set_d3d_decl(ALLEGRO_DISPLAY* display, ALLEGRO_VERTEX_DECL* ret); bool _al_init_d3d_driver(void); void _al_shutdown_d3d_driver(void); void* _al_create_default_shader(void* dev); void _al_setup_default_shader(void* dev, void* shader); void _al_setup_shader(void* dev, const ALLEGRO_VERTEX_DECL* decl); void _al_create_shader(void* dev, ALLEGRO_VERTEX_DECL* decl); void _al_set_texture_matrix(void* dev, float* mat); #endif allegro-5.0.10/addons/primitives/line_soft.c0000644000175000001440000004656612101033341020204 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Software line implementation functions. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #define _AL_NO_BLEND_INLINE_FUNC #include "allegro5/allegro.h" #include "allegro5/allegro_primitives.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_prim.h" #include "allegro5/internal/aintern_prim_soft.h" #include /* Nomenclature shader_{texture}_{grad,solid}_{any,rgb888,rgba8888,etc}_{draw_{shade,opaque},step,first} */ typedef void (*shader_draw)(uintptr_t, int, int); typedef void (*shader_first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*); typedef void (*shader_step)(uintptr_t, int); typedef struct { ALLEGRO_COLOR color; } state_solid_any_2d; static void shader_solid_any_draw_shade(uintptr_t state, int x, int y) { state_solid_any_2d* s = (state_solid_any_2d*)state; al_put_blended_pixel(x, y, s->color); } static void shader_solid_any_draw_opaque(uintptr_t state, int x, int y) { state_solid_any_2d* s = (state_solid_any_2d*)state; al_put_pixel(x, y, s->color); } static void shader_solid_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) { state_solid_any_2d* s = (state_solid_any_2d*)state; s->color = v1->color; (void)start_x; (void)start_y; (void)v2; } static void shader_solid_any_step(uintptr_t state, int minor_step) { (void)state; (void)minor_step; } /*----------------------------------------------------*/ typedef struct { state_solid_any_2d solid; ALLEGRO_COLOR minor_color; ALLEGRO_COLOR major_color; } state_grad_any_2d; static void get_interpolation_parameters(int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, float* param, float* minor_delta_param, float* major_delta_param) { float dx = v2->x - v1->x; float dy = v2->y - v1->y; float lensq = dx * dx + dy * dy; if (lensq == 0) { lensq = 0.0001f; *param = 0; } else { *param = ((float)start_x - v1->x) * dx + ((float)start_y - v1->y) * dy; *param /= lensq; } dx = fabsf(dx); dy = fabsf(dy); if (dx > dy) *minor_delta_param = dx / lensq; else *minor_delta_param = dy / lensq; *major_delta_param = (dx + dy) / lensq; } static void shader_grad_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) { float param; float minor_delta_param; float major_delta_param; state_grad_any_2d* st = (state_grad_any_2d*)state; ALLEGRO_COLOR diff, v1c, v2c; v1c = v1->color; v2c = v2->color; get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); diff.a = v2c.a - v1c.a; diff.r = v2c.r - v1c.r; diff.g = v2c.g - v1c.g; diff.b = v2c.b - v1c.b; st->solid.color.a = v1c.a + diff.a * param; st->solid.color.r = v1c.r + diff.r * param; st->solid.color.g = v1c.g + diff.g * param; st->solid.color.b = v1c.b + diff.b * param; st->minor_color.a = diff.a * minor_delta_param; st->minor_color.r = diff.r * minor_delta_param; st->minor_color.g = diff.g * minor_delta_param; st->minor_color.b = diff.b * minor_delta_param; st->major_color.a = diff.a * major_delta_param; st->major_color.r = diff.r * major_delta_param; st->major_color.g = diff.g * major_delta_param; st->major_color.b = diff.b * major_delta_param; } static void shader_grad_any_step(uintptr_t state, int minor_step) { state_grad_any_2d* s = (state_grad_any_2d*)state; if (minor_step) { s->solid.color.a += s->minor_color.a; s->solid.color.r += s->minor_color.r; s->solid.color.g += s->minor_color.g; s->solid.color.b += s->minor_color.b; } else { s->solid.color.a += s->major_color.a; s->solid.color.r += s->major_color.r; s->solid.color.g += s->major_color.g; s->solid.color.b += s->major_color.b; } } /*===================== Texture Shaders =======================*/ static int fix_var(float var, int max_var) { const int ivar = (int)floorf(var); const int ret = ivar % max_var; if(ret >= 0) return ret; else return ret + max_var; } #define SHADE_COLORS(A, B) \ A.r = B.r * A.r; \ A.g = B.g * A.g; \ A.b = B.b * A.b; \ A.a = B.a * A.a; #define FIX_UV const int u = fix_var(s->u, s->w); const int v = fix_var(s->v, s->h); typedef struct { ALLEGRO_COLOR color; ALLEGRO_BITMAP* texture; int w, h; float u, v; float minor_du; float minor_dv; float major_du; float major_dv; } state_texture_solid_any_2d; static void shader_texture_solid_any_draw_shade(uintptr_t state, int x, int y) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; FIX_UV ALLEGRO_COLOR color = al_get_pixel(s->texture, u, v); SHADE_COLORS(color, s->color) al_put_blended_pixel(x, y, color); } static void shader_texture_solid_any_draw_shade_white(uintptr_t state, int x, int y) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; FIX_UV al_put_blended_pixel(x, y, al_get_pixel(s->texture, u, v)); } static void shader_texture_solid_any_draw_opaque(uintptr_t state, int x, int y) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; FIX_UV ALLEGRO_COLOR color = al_get_pixel(s->texture, u, v); SHADE_COLORS(color, s->color) al_put_pixel(x, y, color); } static void shader_texture_solid_any_draw_opaque_white(uintptr_t state, int x, int y) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; FIX_UV al_put_pixel(x, y, al_get_pixel(s->texture, u, v)); } static void shader_texture_solid_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) { float param; float minor_delta_param; float major_delta_param; state_texture_solid_any_2d* st = (state_texture_solid_any_2d*)state; float du, dv; ALLEGRO_COLOR v1c; v1c = v1->color; get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); st->w = al_get_bitmap_width(st->texture); st->h = al_get_bitmap_height(st->texture); du = v2->u - v1->u; dv = v2->v - v1->v; st->color.r = v1c.r; st->color.g = v1c.g; st->color.b = v1c.b; st->color.a = v1c.a; st->u = v1->u + du * param; st->v = v1->v + dv * param; st->minor_du = du * minor_delta_param; st->minor_dv = dv * minor_delta_param; st->major_du = du * major_delta_param; st->major_dv = dv * major_delta_param; } static void shader_texture_solid_any_step(uintptr_t state, int minor_step) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; if (minor_step) { s->u += s->minor_du; s->v += s->minor_dv; } else { s->u += s->major_du; s->v += s->major_dv; } } /*----------------------------------------------------*/ typedef struct { state_texture_solid_any_2d solid; ALLEGRO_COLOR minor_color; ALLEGRO_COLOR major_color; } state_texture_grad_any_2d; static void shader_texture_grad_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) { float param; float minor_delta_param; float major_delta_param; state_texture_grad_any_2d* st = (state_texture_grad_any_2d*)state; float du, dv; ALLEGRO_COLOR diff, v1c, v2c; v1c = v1->color; v2c = v2->color; get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); st->solid.w = al_get_bitmap_width(st->solid.texture); st->solid.h = al_get_bitmap_height(st->solid.texture); du = v2->u - v1->u; dv = v2->v - v1->v; st->solid.color.r = v1c.r; st->solid.color.g = v1c.g; st->solid.color.b = v1c.b; st->solid.color.a = v1c.a; st->solid.u = v1->u + du * param; st->solid.v = v1->v + dv * param; st->solid.minor_du = du * minor_delta_param; st->solid.minor_dv = dv * minor_delta_param; st->solid.major_du = du * major_delta_param; st->solid.major_dv = dv * major_delta_param; diff.a = v2c.a - v1c.a; diff.r = v2c.r - v1c.r; diff.g = v2c.g - v1c.g; diff.b = v2c.b - v1c.b; st->solid.color.a = v1c.a + diff.a * param; st->solid.color.r = v1c.r + diff.r * param; st->solid.color.g = v1c.g + diff.g * param; st->solid.color.b = v1c.b + diff.b * param; st->minor_color.a = diff.a * minor_delta_param; st->minor_color.r = diff.r * minor_delta_param; st->minor_color.g = diff.g * minor_delta_param; st->minor_color.b = diff.b * minor_delta_param; st->major_color.a = diff.a * major_delta_param; st->major_color.r = diff.r * major_delta_param; st->major_color.g = diff.g * major_delta_param; st->major_color.b = diff.b * major_delta_param; } static void shader_texture_grad_any_step(uintptr_t state, int minor_step) { state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; shader_texture_solid_any_step(state, minor_step); if (minor_step) { s->solid.color.a += s->minor_color.a; s->solid.color.r += s->minor_color.r; s->solid.color.g += s->minor_color.g; s->solid.color.b += s->minor_color.b; } else { s->solid.color.a += s->major_color.a; s->solid.color.r += s->major_color.r; s->solid.color.g += s->major_color.g; s->solid.color.b += s->major_color.b; } } static void line_stepper(uintptr_t state, shader_first first, shader_step step, shader_draw draw, ALLEGRO_VERTEX* vtx1, ALLEGRO_VERTEX* vtx2) { float x1, y1, x2, y2; float dx, dy; int end_x, end_y; if (vtx2->y < vtx1->y) { ALLEGRO_VERTEX* t; t = vtx1; vtx1 = vtx2; vtx2 = t; } vtx1->x -= 0.5001f; vtx1->y -= 0.5001f; vtx2->x -= 0.5001f; vtx2->y -= 0.5001f; x1 = vtx1->x; y1 = vtx1->y; x2 = vtx2->x; y2 = vtx2->y; dx = x2 - x1; dy = y2 - y1; end_x = floorf(x2 + 0.5f); end_y = floorf(y2 + 0.5f); #define FIRST \ first(state, x, y, vtx1, vtx2); \ if((x2 - x1) * ((float)x - x1) + (y2 - y1) * ((float)y - y1) >= 0) \ draw(state, x, y); \ (void)minor; #define STEP \ step(state, minor); \ draw(state, x, y); #define LAST \ step(state, minor); \ if((x1 - x2) * ((float)x - x2) + (y1 - y2) * ((float)y - y2) > 0) \ draw(state, x, y); #define WORKER(var1, var2, comp, dvar1, dvar2, derr1, derr2, func) \ { \ int minor = 1; \ if(err comp) \ { \ var1 += dvar1; \ err += derr1; \ minor = 0; \ } \ \ func \ \ var2 += dvar2; \ err += derr2; \ } if (dx > 0) { if (dx > dy) { int x = floorf(x1 + 0.5f); int y = floorf(y1); float err = (y1 - (float)y) * dx - (x1 - (float)x) * dy; if (x < end_x) { WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, FIRST) } while (x < end_x) { WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, STEP) } if (x <= end_x) { WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, LAST) } } else { int x = floorf(x1); int y = floorf(y1 + 0.5f); float err = (x1 - (float)x) * dy - (y1 - (float)y) * dx; if (y < end_y) { WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, FIRST) } while (y < end_y) { WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, STEP) } if (y <= end_y) { WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, LAST) } } } else { if (-dx > dy) { int x = floorf(x1 + 0.5f); int y = floorf(y1); float err = (y1 - (float)y) * dx - (x1 - (float)x) * dy; if (x > end_x) { WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, FIRST) } while (x > end_x) { WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, STEP) } if (x >= end_x) { WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, LAST) } } else { int x = floorf(x1); int y = floorf(y1 + 0.5f); float err = (x1 - (float)x) * dy - (y1 - (float)y) * dx; /* This is the only correction that needs to be made in the opposite direction of dy (or dx) */ if (err > 0.5f * dy) { x += 1; err -= dy; } if (y < end_y) { WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, FIRST) } while (y < end_y) { WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, STEP) } if (y <= end_y) { WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, LAST) } } } #undef FIRST #undef LAST #undef STEP #undef WORKER } /* This one will check to see what exactly we need to draw... I.e. this will call all of the actual renderers and set the appropriate callbacks */ void _al_line_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) { int shade = 1; int grad = 1; int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR v1c, v2c; v1c = v1->color; v2c = v2->color; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { shade = 0; } if (v1c.r == v2c.r && v1c.g == v2c.g && v1c.b == v2c.b && v1c.a == v2c.a) { grad = 0; } if (texture) { if (grad) { state_texture_grad_any_2d state; state.solid.texture = texture; if (shade) { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_solid_any_draw_shade); } else { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_solid_any_draw_opaque); } } else { int white = 0; state_texture_solid_any_2d state; if (v1c.r == 1 && v1c.g == 1 && v1c.b == 1 && v1c.a == 1) { white = 1; } state.texture = texture; if (shade) { if(white) { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade_white); } else { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade); } } else { if(white) { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque_white); } else { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque); } } } } else { if (grad) { state_grad_any_2d state; if (shade) { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_grad_any_first, shader_grad_any_step, shader_solid_any_draw_shade); } else { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_grad_any_first, shader_grad_any_step, shader_solid_any_draw_opaque); } } else { state_solid_any_2d state; if (shade) { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_shade); } else { al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_opaque); } } } } /* Function: al_draw_soft_line */ void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int)) { /* Copy the vertices, because we need to alter them a bit before drawing. */ ALLEGRO_VERTEX vtx1 = *v1; ALLEGRO_VERTEX vtx2 = *v2; ALLEGRO_BITMAP *target = al_get_target_bitmap(); int need_unlock = 0; ALLEGRO_LOCKED_REGION *lr; int min_x, max_x, min_y, max_y; int clip_min_x, clip_min_y, clip_max_x, clip_max_y; al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); clip_max_x += clip_min_x; clip_max_y += clip_min_y; /* TODO: Need to clip them first, make a copy of the vertices first then */ /* Lock the region we are drawing to. We are choosing the minimum and maximum possible pixels touched from the formula (easily verified by following the above algorithm. */ if (vtx1.x >= vtx2.x) { max_x = (int)ceilf(vtx1.x) + 1; min_x = (int)floorf(vtx2.x) - 1; } else { max_x = (int)ceilf(vtx2.x) + 1; min_x = (int)floorf(vtx1.x) - 1; } if (vtx1.y >= vtx2.y) { max_y = (int)ceilf(vtx1.y) + 1; min_y = (int)floorf(vtx2.y) - 1; } else { max_y = (int)ceilf(vtx2.y) + 1; min_y = (int)floorf(vtx1.y) - 1; } /* TODO: This bit is temporary, the min max's will be guaranteed to be within the bitmap once clipping is implemented */ if (min_x >= clip_max_x || min_y >= clip_max_y) return; if (max_x >= clip_max_x) max_x = clip_max_x; if (max_y >= clip_max_y) max_y = clip_max_y; if (max_x < clip_min_x || max_y < clip_min_y) return; if (min_x < clip_min_x) min_x = clip_min_x; if (min_y < clip_min_y) min_y = clip_min_y; if (al_is_bitmap_locked(target)) { if (!_al_bitmap_region_is_locked(target, min_x, min_y, max_x - min_x, max_y - min_y)) return; } else { if (!(lr = al_lock_bitmap_region(target, min_x, min_y, max_x - min_x, max_y - min_y, ALLEGRO_PIXEL_FORMAT_ANY, 0))) return; need_unlock = 1; } line_stepper(state, first, step, draw, &vtx1, &vtx2); if (need_unlock) al_unlock_bitmap(target); } allegro-5.0.10/addons/primitives/high_primitives.c0000644000175000001440000012046512101033341021403 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Some high level routines, provided for user's convinience. * * * By Pavel Sountsov. * * * Bezier spline plotter By Seymour Shlien. * * Optimised version by Sven Sandberg. * * I'm not sure wether or not we still use the Castelau Algorithm * described in the book :o) * * Interactive Computer Graphics * by Peter Burger and Duncan Gillies * Addison-Wesley Publishing Co 1989 * ISBN 0-201-17439-1 * * The 4 th order Bezier curve is a cubic curve passing * through the first and fourth point. The curve does * not pass through the middle two points. They are merely * guide points which control the shape of the curve. The * curve is tangent to the lines joining points 1 and 2 * and points 3 and 4. * * See readme.txt for copyright information. */ #include "allegro5/allegro_primitives.h" #ifdef ALLEGRO_CFG_OPENGL #include "allegro5/allegro_opengl.h" #endif #include "allegro5/internal/aintern_bitmap.h" #include #ifdef ALLEGRO_MSVC #define hypotf(x, y) _hypotf((x), (y)) #endif #define LOCAL_VERTEX_CACHE ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE] /* * Make an estimate of the scale of the current transformation. */ static float get_scale(void) { const ALLEGRO_TRANSFORM* t = al_get_current_transform(); return (hypotf(t->m[0][0], t->m[0][1]) + hypotf(t->m[1][0], t->m[1][1])) / 2; } /* Function: al_draw_line */ void al_draw_line(float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness) { if (thickness > 0) { int ii; float tx, ty; float len = hypotf(x2 - x1, y2 - y1); ALLEGRO_VERTEX vtx[4]; if (len == 0) return; tx = 0.5f * thickness * (y2 - y1) / len; ty = 0.5f * thickness * -(x2 - x1) / len; vtx[0].x = x1 + tx; vtx[0].y = y1 + ty; vtx[1].x = x1 - tx; vtx[1].y = y1 - ty; vtx[2].x = x2 - tx; vtx[2].y = y2 - ty; vtx[3].x = x2 + tx; vtx[3].y = y2 + ty; for (ii = 0; ii < 4; ii++) { vtx[ii].color = color; vtx[ii].z = 0; } al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); } else { ALLEGRO_VERTEX vtx[2]; vtx[0].x = x1; vtx[0].y = y1; vtx[1].x = x2; vtx[1].y = y2; vtx[0].color = color; vtx[1].color = color; vtx[0].z = 0; vtx[1].z = 0; al_draw_prim(vtx, 0, 0, 0, 2, ALLEGRO_PRIM_LINE_LIST); } } /* Function: al_draw_triangle */ void al_draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color, float thickness) { if (thickness > 0) { int ii = 0; float side1, side2, side3; float perimeter, semi_perimeter; float outer_frac, inner_frac; float incenter_x, incenter_y; float incircle_rad; int idx = 0; ALLEGRO_VERTEX vtx[5]; float x[3] = {x1, x2, x3}; float y[3] = {y1, y2, y3}; ALLEGRO_VERTEX first_inner_vtx; ALLEGRO_VERTEX first_outer_vtx; ALLEGRO_VERTEX ini_vtx; float cross = (x[1] - x[0]) * (y[2] - y[0]) - (x[2] - x[0]) * (y[1] - y[0]); ini_vtx.x = ini_vtx.y = ini_vtx.z = ini_vtx.u = ini_vtx.v = 0; ini_vtx.color = color; first_inner_vtx = ini_vtx; first_outer_vtx = ini_vtx; /* * If the triangle is very flat, draw it as a line */ if(fabsf(cross) < 0.0001f) { float tx, ty, lx, ly; float len; /* * Find the obtuse vertex via two dot products */ float dot = (x[1] - x[0]) * (x[2] - x[0]) + (y[1] - y[0]) * (y[2] - y[0]); if(dot < 0) { x1 = x[1]; y1 = y[1]; x2 = x[2]; y2 = y[2]; } else { dot = (x[0] - x[1]) * (x[2] - x[1]) + (y[0] - y[1]) * (y[2] - y[1]); if(dot < 0) { x1 = x[0]; y1 = y[0]; x2 = x[2]; y2 = y[2]; } else { x1 = x[0]; y1 = y[0]; x2 = x[1]; y2 = y[1]; } } len = hypotf(x2 - x1, y2 - y1); if (len == 0) return; tx = 0.5f * thickness * (y2 - y1) / len; ty = 0.5f * thickness * -(x2 - x1) / len; lx = 0.5f * thickness * (x2 - x1) / len; ly = 0.5f * thickness * (y2 - y1) / len; vtx[0].x = x1 + tx - lx; vtx[0].y = y1 + ty - ly; vtx[1].x = x1 - tx - lx; vtx[1].y = y1 - ty - ly; vtx[2].x = x2 - tx + lx; vtx[2].y = y2 - ty + ly; vtx[3].x = x2 + tx + lx; vtx[3].y = y2 + ty + ly; for (ii = 0; ii < 4; ii++) { vtx[ii].color = color; vtx[ii].z = 0; } al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); return; } else if(cross > 0) { /* * Points need to be wound correctly for the algorithm to work */ float t; t = x[1]; x[1] = x[2]; x[2] = t; t = y[1]; y[1] = y[2]; y[2] = t; } side1 = hypotf(x[1] - x[0], y[1] - y[0]); side2 = hypotf(x[2] - x[0], y[2] - y[0]); side3 = hypotf(x[2] - x[1], y[2] - y[1]); perimeter = side1 + side2 + side3; semi_perimeter = perimeter / 2.0f; if (semi_perimeter < 0.00001f) return; incircle_rad = sqrtf((semi_perimeter - side1) * (semi_perimeter - side2) * (semi_perimeter - side3) / semi_perimeter); if (incircle_rad < 0.00001f) return; outer_frac = (incircle_rad + thickness / 2) / incircle_rad; inner_frac = (incircle_rad - thickness / 2) / incircle_rad; if(inner_frac < 0) inner_frac = 0; incenter_x = (side1 * x[2] + side2 * x[1] + side3 * x[0]) / perimeter; incenter_y = (side1 * y[2] + side2 * y[1] + side3 * y[0]) / perimeter; #define DRAW \ if(ii != 0) { \ vtx[idx++] = outer_vtx; \ vtx[idx++] = inner_vtx; \ \ al_draw_prim(vtx, 0, 0, 0, idx, ALLEGRO_PRIM_TRIANGLE_FAN); \ \ idx = 0; \ } /* * Iterate across the vertices, and draw each side of the triangle separately */ for(ii = 0; ii < 3; ii++) { float vert_x = x[ii] - incenter_x; float vert_y = y[ii] - incenter_y; float o_dx = vert_x * outer_frac; float o_dy = vert_y * outer_frac; float i_dx = vert_x * inner_frac; float i_dy = vert_y * inner_frac; float tdx = o_dx - i_dx; float tdy = o_dy - i_dy; ALLEGRO_VERTEX inner_vtx = ini_vtx; ALLEGRO_VERTEX outer_vtx = ini_vtx; if(tdx * tdx + tdy * tdy > 16 * thickness * thickness) { float x_pos = x[(ii + 1) % 3]; float y_pos = y[(ii + 1) % 3]; float x_neg = x[(ii + 2) % 3]; float y_neg = y[(ii + 2) % 3]; float x1_x2 = x[ii] - x_pos; float y1_y2 = y[ii] - y_pos; float x1_x3 = x[ii] - x_neg; float y1_y3 = y[ii] - y_neg; float mag_1_2 = hypotf(x1_x2, y1_y2); float mag_1_3 = hypotf(x1_x3, y1_y3); ALLEGRO_VERTEX next_vtx = ini_vtx; x1_x2 *= thickness / 2 / mag_1_2; y1_y2 *= thickness / 2 / mag_1_2; x1_x3 *= thickness / 2 / mag_1_3; y1_y3 *= thickness / 2 / mag_1_3; outer_vtx.x = x[ii] + x1_x3 - y1_y3; outer_vtx.y = y[ii] + y1_y3 + x1_x3; inner_vtx.x = incenter_x + i_dx; inner_vtx.y = incenter_y + i_dy; next_vtx.x = x[ii] + x1_x2 + y1_y2; next_vtx.y = y[ii] + y1_y2 - x1_x2; DRAW vtx[idx++] = inner_vtx; vtx[idx++] = outer_vtx; vtx[idx++] = next_vtx; } else { inner_vtx.x = incenter_x + i_dx; inner_vtx.y = incenter_y + i_dy; outer_vtx.x = incenter_x + o_dx; outer_vtx.y = incenter_y + o_dy; DRAW vtx[idx++] = inner_vtx; vtx[idx++] = outer_vtx; } if(ii == 0) { first_inner_vtx = inner_vtx; first_outer_vtx = outer_vtx; } } vtx[idx++] = first_outer_vtx; vtx[idx++] = first_inner_vtx; al_draw_prim(vtx, 0, 0, 0, idx, ALLEGRO_PRIM_TRIANGLE_FAN); #undef DRAW } else { ALLEGRO_VERTEX vtx[3]; vtx[0].x = x1; vtx[0].y = y1; vtx[1].x = x2; vtx[1].y = y2; vtx[2].x = x3; vtx[2].y = y3; vtx[0].color = color; vtx[1].color = color; vtx[2].color = color; vtx[0].z = 0; vtx[1].z = 0; vtx[2].z = 0; al_draw_prim(vtx, 0, 0, 0, 3, ALLEGRO_PRIM_LINE_LOOP); } } /* Function: al_draw_filled_triangle */ void al_draw_filled_triangle(float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color) { ALLEGRO_VERTEX vtx[3]; vtx[0].x = x1; vtx[0].y = y1; vtx[1].x = x2; vtx[1].y = y2; vtx[2].x = x3; vtx[2].y = y3; vtx[0].color = color; vtx[1].color = color; vtx[2].color = color; vtx[0].z = 0; vtx[1].z = 0; vtx[2].z = 0; al_draw_prim(vtx, 0, 0, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); } /* Function: al_draw_rectangle */ void al_draw_rectangle(float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness) { int ii; if (thickness > 0) { float t = thickness / 2; ALLEGRO_VERTEX vtx[10]; vtx[0].x = x1 - t; vtx[0].y = y1 - t; vtx[1].x = x1 + t; vtx[1].y = y1 + t; vtx[2].x = x2 + t; vtx[2].y = y1 - t; vtx[3].x = x2 - t; vtx[3].y = y1 + t; vtx[4].x = x2 + t; vtx[4].y = y2 + t; vtx[5].x = x2 - t; vtx[5].y = y2 - t; vtx[6].x = x1 - t; vtx[6].y = y2 + t; vtx[7].x = x1 + t; vtx[7].y = y2 - t; vtx[8].x = x1 - t; vtx[8].y = y1 - t; vtx[9].x = x1 + t; vtx[9].y = y1 + t; for (ii = 0; ii < 10; ii++) { vtx[ii].color = color; vtx[ii].z = 0; } al_draw_prim(vtx, 0, 0, 0, 10, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { ALLEGRO_VERTEX vtx[4]; vtx[0].x = x1; vtx[0].y = y1; vtx[1].x = x2; vtx[1].y = y1; vtx[2].x = x2; vtx[2].y = y2; vtx[3].x = x1; vtx[3].y = y2; for (ii = 0; ii < 4; ii++) { vtx[ii].color = color; vtx[ii].z = 0; } al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_LINE_LOOP); } } /* Function: al_draw_filled_rectangle */ void al_draw_filled_rectangle(float x1, float y1, float x2, float y2, ALLEGRO_COLOR color) { ALLEGRO_VERTEX vtx[4]; int ii; vtx[0].x = x1; vtx[0].y = y1; vtx[1].x = x1; vtx[1].y = y2; vtx[2].x = x2; vtx[2].y = y2; vtx[3].x = x2; vtx[3].y = y1; for (ii = 0; ii < 4; ii++) { vtx[ii].color = color; vtx[ii].z = 0; } al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); } /* Function: al_calculate_arc */ void al_calculate_arc(float* dest, int stride, float cx, float cy, float rx, float ry, float start_theta, float delta_theta, float thickness, int num_segments) { float theta; float c; float s; float x, y, t; int ii; ASSERT(dest); ASSERT(num_segments > 1); ASSERT(rx >= 0); ASSERT(ry >= 0); if (thickness > 0.0f) { theta = delta_theta / ((float)(num_segments) - 1); c = cosf(theta); s = sinf(theta); x = cosf(start_theta); y = sinf(start_theta); if (rx == ry) { /* The circle case is particularly simple */ float r1 = rx - thickness / 2.0f; float r2 = rx + thickness / 2.0f; for (ii = 0; ii < num_segments; ii ++) { *dest = r2 * x + cx; *(dest + 1) = r2 * y + cy; dest = (float*)(((char*)dest) + stride); *dest = r1 * x + cx; *(dest + 1) = r1 * y + cy; dest = (float*)(((char*)dest) + stride); t = x; x = c * x - s * y; y = s * t + c * y; } } else { if (rx != 0 && !ry == 0) { for (ii = 0; ii < num_segments; ii++) { float denom = hypotf(ry * x, rx * y); float nx = thickness / 2 * ry * x / denom; float ny = thickness / 2 * rx * y / denom; *dest = rx * x + cx + nx; *(dest + 1) = ry * y + cy + ny; dest = (float*)(((char*)dest) + stride); *dest = rx * x + cx - nx; *(dest + 1) = ry * y + cy - ny; dest = (float*)(((char*)dest) + stride); t = x; x = c * x - s * y; y = s * t + c * y; } } } } else { theta = delta_theta / ((float)num_segments - 1); c = cosf(theta); s = sinf(theta); x = cosf(start_theta); y = sinf(start_theta); for (ii = 0; ii < num_segments; ii++) { *dest = rx * x + cx; *(dest + 1) = ry * y + cy; dest = (float*)(((char*)dest) + stride); t = x; x = c * x - s * y; y = s * t + c * y; } } } /* Function: al_draw_pieslice */ void al_draw_pieslice(float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness) { LOCAL_VERTEX_CACHE; float scale = get_scale(); int num_segments, ii; ASSERT(r >= 0); /* Just makes things a bit easier */ if(delta_theta < 0) { delta_theta = -delta_theta; start_theta -= delta_theta; } if (thickness <= 0) { num_segments = fabsf(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf(r)); if (num_segments < 2) num_segments = 2; if (num_segments + 1 >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - 1; } al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments); vertex_cache[0].x = cx; vertex_cache[0].y = cy; for (ii = 0; ii < num_segments + 1; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_LINE_LOOP); } else { float ht = thickness / 2; float inner_side_angle = asinf(ht / (r - ht)); float outer_side_angle = asinf(ht / (r + ht)); float central_angle = delta_theta - 2 * inner_side_angle; bool inverted_winding = ((int)(delta_theta / ALLEGRO_PI)) % 2 == 1; float midangle = start_theta + (fmodf(delta_theta + ALLEGRO_PI, 2 * ALLEGRO_PI) - ALLEGRO_PI) / 2; float midpoint_dir_x = cosf(midangle); float midpoint_dir_y = sinf(midangle); float side_dir_x = cosf(start_theta); float side_dir_y = sinf(start_theta); float sine_half_delta = fabsf(side_dir_x * midpoint_dir_y - side_dir_y * midpoint_dir_x); /* Cross product */ float connect_len = ht / sine_half_delta; bool blunt_tip = connect_len > 2 * thickness; /* The angle is big enough for there to be a hole in the middle */ if (central_angle > 0) { float central_start_angle = start_theta + inner_side_angle; size_t vtx_id; int vtx_delta; /* Two inner hole vertices and the apex (2 vertices if the apex is blunt) */ int extra_vtx = blunt_tip ? 4 : 3; al_draw_arc(cx, cy, r, central_start_angle, central_angle, color, thickness); vertex_cache[0].x = cx + (r - thickness / 2) * cosf(central_start_angle); vertex_cache[0].y = cy + (r - thickness / 2) * sinf(central_start_angle); num_segments = (inner_side_angle + outer_side_angle) / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf(r + ht); if (num_segments < 2) num_segments = 2; if (num_segments + extra_vtx >= ALLEGRO_VERTEX_CACHE_SIZE) num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - extra_vtx; al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r + ht, r + ht, central_start_angle, -(outer_side_angle + inner_side_angle), 0, num_segments); /* Do the tip */ vtx_id = num_segments + 1 + (inverted_winding ? (1 + (blunt_tip ? 1 : 0)) : 0); vtx_delta = inverted_winding ? -1 : 1; if (blunt_tip) { float vx = ht * (side_dir_y * (inverted_winding ? -1 : 1) - side_dir_x); float vy = ht * (-side_dir_x * (inverted_winding ? -1 : 1) - side_dir_y); float dot = vx * midpoint_dir_x + vy * midpoint_dir_y; vertex_cache[vtx_id].x = cx + vx; vertex_cache[vtx_id].y = cy + vy; vtx_id += vtx_delta; vertex_cache[vtx_id].x = cx + dot * midpoint_dir_x; vertex_cache[vtx_id].y = cy + dot * midpoint_dir_y; } else { vertex_cache[vtx_id].x = cx - connect_len * midpoint_dir_x; vertex_cache[vtx_id].y = cy - connect_len * midpoint_dir_y; } vtx_id += vtx_delta; if(connect_len > r - ht) connect_len = r - ht; vertex_cache[vtx_id].x = cx + connect_len * midpoint_dir_x; vertex_cache[vtx_id].y = cy + connect_len * midpoint_dir_y; for (ii = 0; ii < num_segments + extra_vtx; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); /* Mirror the vertices and draw them again */ for (ii = 0; ii < num_segments + extra_vtx; ii++) { float dot = (vertex_cache[ii].x - cx) * midpoint_dir_x + (vertex_cache[ii].y - cy) * midpoint_dir_y; vertex_cache[ii].x = 2 * cx + 2 * dot * midpoint_dir_x - vertex_cache[ii].x; vertex_cache[ii].y = 2 * cy + 2 * dot * midpoint_dir_y - vertex_cache[ii].y; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); } else { /* Apex: 2 vertices if the apex is blunt) */ int extra_vtx = blunt_tip ? 2 : 1; num_segments = (2 * outer_side_angle) / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf(r + ht); if (num_segments < 2) num_segments = 2; if (num_segments + extra_vtx >= ALLEGRO_VERTEX_CACHE_SIZE) num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - extra_vtx; al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r + ht, r + ht, start_theta - outer_side_angle, 2 * outer_side_angle + delta_theta, 0, num_segments); if (blunt_tip) { float vx = ht * (side_dir_y - side_dir_x); float vy = ht * (-side_dir_x - side_dir_y); float dot = vx * midpoint_dir_x + vy * midpoint_dir_y; vertex_cache[0].x = cx + vx; vertex_cache[0].y = cy + vy; vx = 2 * dot * midpoint_dir_x - vx; vy = 2 * dot * midpoint_dir_y - vy; vertex_cache[num_segments + 1].x = cx + vx; vertex_cache[num_segments + 1].y = cy + vy; } else { vertex_cache[0].x = cx - connect_len * midpoint_dir_x; vertex_cache[0].y = cy - connect_len * midpoint_dir_y; } for (ii = 0; ii < num_segments + extra_vtx; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); } } } /* Function: al_draw_filled_pieslice */ void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color) { LOCAL_VERTEX_CACHE; float scale = get_scale(); int num_segments, ii; ASSERT(r >= 0); num_segments = fabsf(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf(r)); if (num_segments < 2) num_segments = 2; if (num_segments + 1 >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - 1; } al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments); vertex_cache[0].x = cx; vertex_cache[0].y = cy; for (ii = 0; ii < num_segments + 1; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN); } /* Function: al_draw_ellipse */ void al_draw_ellipse(float cx, float cy, float rx, float ry, ALLEGRO_COLOR color, float thickness) { LOCAL_VERTEX_CACHE; float scale = get_scale(); ASSERT(rx >= 0); ASSERT(ry >= 0); if (thickness > 0) { int num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f); int ii; /* In case rx and ry are both 0. */ if (num_segments < 2) return; if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, thickness, num_segments); for (ii = 0; ii < 2 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { int num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f); int ii; /* In case rx and ry are both 0. */ if (num_segments < 2) return; if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, 0, num_segments); for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments - 1, ALLEGRO_PRIM_LINE_LOOP); } } /* Function: al_draw_filled_ellipse */ void al_draw_filled_ellipse(float cx, float cy, float rx, float ry, ALLEGRO_COLOR color) { LOCAL_VERTEX_CACHE; int num_segments, ii; float scale = get_scale(); ASSERT(rx >= 0); ASSERT(ry >= 0); num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f); /* In case rx and ry are both close to 0. If al_calculate_arc is passed * 0 or 1 it will assert. */ if (num_segments < 2) return; if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; } al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, 0, num_segments); vertex_cache[0].x = cx; vertex_cache[0].y = cy; for (ii = 0; ii < num_segments + 1; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN); } /* Function: al_draw_circle */ void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color, float thickness) { al_draw_ellipse(cx, cy, r, r, color, thickness); } /* Function: al_draw_filled_circle */ void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color) { al_draw_filled_ellipse(cx, cy, r, r, color); } /* Function: al_draw_elliptical_arc */ void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness) { LOCAL_VERTEX_CACHE; float scale = get_scale(); ASSERT(rx >= 0 && ry >= 0); if (thickness > 0) { int num_segments = fabsf(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f)); int ii; if (num_segments < 2) num_segments = 2; if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, start_theta, delta_theta, thickness, num_segments); for (ii = 0; ii < 2 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { int num_segments = fabsf(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f)); int ii; if (num_segments < 2) num_segments = 2; if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, start_theta, delta_theta, 0, num_segments); for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); } } /* Function: al_draw_arc */ void al_draw_arc(float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness) { al_draw_elliptical_arc(cx, cy, r, r, start_theta, delta_theta, color, thickness); } /* Function: al_draw_rounded_rectangle */ void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color, float thickness) { LOCAL_VERTEX_CACHE; float scale = get_scale(); ASSERT(rx >= 0); ASSERT(ry >= 0); if (thickness > 0) { int num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f) / 4; int ii; /* In case rx and ry are both 0. */ if (num_segments < 2) { al_draw_rectangle(x1, y1, x2, y2, color, thickness); return; } if (8 * num_segments + 2 >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 3) / 8; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, thickness, num_segments); for (ii = 0; ii < 2 * num_segments; ii += 2) { vertex_cache[ii + 2 * num_segments + 1].x = x1 + rx - vertex_cache[2 * num_segments - 1 - ii].x; vertex_cache[ii + 2 * num_segments + 1].y = y1 + ry - vertex_cache[2 * num_segments - 1 - ii].y; vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[2 * num_segments - 1 - ii - 1].x; vertex_cache[ii + 2 * num_segments].y = y1 + ry - vertex_cache[2 * num_segments - 1 - ii - 1].y; vertex_cache[ii + 4 * num_segments].x = x1 + rx - vertex_cache[ii].x; vertex_cache[ii + 4 * num_segments].y = y2 - ry + vertex_cache[ii].y; vertex_cache[ii + 4 * num_segments + 1].x = x1 + rx - vertex_cache[ii + 1].x; vertex_cache[ii + 4 * num_segments + 1].y = y2 - ry + vertex_cache[ii + 1].y; vertex_cache[ii + 6 * num_segments + 1].x = x2 - rx + vertex_cache[2 * num_segments - 1 - ii].x; vertex_cache[ii + 6 * num_segments + 1].y = y2 - ry + vertex_cache[2 * num_segments - 1 - ii].y; vertex_cache[ii + 6 * num_segments].x = x2 - rx + vertex_cache[2 * num_segments - 1 - ii - 1].x; vertex_cache[ii + 6 * num_segments].y = y2 - ry + vertex_cache[2 * num_segments - 1 - ii - 1].y; } for (ii = 0; ii < 2 * num_segments; ii += 2) { vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; vertex_cache[ii + 1].x = x2 - rx + vertex_cache[ii + 1].x; vertex_cache[ii + 1].y = y1 + ry - vertex_cache[ii + 1].y; } vertex_cache[8 * num_segments] = vertex_cache[0]; vertex_cache[8 * num_segments + 1] = vertex_cache[1]; for (ii = 0; ii < 8 * num_segments + 2; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 8 * num_segments + 2, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { int num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f) / 4; int ii; /* In case rx and ry are both 0. */ if (num_segments < 2) { al_draw_rectangle(x1, y1, x2, y2, color, thickness); return; } if (num_segments * 4 >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 4; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, 0, num_segments + 1); for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii + 1 * num_segments].x = x1 + rx - vertex_cache[num_segments - 1 - ii].x; vertex_cache[ii + 1 * num_segments].y = y1 + ry - vertex_cache[num_segments - 1 - ii].y; vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[ii].x; vertex_cache[ii + 2 * num_segments].y = y2 - ry + vertex_cache[ii].y; vertex_cache[ii + 3 * num_segments].x = x2 - rx + vertex_cache[num_segments - 1 - ii].x; vertex_cache[ii + 3 * num_segments].y = y2 - ry + vertex_cache[num_segments - 1 - ii].y; } for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; } for (ii = 0; ii < 4 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 4 * num_segments, ALLEGRO_PRIM_LINE_LOOP); } } /* Function: al_draw_filled_rounded_rectangle */ void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color) { LOCAL_VERTEX_CACHE; int ii; float scale = get_scale(); int num_segments = ALLEGRO_PRIM_QUALITY * scale * sqrtf((rx + ry) / 2.0f) / 4; ASSERT(rx >= 0); ASSERT(ry >= 0); /* In case rx and ry are both 0. */ if (num_segments < 2) { al_draw_filled_rectangle(x1, y1, x2, y2, color); return; } if (num_segments * 4 >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 4; } al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, 0, num_segments + 1); for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii + 1 * num_segments].x = x1 + rx - vertex_cache[num_segments - 1 - ii].x; vertex_cache[ii + 1 * num_segments].y = y1 + ry - vertex_cache[num_segments - 1 - ii].y; vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[ii].x; vertex_cache[ii + 2 * num_segments].y = y2 - ry + vertex_cache[ii].y; vertex_cache[ii + 3 * num_segments].x = x2 - rx + vertex_cache[num_segments - 1 - ii].x; vertex_cache[ii + 3 * num_segments].y = y2 - ry + vertex_cache[num_segments - 1 - ii].y; } for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; } for (ii = 0; ii < 4 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } /* TODO: Doing this as a triangle fan just doesn't sound all that great, perhaps shuffle the vertices somehow to at least make it a strip */ al_draw_prim(vertex_cache, 0, 0, 0, 4 * num_segments, ALLEGRO_PRIM_TRIANGLE_FAN); } /* Function: al_calculate_spline */ void al_calculate_spline(float* dest, int stride, float points[8], float thickness, int num_segments) { /* Derivatives of x(t) and y(t). */ float x, dx, ddx, dddx; float y, dy, ddy, dddy; int ii = 0; /* Temp variables used in the setup. */ float dt, dt2, dt3; float xdt2_term, xdt3_term; float ydt2_term, ydt3_term; /* This is enough to avoid malloc in ex_prim, which I take as a reasonable * guess to what a common number of segments might be. To be honest, it * probably makes no difference. */ float cache_point_buffer_storage[150]; float* cache_point_buffer = cache_point_buffer_storage; ASSERT(num_segments > 1); ASSERT(points); if (num_segments > (int)(sizeof(cache_point_buffer_storage) / sizeof(float) / 2)) { cache_point_buffer = al_malloc(2 * sizeof(float) * num_segments); } dt = 1.0 / (num_segments - 1); dt2 = (dt * dt); dt3 = (dt2 * dt); /* x coordinates. */ xdt2_term = 3 * (points[4] - 2 * points[2] + points[0]); xdt3_term = points[6] + 3 * (-points[4] + points[2]) - points[0]; xdt2_term = dt2 * xdt2_term; xdt3_term = dt3 * xdt3_term; dddx = 6 * xdt3_term; ddx = -6 * xdt3_term + 2 * xdt2_term; dx = xdt3_term - xdt2_term + 3 * dt * (points[2] - points[0]); x = points[0]; /* y coordinates. */ ydt2_term = 3 * (points[5] - 2 * points[3] + points[1]); ydt3_term = points[7] + 3 * (-points[5] + points[3]) - points[1]; ydt2_term = dt2 * ydt2_term; ydt3_term = dt3 * ydt3_term; dddy = 6 * ydt3_term; ddy = -6 * ydt3_term + 2 * ydt2_term; dy = ydt3_term - ydt2_term + dt * 3 * (points[3] - points[1]); y = points[1]; cache_point_buffer[2 * ii] = x; cache_point_buffer[2 * ii + 1] = y; for (ii = 1; ii < num_segments; ii++) { ddx += dddx; dx += ddx; x += dx; ddy += dddy; dy += ddy; y += dy; cache_point_buffer[2 * ii] = x; cache_point_buffer[2 * ii + 1] = y; } al_calculate_ribbon(dest, stride, cache_point_buffer, 2 * sizeof(float), thickness, num_segments); if (cache_point_buffer != cache_point_buffer_storage) { al_free(cache_point_buffer); } } /* Function: al_draw_spline */ void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness) { int ii; float scale = get_scale(); int num_segments = (int)(sqrtf(hypotf(points[2] - points[0], points[3] - points[1]) + hypotf(points[4] - points[2], points[5] - points[3]) + hypotf(points[6] - points[4], points[7] - points[5])) * 1.2 * ALLEGRO_PRIM_QUALITY * scale / 10); LOCAL_VERTEX_CACHE; if(num_segments < 2) num_segments = 2; if (thickness > 0) { if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; } al_calculate_spline(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, thickness, num_segments); for (ii = 0; ii < 2 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; } al_calculate_spline(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, thickness, num_segments); for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); } } /* Function: al_calculate_ribbon */ void al_calculate_ribbon(float* dest, int dest_stride, const float *points, int points_stride, float thickness, int num_segments) { ASSERT(points); ASSERT(num_segments >= 2); if (thickness > 0) { int ii = 0; float x, y; float cur_dir_x; float cur_dir_y; float prev_dir_x = 0; float prev_dir_y = 0; float t = thickness / 2; float tx, ty; float nx, ny; float sign = 1; for (ii = 0; ii < 2 * num_segments - 2; ii += 2) { float dir_len; x = *points; y = *(points + 1); points = (float*)(((char*)points) + points_stride); cur_dir_x = *(points) - x; cur_dir_y = *(points + 1) - y; dir_len = hypotf(cur_dir_x, cur_dir_y); if(dir_len > 0.000001f) { cur_dir_x /= dir_len; cur_dir_y /= dir_len; } else if (ii == 0) { cur_dir_x = 1; cur_dir_y = 0; } else { cur_dir_x = prev_dir_x; cur_dir_y = prev_dir_y; } if (ii == 0) { tx = -t * cur_dir_y; ty = t * cur_dir_x; nx = 0; ny = 0; } else { float dot = cur_dir_x * prev_dir_x + cur_dir_y * prev_dir_y; float norm_len, cosine; if(dot < 0) { /* * This is by no means exact, but seems to produce acceptable results */ float tx_; tx = cur_dir_x - prev_dir_x; ty = cur_dir_y - prev_dir_y; norm_len = hypotf(tx, ty); tx /= norm_len; ty /= norm_len; cosine = tx * cur_dir_x + ty * cur_dir_y; nx = -t * tx / cosine; ny = -t * ty / cosine; tx_ = tx; tx = -t * ty * cosine; ty = t * tx_ * cosine; sign = -sign; } else { float new_norm_len; tx = cur_dir_y + prev_dir_y; ty = -(cur_dir_x + prev_dir_x); norm_len = hypotf(tx, ty); tx /= norm_len; ty /= norm_len; cosine = tx * (-cur_dir_y) + ty * (cur_dir_x); new_norm_len = t / cosine; tx *= new_norm_len; ty *= new_norm_len; nx = 0; ny = 0; } } *dest = x - sign * tx + nx; *(dest + 1) = y - sign * ty + ny; dest = (float*)(((char*)dest) + dest_stride); *dest = x + sign * tx + nx; *(dest + 1) = y + sign * ty + ny; dest = (float*)(((char*)dest) + dest_stride); prev_dir_x = cur_dir_x; prev_dir_y = cur_dir_y; } tx = -t * prev_dir_y; ty = t * prev_dir_x; x = *points; y = *(points + 1); *dest = x - sign * tx; *(dest + 1) = y - sign * ty; dest = (float*)(((char*)dest) + dest_stride); *dest = x + sign * tx; *(dest + 1) = y + sign * ty; } else { int ii; for (ii = 0; ii < num_segments; ii++) { *dest = *points; *(dest + 1) = *(points + 1); dest = (float*)(((char*)dest) + dest_stride); points = (float*)(((char*)points) + points_stride); } } } /* Function: al_draw_ribbon */ void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color, float thickness, int num_segments) { LOCAL_VERTEX_CACHE; int ii; al_calculate_ribbon(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, points_stride, thickness, num_segments); if (thickness > 0) { for (ii = 0; ii < 2 * num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); } else { for (ii = 0; ii < num_segments; ii++) { vertex_cache[ii].color = color; vertex_cache[ii].z = 0; } al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/CMakeLists.txt0000644000175000001440000001141612063001327016413 0ustar tjadenusers# FOO_LINK_WITH and SUPPORT_FOO need to be propagated up to the parent scope so # examples know if they can use the FOO addon, and what to link against. # FOO_LINK_WITH should be the name of a single target. The target should # automatically pull in dependencies so they don't need to be listed. include(FindPackageHandleStandardArgs) set(ADDON_PKG_CONFIG_FILES) if(WANT_PRIMITIVES) add_subdirectory(primitives) set(SUPPORT_PRIMITIVES 1) set(SUPPORT_PRIMITIVES 1 PARENT_SCOPE) set(PRIMITIVES_LINK_WITH ${PRIMITIVES_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_primitives) endif(WANT_PRIMITIVES) if(WANT_IMAGE) add_subdirectory(image) set(SUPPORT_IMAGE 1) set(SUPPORT_IMAGE 1 PARENT_SCOPE) set(IMAGE_LINK_WITH ${IMAGE_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_image) endif(WANT_IMAGE) if(WANT_FONT AND SUPPORT_IMAGE) add_subdirectory(font) set(SUPPORT_FONT 1) set(SUPPORT_FONT 1 PARENT_SCOPE) set(FONT_LINK_WITH ${FONT_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_font) endif(WANT_FONT AND SUPPORT_IMAGE) if(WANT_AUDIO) add_subdirectory(audio) if(SUPPORT_AUDIO) set(SUPPORT_AUDIO 1 PARENT_SCOPE) set(AUDIO_LINK_WITH ${AUDIO_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_audio) endif(SUPPORT_AUDIO) endif(WANT_AUDIO) if(SUPPORT_AUDIO) add_subdirectory(acodec) if(SUPPORT_ACODEC) set(SUPPORT_ACODEC 1 PARENT_SCOPE) set(ACODEC_LINK_WITH ${ACODEC_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_acodec) endif(SUPPORT_ACODEC) endif(SUPPORT_AUDIO) if(SUPPORT_FONT AND WANT_TTF) find_package(Freetype) if(FREETYPE_FOUND) add_subdirectory(ttf) set(SUPPORT_TTF 1 PARENT_SCOPE) set(TTF_LINK_WITH ${TTF_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_ttf) else(FREETYPE_FOUND) message("WARNING: FreeType not found, disabling support.") endif(FREETYPE_FOUND) endif(SUPPORT_FONT AND WANT_TTF) if(WANT_COLOR) add_subdirectory(color) set(SUPPORT_COLOR 1 PARENT_SCOPE) set(COLOR_LINK_WITH ${COLOR_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_color) endif(WANT_COLOR) if(WANT_MEMFILE) add_subdirectory(memfile) set(SUPPORT_MEMFILE 1 PARENT_SCOPE) set(MEMFILE_LINK_WITH ${MEMFILE_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_memfile) endif(WANT_MEMFILE) if(WANT_PHYSFS) find_package(PhysFS) # FindPhysFS.cmake in cmake-2.6.2 doesn't call this but it should. find_package_handle_standard_args(PHYSFS DEFAULT_MSG PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR) mark_as_advanced(PHYSFS_INCLUDE_DIR) mark_as_advanced(PHYSFS_LIBRARY) find_package(ZLIB) # Does this copy of PhysicsFS require zlib to be linked separately? # FindPhysFS should really figure this out for us, but it doesn't. if(PHYSFS_FOUND) set(CMAKE_REQUIRED_INCLUDES ${PHYSFS_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${PHYSFS_LIBRARY}) check_c_source_compiles(" #include int main(int argc, char **argv) { (void)argc; PHYSFS_init(argv[0]); PHYSFS_deinit(); return 0; }" PHYSFS_IMPLICIT_ZLIB) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(PHYSFS_IMPLICIT_ZLIB) set(PHYSFS_LIBRARIES ${PHYSFS_LIBRARY}) set(SUPPORT_PHYSFS 1) elseif(ZLIB_FOUND) set(PHYSFS_LIBRARIES ${PHYSFS_LIBRARY} ${ZLIB_LIBRARY}) set(SUPPORT_PHYSFS 1) else() message("WARNING: PhysicsFS needs zlib, zlib not found, disabling PhysFS support.") endif() endif(PHYSFS_FOUND) if(SUPPORT_PHYSFS) add_subdirectory(physfs) set(SUPPORT_PHYSFS 1 PARENT_SCOPE) set(PHYSFS_LINK_WITH ${PHYSFS_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_physfs) endif(SUPPORT_PHYSFS) endif(WANT_PHYSFS) if(WANT_NATIVE_DIALOG) add_subdirectory(native_dialog) if(SUPPORT_NATIVE_DIALOG) set(SUPPORT_NATIVE_DIALOG 1 PARENT_SCOPE) set(NATIVE_DIALOG_LINK_WITH ${NATIVE_DIALOG_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_dialog) endif() endif(WANT_NATIVE_DIALOG) add_subdirectory(main) set(SUPPORT_ALLEGRO_MAIN ${SUPPORT_ALLEGRO_MAIN} PARENT_SCOPE) set(ALLEGRO_MAIN_LINK_WITH ${ALLEGRO_MAIN_LINK_WITH} PARENT_SCOPE) list(APPEND ADDON_PKG_CONFIG_FILES allegro_main) set(ADDON_PKG_CONFIG_FILES ${ADDON_PKG_CONFIG_FILES} PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/audio/0000755000175000001440000000000012157230736014765 5ustar tjadenusersallegro-5.0.10/addons/audio/alsa.c0000644000175000001440000005402012031445360016042 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * ALSA 1.0 sound driver. * * By Thomas Fjellstrom. * * Extensively modified by Elias Pschernig. * * Rewritten for 4.3 sound API by Milan Mimica, with additional * improvements by Chris Robinson. Updated for 4.9 by Ryan Dickie * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_audio.h" #include ALLEGRO_DEBUG_CHANNEL("alsa") #define ALSA_CHECK(a) \ do { \ int err = (a); \ if (err < 0) { \ ALLEGRO_ERROR("%s: %s\n", snd_strerror(err), #a); \ goto Error; \ } \ } while(0) static snd_output_t *snd_output = NULL; static char *default_device = "default"; static char *alsa_device = NULL; typedef struct ALSA_VOICE { unsigned int frame_size; /* in bytes */ unsigned int len; /* in frames */ snd_pcm_uframes_t frag_len; /* in frames */ bool reversed; /* true if playing reversed ATM. */ volatile bool stop; volatile bool stopped; struct pollfd *ufds; int ufds_count; ALLEGRO_THREAD *poll_thread; snd_pcm_t *pcm_handle; bool mmapped; } ALSA_VOICE; /* initialized output */ static int alsa_open(void) { alsa_device = default_device; ALLEGRO_CONFIG *config = al_get_system_config(); if (config) { const char *config_device; config_device = al_get_config_value(config, "alsa", "device"); if (config_device && config_device[0] != '\0') alsa_device = strdup(config_device); } ALSA_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0)); /* We need to check if alsa is available in this function. */ snd_pcm_t *test_pcm_handle; int alsa_err = snd_pcm_open(&test_pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (alsa_err < 0) { ALLEGRO_WARN("ALSA is not available on the system.\n"); return 1; } else { snd_pcm_close(test_pcm_handle); } return 0; /* ALSA check is a macro that 'goto' error*/ Error: ALLEGRO_ERROR("Error initializing alsa!\n"); return 1; } /* The close method should close the device, freeing any resources, and allow other processes to use the device */ static void alsa_close(void) { if (alsa_device != default_device) al_free(alsa_device); alsa_device = NULL; snd_config_update_free_global(); } /* Underrun and suspend recovery */ static int xrun_recovery(snd_pcm_t *handle, int err) { if (err == -EPIPE) { /* under-run */ err = snd_pcm_prepare(handle); if (err < 0) { ALLEGRO_ERROR("Can't recover from underrun, prepare failed: %s\n", snd_strerror(err)); } else { ALLEGRO_DEBUG("Recovered from underrun\n"); } return 0; } else if (err == -ESTRPIPE) { /* suspend */ err = snd_pcm_resume(handle); if (err < 0) { ALLEGRO_ERROR("Can't recover from suspend, resume failed: %s\n", snd_strerror(err)); } else { ALLEGRO_DEBUG("Resumed successfully\n"); } return 0; } else { ALLEGRO_ERROR("Unknown error code: %d\n", err); ASSERT(0); } return err; } /* * Updates the supplied non-streaming voice. * buf - Returns a pointer to the buffer containing sample data. * bytes - The requested size of the sample data buffer. Returns the actual * size of returned the buffer. * Updates 'stop', 'pos' and 'reversed' fields of the supplied voice to the * future position. * If the voice is played backwards, 'buf' will point to the end of the buffer * and 'bytes' is the size that can be read towards the beginning. */ static int alsa_update_nonstream_voice(ALLEGRO_VOICE *voice, void **buf, int *bytes) { ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; int bpos = voice->attached_stream->pos * alsa_voice->frame_size; int blen = alsa_voice->len * alsa_voice->frame_size; *buf = (char *)voice->attached_stream->spl_data.buffer.ptr + bpos; if (!alsa_voice->reversed) { if (bpos + *bytes > blen) { *bytes = blen - bpos; if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { alsa_voice->stop = true; voice->attached_stream->pos = 0; } if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_LOOP) { voice->attached_stream->pos = 0; } else if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { alsa_voice->reversed = true; voice->attached_stream->pos = alsa_voice->len; } return 1; } else voice->attached_stream->pos += *bytes / alsa_voice->frame_size; } else { if (bpos - *bytes < 0) { *bytes = bpos; /* loop will be ALLEGRO_PLAYMODE_BIDIR, other playing modes that play backwards are not currently supported by the API */ /*if (voice->attached_stream->loop != ALLEGRO_PLAYMODE_BIDIR) alsa_voice->stop = true;*/ voice->attached_stream->pos = 0; alsa_voice->reversed = false; return 1; } else voice->attached_stream->pos -= *bytes / alsa_voice->frame_size; } return 0; } /* Returns true if the voice is ready for more data. */ static int alsa_voice_is_ready(ALSA_VOICE *alsa_voice) { unsigned short revents; int err; poll(alsa_voice->ufds, alsa_voice->ufds_count, 0); snd_pcm_poll_descriptors_revents(alsa_voice->pcm_handle, alsa_voice->ufds, alsa_voice->ufds_count, &revents); if (revents & POLLERR) { if (snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_XRUN || snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_SUSPENDED) { if (snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_XRUN) err = -EPIPE; else err = -ESTRPIPE; if (xrun_recovery(alsa_voice->pcm_handle, err) < 0) { ALLEGRO_ERROR("Write error: %s\n", snd_strerror(err)); return -POLLERR; } } else { ALLEGRO_ERROR("Wait for poll failed\n"); return -POLLERR; } } if (revents & POLLOUT) return true; return false; } /* Custom routine which runs in another thread and fills the hardware PCM buffer from the voice buffer. */ static void *alsa_update_mmap(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*)arg; ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; snd_pcm_state_t last_state = -1; snd_pcm_state_t state; snd_pcm_uframes_t frames; const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset; char *mmap; int ret; ALLEGRO_INFO("ALSA update_mmap thread started\n"); while (!al_get_thread_should_stop(self)) { if (alsa_voice->stop && !alsa_voice->stopped) { snd_pcm_drop(alsa_voice->pcm_handle); al_lock_mutex(voice->mutex); alsa_voice->stopped = true; al_signal_cond(voice->cond); al_unlock_mutex(voice->mutex); } if (!alsa_voice->stop && alsa_voice->stopped) { alsa_voice->stopped = false; } if (alsa_voice->stopped) { /* Keep waiting while the voice is supposed to be stopped but present. */ al_lock_mutex(voice->mutex); while (alsa_voice->stop && !al_get_thread_should_stop(self)) { al_wait_cond(voice->cond, voice->mutex); } al_unlock_mutex(voice->mutex); continue; } state = snd_pcm_state(alsa_voice->pcm_handle); if (state != last_state) { ALLEGRO_DEBUG("state changed to: %s\n", snd_pcm_state_name(state)); last_state = state; } if (state == SND_PCM_STATE_SETUP) { int rc = snd_pcm_prepare(alsa_voice->pcm_handle); ALLEGRO_DEBUG("snd_pcm_prepare returned: %d\n", rc); continue; } if (state == SND_PCM_STATE_PREPARED) { int rc = snd_pcm_start(alsa_voice->pcm_handle); ALLEGRO_DEBUG("snd_pcm_start returned: %d\n", rc); } ret = alsa_voice_is_ready(alsa_voice); if (ret < 0) break; if (ret == 0) { al_rest(0.005); /* TODO: Why not use an event or condition variable? */ continue; } snd_pcm_avail_update(alsa_voice->pcm_handle); frames = alsa_voice->frag_len; ret = snd_pcm_mmap_begin(alsa_voice->pcm_handle, &areas, &offset, &frames); if (ret < 0) { if ((ret = xrun_recovery(alsa_voice->pcm_handle, ret)) < 0) { ALLEGRO_ERROR("MMAP begin avail error: %s\n", snd_strerror(ret)); } break; } ASSERT(frames); /* mmaped driver's memory. Interleaved channels format. */ mmap = (char *) areas[0].addr + areas[0].first / 8 + offset * areas[0].step / 8; /* Read sample data into the buffer. */ if (!voice->is_streaming && !alsa_voice->stopped) { void *buf; bool reverse = alsa_voice->reversed; int bytes = frames * alsa_voice->frame_size; alsa_update_nonstream_voice(voice, &buf, &bytes); frames = bytes / alsa_voice->frame_size; if (!reverse) { memcpy(mmap, buf, bytes); } else { /* Put a reversed copy in the driver's buffer. */ unsigned int i; int fs = alsa_voice->frame_size; for (i = 1; i <= frames; i++) memcpy(mmap + i * fs, (char *) buf - i * fs, fs); } } else if (voice->is_streaming && !alsa_voice->stopped) { /* This should fit. */ unsigned int iframes = frames; const void *data = _al_voice_update(voice, &iframes); frames = iframes; if (data == NULL) goto silence; memcpy(mmap, data, frames * alsa_voice->frame_size); } else { int silence; silence: /* If stopped just fill with silence. */ silence = _al_kcm_get_silence(voice->depth); memset(mmap, silence, frames * alsa_voice->frame_size); } snd_pcm_sframes_t commitres = snd_pcm_mmap_commit(alsa_voice->pcm_handle, offset, frames); if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) { if ((ret = xrun_recovery(alsa_voice->pcm_handle, commitres >= 0 ? -EPIPE : commitres)) < 0) { ALLEGRO_ERROR("MMAP commit error: %s\n", snd_strerror(ret)); break; } } } ALLEGRO_INFO("ALSA update_mmap thread stopped\n"); return NULL; } static void *alsa_update_rw(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*)arg; ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; snd_pcm_state_t last_state = -1; snd_pcm_state_t state; snd_pcm_uframes_t frames; snd_pcm_sframes_t err; ALLEGRO_INFO("ALSA update_rw thread started\n"); while (!al_get_thread_should_stop(self)) { if (alsa_voice->stop && !alsa_voice->stopped) { snd_pcm_drop(alsa_voice->pcm_handle); al_lock_mutex(voice->mutex); alsa_voice->stopped = true; al_signal_cond(voice->cond); al_unlock_mutex(voice->mutex); } if (!alsa_voice->stop && alsa_voice->stopped) { alsa_voice->stopped = false; } if (alsa_voice->stopped) { /* Keep waiting while the voice is supposed to be stopped but present. */ al_lock_mutex(voice->mutex); while (alsa_voice->stop && !al_get_thread_should_stop(self)) { al_wait_cond(voice->cond, voice->mutex); } al_unlock_mutex(voice->mutex); continue; } state = snd_pcm_state(alsa_voice->pcm_handle); if (state != last_state) { ALLEGRO_DEBUG("state changed to: %s\n", snd_pcm_state_name(state)); last_state = state; } if (state == SND_PCM_STATE_SETUP) { int rc = snd_pcm_prepare(alsa_voice->pcm_handle); ALLEGRO_DEBUG("snd_pcm_prepare returned: %d\n", rc); continue; } if (state == SND_PCM_STATE_PREPARED) { int rc = snd_pcm_start(alsa_voice->pcm_handle); ALLEGRO_DEBUG("snd_pcm_start returned: %d\n", rc); } snd_pcm_wait(alsa_voice->pcm_handle, 10); err = snd_pcm_avail_update(alsa_voice->pcm_handle); if (err < 0) { if (err == -EPIPE) { snd_pcm_prepare(alsa_voice->pcm_handle); } else { ALLEGRO_WARN("Alsa r/w thread exited " "with error code %s.\n", snd_strerror(-err)); break; } } if (err == 0) { continue; } frames = err; if (frames > alsa_voice->frag_len) frames = alsa_voice->frag_len; /* Write sample data into the buffer. */ int bytes = frames * alsa_voice->frame_size; uint8_t data[bytes]; void *buf; if (!voice->is_streaming && !alsa_voice->stopped) { ASSERT(!alsa_voice->reversed); // FIXME alsa_update_nonstream_voice(voice, &buf, &bytes); frames = bytes / alsa_voice->frame_size; } else if (voice->is_streaming && !alsa_voice->stopped) { /* This should fit. */ unsigned int iframes = frames; buf = (void *)_al_voice_update(voice, &iframes); frames = iframes; if (buf == NULL) goto silence; } else { int silence; silence: /* If stopped just fill with silence. */ silence = _al_kcm_get_silence(voice->depth); memset(data, silence, bytes); buf = data; } err = snd_pcm_writei(alsa_voice->pcm_handle, buf, frames); if (err < 0) { if (err == -EPIPE) { snd_pcm_prepare(alsa_voice->pcm_handle); } } } ALLEGRO_INFO("ALSA update_rw thread stopped\n"); return NULL; } /* The load_voice method loads a sample into the driver's memory. The voice's 'streaming' field will be set to false for these voices, and it's 'buffer_size' field will be the total length in bytes of the sample data. The voice's attached stream's looping mode should be honored, and loading must fail if it cannot be. */ static int alsa_load_voice(ALLEGRO_VOICE *voice, const void *data) { ALSA_VOICE *ex_data = voice->extra; voice->attached_stream->pos = 0; ex_data->len = voice->attached_stream->spl_data.len; return 0; (void)data; } /* The unload_voice method unloads a sample previously loaded with load_voice. This method should not be called on a streaming voice. */ static void alsa_unload_voice(ALLEGRO_VOICE *voice) { (void)voice; } /* The start_voice should, surprise, start the voice. For streaming voices, it should start polling the device and call _al_voice_update for audio data. For non-streaming voices, it should resume playing from the last set position */ static int alsa_start_voice(ALLEGRO_VOICE *voice) { ALSA_VOICE *ex_data = voice->extra; /* We already hold voice->mutex. */ ex_data->stop = false; al_signal_cond(voice->cond); return 0; } /* The stop_voice method should stop playback. For non-streaming voices, it should leave the data loaded, and reset the voice position to 0. */ static int alsa_stop_voice(ALLEGRO_VOICE *voice) { ALSA_VOICE *ex_data = voice->extra; /* We already hold voice->mutex. */ ex_data->stop = true; al_signal_cond(voice->cond); if (!voice->is_streaming) { voice->attached_stream->pos = 0; } while (!ex_data->stopped) { al_wait_cond(voice->cond, voice->mutex); } return 0; } /* The voice_is_playing method should only be called on non-streaming sources, and should return true if the voice is playing */ static bool alsa_voice_is_playing(const ALLEGRO_VOICE *voice) { ALSA_VOICE *ex_data = voice->extra; return !ex_data->stopped; } /* The allocate_voice method should grab a voice from the system, and allocate any data common to streaming and non-streaming sources. */ static int alsa_allocate_voice(ALLEGRO_VOICE *voice) { snd_pcm_format_t format; int chan_count; unsigned int req_freq; ALSA_VOICE *ex_data = al_calloc(1, sizeof(ALSA_VOICE)); if (!ex_data) return 1; chan_count = al_get_channel_count(voice->chan_conf); ex_data->frame_size = chan_count * al_get_audio_depth_size(voice->depth); if (!ex_data->frame_size) goto Error; ex_data->stop = true; ex_data->stopped = true; ex_data->reversed = false; // TODO: Setting this to 256 causes (extreme, about than 10 seconds) // lag if the alsa device is really pulseaudio. // // pw: But there are calls later which expect this variable to be set an on // my machine (without PulseAudio) the driver doesn't work properly with // anything lower than 32. ex_data->frag_len = 32; if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT8) format = SND_PCM_FORMAT_S8; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) format = SND_PCM_FORMAT_U8; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) format = SND_PCM_FORMAT_S16; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) format = SND_PCM_FORMAT_U16; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) format = SND_PCM_FORMAT_S24; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT24) format = SND_PCM_FORMAT_U24; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) format = SND_PCM_FORMAT_FLOAT; else goto Error; /* Why is this? And what is this? */ if (voice->chan_conf == ALLEGRO_CHANNEL_CONF_3) goto Error; req_freq = voice->frequency; ALSA_CHECK(snd_pcm_open(&ex_data->pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)); snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_alloca(&hwparams); ALSA_CHECK(snd_pcm_hw_params_any(ex_data->pcm_handle, hwparams)); if (snd_pcm_hw_params_set_access(ex_data->pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) == 0) { ex_data->mmapped = true; } else { ALSA_CHECK(snd_pcm_hw_params_set_access(ex_data->pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)); ex_data->mmapped = false; } ALSA_CHECK(snd_pcm_hw_params_set_format(ex_data->pcm_handle, hwparams, format)); ALSA_CHECK(snd_pcm_hw_params_set_channels(ex_data->pcm_handle, hwparams, chan_count)); ALSA_CHECK(snd_pcm_hw_params_set_rate_near(ex_data->pcm_handle, hwparams, &req_freq, NULL)); ALSA_CHECK(snd_pcm_hw_params_set_period_size_near(ex_data->pcm_handle, hwparams, &ex_data->frag_len, NULL)); ALSA_CHECK(snd_pcm_hw_params(ex_data->pcm_handle, hwparams)); if (voice->frequency != req_freq) { ALLEGRO_ERROR("Unsupported rate! Requested %u, got %iu.\n", voice->frequency, req_freq); goto Error; } snd_pcm_sw_params_t *swparams; snd_pcm_sw_params_alloca(&swparams); ALSA_CHECK(snd_pcm_sw_params_current(ex_data->pcm_handle, swparams)); ALSA_CHECK(snd_pcm_sw_params_set_start_threshold(ex_data->pcm_handle, swparams, ex_data->frag_len)); ALSA_CHECK(snd_pcm_sw_params_set_avail_min(ex_data->pcm_handle, swparams, ex_data->frag_len)); ALSA_CHECK(snd_pcm_sw_params(ex_data->pcm_handle, swparams)); ex_data->ufds_count = snd_pcm_poll_descriptors_count(ex_data->pcm_handle); ex_data->ufds = al_malloc(sizeof(struct pollfd) * ex_data->ufds_count); ALSA_CHECK(snd_pcm_poll_descriptors(ex_data->pcm_handle, ex_data->ufds, ex_data->ufds_count)); voice->extra = ex_data; if (ex_data->mmapped) { ex_data->poll_thread = al_create_thread(alsa_update_mmap, (void*)voice); } else { ALLEGRO_WARN("Falling back to non-mmapped transfer.\n"); snd_pcm_nonblock(ex_data->pcm_handle, 0); ex_data->poll_thread = al_create_thread(alsa_update_rw, (void*)voice); } al_start_thread(ex_data->poll_thread); return 0; Error: if (ex_data->pcm_handle) snd_pcm_close(ex_data->pcm_handle); al_free(ex_data); voice->extra = NULL; return 1; } /* The deallocate_voice method should free the resources for the given voice, but still retain a hold on the device. The voice should be stopped and unloaded by the time this is called */ static void alsa_deallocate_voice(ALLEGRO_VOICE *voice) { ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; al_lock_mutex(voice->mutex); al_set_thread_should_stop(alsa_voice->poll_thread); al_broadcast_cond(voice->cond); al_unlock_mutex(voice->mutex); al_join_thread(alsa_voice->poll_thread, NULL); snd_pcm_drop(alsa_voice->pcm_handle); snd_pcm_close(alsa_voice->pcm_handle); al_destroy_thread(alsa_voice->poll_thread); al_free(alsa_voice->ufds); al_free(voice->extra); voice->extra = NULL; } /* The get_voice_position method should return the current sample position of the voice (sample_pos = byte_pos / (depth/8) / channels). This should never be called on a streaming voice. */ static unsigned int alsa_get_voice_position(const ALLEGRO_VOICE *voice) { return voice->attached_stream->pos; } /* The set_voice_position method should set the voice's playback position, given the value in samples. This should never be called on a streaming voice. */ static int alsa_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { voice->attached_stream->pos = val; return 0; } ALLEGRO_AUDIO_DRIVER _al_kcm_alsa_driver = { "ALSA", alsa_open, alsa_close, alsa_allocate_voice, alsa_deallocate_voice, alsa_load_voice, alsa_unload_voice, alsa_start_voice, alsa_stop_voice, alsa_voice_is_playing, alsa_get_voice_position, alsa_set_voice_position }; /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/pulseaudio.c0000644000175000001440000002573312137071470017311 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * PulseAudio sound driver. * * By Matthew Leverton. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_audio.h" #include #include #include #include #include ALLEGRO_DEBUG_CHANNEL("PulseAudio") enum PULSEAUDIO_VOICE_STATUS { PV_IDLE, PV_PLAYING, PV_STOPPING, PV_JOIN }; typedef struct PULSEAUDIO_VOICE { pa_simple *s; unsigned int buffer_size_in_frames; unsigned int frame_size_in_bytes; ALLEGRO_THREAD *poll_thread; ALLEGRO_MUTEX *status_mutex; ALLEGRO_COND *status_cond; enum PULSEAUDIO_VOICE_STATUS status; // direct buffer (non-streaming): ALLEGRO_MUTEX *buffer_mutex; char *buffer; char *buffer_end; } PULSEAUDIO_VOICE; #define DEFAULT_BUFFER_SIZE 1024 #define MIN_BUFFER_SIZE 128 static unsigned int get_buffer_size(const ALLEGRO_CONFIG *config) { if (config) { const char *val = al_get_config_value(config, "pulseaudio", "buffer_size"); if (val && val[0] != '\0') { int n = atoi(val); if (n < MIN_BUFFER_SIZE) n = MIN_BUFFER_SIZE; return n; } } return DEFAULT_BUFFER_SIZE; } static void sink_info_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { (void)c; (void)eol; pa_sink_state_t *ret = userdata; if (!i) return; *ret = i->state; } static int pulseaudio_open(void) { /* Use PA_CONTEXT_NOAUTOSPAWN to see if a PA server is running. * If not, fail - we're better off using ALSA/OSS. * * Also check for suspended PA - again better using ALSA/OSS in * that case (pa_simple_write just blocks until PA is unsuspended * otherwise). * * TODO: Maybe we should have a force flag to the audio driver * open method, which in the case of PA would spawn a server if * none is running (and also unsuspend?). */ pa_mainloop *mainloop = pa_mainloop_new(); pa_context *c = pa_context_new(pa_mainloop_get_api(mainloop), al_get_app_name()); if (!c) { pa_mainloop_free(mainloop); return 1; } pa_context_connect(c, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); while (1) { /* Don't block or it will hang if there is no server to connect to. */ const int blocking = 0; if (pa_mainloop_iterate(mainloop, blocking, NULL) < 0) { ALLEGRO_ERROR("pa_mainloop_iterate failed\n"); pa_context_disconnect(c); pa_mainloop_free(mainloop); break; } pa_context_state_t s = pa_context_get_state(c); if (s == PA_CONTEXT_READY) { ALLEGRO_DEBUG("PA_CONTEXT_READY\n"); break; } if (s == PA_CONTEXT_FAILED) { ALLEGRO_ERROR("PA_CONTEXT_FAILED\n"); pa_context_disconnect(c); pa_mainloop_free(mainloop); return 1; } } pa_sink_state_t state = 0; pa_operation *op = pa_context_get_sink_info_list(c, sink_info_cb, &state); while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) { pa_mainloop_iterate(mainloop, 1, NULL); } /*if (state == PA_SINK_SUSPENDED) { pa_context_disconnect(c); pa_mainloop_free(mainloop); return 1; }*/ pa_operation_unref(op); pa_context_disconnect(c); pa_context_unref(c); pa_mainloop_free(mainloop); return 0; } static void pulseaudio_close(void) { } static void *pulseaudio_update(ALLEGRO_THREAD *self, void *data) { ALLEGRO_VOICE *voice = data; PULSEAUDIO_VOICE *pv = voice->extra; (void)self; for (;;) { enum PULSEAUDIO_VOICE_STATUS status; al_lock_mutex(pv->status_mutex); while ((status = pv->status) == PV_IDLE) { al_wait_cond(pv->status_cond, pv->status_mutex); } al_unlock_mutex(pv->status_mutex); if (status == PV_JOIN) { break; } if (status == PV_PLAYING) { unsigned int frames = pv->buffer_size_in_frames; if (voice->is_streaming) { // streaming audio const void *data = _al_voice_update(voice, &frames); if (data) { pa_simple_write(pv->s, data, frames * pv->frame_size_in_bytes, NULL); } } else { // direct buffer audio al_lock_mutex(pv->buffer_mutex); const char *data = pv->buffer; unsigned int len = frames * pv->frame_size_in_bytes; pv->buffer += frames * pv->frame_size_in_bytes; if (pv->buffer > pv->buffer_end) { len = pv->buffer_end - data; pv->buffer = voice->attached_stream->spl_data.buffer.ptr; voice->attached_stream->pos = 0; if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { al_lock_mutex(pv->status_mutex); pv->status = PV_STOPPING; al_broadcast_cond(pv->status_cond); al_unlock_mutex(pv->status_mutex); } } else { voice->attached_stream->pos += frames; } al_unlock_mutex(pv->buffer_mutex); pa_simple_write(pv->s, data, len, NULL); } } else if (status == PV_STOPPING) { pa_simple_flush(pv->s, NULL); al_lock_mutex(pv->status_mutex); pv->status = PV_IDLE; al_broadcast_cond(pv->status_cond); al_unlock_mutex(pv->status_mutex); } } return NULL; } static int pulseaudio_allocate_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = al_malloc(sizeof(PULSEAUDIO_VOICE)); pa_sample_spec ss; pa_buffer_attr ba; ss.channels = al_get_channel_count(voice->chan_conf); ss.rate = voice->frequency; if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) ss.format = PA_SAMPLE_U8; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) ss.format = PA_SAMPLE_S16NE; #if PA_API_VERSION > 11 else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) ss.format = PA_SAMPLE_S24NE; #endif else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) ss.format = PA_SAMPLE_FLOAT32NE; else { ALLEGRO_ERROR("Unsupported PulseAudio sound format.\n"); al_free(pv); return 1; } ba.maxlength = 0x10000; // maximum length of buffer ba.tlength = 0x2000; // target length of buffer ba.prebuf = 0; // minimum data size required before playback starts ba.minreq = 0; // minimum size of request ba.fragsize = -1; // fragment size (recording) pv->s = pa_simple_new( NULL, // Use the default server. al_get_app_name(), PA_STREAM_PLAYBACK, NULL, // Use the default device. "Allegro Voice", &ss, NULL, // Use default channel map &ba, NULL // Ignore error code. ); if (!pv->s) { al_free(pv); return 1; } voice->extra = pv; pv->buffer_size_in_frames = get_buffer_size(al_get_system_config()); pv->frame_size_in_bytes = ss.channels * al_get_audio_depth_size(voice->depth); pv->status = PV_IDLE; pv->status_mutex = al_create_mutex(); pv->status_cond = al_create_cond(); pv->buffer_mutex = al_create_mutex(); pv->poll_thread = al_create_thread(pulseaudio_update, (void*)voice); al_start_thread(pv->poll_thread); return 0; } static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; al_lock_mutex(pv->status_mutex); pv->status = PV_JOIN; al_broadcast_cond(pv->status_cond); al_unlock_mutex(pv->status_mutex); /* We do NOT hold the voice mutex here, so this does NOT result in a * deadlock when the thread calls _al_voice_update. */ al_join_thread(pv->poll_thread, NULL); al_destroy_thread(pv->poll_thread); al_destroy_mutex(pv->status_mutex); al_destroy_cond(pv->status_cond); al_destroy_mutex(pv->buffer_mutex); pa_simple_free(pv->s); al_free(pv); } static int pulseaudio_load_voice(ALLEGRO_VOICE *voice, const void *data) { PULSEAUDIO_VOICE *pv = voice->extra; (void)data; if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { ALLEGRO_INFO("Backwards playing not supported by the driver.\n"); return 1; } voice->attached_stream->pos = 0; pv->buffer = voice->attached_stream->spl_data.buffer.ptr; pv->buffer_end = pv->buffer + (voice->attached_stream->spl_data.len) * pv->frame_size_in_bytes; return 0; } static void pulseaudio_unload_voice(ALLEGRO_VOICE *voice) { (void) voice; } static int pulseaudio_start_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; int ret; al_lock_mutex(pv->status_mutex); if (pv->status == PV_IDLE) { pv->status = PV_PLAYING; al_broadcast_cond(pv->status_cond); ret = 0; } else { ret = 1; } al_unlock_mutex(pv->status_mutex); return ret; } static int pulseaudio_stop_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; al_lock_mutex(pv->status_mutex); if (pv->status == PV_PLAYING) { pv->status = PV_STOPPING; al_broadcast_cond(pv->status_cond); } while (pv->status != PV_IDLE) { al_wait_cond(pv->status_cond, pv->status_mutex); } al_unlock_mutex(pv->status_mutex); return 0; } static bool pulseaudio_voice_is_playing(const ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; enum PULSEAUDIO_VOICE_STATUS status; al_lock_mutex(pv->status_mutex); status = pv->status; al_unlock_mutex(pv->status_mutex); return (status == PV_PLAYING); } static unsigned int pulseaudio_get_voice_position(const ALLEGRO_VOICE *voice) { return voice->attached_stream->pos; } static int pulseaudio_set_voice_position(ALLEGRO_VOICE *voice, unsigned int pos) { PULSEAUDIO_VOICE *pv = voice->extra; pa_simple_drain(pv->s, NULL); al_lock_mutex(pv->buffer_mutex); voice->attached_stream->pos = pos; pv->buffer = (char *)voice->attached_stream->spl_data.buffer.ptr + pos * pv->frame_size_in_bytes; al_unlock_mutex(pv->buffer_mutex); return 0; } ALLEGRO_AUDIO_DRIVER _al_kcm_pulseaudio_driver = { "PulseAudio", pulseaudio_open, pulseaudio_close, pulseaudio_allocate_voice, pulseaudio_deallocate_voice, pulseaudio_load_voice, pulseaudio_unload_voice, pulseaudio_start_voice, pulseaudio_stop_voice, pulseaudio_voice_is_playing, pulseaudio_get_voice_position, pulseaudio_set_voice_position }; /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/CMakeLists.txt0000644000175000001440000001202311520362625017517 0ustar tjadenusersoption(WANT_ALSA "Enable ALSA digital audio driver (Unix)" on) option(WANT_OSS "Enable OSS digital audio driver (Unix)" on) option(WANT_PULSEAUDIO "Enable PulseAudio audio driver (Unix)" on) option(WANT_OPENAL "Enable OpenAL digital audio driver" on) option(WANT_DSOUND "Enable DSound digital audio driver (Windows)" on) option(WANT_AQUEUE "Enable AudioQueue digital audio driver (Mac)" on) set(AUDIO_SOURCES audio.c audio_io.c kcm_dtor.c kcm_instance.c kcm_mixer.c kcm_sample.c kcm_stream.c kcm_voice.c ) set(AUDIO_INCLUDE_FILES allegro5/allegro_audio.h) set_our_header_properties(${AUDIO_INCLUDE_FILES}) # The platform conditions are not really necessary but prevent confusing the # user, e.g. it's pretty weird to get a warning about missing DSound on Unix. if(WANT_OSS AND ALLEGRO_UNIX) include(AllegroFindOSS) if(OSS_FOUND) set(SUPPORT_OSS 1) endif(OSS_FOUND) endif(WANT_OSS AND ALLEGRO_UNIX) if(SUPPORT_OSS) set(ALLEGRO_CFG_KCM_OSS 1) list(APPEND AUDIO_SOURCES oss.c) set(SUPPORT_AUDIO 1) endif(SUPPORT_OSS) if(WANT_PULSEAUDIO AND ALLEGRO_UNIX) pkg_check_modules(PULSEAUDIO libpulse-simple) if(PULSEAUDIO_FOUND) set(CMAKE_REQUIRED_INCLUDES ${PULSEAUDIO_INCLUDE_DIRS}) check_c_source_compiles(" #include #include #include #include int main(void) { /* Require pulseaudio 0.9.15 */ pa_context *c; pa_sink_info *si; pa_sink_state_t *ss; return 0; }" PULSEAUDIO_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(SUPPORT_PULSEAUDIO ${PULSEAUDIO_COMPILES}) if(NOT SUPPORT_PULSEAUDIO) message("WARNING: PulseAudio compile test failed, disabling support") endif() endif(PULSEAUDIO_FOUND) endif(WANT_PULSEAUDIO AND ALLEGRO_UNIX) if(SUPPORT_PULSEAUDIO) set(ALLEGRO_CFG_KCM_PULSEAUDIO 1) list(APPEND AUDIO_SOURCES pulseaudio.c) list(APPEND AUDIO_LIBRARIES ${PULSEAUDIO_LIBRARIES}) include_directories(SYSTEM ${PULSEAUDIO_INCLUDE_DIRS}) link_directories(${PULSEAUDIO_LIBRARY_DIRS}) set(SUPPORT_AUDIO 1) endif(SUPPORT_PULSEAUDIO) if(WANT_ALSA AND ALLEGRO_UNIX) pkg_check_modules(ALSA alsa) if(ALSA_FOUND) set(SUPPORT_ALSA 1) endif(ALSA_FOUND) endif(WANT_ALSA AND ALLEGRO_UNIX) if(SUPPORT_ALSA) set(ALLEGRO_CFG_KCM_ALSA 1) list(APPEND AUDIO_SOURCES alsa.c) list(APPEND AUDIO_LIBRARIES ${ALSA_LIBRARIES}) include_directories(SYSTEM ${ALSA_INCLUDE_DIRS}) set(SUPPORT_AUDIO 1) endif(SUPPORT_ALSA) if(WANT_DSOUND AND WIN32) find_package(DSound) if(DSOUND_FOUND) set(SUPPORT_DSOUND 1) endif(DSOUND_FOUND) endif(WANT_DSOUND AND WIN32) if(SUPPORT_DSOUND) set(ALLEGRO_CFG_KCM_DSOUND 1) list(APPEND AUDIO_SOURCES dsound.cpp) list(APPEND AUDIO_LIBRARIES ${DSOUND_LIBRARIES}) include_directories(SYSTEM ${DSOUND_INCLUDE_DIR}) set(SUPPORT_AUDIO 1) endif(SUPPORT_DSOUND) if(WANT_AQUEUE AND MACOSX) # Should check the presence just to be sure. find_library(AUDIO_TOOLBOX_LIB NAMES AudioToolbox) if(AUDIO_TOOLBOX_LIB) find_path(AQUEUE_INCLUDE_DIR AudioToolbox/AudioQueue.h) if(AQUEUE_INCLUDE_DIR) set(SUPPORT_AQUEUE 1) endif(AQUEUE_INCLUDE_DIR) endif(AUDIO_TOOLBOX_LIB) if(NOT SUPPORT_AQUEUE) message("WARNING: could not find AudioQueue. (This is normal on OS X 10.4)") endif(NOT SUPPORT_AQUEUE) endif(WANT_AQUEUE AND MACOSX) if(SUPPORT_AQUEUE) set(ALLEGRO_CFG_KCM_AQUEUE 1) list(APPEND AUDIO_SOURCES aqueue.m) list(APPEND AUDIO_LIBRARIES ${AUDIO_TOOLBOX_LIB}) set(SUPPORT_AUDIO 1) endif(SUPPORT_AQUEUE) if(WANT_OPENAL) find_package(OpenAL) mark_as_advanced(OPENAL_INCLUDE_DIR OPENAL_LIBRARY) if(OPENAL_FOUND) set(SUPPORT_OPENAL 1) endif(OPENAL_FOUND) endif(WANT_OPENAL) if(SUPPORT_OPENAL) set(ALLEGRO_CFG_KCM_OPENAL 1) list(APPEND AUDIO_SOURCES openal.c) list(APPEND AUDIO_LIBRARIES ${OPENAL_LIBRARY}) include_directories(SYSTEM ${OPENAL_INCLUDE_DIR}) set(SUPPORT_AUDIO 1) endif(SUPPORT_OPENAL) configure_file( allegro5/internal/aintern_audio_cfg.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/internal/aintern_audio_cfg.h ) if(NOT SUPPORT_AUDIO) message("WARNING: allegro_audio wanted but no supported backend found") return() endif(NOT SUPPORT_AUDIO) # Let examples know that audio is supported. set(SUPPORT_AUDIO 1 PARENT_SCOPE) add_our_library(allegro_audio "${AUDIO_SOURCES};${AUDIO_INCLUDE_FILES}" "-DALLEGRO_KCM_AUDIO_SRC" "${ALLEGRO_LINK_WITH};${AUDIO_LIBRARIES}" ) set_our_framework_properties(allegro_audio AllegroAudio-${ALLEGRO_SOVERSION}) install_our_library(allegro_audio) install_our_headers(${AUDIO_INCLUDE_FILES}) set(AUDIO_LINK_WITH allegro_audio PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/audio/audio.c0000644000175000001440000002314412125160224016223 0ustar tjadenusers/** * Originally digi.c from allegro wiki * Original authors: KC/Milan * * Converted to allegro5 by Ryan Dickie */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" ALLEGRO_DEBUG_CHANNEL("audio") void _al_set_error(int error, char* string) { ALLEGRO_ERROR("%s (error code: %d)\n", string, error); } ALLEGRO_AUDIO_DRIVER *_al_kcm_driver = NULL; #if defined(ALLEGRO_CFG_KCM_OPENAL) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_openal_driver; #endif #if defined(ALLEGRO_CFG_KCM_ALSA) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_alsa_driver; #endif #if defined(ALLEGRO_CFG_KCM_OSS) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_oss_driver; #endif #if defined(ALLEGRO_CFG_KCM_DSOUND) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_dsound_driver; #endif #if defined(ALLEGRO_CFG_KCM_AQUEUE) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_aqueue_driver; #endif #if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_pulseaudio_driver; #endif /* Channel configuration helpers */ /* Function: al_get_channel_count */ size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf) { return (conf>>4)+(conf&0xF); } /* Depth configuration helpers */ /* Function: al_get_audio_depth_size */ size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth) { switch (depth) { case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_UINT8: return sizeof(int8_t); case ALLEGRO_AUDIO_DEPTH_INT16: case ALLEGRO_AUDIO_DEPTH_UINT16: return sizeof(int16_t); case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT24: return sizeof(int32_t); case ALLEGRO_AUDIO_DEPTH_FLOAT32: return sizeof(float); default: ASSERT(false); return 0; } } /* FIXME: use the allegro provided helpers */ ALLEGRO_CHANNEL_CONF _al_count_to_channel_conf(int num_channels) { switch (num_channels) { case 1: return ALLEGRO_CHANNEL_CONF_1; case 2: return ALLEGRO_CHANNEL_CONF_2; case 3: return ALLEGRO_CHANNEL_CONF_3; case 4: return ALLEGRO_CHANNEL_CONF_4; case 6: return ALLEGRO_CHANNEL_CONF_5_1; case 7: return ALLEGRO_CHANNEL_CONF_6_1; case 8: return ALLEGRO_CHANNEL_CONF_7_1; default: return 0; } } /* FIXME: assumes 8-bit is unsigned, and all others are signed. */ ALLEGRO_AUDIO_DEPTH _al_word_size_to_depth_conf(int word_size) { switch (word_size) { case 1: return ALLEGRO_AUDIO_DEPTH_UINT8; case 2: return ALLEGRO_AUDIO_DEPTH_INT16; case 3: return ALLEGRO_AUDIO_DEPTH_INT24; case 4: return ALLEGRO_AUDIO_DEPTH_FLOAT32; default: return 0; } } /* Returns a silent sample frame. */ int _al_kcm_get_silence(ALLEGRO_AUDIO_DEPTH depth) { switch (depth) { case ALLEGRO_AUDIO_DEPTH_UINT8: return 0x80; case ALLEGRO_AUDIO_DEPTH_INT16: return 0x8000; case ALLEGRO_AUDIO_DEPTH_INT24: return 0x800000; default: return 0; } } static ALLEGRO_AUDIO_DRIVER_ENUM get_config_audio_driver(void) { ALLEGRO_CONFIG *config = al_get_system_config(); const char *value; if (!config) return ALLEGRO_AUDIO_DRIVER_AUTODETECT; value = al_get_config_value(config, "audio", "driver"); if (!value || value[0] == '\0') return ALLEGRO_AUDIO_DRIVER_AUTODETECT; if (0 == _al_stricmp(value, "ALSA")) return ALLEGRO_AUDIO_DRIVER_ALSA; if (0 == _al_stricmp(value, "OPENAL")) return ALLEGRO_AUDIO_DRIVER_OPENAL; if (0 == _al_stricmp(value, "OSS")) return ALLEGRO_AUDIO_DRIVER_OSS; if (0 == _al_stricmp(value, "PULSEAUDIO")) return ALLEGRO_AUDIO_DRIVER_PULSEAUDIO; if (0 == _al_stricmp(value, "DSOUND") || 0 == _al_stricmp(value, "DIRECTSOUND")) return ALLEGRO_AUDIO_DRIVER_DSOUND; return ALLEGRO_AUDIO_DRIVER_AUTODETECT; } static bool do_install_audio(ALLEGRO_AUDIO_DRIVER_ENUM mode) { bool retVal; /* check to see if a driver is already installed and running */ if (_al_kcm_driver) { _al_set_error(ALLEGRO_GENERIC_ERROR, "A driver already running"); return false; } if (mode == ALLEGRO_AUDIO_DRIVER_AUTODETECT) { mode = get_config_audio_driver(); } switch (mode) { case ALLEGRO_AUDIO_DRIVER_AUTODETECT: #if defined(ALLEGRO_CFG_KCM_AQUEUE) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_AQUEUE); if (retVal) return retVal; #endif /* If a PA server is running, we should use it by default as it will * hijack ALSA and OSS and using those then just means extra lag. * * FIXME: Detect if no PA server is running and in that case prefer * ALSA and OSS first. */ #if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_PULSEAUDIO); if (retVal) return retVal; #endif #if defined(ALLEGRO_CFG_KCM_ALSA) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_ALSA); if (retVal) return retVal; #endif #if defined(ALLEGRO_CFG_KCM_DSOUND) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_DSOUND); if (retVal) return retVal; #endif #if defined(ALLEGRO_CFG_KCM_OSS) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_OSS); if (retVal) return retVal; #endif #if defined(ALLEGRO_CFG_KCM_OPENAL) retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_OPENAL); if (retVal) return retVal; #endif _al_set_error(ALLEGRO_INVALID_PARAM, "No audio driver can be used."); _al_kcm_driver = NULL; return false; case ALLEGRO_AUDIO_DRIVER_AQUEUE: #if defined(ALLEGRO_CFG_KCM_AQUEUE) if (_al_kcm_aqueue_driver.open() == 0) { ALLEGRO_INFO("Using Apple Audio Queue driver\n"); _al_kcm_driver = &_al_kcm_aqueue_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "Audio Queue driver not available on this platform"); return false; #endif case ALLEGRO_AUDIO_DRIVER_OPENAL: #if defined(ALLEGRO_CFG_KCM_OPENAL) if (_al_kcm_openal_driver.open() == 0) { ALLEGRO_INFO("Using OpenAL driver\n"); _al_kcm_driver = &_al_kcm_openal_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "OpenAL not available on this platform"); return false; #endif case ALLEGRO_AUDIO_DRIVER_ALSA: #if defined(ALLEGRO_CFG_KCM_ALSA) if (_al_kcm_alsa_driver.open() == 0) { ALLEGRO_INFO("Using ALSA driver\n"); _al_kcm_driver = &_al_kcm_alsa_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "ALSA not available on this platform"); return false; #endif case ALLEGRO_AUDIO_DRIVER_OSS: #if defined(ALLEGRO_CFG_KCM_OSS) if (_al_kcm_oss_driver.open() == 0) { ALLEGRO_INFO("Using OSS driver\n"); _al_kcm_driver = &_al_kcm_oss_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "OSS not available on this platform"); return false; #endif case ALLEGRO_AUDIO_DRIVER_PULSEAUDIO: #if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) if (_al_kcm_pulseaudio_driver.open() == 0) { ALLEGRO_INFO("Using PulseAudio driver\n"); _al_kcm_driver = &_al_kcm_pulseaudio_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "PulseAudio not available on this platform"); return false; #endif case ALLEGRO_AUDIO_DRIVER_DSOUND: #if defined(ALLEGRO_CFG_KCM_DSOUND) if (_al_kcm_dsound_driver.open() == 0) { ALLEGRO_INFO("Using DirectSound driver\n"); _al_kcm_driver = &_al_kcm_dsound_driver; return true; } return false; #else _al_set_error(ALLEGRO_INVALID_PARAM, "DirectSound not available on this platform"); return false; #endif default: _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid audio driver"); return false; } } /* Function: al_install_audio */ bool al_install_audio(void) { if (_al_kcm_driver) return true; /* The destructors are initialised even if the audio driver fails to install * because the user may still create samples. */ _al_kcm_init_destructors(); _al_add_exit_func(al_uninstall_audio, "al_uninstall_audio"); return do_install_audio(ALLEGRO_AUDIO_DRIVER_AUTODETECT); } /* Function: al_uninstall_audio */ void al_uninstall_audio(void) { if (_al_kcm_driver) { _al_kcm_shutdown_default_mixer(); _al_kcm_shutdown_destructors(); _al_kcm_driver->close(); _al_kcm_driver = NULL; } else { _al_kcm_shutdown_destructors(); } } /* Function: al_is_audio_installed */ bool al_is_audio_installed(void) { return _al_kcm_driver ? true : false; } /* Function: al_get_allegro_audio_version */ uint32_t al_get_allegro_audio_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_mixer.c0000644000175000001440000007312312020407417017104 0ustar tjadenusers/** * Originally digi.c from allegro wiki * Original authors: KC/Milan * * Converted to allegro5 by Ryan Dickie */ /* Title: Mixer functions */ #include #include #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" ALLEGRO_DEBUG_CHANNEL("audio") typedef union { float f32[ALLEGRO_MAX_CHANNELS]; /* max: 7.1 */ int16_t s16[ALLEGRO_MAX_CHANNELS]; void *ptr; } SAMP_BUF; static void maybe_lock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_lock_mutex(mutex); } } static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_unlock_mutex(mutex); } } /* _al_rechannel_matrix: * This function provides a (temporary!) matrix that can be used to convert * one channel configuration into another. * * Returns a pointer to a statically allocated array. */ static float *_al_rechannel_matrix(ALLEGRO_CHANNEL_CONF orig, ALLEGRO_CHANNEL_CONF target, float gain, float pan) { /* Max 7.1 (8 channels) for input and output */ static float mat[ALLEGRO_MAX_CHANNELS][ALLEGRO_MAX_CHANNELS]; size_t dst_chans = al_get_channel_count(target); size_t src_chans = al_get_channel_count(orig); size_t i, j; /* Start with a simple identity matrix */ memset(mat, 0, sizeof(mat)); for (i = 0; i < src_chans && i < dst_chans; i++) { mat[i][i] = 1.0; } /* Multi-channel -> mono conversion (cuts rear/side channels) */ if (dst_chans == 1 && (orig>>4) > 1) { for (i = 0; i < 2; i++) { mat[0][i] = 1.0 / sqrt(2.0); } /* If the source has a center channel, make sure that's copied 1:1 * (perhaps it should scale the overall output?) */ if ((orig >> 4) & 1) { mat[0][(orig >> 4) - 1] = 1.0; } } /* Center (or mono) -> front l/r conversion */ else if (((orig >> 4) & 1) && !((target >> 4) & 1)) { mat[0][(orig >> 4) - 1] = 1.0 / sqrt(2.0); mat[1][(orig >> 4) - 1] = 1.0 / sqrt(2.0); } /* Copy LFE */ if ((orig >> 4) != (target >> 4) && (orig & 0xF) && (target & 0xF)) { mat[dst_chans-1][src_chans-1] = 1.0; } /* Apply panning, which is supposed to maintain a constant power level. * I took that to mean we want: * sqrt(rgain^2 + lgain^2) = 1.0 */ if (pan != ALLEGRO_AUDIO_PAN_NONE) { float rgain = gain * sqrt(( pan + 1.0f) / 2.0f); float lgain = gain * sqrt((-pan + 1.0f) / 2.0f); /* I dunno what to do about >2 channels, so don't even try for now. */ for (j = 0; j < src_chans; j++) { mat[0][j] *= lgain; mat[1][j] *= rgain; } } /* Apply gain */ if (gain != 1.0f) { for (i = 0; i < dst_chans; i++) { for (j = 0; j < src_chans; j++) { mat[i][j] *= gain; } } } #ifdef DEBUGMODE { char debug[1024]; ALLEGRO_DEBUG("sample matrix:\n"); for (i = 0; i < dst_chans; i++) { strcpy(debug, ""); for (j = 0; j < src_chans; j++) { sprintf(debug + strlen(debug), " %f", mat[i][j]); } ALLEGRO_DEBUG("%s\n", debug); } } #endif return &mat[0][0]; } /* _al_kcm_mixer_rejig_sample_matrix: * Recompute the mixing matrix for a sample attached to a mixer. * The caller must be holding the mixer mutex. */ void _al_kcm_mixer_rejig_sample_matrix(ALLEGRO_MIXER *mixer, ALLEGRO_SAMPLE_INSTANCE *spl) { float *mat; size_t dst_chans; size_t src_chans; size_t i, j; if (spl->matrix) { al_free(spl->matrix); } mat = _al_rechannel_matrix(spl->spl_data.chan_conf, mixer->ss.spl_data.chan_conf, spl->gain, spl->pan); dst_chans = al_get_channel_count(mixer->ss.spl_data.chan_conf); src_chans = al_get_channel_count(spl->spl_data.chan_conf); spl->matrix = al_calloc(1, src_chans * dst_chans * sizeof(float)); for (i = 0; i < dst_chans; i++) { for (j = 0; j < src_chans; j++) { spl->matrix[i*src_chans + j] = mat[i*ALLEGRO_MAX_CHANNELS + j]; } } } /* fix_looped_position: * When a stream loops, this will fix up the position and anything else to * allow it to safely continue playing as expected. Returns false if it * should stop being mixed. */ static bool fix_looped_position(ALLEGRO_SAMPLE_INSTANCE *spl) { bool is_empty; ALLEGRO_AUDIO_STREAM *stream; /* Looping! Should be mostly self-explanatory */ switch (spl->loop) { case ALLEGRO_PLAYMODE_LOOP: if (spl->step > 0) { while (spl->pos >= spl->loop_end) { spl->pos -= (spl->loop_end - spl->loop_start); } } else if (spl->step < 0) { while (spl->pos < spl->loop_start) { spl->pos += (spl->loop_end - spl->loop_start); } } return true; case ALLEGRO_PLAYMODE_BIDIR: /* When doing bi-directional looping, you need to do a follow-up * check for the opposite direction if a loop occurred, otherwise * you could end up misplaced on small, high-step loops. */ if (spl->step >= 0) { check_forward: if (spl->pos >= spl->loop_end) { spl->step = -spl->step; spl->pos = spl->loop_end - (spl->pos - spl->loop_end) - 1; goto check_backward; } } else { check_backward: if (spl->pos < spl->loop_start || spl->pos >= spl->loop_end) { spl->step = -spl->step; spl->pos = spl->loop_start + (spl->loop_start - spl->pos); goto check_forward; } } return true; case ALLEGRO_PLAYMODE_ONCE: if (spl->pos < spl->spl_data.len) { return true; } spl->pos = 0; spl->is_playing = false; return false; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: if (spl->pos < spl->spl_data.len) { return true; } stream = (ALLEGRO_AUDIO_STREAM *)spl; is_empty = !_al_kcm_refill_stream(stream); if (is_empty && stream->is_draining) { stream->spl.is_playing = false; } _al_kcm_emit_stream_events(stream); return !(is_empty); } ASSERT(false); return false; } #include "kcm_mixer_helpers.inc" static INLINE int32_t clamp(int32_t val, int32_t min, int32_t max) { /* Clamp to min */ val -= min; val &= (~val) >> 31; val += min; /* Clamp to max */ val -= max; val &= val >> 31; val += max; return val; } /* Mix as many sample values as possible from the source sample into a mixer * buffer. Implements stream_reader_t. * * TYPE is the type of the sample values in the mixer buffer, and * NEXT_SAMPLE_VALUE must return a buffer of the same type. * * Note: Uses Bresenham to keep the precise sample position. */ #define BRESENHAM \ do { \ delta = spl->step > 0 ? spl->step : spl->step - spl->step_denom + 1; \ delta /= spl->step_denom; \ delta_error = spl->step - delta * spl->step_denom; \ } while (0) #define MAKE_MIXER(NAME, NEXT_SAMPLE_VALUE, TYPE) \ static void NAME(void *source, void **vbuf, unsigned int *samples, \ ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) \ { \ ALLEGRO_SAMPLE_INSTANCE *spl = (ALLEGRO_SAMPLE_INSTANCE *)source; \ TYPE *buf = *vbuf; \ size_t maxc = al_get_channel_count(spl->spl_data.chan_conf); \ size_t samples_l = *samples; \ size_t c; \ int delta, delta_error; \ SAMP_BUF samp_buf; \ \ BRESENHAM; \ \ if (!spl->is_playing) \ return; \ \ while (samples_l > 0) { \ const TYPE *s; \ int old_step = spl->step; \ \ if (!fix_looped_position(spl)) \ return; \ if (old_step != spl->step) { \ BRESENHAM; \ } \ \ /* It might be worth preparing multiple sample values at once. */ \ s = (TYPE *) NEXT_SAMPLE_VALUE(&samp_buf, spl, maxc); \ \ for (c = 0; c < dest_maxc; c++) { \ ALLEGRO_STATIC_ASSERT(kcm_mixer, ALLEGRO_MAX_CHANNELS == 8); \ switch (maxc) { \ /* Each case falls through. */ \ case 8: *buf += s[7] * spl->matrix[c*maxc + 7]; \ case 7: *buf += s[6] * spl->matrix[c*maxc + 6]; \ case 6: *buf += s[5] * spl->matrix[c*maxc + 5]; \ case 5: *buf += s[4] * spl->matrix[c*maxc + 4]; \ case 4: *buf += s[3] * spl->matrix[c*maxc + 3]; \ case 3: *buf += s[2] * spl->matrix[c*maxc + 2]; \ case 2: *buf += s[1] * spl->matrix[c*maxc + 1]; \ case 1: *buf += s[0] * spl->matrix[c*maxc + 0]; \ default: break; \ } \ buf++; \ } \ \ spl->pos += delta; \ spl->pos_bresenham_error += delta_error; \ if (spl->pos_bresenham_error >= spl->step_denom) { \ spl->pos++; \ spl->pos_bresenham_error -= spl->step_denom; \ } \ samples_l--; \ } \ fix_looped_position(spl); \ (void)buffer_depth; \ } MAKE_MIXER(read_to_mixer_point_float_32, point_spl32, float) MAKE_MIXER(read_to_mixer_linear_float_32, linear_spl32, float) MAKE_MIXER(read_to_mixer_cubic_float_32, cubic_spl32, float) MAKE_MIXER(read_to_mixer_point_int16_t_16, point_spl16, int16_t) MAKE_MIXER(read_to_mixer_linear_int16_t_16, linear_spl16, int16_t) #undef MAKE_MIXER /* _al_kcm_mixer_read: * Mixes the streams attached to the mixer and writes additively to the * specified buffer (or if *buf is NULL, indicating a voice, convert it and * set it to the buffer pointer). */ void _al_kcm_mixer_read(void *source, void **buf, unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) { const ALLEGRO_MIXER *mixer; ALLEGRO_MIXER *m = (ALLEGRO_MIXER *)source; int maxc = al_get_channel_count(m->ss.spl_data.chan_conf); int samples_l = *samples; int i; if (!m->ss.is_playing) return; /* Make sure the mixer buffer is big enough. */ if (m->ss.spl_data.len*maxc < samples_l*maxc) { al_free(m->ss.spl_data.buffer.ptr); m->ss.spl_data.buffer.ptr = al_malloc(samples_l*maxc*al_get_audio_depth_size(m->ss.spl_data.depth)); if (!m->ss.spl_data.buffer.ptr) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating mixer buffer"); m->ss.spl_data.len = 0; return; } m->ss.spl_data.len = samples_l; } mixer = m; /* Clear the buffer to silence. */ memset(mixer->ss.spl_data.buffer.ptr, 0, samples_l * maxc * al_get_audio_depth_size(mixer->ss.spl_data.depth)); /* Mix the streams into the mixer buffer. */ for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); ALLEGRO_SAMPLE_INSTANCE *spl = *slot; ASSERT(spl->spl_read); spl->spl_read(spl, (void **) &mixer->ss.spl_data.buffer.ptr, samples, m->ss.spl_data.depth, maxc); } /* Call the post-processing callback. */ if (mixer->postprocess_callback) { mixer->postprocess_callback(mixer->ss.spl_data.buffer.ptr, *samples, mixer->pp_callback_userdata); } samples_l *= maxc; /* Apply the gain if necessary. */ if (mixer->ss.gain != 1.0f) { float mixer_gain = mixer->ss.gain; unsigned long i = samples_l; switch (m->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { float *p = mixer->ss.spl_data.buffer.f32; while (i-- > 0) { *p++ *= mixer_gain; } break; } case ALLEGRO_AUDIO_DEPTH_INT16: { int16_t *p = mixer->ss.spl_data.buffer.s16; while (i-- > 0) { *p++ *= mixer_gain; } break; } case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } } /* Feeding to a non-voice. * Currently we only support mixers of the same audio depth doing this. */ if (*buf) { switch (m->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { /* We don't need to clamp in the mixer yet. */ float *lbuf = *buf; float *src = mixer->ss.spl_data.buffer.f32; while (samples_l-- > 0) { *lbuf += *src; lbuf++; src++; } break; case ALLEGRO_AUDIO_DEPTH_INT16: { int16_t *lbuf = *buf; int16_t *src = mixer->ss.spl_data.buffer.s16; while (samples_l-- > 0) { int32_t x = *lbuf + *src; if (x < -32768) x = -32768; else if (x > 32767) x = 32767; *lbuf = (int16_t)x; lbuf++; src++; } break; } case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } } return; } /* We're feeding to a voice. * Clamp and convert the mixed data for the voice. */ *buf = mixer->ss.spl_data.buffer.ptr; switch (buffer_depth & ~ALLEGRO_AUDIO_DEPTH_UNSIGNED) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: /* Do we need to clamp? */ break; case ALLEGRO_AUDIO_DEPTH_INT24: switch (mixer->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { int32_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) ? 0x800000 : 0); int32_t *lbuf = mixer->ss.spl_data.buffer.s24; float *src = mixer->ss.spl_data.buffer.f32; while (samples_l > 0) { *lbuf = clamp(*(src++) * ((float)0x7FFFFF + 0.5f), ~0x7FFFFF, 0x7FFFFF); *lbuf += off; lbuf++; samples_l--; } break; } case ALLEGRO_AUDIO_DEPTH_INT16: /* XXX not yet implemented */ ASSERT(false); break; case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } break; case ALLEGRO_AUDIO_DEPTH_INT16: switch (mixer->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { int16_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) ? 0x8000 : 0); int16_t *lbuf = mixer->ss.spl_data.buffer.s16; float *src = mixer->ss.spl_data.buffer.f32; while (samples_l > 0) { *lbuf = clamp(*(src++) * ((float)0x7FFF + 0.5f), ~0x7FFF, 0x7FFF); *lbuf += off; lbuf++; samples_l--; } break; } case ALLEGRO_AUDIO_DEPTH_INT16: /* Handle signedness differences. */ if (buffer_depth != ALLEGRO_AUDIO_DEPTH_INT16) { int16_t *lbuf = mixer->ss.spl_data.buffer.s16; while (samples_l > 0) { *lbuf++ ^= 0x8000; samples_l--; } } break; case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } break; /* Ugh, do we really want to support 8-bit output? */ case ALLEGRO_AUDIO_DEPTH_INT8: switch (mixer->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { int8_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) ? 0x80 : 0); int8_t *lbuf = mixer->ss.spl_data.buffer.s8; float *src = mixer->ss.spl_data.buffer.f32; while (samples_l > 0) { *lbuf = clamp(*(src++) * ((float)0x7F + 0.5f), ~0x7F, 0x7F); *lbuf += off; lbuf++; samples_l--; } break; } case ALLEGRO_AUDIO_DEPTH_INT16: /* XXX not yet implemented */ ASSERT(false); break; case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } break; case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Impossible. */ ASSERT(false); break; } (void)dest_maxc; } /* Function: al_create_mixer */ ALLEGRO_MIXER *al_create_mixer(unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) { ALLEGRO_MIXER *mixer; ALLEGRO_CONFIG *config; int default_mixer_quality = ALLEGRO_MIXER_QUALITY_LINEAR; /* XXX this is in the wrong place */ config = al_get_system_config(); if (config) { const char *p; p = al_get_config_value(config, "audio", "default_mixer_quality"); if (p && p[0] != '\0') { if (!_al_stricmp(p, "point")) { ALLEGRO_INFO("Point sampling\n"); default_mixer_quality = ALLEGRO_MIXER_QUALITY_POINT; } else if (!_al_stricmp(p, "linear")) { ALLEGRO_INFO("Linear interpolation\n"); default_mixer_quality = ALLEGRO_MIXER_QUALITY_LINEAR; } else if (!_al_stricmp(p, "cubic")) { ALLEGRO_INFO("Cubic interpolation\n"); default_mixer_quality = ALLEGRO_MIXER_QUALITY_CUBIC; } } } if (!freq) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to create mixer with no frequency"); return NULL; } if (depth != ALLEGRO_AUDIO_DEPTH_FLOAT32 && depth != ALLEGRO_AUDIO_DEPTH_INT16) { _al_set_error(ALLEGRO_INVALID_PARAM, "Unsupported mixer depth"); return NULL; } mixer = al_calloc(1, sizeof(ALLEGRO_MIXER)); if (!mixer) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating mixer object"); return NULL; } mixer->ss.is_playing = true; mixer->ss.spl_data.free_buf = true; mixer->ss.loop = ALLEGRO_PLAYMODE_ONCE; /* XXX should we have a specific loop mode? */ mixer->ss.gain = 1.0f; mixer->ss.spl_data.depth = depth; mixer->ss.spl_data.chan_conf = chan_conf; mixer->ss.spl_data.frequency = freq; mixer->ss.is_mixer = true; mixer->ss.spl_read = NULL; mixer->quality = default_mixer_quality; _al_vector_init(&mixer->streams, sizeof(ALLEGRO_SAMPLE_INSTANCE *)); _al_kcm_register_destructor(mixer, (void (*)(void *)) al_destroy_mixer); return mixer; } /* Function: al_destroy_mixer */ void al_destroy_mixer(ALLEGRO_MIXER *mixer) { if (mixer) { _al_kcm_unregister_destructor(mixer); _al_kcm_destroy_sample(&mixer->ss, false); } } /* This function is ALLEGRO_MIXER aware */ /* Function: al_attach_sample_instance_to_mixer */ bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_MIXER *mixer) { ALLEGRO_SAMPLE_INSTANCE **slot; ASSERT(mixer); ASSERT(spl); /* Already referenced, do not attach. */ if (spl->parent.u.ptr) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach a sample that's already attached"); return false; } maybe_lock_mutex(mixer->ss.mutex); _al_kcm_stream_set_mutex(spl, mixer->ss.mutex); slot = _al_vector_alloc_back(&mixer->streams); if (!slot) { if (mixer->ss.mutex) { al_unlock_mutex(mixer->ss.mutex); } _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating attachment pointers"); return false; } (*slot) = spl; spl->step = (spl->spl_data.frequency) * spl->speed; spl->step_denom = mixer->ss.spl_data.frequency; /* Don't want to be trapped with a step value of 0. */ if (spl->step == 0) { if (spl->speed > 0.0f) spl->step = 1; else spl->step = -1; } /* Set the proper sample stream reader. */ ASSERT(spl->spl_read == NULL); if (spl->is_mixer) { spl->spl_read = _al_kcm_mixer_read; } else { switch (mixer->ss.spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: switch (mixer->quality) { case ALLEGRO_MIXER_QUALITY_POINT: spl->spl_read = read_to_mixer_point_float_32; break; case ALLEGRO_MIXER_QUALITY_LINEAR: spl->spl_read = read_to_mixer_linear_float_32; break; case ALLEGRO_MIXER_QUALITY_CUBIC: spl->spl_read = read_to_mixer_cubic_float_32; break; } break; case ALLEGRO_AUDIO_DEPTH_INT16: switch (mixer->quality) { case ALLEGRO_MIXER_QUALITY_POINT: spl->spl_read = read_to_mixer_point_int16_t_16; break; case ALLEGRO_MIXER_QUALITY_CUBIC: ALLEGRO_WARN("Falling back to linear interpolation\n"); /* fallthrough */ case ALLEGRO_MIXER_QUALITY_LINEAR: spl->spl_read = read_to_mixer_linear_int16_t_16; break; } break; case ALLEGRO_AUDIO_DEPTH_INT8: case ALLEGRO_AUDIO_DEPTH_INT24: case ALLEGRO_AUDIO_DEPTH_UINT8: case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_UINT24: /* Unsupported mixer depths. */ ASSERT(false); break; } _al_kcm_mixer_rejig_sample_matrix(mixer, spl); } spl->parent.u.mixer = mixer; spl->parent.is_voice = false; maybe_unlock_mutex(mixer->ss.mutex); return true; } /* Function: al_attach_audio_stream_to_mixer */ bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer) { ASSERT(mixer); ASSERT(stream); return al_attach_sample_instance_to_mixer(&stream->spl, mixer); } /* Function: al_attach_mixer_to_mixer */ bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer) { ASSERT(mixer); ASSERT(stream); if (mixer->ss.spl_data.frequency != stream->ss.spl_data.frequency) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach a mixer with different frequencies"); return false; } if (mixer->ss.spl_data.depth != stream->ss.spl_data.depth) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Mixers of different audio depths cannot be attached to one another"); return false; } return al_attach_sample_instance_to_mixer(&stream->ss, mixer); } /* Function: al_set_mixer_postprocess_callback */ bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer, void (*pp_callback)(void *buf, unsigned int samples, void *data), void *pp_callback_userdata) { ASSERT(mixer); maybe_lock_mutex(mixer->ss.mutex); mixer->postprocess_callback = pp_callback; mixer->pp_callback_userdata = pp_callback_userdata; maybe_unlock_mutex(mixer->ss.mutex); return true; } /* Function: al_get_mixer_frequency */ unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->ss.spl_data.frequency; } /* Function: al_get_mixer_channels */ ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->ss.spl_data.chan_conf; } /* Function: al_get_mixer_depth */ ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->ss.spl_data.depth; } /* Function: al_get_mixer_quality */ ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->quality; } /* Function: al_get_mixer_gain */ float al_get_mixer_gain(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->ss.gain; } /* Function: al_get_mixer_playing */ bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return mixer->ss.is_playing; } /* Function: al_get_mixer_attached */ bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer) { ASSERT(mixer); return _al_vector_is_nonempty(&mixer->streams); } /* Function: al_set_mixer_frequency */ bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val) { ASSERT(mixer); /* You can change the frequency of a mixer as long as it's not attached * to anything. */ if (mixer->ss.parent.u.ptr) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to change the frequency of an attached mixer"); return false; } mixer->ss.spl_data.frequency = val; return true; } /* Function: al_set_mixer_quality */ bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality) { bool ret; ASSERT(mixer); maybe_lock_mutex(mixer->ss.mutex); if (mixer->quality == new_quality) { ret = true; } else if (_al_vector_size(&mixer->streams) == 0) { mixer->quality = new_quality; ret = true; } else { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to change the quality of a mixer with attachments"); ret = false; } maybe_unlock_mutex(mixer->ss.mutex); return ret; } /* Function: al_set_mixer_gain */ bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain) { int i; ASSERT(mixer); maybe_lock_mutex(mixer->ss.mutex); if (mixer->ss.gain != new_gain) { mixer->ss.gain = new_gain; for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); _al_kcm_mixer_rejig_sample_matrix(mixer, *slot); } } maybe_unlock_mutex(mixer->ss.mutex); return true; } /* Function: al_set_mixer_playing */ bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val) { ASSERT(mixer); mixer->ss.is_playing = val; return true; } /* Function: al_detach_mixer */ bool al_detach_mixer(ALLEGRO_MIXER *mixer) { ASSERT(mixer); _al_kcm_detach_from_parent(&mixer->ss); ASSERT(mixer->ss.spl_read == NULL); return true; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/dsound.cpp0000644000175000001440000004571412154703577017005 0ustar tjadenusers/* * Based on DirectSound driver by KC/Milan */ #include #include #include #include /* dsound.h from the official DirectX SDK uses __null to annotate some * function arguments. It is #defined away by a macro in sal.h, but this * breaks GCC headers, as they also use __null (but for a different * purpose). This pre-processor block undefines __null which returns * __null to acting like a GCC keyword. * This does nothing for the unofficial DirectX SDK, which has __null * manually removed. */ #if defined __MINGW32__ && defined __null #undef __null #endif /* I'm not sure what library this is supposed to be in, but I couldn't find it yet */ const IID GUID_NULL = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; static const IID _al_IID_IDirectSoundBuffer8 = { 0x6825a449, 0x7524, 0x4d82, { 0x92, 0x0f, 0x50, 0xe3, 0x6a, 0xb3, 0xab, 0x1e } }; #include "allegro5/allegro.h" extern "C" { ALLEGRO_DEBUG_CHANNEL("audio-dsound") #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_system.h" /* This is used to stop MinGW from complaining about type-punning */ #define MAKE_UNION(ptr, t) \ union { \ LPVOID *v; \ t p; \ } u; \ u.p = (ptr); typedef HRESULT (WINAPI *DIRECTSOUNDCREATE8PROC)(LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter); /* DirectSound vars */ static const char* _al_dsound_module_name = "dsound.dll"; static void *_al_dsound_module = NULL; static DIRECTSOUNDCREATE8PROC _al_dsound_create = (DIRECTSOUNDCREATE8PROC)NULL; static IDirectSound8 *device; static char ds_err_str[100]; static int buffer_size_in_samples = 8192; // default static int buffer_size; // in bytes #define MIN_BUFFER_SIZE 1024 #define MIN_FILL 512 #define MAX_FILL 1024 static void dsound_set_buffer_size(int bits_per_sample) { ALLEGRO_CONFIG *config = al_get_system_config(); if (config) { const char *val = al_get_config_value(config, "directsound", "buffer_size"); if (val && val[0] != '\0') { int n = atoi(val); if (n < MIN_BUFFER_SIZE) n = MIN_BUFFER_SIZE; buffer_size_in_samples = n; } } buffer_size = buffer_size_in_samples * (bits_per_sample/8); } static char *ds_get_error(HRESULT hr) { switch (hr) { case DSERR_ALLOCATED: strcpy(ds_err_str, "DSERR_ALLOCATED"); break; case DSERR_BADFORMAT: strcpy(ds_err_str, "DSERR_BADFORMAT"); break; case DSERR_BUFFERTOOSMALL: strcpy(ds_err_str, "DSERR_BUFFERTOOSMALL"); break; case DSERR_CONTROLUNAVAIL: strcpy(ds_err_str, "DSERR_CONTROLUNAVAIL"); break; case DSERR_DS8_REQUIRED: strcpy(ds_err_str, "DSERR_DS8_REQUIRED"); break; case DSERR_INVALIDCALL: strcpy(ds_err_str, "DSERR_INVALIDCALL"); break; case DSERR_INVALIDPARAM: strcpy(ds_err_str, "DSERR_INVALIDPARAM"); break; case DSERR_NOAGGREGATION: strcpy(ds_err_str, "DSERR_NOAGGREGATION"); break; case DSERR_OUTOFMEMORY: strcpy(ds_err_str, "DSERR_OUTOFMEMORY"); break; case DSERR_UNINITIALIZED: strcpy(ds_err_str, "DSERR_UNINITIALIZED"); break; case DSERR_UNSUPPORTED: strcpy(ds_err_str, "DSERR_UNSUPPORTED"); break; } return ds_err_str; } /* Custom struct to hold voice information DirectSound needs */ /* TODO: review */ typedef struct ALLEGRO_DS_DATA { int bits_per_sample; int channels; DSBUFFERDESC desc; WAVEFORMATEX wave_fmt; LPDIRECTSOUNDBUFFER ds_buffer; LPDIRECTSOUNDBUFFER8 ds8_buffer; int stop_voice; ALLEGRO_THREAD *thread; } ALLEGRO_DS_DATA; static bool _dsound_voice_is_playing(const ALLEGRO_VOICE *voice); /* Custom routine which runs in another thread to periodically check if DirectSound wants more data for a stream */ static void* _dsound_update(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = (ALLEGRO_VOICE *)arg; ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA*)voice->extra; const int bytes_per_sample = ex_data->bits_per_sample / 8; DWORD play_cursor = 0; DWORD write_cursor; DWORD saved_play_cursor = 0; unsigned int samples; LPVOID ptr1, ptr2; DWORD block1_bytes, block2_bytes; unsigned char *data; HRESULT hr; (void)self; unsigned char *silence = (unsigned char *)al_malloc(buffer_size); int silence_value = _al_kcm_get_silence(voice->depth); memset(silence, silence_value, buffer_size); /* Fill buffer */ hr = ex_data->ds8_buffer->Lock(0, buffer_size, &ptr1, &block1_bytes, &ptr2, &block2_bytes, DSBLOCK_ENTIREBUFFER); if (!FAILED(hr)) { samples = buffer_size / bytes_per_sample / ex_data->channels; data = (unsigned char *) _al_voice_update(voice, &samples); memcpy(ptr1, data, block1_bytes); memcpy(ptr2, data + block1_bytes, block2_bytes); ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, ptr2, block2_bytes); } ex_data->ds8_buffer->Play(0, 0, DSBPLAY_LOOPING); do { if (!_dsound_voice_is_playing(voice)) { ex_data->ds8_buffer->Play(0, 0, DSBPLAY_LOOPING); } ex_data->ds8_buffer->GetCurrentPosition(&play_cursor, &write_cursor); /* We try to fill the gap between the saved_play_cursor and the * play_cursor. */ int d = play_cursor - saved_play_cursor; if (d < 0) d += buffer_size; /* Don't fill small gaps. Let it accumulate to amortise the cost of * mixing the samples and locking/unlocking the buffer. */ if (d < MIN_FILL) { al_rest(0.005); continue; } /* Don't generate too many samples at once. The buffer may underrun * while we wait for _al_voice_update to complete. */ samples = d / bytes_per_sample / ex_data->channels; if (samples > MAX_FILL) { samples = MAX_FILL; } /* Generate the samples. */ data = (unsigned char *) _al_voice_update(voice, &samples); if (data == NULL) { data = silence; } hr = ex_data->ds8_buffer->Lock(saved_play_cursor, samples * bytes_per_sample * ex_data->channels, &ptr1, &block1_bytes, &ptr2, &block2_bytes, 0); if (!FAILED(hr)) { memcpy(ptr1, data, block1_bytes); memcpy(ptr2, data + block1_bytes, block2_bytes); hr = ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, ptr2, block2_bytes); if (FAILED(hr)) { ALLEGRO_ERROR("Unlock failed: %s\n", ds_get_error(hr)); } } saved_play_cursor += block1_bytes + block2_bytes; saved_play_cursor %= buffer_size; } while (!ex_data->stop_voice); ex_data->ds8_buffer->Stop(); al_free(silence); ex_data->stop_voice = 0; al_broadcast_cond(voice->cond); return NULL; } /* The open method starts up the driver and should lock the device, using the previously set paramters, or defaults. It shouldn't need to start sending audio data to the device yet, however. */ static int _dsound_open() { HRESULT hr; ALLEGRO_DEBUG("Loading DirectSound module\n"); /* load DirectSound module */ _al_dsound_module = _al_open_library(_al_dsound_module_name); if (_al_dsound_module == NULL) { ALLEGRO_ERROR("Failed to open '%s' library\n", _al_dsound_module_name); return 1; } /* import DirectSound create proc */ _al_dsound_create = (DIRECTSOUNDCREATE8PROC)_al_import_symbol(_al_dsound_module, "DirectSoundCreate8"); if (_al_dsound_create == NULL) { ALLEGRO_ERROR("DirectSoundCreate8 not in %s\n", _al_dsound_module_name); _al_close_library(_al_dsound_module); return 1; } ALLEGRO_INFO("Starting DirectSound...\n"); /* FIXME: Use default device until we have device enumeration */ hr = _al_dsound_create(NULL, &device, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("DirectSoundCreate8 failed\n"); _al_close_library(_al_dsound_module); return 1; } ALLEGRO_DEBUG("DirectSoundCreate8 succeeded\n"); /* FIXME: The window specified here is probably very wrong. NULL won't work either. */ hr = device->SetCooperativeLevel(GetForegroundWindow(), DSSCL_PRIORITY); if (FAILED(hr)) { ALLEGRO_ERROR("SetCooperativeLevel failed\n"); _al_close_library(_al_dsound_module); return 1; } return 0; } /* The close method should close the device, freeing any resources, and allow other processes to use the device */ static void _dsound_close() { ALLEGRO_DEBUG("Releasing device\n"); device->Release(); ALLEGRO_DEBUG("Released device\n"); _al_close_library(_al_dsound_module); ALLEGRO_INFO("DirectSound closed\n"); } /* The allocate_voice method should grab a voice from the system, and allocate any data common to streaming and non-streaming sources. */ static int _dsound_allocate_voice(ALLEGRO_VOICE *voice) { ALLEGRO_DS_DATA *ex_data; int bits_per_sample; int channels; ALLEGRO_DEBUG("Allocating voice\n"); /* openal doesn't support very much! */ switch (voice->depth) { case ALLEGRO_AUDIO_DEPTH_UINT8: /* format supported */ bits_per_sample = 8; break; case ALLEGRO_AUDIO_DEPTH_INT8: ALLEGRO_ERROR("DirectSound requires 8-bit data to be unsigned\n"); return 1; case ALLEGRO_AUDIO_DEPTH_UINT16: ALLEGRO_ERROR("DirectSound requires 16-bit data to be signed\n"); return 1; case ALLEGRO_AUDIO_DEPTH_INT16: /* format supported */ bits_per_sample = 16; break; case ALLEGRO_AUDIO_DEPTH_UINT24: ALLEGRO_ERROR("DirectSound does not support 24-bit data\n"); return 1; case ALLEGRO_AUDIO_DEPTH_INT24: ALLEGRO_ERROR("DirectSound does not support 24-bit data\n"); return 1; case ALLEGRO_AUDIO_DEPTH_FLOAT32: ALLEGRO_ERROR("DirectSound does not support 32-bit floating data\n"); return 1; default: ALLEGRO_ERROR("Cannot allocate unknown voice depth\n"); return 1; } switch (voice->chan_conf) { case ALLEGRO_CHANNEL_CONF_1: channels = 1; break; case ALLEGRO_CHANNEL_CONF_2: channels = 2; break; default: ALLEGRO_ERROR("Unsupported number of channels\n"); return 1; } ex_data = (ALLEGRO_DS_DATA *)al_calloc(1, sizeof(*ex_data)); if (!ex_data) { ALLEGRO_ERROR("Could not allocate voice data memory\n"); return 1; } ex_data->bits_per_sample = bits_per_sample; ex_data->channels = channels; ex_data->stop_voice = 1; dsound_set_buffer_size(bits_per_sample); voice->extra = ex_data; ALLEGRO_DEBUG("Allocated voice\n"); return 0; } /* The deallocate_voice method should free the resources for the given voice, but still retain a hold on the device. The voice should be stopped and unloaded by the time this is called */ static void _dsound_deallocate_voice(ALLEGRO_VOICE *voice) { ALLEGRO_DEBUG("Deallocating voice\n"); al_free(voice->extra); voice->extra = NULL; ALLEGRO_DEBUG("Deallocated voice\n"); } /* The load_voice method loads a sample into the driver's memory. The voice's 'streaming' field will be set to false for these voices, and it's 'buffer_size' field will be the total length in bytes of the sample data. The voice's attached sample's looping mode should be honored, and loading must fail if it cannot be. */ static int _dsound_load_voice(ALLEGRO_VOICE *voice, const void *_data) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; HRESULT hr; LPVOID ptr1, ptr2; DWORD block1_bytes, block2_bytes; MAKE_UNION(&ex_data->ds8_buffer, LPDIRECTSOUNDBUFFER8 *); ALLEGRO_DEBUG("Loading voice\n"); ex_data->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; ex_data->wave_fmt.nChannels = ex_data->channels; ex_data->wave_fmt.nSamplesPerSec = voice->frequency; ex_data->wave_fmt.nBlockAlign = ex_data->channels * (ex_data->bits_per_sample/8); ex_data->wave_fmt.nAvgBytesPerSec = ex_data->wave_fmt.nBlockAlign * voice->frequency; ex_data->wave_fmt.wBitsPerSample = ex_data->bits_per_sample; ex_data->wave_fmt.cbSize = 0; ex_data->desc.dwSize = sizeof(DSBUFFERDESC); ex_data->desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS; /* FIXME: software mixing for now */ ex_data->desc.dwBufferBytes = voice->buffer_size; ex_data->desc.dwReserved = 0; ex_data->desc.lpwfxFormat = &ex_data->wave_fmt; ex_data->desc.guid3DAlgorithm = DS3DALG_DEFAULT; hr = device->CreateSoundBuffer(&ex_data->desc, &ex_data->ds_buffer, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("CreateSoundBuffer failed\n"); al_free(ex_data); return 1; } ex_data->ds_buffer->QueryInterface(_al_IID_IDirectSoundBuffer8, u.v); hr = ex_data->ds8_buffer->Lock(0, voice->buffer_size, &ptr1, &block1_bytes, &ptr2, &block2_bytes, 0); if (FAILED(hr)) { ALLEGRO_ERROR("Locking buffer failed\n"); return 1; } unsigned char *data = (unsigned char *) _data; memcpy(ptr1, data, block1_bytes); memcpy(ptr2, data + block1_bytes, block2_bytes); ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, ptr2, block2_bytes); return 0; } /* The unload_voice method unloads a sample previously loaded with load_voice. This method should not be called on a streaming voice. */ static void _dsound_unload_voice(ALLEGRO_VOICE *voice) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; ALLEGRO_DEBUG("Unloading voice\n"); ex_data->ds8_buffer->Release(); ALLEGRO_DEBUG("Unloaded voice\n"); } /* The start_voice should, surprise, start the voice. For streaming voices, it should start polling the device and call _al_voice_update for audio data. For non-streaming voices, it should resume playing from the last set position */ static int _dsound_start_voice(ALLEGRO_VOICE *voice) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; HRESULT hr; MAKE_UNION(&ex_data->ds8_buffer, LPDIRECTSOUNDBUFFER8 *); ALLEGRO_DEBUG("Starting voice\n"); if (!voice->is_streaming) { ex_data->ds8_buffer->SetCurrentPosition(0); hr = ex_data->ds8_buffer->Play(0, 0, 0); if (FAILED(hr)) { ALLEGRO_ERROR("Streaming voice failed to start\n"); return 1; } ALLEGRO_INFO("Streaming voice started\n"); return 0; } if (ex_data->stop_voice != 0) { ex_data->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; ex_data->wave_fmt.nChannels = ex_data->channels; ex_data->wave_fmt.nSamplesPerSec = voice->frequency; ex_data->wave_fmt.nBlockAlign = ex_data->channels * (ex_data->bits_per_sample/8); ex_data->wave_fmt.nAvgBytesPerSec = ex_data->wave_fmt.nBlockAlign * voice->frequency; ex_data->wave_fmt.wBitsPerSample = ex_data->bits_per_sample; ex_data->wave_fmt.cbSize = 0; ex_data->desc.dwSize = sizeof(DSBUFFERDESC); ex_data->desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS; /* FIXME: software mixing for now */ ex_data->desc.dwBufferBytes = buffer_size; ex_data->desc.dwReserved = 0; ex_data->desc.lpwfxFormat = &ex_data->wave_fmt; ex_data->desc.guid3DAlgorithm = DS3DALG_DEFAULT; ALLEGRO_DEBUG("CreateSoundBuffer\n"); hr = device->CreateSoundBuffer(&ex_data->desc, &ex_data->ds_buffer, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("CreateSoundBuffer failed: %s\n", ds_get_error(hr)); al_free(ex_data); return 1; } ALLEGRO_DEBUG("CreateSoundBuffer succeeded\n"); ex_data->ds_buffer->QueryInterface(_al_IID_IDirectSoundBuffer8, u.v); ex_data->ds8_buffer->SetVolume(DSBVOLUME_MAX); ALLEGRO_DEBUG("Starting _dsound_update thread\n"); ex_data->stop_voice = 0; ex_data->thread = al_create_thread(_dsound_update, (void*) voice); al_start_thread(ex_data->thread); } else { ALLEGRO_WARN("stop_voice == 0\n"); } ALLEGRO_INFO("Voice started\n"); return 0; } /* The stop_voice method should stop playback. For non-streaming voices, it should leave the data loaded, and reset the voice position to 0. */ static int _dsound_stop_voice(ALLEGRO_VOICE* voice) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; ALLEGRO_DEBUG("Stopping voice\n"); if (!ex_data->ds8_buffer) { ALLEGRO_ERROR("Trying to stop empty voice buffer\n"); return 1; } /* if playing a sample */ if (!voice->is_streaming) { ALLEGRO_DEBUG("Stopping non-streaming voice\n"); ex_data->ds8_buffer->Stop(); ALLEGRO_INFO("Non-streaming voice stopped\n"); return 0; } if (ex_data->stop_voice == 0) { ALLEGRO_DEBUG("Joining thread\n"); ex_data->stop_voice = 1; while (ex_data->stop_voice == 1) { al_wait_cond(voice->cond, voice->mutex); } al_join_thread(ex_data->thread, NULL); ALLEGRO_DEBUG("Joined thread\n"); ALLEGRO_DEBUG("Destroying thread\n"); al_destroy_thread(ex_data->thread); ALLEGRO_DEBUG("Thread destroyed\n"); } ALLEGRO_DEBUG("Releasing buffer\n"); ex_data->ds8_buffer->Release(); ex_data->ds8_buffer = NULL; ALLEGRO_INFO("Voice stopped\n"); return 0; } /* The voice_is_playing method should only be called on non-streaming sources, and should return true if the voice is playing */ static bool _dsound_voice_is_playing(const ALLEGRO_VOICE *voice) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; DWORD status; if (!ex_data) { ALLEGRO_WARN("ex_data is null\n"); return false; } ex_data->ds8_buffer->GetStatus(&status); return (status & DSBSTATUS_PLAYING); } /* The get_voice_position method should return the current sample position of the voice (sample_pos = byte_pos / (depth/8) / channels). This should never be called on a streaming voice. */ static unsigned int _dsound_get_voice_position(const ALLEGRO_VOICE *voice) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; DWORD play_pos; HRESULT hr; hr = ex_data->ds8_buffer->GetCurrentPosition(&play_pos, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("GetCurrentPosition failed\n"); return 0; } return play_pos / (ex_data->channels / (ex_data->bits_per_sample/8)); } /* The set_voice_position method should set the voice's playback position, given the value in samples. This should never be called on a streaming voice. */ static int _dsound_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; HRESULT hr; val *= ex_data->channels * (ex_data->bits_per_sample/8); hr = ex_data->ds8_buffer->SetCurrentPosition(val); if (FAILED(hr)) { ALLEGRO_ERROR("SetCurrentPosition failed\n"); return 1; } return 0; } ALLEGRO_AUDIO_DRIVER _al_kcm_dsound_driver = { "DirectSound", _dsound_open, _dsound_close, _dsound_allocate_voice, _dsound_deallocate_voice, _dsound_load_voice, _dsound_unload_voice, _dsound_start_voice, _dsound_stop_voice, _dsound_voice_is_playing, _dsound_get_voice_position, _dsound_set_voice_position, }; } /* End extern "C" */ allegro-5.0.10/addons/audio/kcm_dtor.c0000644000175000001440000000366411465256750016751 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Destructors. * * By Peter Wang. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_audio.h" static _AL_DTOR_LIST *kcm_dtors = NULL; /* _al_kcm_init_destructors: * Initialise the destructor list. */ void _al_kcm_init_destructors(void) { if (!kcm_dtors) { kcm_dtors = _al_init_destructors(); } } /* _al_kcm_shutdown_destructors: * Run all destructors and free the destructor list. */ void _al_kcm_shutdown_destructors(void) { if (kcm_dtors) { _al_run_destructors(kcm_dtors); _al_shutdown_destructors(kcm_dtors); kcm_dtors = NULL; } } /* _al_kcm_register_destructor: * Register an object to be destroyed. */ void _al_kcm_register_destructor(void *object, void (*func)(void*)) { _al_register_destructor(kcm_dtors, object, func); } /* _al_kcm_unregister_destructor: * Unregister an object to be destroyed. */ void _al_kcm_unregister_destructor(void *object) { _al_unregister_destructor(kcm_dtors, object); } /* _al_kcm_foreach_destructor: * Call the callback for each registered object. */ void _al_kcm_foreach_destructor( void (*callback)(void *object, void (*func)(void *), void *udata), void *userdata) { _al_foreach_destructor(kcm_dtors, callback, userdata); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_voice.c0000644000175000001440000003057712031445360017074 0ustar tjadenusers/** * Originally digi.c from allegro wiki * Original authors: KC/Milan * * Converted to allegro5 by Ryan Dickie */ /* Title: Voice functions */ #include #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" ALLEGRO_DEBUG_CHANNEL("audio") /* forward declarations */ static void stream_read(void *source, void **vbuf, unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); /* _al_voice_update: * Reads the attached stream and provides a buffer for the sound card. It is * the driver's responsiblity to call this and to make sure any * driver-specific resources associated with the voice are locked. This should * only be called for streaming sources. * * The return value is a pointer to the next chunk of audio data in the format * the voice was allocated with. It may return NULL, in which case it is the * driver's responsilibty to play silence for the voice. The returned buffer * must *not* be modified. The 'samples' argument is set to the samples count * in the returned audio data and it may be less or equal to the requested * samples count. */ const void *_al_voice_update(ALLEGRO_VOICE *voice, unsigned int *samples) { void *buf = NULL; ASSERT(voice); al_lock_mutex(voice->mutex); if (voice->attached_stream) { ASSERT(voice->attached_stream->spl_read); voice->attached_stream->spl_read(voice->attached_stream, &buf, samples, voice->depth, 0); } al_unlock_mutex(voice->mutex); return buf; } /* Function: al_create_voice */ ALLEGRO_VOICE *al_create_voice(unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) { ALLEGRO_VOICE *voice = NULL; if (!freq) { _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid Voice Frequency"); return NULL; } voice = al_calloc(1, sizeof(*voice)); if (!voice) { return NULL; } voice->depth = depth; voice->chan_conf = chan_conf; voice->frequency = freq; voice->mutex = al_create_mutex(); voice->cond = al_create_cond(); /* XXX why is this needed? there should only be one active driver */ voice->driver = _al_kcm_driver; ASSERT(_al_kcm_driver); if (_al_kcm_driver->allocate_voice(voice) != 0) { al_destroy_mutex(voice->mutex); al_destroy_cond(voice->cond); al_free(voice); return NULL; } _al_kcm_register_destructor(voice, (void (*)(void *)) al_destroy_voice); return voice; } /* Function: al_destroy_voice */ void al_destroy_voice(ALLEGRO_VOICE *voice) { if (voice) { _al_kcm_unregister_destructor(voice); al_detach_voice(voice); ASSERT(al_get_voice_playing(voice) == false); /* We do NOT lock the voice mutex when calling this method. */ voice->driver->deallocate_voice(voice); al_destroy_mutex(voice->mutex); al_destroy_cond(voice->cond); al_free(voice); } } /* Function: al_attach_sample_instance_to_voice */ bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_VOICE *voice) { bool ret; ASSERT(voice); ASSERT(spl); if (voice->attached_stream) { ALLEGRO_WARN( "Attempted to attach to a voice that already has an attachment\n"); _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach to a voice that already has an attachment"); return false; } if (spl->parent.u.ptr) { ALLEGRO_WARN("Attempted to attach a sample that is already attached\n"); _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach a sample that is already attached"); return false; } if (voice->chan_conf != spl->spl_data.chan_conf || voice->frequency != spl->spl_data.frequency || voice->depth != spl->spl_data.depth) { ALLEGRO_WARN("Sample settings do not match voice settings\n"); _al_set_error(ALLEGRO_INVALID_OBJECT, "Sample settings do not match voice settings"); return false; } al_lock_mutex(voice->mutex); voice->attached_stream = spl; voice->is_streaming = false; voice->num_buffers = 1; voice->buffer_size = (spl->spl_data.len) * al_get_channel_count(voice->chan_conf) * al_get_audio_depth_size(voice->depth); spl->spl_read = NULL; _al_kcm_stream_set_mutex(spl, voice->mutex); spl->parent.u.voice = voice; spl->parent.is_voice = true; if (voice->driver->load_voice(voice, spl->spl_data.buffer.ptr) != 0 || (spl->is_playing && voice->driver->start_voice(voice) != 0)) { voice->attached_stream = NULL; spl->spl_read = NULL; _al_kcm_stream_set_mutex(spl, NULL); spl->parent.u.voice = NULL; ALLEGRO_ERROR("Unable to load sample into voice\n"); ret = false; } else { ret = true; } al_unlock_mutex(voice->mutex); return ret; } /* stream_read: * This passes the next waiting stream buffer to the voice via vbuf. */ static void stream_read(void *source, void **vbuf, unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) { ALLEGRO_AUDIO_STREAM *stream = (ALLEGRO_AUDIO_STREAM*)source; unsigned int len = stream->spl.spl_data.len; unsigned int pos = stream->spl.pos; if (!stream->spl.is_playing) { *vbuf = NULL; return; } if (*samples > len) *samples = len; if (pos >= len) { _al_kcm_refill_stream(stream); if (!stream->pending_bufs[0]) { if (stream->is_draining) { stream->spl.is_playing = false; } *vbuf = NULL; return; } *vbuf = stream->pending_bufs[0]; pos = *samples; _al_kcm_emit_stream_events(stream); } else { int bytes = pos * al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth); *vbuf = ((char *)stream->pending_bufs[0]) + bytes; if (pos + *samples > len) *samples = len - pos; pos += *samples; } stream->spl.pos = pos; (void)dest_maxc; (void)buffer_depth; } /* Function: al_attach_audio_stream_to_voice */ bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_VOICE *voice) { bool ret; ASSERT(voice); ASSERT(stream); if (voice->attached_stream) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach to a voice that already has an attachment"); return false; } if (stream->spl.parent.u.ptr) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to attach a stream that is already attached"); return false; } if (voice->chan_conf != stream->spl.spl_data.chan_conf || voice->frequency != stream->spl.spl_data.frequency || voice->depth != stream->spl.spl_data.depth) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Stream settings do not match voice settings"); return false; } al_lock_mutex(voice->mutex); voice->attached_stream = &stream->spl; _al_kcm_stream_set_mutex(&stream->spl, voice->mutex); stream->spl.parent.u.voice = voice; stream->spl.parent.is_voice = true; voice->is_streaming = true; voice->num_buffers = stream->buf_count; voice->buffer_size = (stream->spl.spl_data.len) * al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth); ASSERT(stream->spl.spl_read == NULL); stream->spl.spl_read = stream_read; if (voice->driver->start_voice(voice) != 0) { voice->attached_stream = NULL; _al_kcm_stream_set_mutex(&stream->spl, NULL); stream->spl.parent.u.voice = NULL; stream->spl.spl_read = NULL; _al_set_error(ALLEGRO_GENERIC_ERROR, "Unable to start stream"); ret = false; } else { ret = true; } al_unlock_mutex(voice->mutex); return ret; } /* Function: al_attach_mixer_to_voice */ bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice) { bool ret; ASSERT(voice); ASSERT(mixer); ASSERT(mixer->ss.is_mixer); if (voice->attached_stream) return false; if (mixer->ss.parent.u.ptr) return false; if (voice->chan_conf != mixer->ss.spl_data.chan_conf || voice->frequency != mixer->ss.spl_data.frequency) { return false; } al_lock_mutex(voice->mutex); voice->attached_stream = &mixer->ss; ASSERT(mixer->ss.spl_read == NULL); mixer->ss.spl_read = _al_kcm_mixer_read; _al_kcm_stream_set_mutex(&mixer->ss, voice->mutex); mixer->ss.parent.u.voice = voice; mixer->ss.parent.is_voice = true; voice->is_streaming = true; voice->num_buffers = 0; voice->buffer_size = 0; if (voice->driver->start_voice(voice) != 0) { voice->attached_stream = NULL; _al_kcm_stream_set_mutex(&mixer->ss, NULL); mixer->ss.parent.u.voice = NULL; ret = false; } else { ret = true; } al_unlock_mutex(voice->mutex); return ret; } /* Function: al_detach_voice */ void al_detach_voice(ALLEGRO_VOICE *voice) { ASSERT(voice); if (!voice->attached_stream) { return; } al_lock_mutex(voice->mutex); if (!voice->is_streaming) { ALLEGRO_SAMPLE_INSTANCE *spl = voice->attached_stream; spl->pos = voice->driver->get_voice_position(voice); spl->is_playing = voice->driver->voice_is_playing(voice); voice->driver->stop_voice(voice); voice->driver->unload_voice(voice); } else { voice->driver->stop_voice(voice); } _al_kcm_stream_set_mutex(voice->attached_stream, NULL); voice->attached_stream->parent.u.voice = NULL; voice->attached_stream->spl_read = NULL; voice->attached_stream = NULL; al_unlock_mutex(voice->mutex); } /* Function: al_get_voice_frequency */ unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice) { ASSERT(voice); return voice->frequency; } /* Function: al_get_voice_position */ unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice) { ASSERT(voice); if (voice->attached_stream && !voice->is_streaming) { unsigned int ret; al_lock_mutex(voice->mutex); ret = voice->driver->get_voice_position(voice); al_unlock_mutex(voice->mutex); return ret; } else return 0; } /* Function: al_get_voice_channels */ ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice) { ASSERT(voice); return voice->chan_conf; } /* Function: al_get_voice_depth */ ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice) { ASSERT(voice); return voice->depth; } /* Function: al_get_voice_playing */ bool al_get_voice_playing(const ALLEGRO_VOICE *voice) { ASSERT(voice); if (voice->attached_stream && !voice->is_streaming) { bool ret; al_lock_mutex(voice->mutex); ret = voice->driver->voice_is_playing(voice); al_unlock_mutex(voice->mutex); return ret; } return voice->attached_stream ? true : false; } /* Function: al_set_voice_position */ bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { ASSERT(voice); if (voice->attached_stream && !voice->is_streaming) { bool ret; al_lock_mutex(voice->mutex); // XXX change method ret = voice->driver->set_voice_position(voice, val) == 0; al_unlock_mutex(voice->mutex); return ret; } return false; } /* Function: al_set_voice_playing */ bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val) { ASSERT(voice); if (!voice->attached_stream) { ALLEGRO_DEBUG("Voice has no attachment\n"); return false; } if (voice->is_streaming) { ALLEGRO_WARN("Attempted to change the playing state of a voice " "with a streaming attachment (mixer or audiostreams)\n"); return false; } else { bool playing = al_get_voice_playing(voice); if (playing == val) { if (playing) { ALLEGRO_DEBUG("Voice is already playing\n"); } else { ALLEGRO_DEBUG("Voice is already stopped\n"); } return true; } return _al_kcm_set_voice_playing(voice, val); } } bool _al_kcm_set_voice_playing(ALLEGRO_VOICE *voice, bool val) { bool ret; ASSERT(voice); al_lock_mutex(voice->mutex); // XXX change methods if (val) ret = voice->driver->start_voice(voice) == 0; else ret = voice->driver->stop_voice(voice) == 0; al_unlock_mutex(voice->mutex); return ret; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/aqueue.m0000644000175000001440000002564311507222510016427 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Apple Audio Queue driver * * By Trent Gamblin. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" #import #import #ifdef ALLEGRO_IPHONE #import #import #endif #import #define THREAD_BEGIN NSAutoreleasePool *___p = [[NSAutoreleasePool alloc] init]; #define THREAD_DRAIN [___p drain]; #define THREAD_RECREATE ___p = [[NSAutoreleasePool alloc] init]; #define THREAD_END [___p release]; // Make configurable #define BUFFER_SIZE 1024*2 // in samples #define NUM_BUFFERS 4 typedef struct ALLEGRO_AQ_DATA { int bits_per_sample; int channels; bool playing; unsigned int buffer_size; ALLEGRO_VOICE *voice; AudioQueueBufferRef buffers[NUM_BUFFERS]; } ALLEGRO_AQ_DATA; static bool playing = false; static AudioQueueRef queue; static unsigned char *silence; static ALLEGRO_VOICE *saved_voice; /* Audio queue callback */ static void handle_buffer( void *in_data, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { ALLEGRO_AQ_DATA *ex_data = in_data; const void *data; (void)inAQ; // unsused unsigned int samples = (ex_data->buffer_size/ex_data->channels)/(ex_data->bits_per_sample/8); data = _al_voice_update(ex_data->voice, &samples); if (data == NULL) data = silence; unsigned int copy_bytes = samples * ex_data->channels * (ex_data->bits_per_sample/8); copy_bytes = _ALLEGRO_MIN(copy_bytes, inBuffer->mAudioDataBytesCapacity); memcpy(inBuffer->mAudioData, data, copy_bytes); inBuffer->mAudioDataByteSize = copy_bytes; AudioQueueEnqueueBuffer( queue, inBuffer, 0, NULL ); } #ifdef ALLEGRO_IPHONE static int _aqueue_start_voice(ALLEGRO_VOICE *voice); static int _aqueue_stop_voice(ALLEGRO_VOICE* voice); static void interruption_callback(void *inClientData, UInt32 inInterruptionState) { if (inInterruptionState == kAudioSessionBeginInterruption) { _aqueue_stop_voice(saved_voice); } else { _aqueue_start_voice(saved_voice); } } // This allows plugging/unplugging of hardware/bluetooth/speakers etc while keeping the sound playing static void property_listener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) { if (inID == kAudioSessionProperty_AudioRouteChange) { UInt32 reason = (UInt32)inData; if (reason == kAudioSessionRouteChangeReason_NewDeviceAvailable) { _aqueue_stop_voice(saved_voice); _aqueue_start_voice(saved_voice); } } } #endif /* The open method starts up the driver and should lock the device, using the previously set paramters, or defaults. It shouldn't need to start sending audio data to the device yet, however. */ static int _aqueue_open() { #ifdef ALLEGRO_IPHONE /* These settings allow ipod music playback simultaneously with * our Allegro music/sfx, and also do not stop the streams when * a phone call comes in (it's muted for the duration of the call). */ AudioSessionInitialize(NULL, NULL, interruption_callback, NULL); UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); UInt32 mix = TRUE; AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(mix), &mix); AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, property_listener, NULL); #endif return 0; } /* The close method should close the device, freeing any resources, and allow other processes to use the device */ static void _aqueue_close() { } /* The allocate_voice method should grab a voice from the system, and allocate any data common to streaming and non-streaming sources. */ static int _aqueue_allocate_voice(ALLEGRO_VOICE *voice) { ALLEGRO_AQ_DATA *ex_data; int bits_per_sample; int channels; switch (voice->depth) { case ALLEGRO_AUDIO_DEPTH_UINT16: case ALLEGRO_AUDIO_DEPTH_INT16: bits_per_sample = 16; break; default: return 1; } switch (voice->chan_conf) { case ALLEGRO_CHANNEL_CONF_1: channels = 1; break; case ALLEGRO_CHANNEL_CONF_2: channels = 2; break; default: fprintf(stderr, "Unsupported number of channels\n"); return 1; } ex_data = (ALLEGRO_AQ_DATA *)al_calloc(1, sizeof(*ex_data)); if (!ex_data) { fprintf(stderr, "Could not allocate voice data memory\n"); return 1; } ex_data->bits_per_sample = bits_per_sample; ex_data->channels = channels; ex_data->buffer_size = BUFFER_SIZE*channels*(bits_per_sample/8); ex_data->playing = false; playing = false; voice->extra = ex_data; ex_data->voice = voice; silence = al_calloc(1, ex_data->buffer_size); return 0; } /* The deallocate_voice method should free the resources for the given voice, but still retain a hold on the device. The voice should be stopped and unloaded by the time this is called */ static void _aqueue_deallocate_voice(ALLEGRO_VOICE *voice) { al_free(voice->extra); al_free(silence); voice->extra = NULL; } /* The load_voice method loads a sample into the driver's memory. The voice's 'streaming' field will be set to false for these voices, and it's 'buffer_size' field will be the total length in bytes of the sample data. The voice's attached sample's looping mode should be honored, and loading must fail if it cannot be. */ static int _aqueue_load_voice(ALLEGRO_VOICE *voice, const void *data) { /* FIXME */ (void)voice; (void)data; return 1; } /* The unload_voice method unloads a sample previously loaded with load_voice. This method should not be called on a streaming voice. */ static void _aqueue_unload_voice(ALLEGRO_VOICE *voice) { /* FIXME */ (void)voice; } static void *stream_proc(void *in_data) { #ifdef ALLEGRO_IPHONE THREAD_BEGIN /* We need to periodically drain and recreate the autorelease pool * so it doesn't fill up memory. */ double last_drain = al_get_time(); #endif ALLEGRO_VOICE *voice = in_data; ALLEGRO_AQ_DATA *ex_data = voice->extra; AudioStreamBasicDescription desc; desc.mSampleRate = voice->frequency; desc.mFormatID = kAudioFormatLinearPCM; if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; else desc.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked; desc.mBytesPerPacket = ex_data->channels * (ex_data->bits_per_sample/8); desc.mFramesPerPacket = 1; desc.mBytesPerFrame = ex_data->channels * (ex_data->bits_per_sample/8); desc.mChannelsPerFrame = ex_data->channels; desc.mBitsPerChannel = ex_data->bits_per_sample; int ret = AudioQueueNewOutput( &desc, handle_buffer, ex_data, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &queue); int i; for (i = 0; i < NUM_BUFFERS; ++i) { AudioQueueAllocateBuffer( queue, ex_data->buffer_size, &ex_data->buffers[i] ); memcpy(ex_data->buffers[i]->mAudioData, silence, ex_data->buffer_size); ex_data->buffers[i]->mAudioDataByteSize = ex_data->buffer_size; ex_data->buffers[i]->mUserData = ex_data; // FIXME: Safe to comment this out? //ex_data->buffers[i]->mPacketDescriptionCount = 0; AudioQueueEnqueueBuffer( queue, ex_data->buffers[i], 0, NULL ); } AudioQueueSetParameter( queue, kAudioQueueParam_Volume, 1.0f ); ret = AudioQueueStart( queue, NULL ); ex_data->playing = true; playing = true; do { CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.05, false ); #ifdef ALLEGRO_IPHONE double now = al_get_time(); if (now > last_drain+30) { last_drain = now; THREAD_DRAIN THREAD_RECREATE } #endif } while (playing); #ifdef ALLEGRO_IPHONE THREAD_END #endif return NULL; } /* The start_voice should, surprise, start the voice. For streaming voices, it should start polling the device and call _al_voice_update for audio data. For non-streaming voices, it should resume playing from the last set position */ static int _aqueue_start_voice(ALLEGRO_VOICE *voice) { saved_voice = voice; if (voice->is_streaming && playing == false) { al_run_detached_thread(stream_proc, voice); return 0; } /* FIXME */ return 1; } /* The stop_voice method should stop playback. For non-streaming voices, it should leave the data loaded, and reset the voice position to 0. */ static int _aqueue_stop_voice(ALLEGRO_VOICE* voice) { ALLEGRO_AQ_DATA *ex_data = voice->extra; if (playing == true) { playing = false; ex_data->playing = false; AudioQueueDispose( queue, true ); } return 0; } /* The voice_is_playing method should only be called on non-streaming sources, and should return true if the voice is playing */ static bool _aqueue_voice_is_playing(const ALLEGRO_VOICE *voice) { ALLEGRO_AQ_DATA *ex_data = (ALLEGRO_AQ_DATA *)voice->extra; return ex_data->playing; } /* The get_voice_position method should return the current sample position of the voice (sample_pos = byte_pos / (depth/8) / channels). This should never be called on a streaming voice. */ static unsigned int _aqueue_get_voice_position(const ALLEGRO_VOICE *voice) { /* FIXME */ (void)voice; return 0; } /* The set_voice_position method should set the voice's playback position, given the value in samples. This should never be called on a streaming voice. */ static int _aqueue_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { /* FIXME */ (void)voice; (void)val; return 0; } ALLEGRO_AUDIO_DRIVER _al_kcm_aqueue_driver = { "Apple Audio Queues", _aqueue_open, _aqueue_close, _aqueue_allocate_voice, _aqueue_deallocate_voice, _aqueue_load_voice, _aqueue_unload_voice, _aqueue_start_voice, _aqueue_stop_voice, _aqueue_voice_is_playing, _aqueue_get_voice_position, _aqueue_set_voice_position, }; allegro-5.0.10/addons/audio/audio_io.c0000644000175000001440000001671212125160224016715 0ustar tjadenusers/* * Allegro audio codec table. */ #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_vector.h" ALLEGRO_DEBUG_CHANNEL("audio") #define MAX_EXTENSION_LENGTH (32) typedef struct ACODEC_TABLE ACODEC_TABLE; struct ACODEC_TABLE { char ext[MAX_EXTENSION_LENGTH]; ALLEGRO_SAMPLE * (*loader)(const char *filename); bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl); ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_SAMPLE * (*fs_loader)(ALLEGRO_FILE *fp); bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl); ALLEGRO_AUDIO_STREAM *(*fs_stream_loader)(ALLEGRO_FILE *fp, size_t buffer_count, unsigned int samples); }; /* globals */ static bool acodec_inited = false; static _AL_VECTOR acodec_table = _AL_VECTOR_INITIALIZER(ACODEC_TABLE); static void acodec_shutdown(void) { if (acodec_inited) { _al_vector_free(&acodec_table); acodec_inited = false; } } static ACODEC_TABLE *find_acodec_table_entry(const char *ext) { ACODEC_TABLE *ent; unsigned i; if (!acodec_inited) { acodec_inited = true; _al_add_exit_func(acodec_shutdown, "acodec_shutdown"); } for (i = 0; i < _al_vector_size(&acodec_table); i++) { ent = _al_vector_ref(&acodec_table, i); if (0 == _al_stricmp(ent->ext, ext)) { return ent; } } return NULL; } static ACODEC_TABLE *add_acodec_table_entry(const char *ext) { ACODEC_TABLE *ent; ent = _al_vector_alloc_back(&acodec_table); strcpy(ent->ext, ext); ent->loader = NULL; ent->saver = NULL; ent->stream_loader = NULL; ent->fs_loader = NULL; ent->fs_saver = NULL; ent->fs_stream_loader = NULL; return ent; } /* Function: al_register_sample_loader */ bool al_register_sample_loader(const char *ext, ALLEGRO_SAMPLE *(*loader)(const char *filename)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!loader) { if (!ent || !ent->loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->loader = loader; return true; } /* Function: al_register_sample_loader_f */ bool al_register_sample_loader_f(const char *ext, ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!loader) { if (!ent || !ent->fs_loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->fs_loader = loader; return true; } /* Function: al_register_sample_saver */ bool al_register_sample_saver(const char *ext, bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!saver) { if (!ent || !ent->saver) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->saver = saver; return true; } /* Function: al_register_sample_saver_f */ bool al_register_sample_saver_f(const char *ext, bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!saver) { if (!ent || !ent->fs_saver) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->fs_saver = saver; return true; } /* Function: al_register_audio_stream_loader */ bool al_register_audio_stream_loader(const char *ext, ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, size_t buffer_count, unsigned int samples)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!stream_loader) { if (!ent || !ent->stream_loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->stream_loader = stream_loader; return true; } /* Function: al_register_audio_stream_loader_f */ bool al_register_audio_stream_loader_f(const char *ext, ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp, size_t buffer_count, unsigned int samples)) { ACODEC_TABLE *ent; if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { return false; } ent = find_acodec_table_entry(ext); if (!stream_loader) { if (!ent || !ent->fs_stream_loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_acodec_table_entry(ext); } ent->fs_stream_loader = stream_loader; return true; } /* Function: al_load_sample */ ALLEGRO_SAMPLE *al_load_sample(const char *filename) { const char *ext; ACODEC_TABLE *ent; ASSERT(filename); ext = strrchr(filename, '.'); if (ext == NULL) return NULL; ent = find_acodec_table_entry(ext); if (ent && ent->loader) { return (ent->loader)(filename); } return NULL; } /* Function: al_load_sample_f */ ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident) { ACODEC_TABLE *ent; ASSERT(fp); ASSERT(ident); ent = find_acodec_table_entry(ident); if (ent && ent->fs_loader) { return (ent->fs_loader)(fp); } return NULL; } /* Function: al_load_audio_stream */ ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { const char *ext; ACODEC_TABLE *ent; ASSERT(filename); ext = strrchr(filename, '.'); if (ext == NULL) return NULL; ent = find_acodec_table_entry(ext); if (ent && ent->stream_loader) { return (ent->stream_loader)(filename, buffer_count, samples); } ALLEGRO_ERROR("Error creating ALLEGRO_AUDIO_STREAM from '%s'.\n", filename); return NULL; } /* Function: al_load_audio_stream_f */ ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident, size_t buffer_count, unsigned int samples) { ACODEC_TABLE *ent; ASSERT(fp); ASSERT(ident); ent = find_acodec_table_entry(ident); if (ent && ent->fs_stream_loader) { return (ent->fs_stream_loader)(fp, buffer_count, samples); } return NULL; } /* Function: al_save_sample */ bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl) { const char *ext; ACODEC_TABLE *ent; ASSERT(filename); ext = strrchr(filename, '.'); if (ext == NULL) return false; ent = find_acodec_table_entry(ext); if (ent && ent->saver) { return (ent->saver)(filename, spl); } return false; } /* Function: al_save_sample_f */ bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl) { ACODEC_TABLE *ent; ASSERT(fp); ASSERT(ident); ent = find_acodec_table_entry(ident); if (ent && ent->fs_saver) { return (ent->fs_saver)(fp, spl); } return false; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_mixer_helpers.inc0000644000175000001440000004162712020407417021161 0ustar tjadenusers// Warning: This file was created by make_resamplers.py - do not edit. // vim: set ft=c: static INLINE const void *point_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { unsigned int i0 = spl->pos * maxc; unsigned int i; switch (spl->spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = spl->spl_data.buffer.f32[i0 + i]; } break; case ALLEGRO_AUDIO_DEPTH_INT24: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.s24[i0 + i] / ((float) 0x7FFFFF + 0.5f); } break; case ALLEGRO_AUDIO_DEPTH_UINT24: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.u24[i0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; } break; case ALLEGRO_AUDIO_DEPTH_INT16: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.s16[i0 + i] / ((float) 0x7FFF + 0.5f); } break; case ALLEGRO_AUDIO_DEPTH_UINT16: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.u16[i0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; } break; case ALLEGRO_AUDIO_DEPTH_INT8: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.s8[i0 + i] / ((float) 0x7F + 0.5f); } break; case ALLEGRO_AUDIO_DEPTH_UINT8: for (i = 0; i < maxc; i++) { samp_buf->f32[i] = (float) spl->spl_data.buffer.u8[i0 + i] / ((float) 0x7F + 0.5f) - 1.0f; } break; } return samp_buf->f32; } static INLINE const void *point_spl16(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { unsigned int i0 = spl->pos * maxc; unsigned int i; switch (spl->spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.f32[i0 + i] * 0x7FFF); } break; case ALLEGRO_AUDIO_DEPTH_INT24: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.s24[i0 + i] >> 9); } break; case ALLEGRO_AUDIO_DEPTH_UINT24: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) ((spl->spl_data.buffer.u24[i0 + i] - 0x800000) >> 9); } break; case ALLEGRO_AUDIO_DEPTH_INT16: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = spl->spl_data.buffer.s16[i0 + i]; } break; case ALLEGRO_AUDIO_DEPTH_UINT16: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.u16[i0 + i] - 0x8000); } break; case ALLEGRO_AUDIO_DEPTH_INT8: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) spl->spl_data.buffer.s8[i0 + i] << 7; } break; case ALLEGRO_AUDIO_DEPTH_UINT8: for (i = 0; i < maxc; i++) { samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.u8[i0 + i] - 0x80) << 7; } break; } return samp_buf->s16; } static INLINE const void *linear_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { int p0 = spl->pos; int p1 = spl->pos + 1; switch (spl->loop) { case ALLEGRO_PLAYMODE_ONCE: if (p1 >= spl->spl_data.len) p1 = p0; break; case ALLEGRO_PLAYMODE_LOOP: if (p1 >= spl->loop_end) p1 = spl->loop_start; break; case ALLEGRO_PLAYMODE_BIDIR: if (p1 >= spl->loop_end) { p1 = spl->loop_end - 1; if (p1 < spl->loop_start) p1 = spl->loop_start; } break; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: p0--; p1--; break; } p0 *= maxc; p1 *= maxc; switch (spl->spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = spl->spl_data.buffer.f32[p0 + i]; const float x1 = spl->spl_data.buffer.f32[p1 + i]; const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT24: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.s24[p0 + i] / ((float) 0x7FFFFF + 0.5f); const float x1 = (float) spl->spl_data.buffer.s24[p1 + i] / ((float) 0x7FFFFF + 0.5f); const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT24: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.u24[p0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; const float x1 = (float) spl->spl_data.buffer.u24[p1 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT16: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.s16[p0 + i] / ((float) 0x7FFF + 0.5f); const float x1 = (float) spl->spl_data.buffer.s16[p1 + i] / ((float) 0x7FFF + 0.5f); const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT16: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.u16[p0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; const float x1 = (float) spl->spl_data.buffer.u16[p1 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT8: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.s8[p0 + i] / ((float) 0x7F + 0.5f); const float x1 = (float) spl->spl_data.buffer.s8[p1 + i] / ((float) 0x7F + 0.5f); const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT8: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const float x0 = (float) spl->spl_data.buffer.u8[p0 + i] / ((float) 0x7F + 0.5f) - 1.0f; const float x1 = (float) spl->spl_data.buffer.u8[p1 + i] / ((float) 0x7F + 0.5f) - 1.0f; const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; } } break; } return samp_buf->f32; } static INLINE const void *linear_spl16(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { int p0 = spl->pos; int p1 = spl->pos + 1; switch (spl->loop) { case ALLEGRO_PLAYMODE_ONCE: if (p1 >= spl->spl_data.len) p1 = p0; break; case ALLEGRO_PLAYMODE_LOOP: if (p1 >= spl->loop_end) p1 = spl->loop_start; break; case ALLEGRO_PLAYMODE_BIDIR: if (p1 >= spl->loop_end) { p1 = spl->loop_end - 1; if (p1 < spl->loop_start) p1 = spl->loop_start; } break; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: p0--; p1--; break; } p0 *= maxc; p1 *= maxc; switch (spl->spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) (spl->spl_data.buffer.f32[p0 + i] * 0x7FFF); const int32_t x1 = (int16_t) (spl->spl_data.buffer.f32[p1 + i] * 0x7FFF); const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_INT24: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) (spl->spl_data.buffer.s24[p0 + i] >> 9); const int32_t x1 = (int16_t) (spl->spl_data.buffer.s24[p1 + i] >> 9); const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT24: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) ((spl->spl_data.buffer.u24[p0 + i] - 0x800000) >> 9); const int32_t x1 = (int16_t) ((spl->spl_data.buffer.u24[p1 + i] - 0x800000) >> 9); const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_INT16: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = spl->spl_data.buffer.s16[p0 + i]; const int32_t x1 = spl->spl_data.buffer.s16[p1 + i]; const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT16: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) (spl->spl_data.buffer.u16[p0 + i] - 0x8000); const int32_t x1 = (int16_t) (spl->spl_data.buffer.u16[p1 + i] - 0x8000); const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_INT8: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) spl->spl_data.buffer.s8[p0 + i] << 7; const int32_t x1 = (int16_t) spl->spl_data.buffer.s8[p1 + i] << 7; const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT8: { const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int) maxc; i++) { const int32_t x0 = (int16_t) (spl->spl_data.buffer.u8[p0 + i] - 0x80) << 7; const int32_t x1 = (int16_t) (spl->spl_data.buffer.u8[p1 + i] - 0x80) << 7; const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); samp_buf->s16[i] = (int16_t) s; } } break; } return samp_buf->s16; } static INLINE const void *cubic_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { int p0 = spl->pos - 1; int p1 = spl->pos; int p2 = spl->pos + 1; int p3 = spl->pos + 2; switch (spl->loop) { case ALLEGRO_PLAYMODE_ONCE: if (p0 < 0) p0 = 0; if (p2 >= spl->spl_data.len) p2 = spl->spl_data.len - 1; if (p3 >= spl->spl_data.len) p3 = spl->spl_data.len - 1; break; case ALLEGRO_PLAYMODE_LOOP: case ALLEGRO_PLAYMODE_BIDIR: /* These positions should really wrap/bounce instead of clamping * but it's probably unnoticeable. */ if (p0 < spl->loop_start) p0 = spl->loop_end - 1; if (p2 >= spl->loop_end) p2 = spl->loop_start; if (p3 >= spl->loop_end) p3 = spl->loop_start; break; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: /* Lag by three samples in total. */ p0 -= 2; p1 -= 2; p2 -= 2; p3 -= 2; break; } p0 *= maxc; p1 *= maxc; p2 *= maxc; p3 *= maxc; switch (spl->spl_data.depth) { case ALLEGRO_AUDIO_DEPTH_FLOAT32: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = spl->spl_data.buffer.f32[p0 + i]; float x1 = spl->spl_data.buffer.f32[p1 + i]; float x2 = spl->spl_data.buffer.f32[p2 + i]; float x3 = spl->spl_data.buffer.f32[p3 + i]; float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT24: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.s24[p0 + i] / ((float) 0x7FFFFF + 0.5f); float x1 = (float) spl->spl_data.buffer.s24[p1 + i] / ((float) 0x7FFFFF + 0.5f); float x2 = (float) spl->spl_data.buffer.s24[p2 + i] / ((float) 0x7FFFFF + 0.5f); float x3 = (float) spl->spl_data.buffer.s24[p3 + i] / ((float) 0x7FFFFF + 0.5f); float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT24: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.u24[p0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; float x1 = (float) spl->spl_data.buffer.u24[p1 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; float x2 = (float) spl->spl_data.buffer.u24[p2 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; float x3 = (float) spl->spl_data.buffer.u24[p3 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT16: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.s16[p0 + i] / ((float) 0x7FFF + 0.5f); float x1 = (float) spl->spl_data.buffer.s16[p1 + i] / ((float) 0x7FFF + 0.5f); float x2 = (float) spl->spl_data.buffer.s16[p2 + i] / ((float) 0x7FFF + 0.5f); float x3 = (float) spl->spl_data.buffer.s16[p3 + i] / ((float) 0x7FFF + 0.5f); float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT16: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.u16[p0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; float x1 = (float) spl->spl_data.buffer.u16[p1 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; float x2 = (float) spl->spl_data.buffer.u16[p2 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; float x3 = (float) spl->spl_data.buffer.u16[p3 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_INT8: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.s8[p0 + i] / ((float) 0x7F + 0.5f); float x1 = (float) spl->spl_data.buffer.s8[p1 + i] / ((float) 0x7F + 0.5f); float x2 = (float) spl->spl_data.buffer.s8[p2 + i] / ((float) 0x7F + 0.5f); float x3 = (float) spl->spl_data.buffer.s8[p3 + i] / ((float) 0x7F + 0.5f); float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; case ALLEGRO_AUDIO_DEPTH_UINT8: { const float t = (float) spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int) maxc; i++) { float x0 = (float) spl->spl_data.buffer.u8[p0 + i] / ((float) 0x7F + 0.5f) - 1.0f; float x1 = (float) spl->spl_data.buffer.u8[p1 + i] / ((float) 0x7F + 0.5f) - 1.0f; float x2 = (float) spl->spl_data.buffer.u8[p2 + i] / ((float) 0x7F + 0.5f) - 1.0f; float x3 = (float) spl->spl_data.buffer.u8[p3 + i] / ((float) 0x7F + 0.5f) - 1.0f; float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; } return samp_buf->f32; } allegro-5.0.10/addons/audio/oss.c0000644000175000001440000003732312031446743015743 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Open Sound System sound driver. * * By Milan Mimica. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_audio.h" #include #include #include #include #include #include ALLEGRO_DEBUG_CHANNEL("oss") #if defined ALLEGRO_HAVE_SOUNDCARD_H #include #elif defined ALLEGRO_HAVE_SYS_SOUNDCARD_H #include #elif defined ALLEGRO_HAVE_LINUX_SOUNDCARD_H #include #elif defined ALLEGRO_HAVE_MACHINE_SOUNDCARD_H #include #endif #if OSS_VERSION >= 0x040000 #define OSS_VER_4 #else #define OSS_VER_3 #endif #ifndef AFMT_S16_NE #ifdef ALLEGRO_BIG_ENDIAN #define AFMT_S16_NE AFMT_S16_BE #else #define AFMT_S16_NE AFMT_S16_LE #endif #endif #ifndef AFMT_U16_NE #ifdef ALLEGRO_BIG_ENDIAN #define AFMT_U16_NE AFMT_U16_BE #else #define AFMT_U16_NE AFMT_U16_LE #endif #endif /* Audio device used by OSS3. * Make this configurable. */ static const char* oss_audio_device_ver3 = "/dev/dsp"; /* Audio device is dynamically retrived in OSS4. */ static char oss_audio_device[512]; /* timing policy (between 0 and 10), used by OSS4 * Make this configurable? */ static const int oss_timing_policy = 5; /* Fragment size, used by OSS3 * Make this configurable? */ static int oss_fragsize = (8 << 16) | (10); /* Auxiliary buffer used to store silence. */ #define SIL_BUF_SIZE 1024 static char sil_buf[SIL_BUF_SIZE]; static bool using_ver_4; typedef struct OSS_VOICE { int fd; int volume; /* Copied from the parent ALLEGRO_VOICE. Used for convenince. */ unsigned int len; /* in frames */ unsigned int frame_size; /* in bytes */ volatile bool stopped; volatile bool stop; ALLEGRO_THREAD *poll_thread; } OSS_VOICE; #ifdef OSS_VER_4 static int oss_open_ver4() { int mixer_fd, i; oss_sysinfo sysinfo; if ((mixer_fd = open("/dev/mixer", O_RDWR, 0)) == -1) { switch (errno) { case ENXIO: case ENODEV: ALLEGRO_ERROR("Open Sound System is not running in your system.\n"); break; case ENOENT: ALLEGRO_ERROR("No /dev/mixer device available in your system.\n"); ALLEGRO_ERROR("Perhaps Open Sound System is not installed or " "running.\n"); break; default: ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); } return 1; } if (ioctl(mixer_fd, SNDCTL_SYSINFO, &sysinfo) == -1) { if (errno == ENXIO) { ALLEGRO_ERROR("OSS has not detected any supported sound hardware in " "your system.\n"); } else if (errno == EINVAL) { ALLEGRO_INFO("The version of OSS installed on the system is not " "compatible with OSS4.\n"); } else ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); close(mixer_fd); return 1; } /* Some OSS implementations (ALSA emulation) don't fail on SNDCTL_SYSINFO even * though they don't support OSS4. They *seem* to set numcards to 0. */ if (sysinfo.numcards < 1) { ALLEGRO_WARN("The version of OSS installed on the system is not " "compatible with OSS4.\n"); return 1; } ALLEGRO_INFO("OSS Version: %s\n", sysinfo.version); ALLEGRO_INFO("Found %i sound cards.\n", sysinfo.numcards); for (i = 0; i < sysinfo.numcards; i++) { oss_audioinfo audioinfo; memset(&audioinfo, 0, sizeof(oss_audioinfo)); audioinfo.dev = i; ALLEGRO_INFO("Trying sound card no. %i ...\n", audioinfo.dev); ioctl(mixer_fd, SNDCTL_AUDIOINFO, &audioinfo); if (audioinfo.enabled) { if (strlen(audioinfo.devnode)) { strncpy(oss_audio_device, audioinfo.devnode, 512); } else if (audioinfo.legacy_device != -1) { sprintf(oss_audio_device, "/dev/dsp%i", audioinfo.legacy_device); } else { ALLEGRO_ERROR("Cannot find device name.\n"); } ALLEGRO_INFO("Using device: %s\n", oss_audio_device); break; } else { ALLEGRO_INFO("Device disabled.\n"); } } if (i == sysinfo.numcards) { ALLEGRO_ERROR("Couldn't find a suitable device.\n"); close(mixer_fd); return 1; } close(mixer_fd); using_ver_4 = true; return 0; } #endif static int oss_open_ver3(void) { ALLEGRO_CONFIG *config = al_get_system_config(); if (config) { const char *config_device; config_device = al_get_config_value(config, "oss", "device"); if (config_device && config_device[0] != '\0') oss_audio_device_ver3 = config_device; } int fd = open(oss_audio_device_ver3, O_WRONLY); if (fd == -1) { switch (errno) { case ENXIO: case ENODEV: ALLEGRO_ERROR("Open Sound System is not running in your " "system.\n"); break; case ENOENT: ALLEGRO_ERROR("No '%s' device available in your system.\n", oss_audio_device_ver3); ALLEGRO_ERROR("Perhaps Open Sound System is not installed " "or running.\n"); break; default: ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); } return 1; } close(fd); strncpy(oss_audio_device, oss_audio_device_ver3, 512); ALLEGRO_INFO("Using device: %s\n", oss_audio_device); using_ver_4 = false; return 0; } static int oss_open(void) { bool force_oss3 = false; ALLEGRO_CONFIG *config = al_get_system_config(); if (config) { const char *force_oss3_cfg; force_oss3_cfg = al_get_config_value(config, "oss", "force_ver3"); if (force_oss3_cfg && force_oss3_cfg[0] != '\0') force_oss3 = strcmp(force_oss3_cfg, "yes") ? false : true; } if (force_oss3) { ALLEGRO_WARN("Skipping OSS4 probe.\n"); } #ifdef OSS_VER_4 bool inited = false; if (!force_oss3) { if (oss_open_ver4()) ALLEGRO_WARN("OSS ver. 4 init failed, trying ver. 3...\n"); else inited = true; } if (!inited && oss_open_ver3()) { ALLEGRO_ERROR("Failed to init OSS.\n"); return 1; } #else ALLEGRO_INFO("OSS4 support not compiled in. Skipping OSS4 probe.\n"); if (oss_open_ver3()) { ALLEGRO_ERROR("Failed to init OSS.\n"); return 1; } #endif return 0; } static void oss_close(void) { } static void oss_deallocate_voice(ALLEGRO_VOICE *voice) { OSS_VOICE *oss_voice = voice->extra; /* We do NOT hold the voice mutex here, so this does NOT result in a * deadlock when oss_update calls _al_voice_update (which tries to * acquire the voice->mutex). */ al_join_thread(oss_voice->poll_thread, NULL); al_destroy_thread(oss_voice->poll_thread); close(oss_voice->fd); al_free(voice->extra); voice->extra = NULL; } static int oss_start_voice(ALLEGRO_VOICE *voice) { OSS_VOICE *ex_data = voice->extra; ex_data->stop = false; return 0; } static int oss_stop_voice(ALLEGRO_VOICE *voice) { OSS_VOICE *ex_data = voice->extra; ex_data->stop = true; if (!voice->is_streaming) { voice->attached_stream->pos = 0; } while (!ex_data->stopped) al_rest(0.001); return 0; } static int oss_load_voice(ALLEGRO_VOICE *voice, const void *data) { OSS_VOICE *ex_data = voice->extra; /* * One way to support backward playing would be to do like alsa driver does: * mmap(2) the FD and write reversed samples into that. To much trouble for * an optional feature IMO. -- milan */ if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { ALLEGRO_INFO("Backwards playing not supported by the driver.\n"); return -1; } voice->attached_stream->pos = 0; ex_data->len = voice->attached_stream->spl_data.len; return 0; (void)data; } static void oss_unload_voice(ALLEGRO_VOICE *voice) { (void)voice; } static bool oss_voice_is_playing(const ALLEGRO_VOICE *voice) { OSS_VOICE *ex_data = voice->extra; return !ex_data->stopped; } static unsigned int oss_get_voice_position(const ALLEGRO_VOICE *voice) { return voice->attached_stream->pos; } static int oss_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { voice->attached_stream->pos = val; return 0; } /* * Updates the supplied non-streaming voice. * buf - Returns a pointer to the buffer containing sample data. * bytes - The requested size of the sample data buffer. Returns the actual * size of returned the buffer. * Updates 'stop', 'pos' and 'reversed' fields of the supplied voice to the * future position. */ static int oss_update_nonstream_voice(ALLEGRO_VOICE *voice, void **buf, int *bytes) { OSS_VOICE *oss_voice = voice->extra; int bpos = voice->attached_stream->pos * oss_voice->frame_size; int blen = oss_voice->len * oss_voice->frame_size; *buf = (char *)voice->attached_stream->spl_data.buffer.ptr + bpos; if (bpos + *bytes > blen) { *bytes = blen - bpos; if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { oss_voice->stop = true; voice->attached_stream->pos = 0; } if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_LOOP) { voice->attached_stream->pos = 0; } /*else if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { oss_voice->reversed = true; voice->attached_stream->pos = oss_voice->len; }*/ return 1; } else voice->attached_stream->pos += *bytes / oss_voice->frame_size; return 0; } static void* oss_update(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = arg; OSS_VOICE *oss_voice = voice->extra; (void)self; while (!al_get_thread_should_stop(self)) { /* For possible eventual non-blocking mode: audio_buf_info bi; if (ioctl(oss_voice->fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) { ALLEGRO_ERROR("Error SNDCTL_DSP_GETOSPACE, errno=%i (%s)\n", errno, strerror(errno)); return NULL; } len = bi.bytes; */ /* How many bytes are we supposed to try to write at once? */ unsigned int frames = 1024; if (oss_voice->stop && !oss_voice->stopped) { oss_voice->stopped = true; } if (!oss_voice->stop && oss_voice->stopped) { oss_voice->stopped = false; } if (!voice->is_streaming && !oss_voice->stopped) { void *buf; int bytes = frames * oss_voice->frame_size; oss_update_nonstream_voice(voice, &buf, &bytes); frames = bytes / oss_voice->frame_size; if (write(oss_voice->fd, buf, bytes) == -1) { ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); if (errno != EINTR) return NULL; } } else if (voice->is_streaming && !oss_voice->stopped) { const void *data = _al_voice_update(voice, &frames); if (data == NULL) goto silence; if (write(oss_voice->fd, data, frames * oss_voice->frame_size) == -1) { ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); if (errno != EINTR) return NULL; } } else { silence: /* If stopped just fill with silence. */ memset(sil_buf, _al_kcm_get_silence(voice->depth), SIL_BUF_SIZE); if (write(oss_voice->fd, sil_buf, SIL_BUF_SIZE) == -1) { ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); } } } return NULL; } static int oss_allocate_voice(ALLEGRO_VOICE *voice) { int format; int chan_count; OSS_VOICE *ex_data = al_calloc(1, sizeof(OSS_VOICE)); if (!ex_data) return 1; ex_data->fd = open(oss_audio_device, O_WRONLY/*, O_NONBLOCK*/); if (ex_data->fd == -1) { ALLEGRO_ERROR("Failed to open audio device '%s'.\n", oss_audio_device); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); al_free(ex_data); return 1; } chan_count = al_get_channel_count(voice->chan_conf); ex_data->frame_size = chan_count * al_get_audio_depth_size(voice->depth); if (!ex_data->frame_size) goto Error; ex_data->stop = true; ex_data->stopped = true; if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT8) format = AFMT_S8; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) format = AFMT_U8; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) format = AFMT_S16_NE; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) format = AFMT_U16_NE; #ifdef OSS_VER_4 else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) format = AFMT_S24_NE; else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) format = AFMT_FLOAT; #endif else { ALLEGRO_ERROR("Unsupported OSS sound format.\n"); goto Error; } int tmp_format = format; int tmp_chan_count = chan_count; unsigned int tmp_freq = voice->frequency; int tmp_oss_fragsize = oss_fragsize; if (using_ver_4) { #ifdef OSS_VER_4 int tmp_oss_timing_policy = oss_timing_policy; if (ioctl(ex_data->fd, SNDCTL_DSP_POLICY, &tmp_oss_timing_policy) == -1) { ALLEGRO_ERROR("Failed to set_timig policity to '%i'.\n", tmp_oss_timing_policy); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); goto Error; } ALLEGRO_INFO("Accepted timing policy value: %i\n", tmp_oss_timing_policy); #endif } else { if (ioctl(ex_data->fd, SNDCTL_DSP_SETFRAGMENT, &tmp_oss_fragsize) == -1) { ALLEGRO_ERROR("Failed to set fragment size.\n"); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); goto Error; } } if (ioctl(ex_data->fd, SNDCTL_DSP_SETFMT, &tmp_format) == -1) { ALLEGRO_ERROR("Failed to set sample format.\n"); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); goto Error; } if (tmp_format != format) { ALLEGRO_ERROR("Sample format not supported by the driver.\n"); goto Error; } if (ioctl(ex_data->fd, SNDCTL_DSP_CHANNELS, &tmp_chan_count)) { ALLEGRO_ERROR("Failed to set channel count.\n"); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); goto Error; } if (tmp_chan_count != chan_count) { ALLEGRO_ERROR("Requested sample channe count %i, got %i.\n", tmp_chan_count, chan_count); } if (ioctl(ex_data->fd, SNDCTL_DSP_SPEED, &tmp_freq) == -1) { ALLEGRO_ERROR("Failed to set sample rate.\n"); ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); goto Error; } if (voice->frequency != tmp_freq) { ALLEGRO_ERROR("Requested sample rate %u, got %iu.\n", voice->frequency, tmp_freq); } voice->extra = ex_data; ex_data->poll_thread = al_create_thread(oss_update, (void*)voice); al_start_thread(ex_data->poll_thread); return 0; Error: close(ex_data->fd); al_free(ex_data); return 1; } ALLEGRO_AUDIO_DRIVER _al_kcm_oss_driver = { "OSS", oss_open, oss_close, oss_allocate_voice, oss_deallocate_voice, oss_load_voice, oss_unload_voice, oss_start_voice, oss_stop_voice, oss_voice_is_playing, oss_get_voice_position, oss_set_voice_position }; /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/allegro5/0000755000175000001440000000000012157230736016477 5ustar tjadenusersallegro-5.0.10/addons/audio/allegro5/allegro_audio.h0000644000175000001440000004074212020407417021454 0ustar tjadenusers/* * Updated for 4.9 api inclusion by Ryan Dickie * Originally done by KC/Milan */ #ifndef __al_included_allegro5_allegro_audio_h #define __al_included_allegro5_allegro_audio_h #ifdef __cplusplus extern "C" { #endif /* Title: Audio types */ #include "allegro5/allegro.h" #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_KCM_AUDIO_SRC #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllexport) #else #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_KCM_AUDIO_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) _ALLEGRO_KCM_AUDIO_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern _ALLEGRO_KCM_AUDIO_DLL type name args #else #define ALLEGRO_KCM_AUDIO_FUNC AL_FUNC #endif /* Internal, used to communicate with acodec. */ /* Must be in 512 <= n < 1024 */ #define _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE (512) /* User event type emitted when a stream fragment is ready to be * refilled with more audio data. * Must be in 512 <= n < 1024 */ #define ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT (513) #define ALLEGRO_EVENT_AUDIO_STREAM_FINISHED (514) /* Enum: ALLEGRO_AUDIO_DEPTH */ enum ALLEGRO_AUDIO_DEPTH { /* Sample depth and type, and signedness. Mixers only use 32-bit signed * float (-1..+1). The unsigned value is a bit-flag applied to the depth * value. */ ALLEGRO_AUDIO_DEPTH_INT8 = 0x00, ALLEGRO_AUDIO_DEPTH_INT16 = 0x01, ALLEGRO_AUDIO_DEPTH_INT24 = 0x02, ALLEGRO_AUDIO_DEPTH_FLOAT32 = 0x03, ALLEGRO_AUDIO_DEPTH_UNSIGNED = 0x08, /* For convenience */ ALLEGRO_AUDIO_DEPTH_UINT8 = ALLEGRO_AUDIO_DEPTH_INT8 | ALLEGRO_AUDIO_DEPTH_UNSIGNED, ALLEGRO_AUDIO_DEPTH_UINT16 = ALLEGRO_AUDIO_DEPTH_INT16 | ALLEGRO_AUDIO_DEPTH_UNSIGNED, ALLEGRO_AUDIO_DEPTH_UINT24 = ALLEGRO_AUDIO_DEPTH_INT24 | ALLEGRO_AUDIO_DEPTH_UNSIGNED }; /* Enum: ALLEGRO_CHANNEL_CONF */ enum ALLEGRO_CHANNEL_CONF { /* Speaker configuration (mono, stereo, 2.1, 3, etc). With regards to * behavior, most of this code makes no distinction between, say, 4.1 and * 5 speaker setups.. they both have 5 "channels". However, users would * like the distinction, and later when the higher-level stuff is added, * the differences will become more important. (v>>4)+(v&0xF) should yield * the total channel count. */ ALLEGRO_CHANNEL_CONF_1 = 0x10, ALLEGRO_CHANNEL_CONF_2 = 0x20, ALLEGRO_CHANNEL_CONF_3 = 0x30, ALLEGRO_CHANNEL_CONF_4 = 0x40, ALLEGRO_CHANNEL_CONF_5_1 = 0x51, ALLEGRO_CHANNEL_CONF_6_1 = 0x61, ALLEGRO_CHANNEL_CONF_7_1 = 0x71 #define ALLEGRO_MAX_CHANNELS 8 }; /* Enum: ALLEGRO_PLAYMODE */ enum ALLEGRO_PLAYMODE { ALLEGRO_PLAYMODE_ONCE = 0x100, ALLEGRO_PLAYMODE_LOOP = 0x101, ALLEGRO_PLAYMODE_BIDIR = 0x102, _ALLEGRO_PLAYMODE_STREAM_ONCE = 0x103, /* internal */ _ALLEGRO_PLAYMODE_STREAM_ONEDIR = 0x104 /* internal */ }; /* Enum: ALLEGRO_MIXER_QUALITY */ enum ALLEGRO_MIXER_QUALITY { ALLEGRO_MIXER_QUALITY_POINT = 0x110, ALLEGRO_MIXER_QUALITY_LINEAR = 0x111, ALLEGRO_MIXER_QUALITY_CUBIC = 0x112 }; /* Enum: ALLEGRO_AUDIO_PAN_NONE */ #define ALLEGRO_AUDIO_PAN_NONE (-1000.0f) /* Type: ALLEGRO_SAMPLE */ typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE; /* Type: ALLEGRO_SAMPLE_ID */ typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID; struct ALLEGRO_SAMPLE_ID { int _index; int _id; }; /* Type: ALLEGRO_SAMPLE_INSTANCE */ typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE; /* Type: ALLEGRO_AUDIO_STREAM */ typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM; /* Type: ALLEGRO_MIXER */ typedef struct ALLEGRO_MIXER ALLEGRO_MIXER; /* Type: ALLEGRO_VOICE */ typedef struct ALLEGRO_VOICE ALLEGRO_VOICE; #ifndef __cplusplus typedef enum ALLEGRO_AUDIO_DEPTH ALLEGRO_AUDIO_DEPTH; typedef enum ALLEGRO_CHANNEL_CONF ALLEGRO_CHANNEL_CONF; typedef enum ALLEGRO_PLAYMODE ALLEGRO_PLAYMODE; typedef enum ALLEGRO_MIXER_QUALITY ALLEGRO_MIXER_QUALITY; #endif /* Sample functions */ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_create_sample, (void *buf, unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)); ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample, (ALLEGRO_SAMPLE *spl)); /* Sample instance functions */ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE_INSTANCE*, al_create_sample_instance, ( ALLEGRO_SAMPLE *data)); ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample_instance, ( ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_frequency, (const ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_length, (const ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_depth, (const ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_channels, (const ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_sample_data, (const ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_frequency, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_length, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_position, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_speed, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_gain, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_pan, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_time, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_instance_depth, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_instance_channels, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_sample_instance_playmode, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_playing, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_attached, (const ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_position, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_length, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_speed, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_gain, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_pan, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playmode, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_PLAYMODE val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playing, (ALLEGRO_SAMPLE_INSTANCE *spl, bool val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_get_sample, (ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_stop_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); /* Stream functions */ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM*, al_create_audio_stream, (size_t buffer_count, unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(void, al_drain_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_frequency, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_length, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_available_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_speed, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_gain, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_pan, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_audio_stream_channels, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_audio_stream_depth, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_audio_stream_playmode, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_playing, (const ALLEGRO_AUDIO_STREAM *spl)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_attached, (const ALLEGRO_AUDIO_STREAM *spl)); ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_audio_stream_fragment, (const ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_speed, (ALLEGRO_AUDIO_STREAM *stream, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_gain, (ALLEGRO_AUDIO_STREAM *stream, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_pan, (ALLEGRO_AUDIO_STREAM *stream, float val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playmode, (ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_PLAYMODE val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playing, (ALLEGRO_AUDIO_STREAM *stream, bool val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_fragment, (ALLEGRO_AUDIO_STREAM *stream, void *val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_rewind_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_seek_audio_stream_secs, (ALLEGRO_AUDIO_STREAM *stream, double time)); ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_position_secs, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_length_secs, (ALLEGRO_AUDIO_STREAM *stream)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_loop_secs, (ALLEGRO_AUDIO_STREAM *stream, double start, double end)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_audio_stream_event_source, (ALLEGRO_AUDIO_STREAM *stream)); /* Mixer functions */ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER*, al_create_mixer, (unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_mixer, (ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_mixer, ( ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_mixer, (ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_mixer, (ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_postprocess_callback, ( ALLEGRO_MIXER *mixer, void (*cb)(void *buf, unsigned int samples, void *data), void *data)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_mixer_frequency, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_mixer_channels, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_mixer_depth, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER_QUALITY, al_get_mixer_quality, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(float, al_get_mixer_gain, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_playing, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_attached, (const ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_frequency, (ALLEGRO_MIXER *mixer, unsigned int val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_quality, (ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_gain, (ALLEGRO_MIXER *mixer, float gain)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_playing, (ALLEGRO_MIXER *mixer, bool val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_mixer, (ALLEGRO_MIXER *mixer)); /* Voice functions */ ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_VOICE*, al_create_voice, (unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_voice, (ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_voice, ( ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_voice, ( ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_VOICE *voice )); ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_voice, (ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(void, al_detach_voice, (ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_frequency, (const ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_position, (const ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_voice_channels, (const ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_voice_depth, (const ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_voice_playing, (const ALLEGRO_VOICE *voice)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_position, (ALLEGRO_VOICE *voice, unsigned int val)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_playing, (ALLEGRO_VOICE *voice, bool val)); /* Misc. audio functions */ ALLEGRO_KCM_AUDIO_FUNC(bool, al_install_audio, (void)); ALLEGRO_KCM_AUDIO_FUNC(void, al_uninstall_audio, (void)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_is_audio_installed, (void)); ALLEGRO_KCM_AUDIO_FUNC(uint32_t, al_get_allegro_audio_version, (void)); ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_channel_count, (ALLEGRO_CHANNEL_CONF conf)); ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_audio_depth_size, (ALLEGRO_AUDIO_DEPTH conf)); /* Simple audio layer */ ALLEGRO_KCM_AUDIO_FUNC(bool, al_reserve_samples, (int reserve_samples)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER *, al_get_default_mixer, (void)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_default_mixer, (ALLEGRO_MIXER *mixer)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_restore_default_mixer, (void)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample, (ALLEGRO_SAMPLE *data, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)); ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_sample, (ALLEGRO_SAMPLE_ID *spl_id)); ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_samples, (void)); /* File type handlers */ ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader, (const char *ext, ALLEGRO_SAMPLE *(*loader)(const char *filename))); ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver, (const char *ext, bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))); ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader, (const char *ext, ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, size_t buffer_count, unsigned int samples))); ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader_f, (const char *ext, ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE *fp))); ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver_f, (const char *ext, bool (*saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl))); ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader_f, (const char *ext, ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE *fp, size_t buffer_count, unsigned int samples))); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample, (const char *filename)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample, (const char *filename, ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream, (const char *filename, size_t buffer_count, unsigned int samples)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample_f, (ALLEGRO_FILE* fp, const char *ident)); ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample_f, (ALLEGRO_FILE* fp, const char *ident, ALLEGRO_SAMPLE *spl)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream_f, (ALLEGRO_FILE* fp, const char *ident, size_t buffer_count, unsigned int samples)); #ifdef __cplusplus } /* End extern "C" */ #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/allegro5/internal/0000755000175000001440000000000012157230736020313 5ustar tjadenusersallegro-5.0.10/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake0000644000175000001440000000032711256470307025204 0ustar tjadenusers#cmakedefine ALLEGRO_CFG_KCM_ALSA #cmakedefine ALLEGRO_CFG_KCM_OPENAL #cmakedefine ALLEGRO_CFG_KCM_DSOUND #cmakedefine ALLEGRO_CFG_KCM_OSS #cmakedefine ALLEGRO_CFG_KCM_PULSEAUDIO #cmakedefine ALLEGRO_CFG_KCM_AQUEUE allegro-5.0.10/addons/audio/allegro5/internal/aintern_audio.h0000644000175000001440000002716712102205744023311 0ustar tjadenusers/* internal-only header * Updated for 4.9 api inclusion by Ryan Dickie * Originally done by KC/Milan */ #ifndef AINTERN_AUDIO_H #define AINTERN_AUDIO_H #include "allegro5/allegro.h" #include "allegro5/internal/aintern_vector.h" #include "../allegro_audio.h" typedef enum ALLEGRO_AUDIO_DRIVER_ENUM { /* Various driver modes. */ ALLEGRO_AUDIO_DRIVER_AUTODETECT = 0x20000, ALLEGRO_AUDIO_DRIVER_OPENAL = 0x20001, ALLEGRO_AUDIO_DRIVER_ALSA = 0x20002, ALLEGRO_AUDIO_DRIVER_DSOUND = 0x20003, ALLEGRO_AUDIO_DRIVER_OSS = 0x20004, ALLEGRO_AUDIO_DRIVER_AQUEUE = 0x20005, ALLEGRO_AUDIO_DRIVER_PULSEAUDIO = 0x20006 } ALLEGRO_AUDIO_DRIVER_ENUM; typedef struct ALLEGRO_AUDIO_DRIVER ALLEGRO_AUDIO_DRIVER; struct ALLEGRO_AUDIO_DRIVER { const char *specifier; int (*open)(void); void (*close)(void); int (*allocate_voice)(ALLEGRO_VOICE*); void (*deallocate_voice)(ALLEGRO_VOICE*); int (*load_voice)(ALLEGRO_VOICE*, const void*); void (*unload_voice)(ALLEGRO_VOICE*); int (*start_voice)(ALLEGRO_VOICE*); int (*stop_voice)(ALLEGRO_VOICE*); bool (*voice_is_playing)(const ALLEGRO_VOICE*); unsigned int (*get_voice_position)(const ALLEGRO_VOICE*); int (*set_voice_position)(ALLEGRO_VOICE*, unsigned int); }; extern ALLEGRO_AUDIO_DRIVER *_al_kcm_driver; const void *_al_voice_update(ALLEGRO_VOICE *voice, unsigned int *samples); bool _al_kcm_set_voice_playing(ALLEGRO_VOICE *voice, bool val); /* A voice structure that you'd attach a mixer or sample to. Ideally there * would be one ALLEGRO_VOICE per system/hardware voice. */ struct ALLEGRO_VOICE { ALLEGRO_AUDIO_DEPTH depth; ALLEGRO_CHANNEL_CONF chan_conf; unsigned int frequency; size_t buffer_size; size_t num_buffers; /* If non-0, they must be honored by the driver. */ ALLEGRO_SAMPLE_INSTANCE *attached_stream; /* The stream that is attached to the voice, or NULL. * May be an ALLEGRO_SAMPLE_INSTANCE or ALLEGRO_MIXER object. */ bool is_streaming; /* True for voices with an attached mixer. */ ALLEGRO_MUTEX *mutex; ALLEGRO_COND *cond; ALLEGRO_AUDIO_DRIVER *driver; /* XXX shouldn't there only be one audio driver active * at a time? */ void *extra; /* Extra data for use by the driver. */ }; typedef union { float *f32; uint32_t *u24; int32_t *s24; uint16_t *u16; int16_t *s16; uint8_t *u8; int8_t *s8; void *ptr; } any_buffer_t; struct ALLEGRO_SAMPLE { ALLEGRO_AUDIO_DEPTH depth; ALLEGRO_CHANNEL_CONF chan_conf; unsigned int frequency; int len; any_buffer_t buffer; bool free_buf; /* Whether `buffer' needs to be freed when the sample * is destroyed, or when `buffer' changes. */ }; /* Read some samples into a mixer buffer. * * source: * The object to read samples from. This may be one of several types. * * *vbuf: (in-out parameter) * Pointer to pointer to destination buffer. * (should confirm what it means to change the pointer on return) * * *samples: (in-out parameter) * On input indicates the maximum number of samples that can fit into *vbuf. * On output indicates the actual number of samples that were read. * * buffer_depth: * The audio depth of the destination buffer. * * dest_maxc: * The number of channels in the destination. */ typedef void (*stream_reader_t)(void *source, void **vbuf, unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); typedef struct { union { ALLEGRO_MIXER *mixer; ALLEGRO_VOICE *voice; void *ptr; } u; bool is_voice; } sample_parent_t; /* The sample struct also serves the base of ALLEGRO_AUDIO_STREAM, ALLEGRO_MIXER. */ struct ALLEGRO_SAMPLE_INSTANCE { /* ALLEGRO_SAMPLE_INSTANCE does not generate any events yet but ALLEGRO_AUDIO_STREAM * does, which can inherit only ALLEGRO_SAMPLE_INSTANCE. */ ALLEGRO_EVENT_SOURCE es; ALLEGRO_SAMPLE spl_data; volatile bool is_playing; /* Is this sample is playing? */ ALLEGRO_PLAYMODE loop; float speed; float gain; float pan; /* When resampling an audio stream there will be fractional sample * positions due to the difference in frequencies. */ int pos; int pos_bresenham_error; int loop_start; int loop_end; int step; int step_denom; /* The numerator and denominator of the step are * stored separately. The actual step is obtained by * dividing step by step_denom */ float *matrix; /* Used to convert from this format to the attached * mixers, if any. Otherwise is NULL. * The gain is premultiplied in. */ bool is_mixer; stream_reader_t spl_read; /* Reads sample data into the provided buffer, using * the specified format, converting as necessary. */ ALLEGRO_MUTEX *mutex; /* Points to the parent object's mutex. It is NULL if * the sample is not directly or indirectly attached * to a voice. */ sample_parent_t parent; /* The object that this sample is attached to, if any. */ }; void _al_kcm_destroy_sample(ALLEGRO_SAMPLE_INSTANCE *sample, bool unregister); void _al_kcm_stream_set_mutex(ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MUTEX *mutex); void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl); typedef size_t (*stream_callback_t)(ALLEGRO_AUDIO_STREAM *, void *, size_t); typedef void (*unload_feeder_t)(ALLEGRO_AUDIO_STREAM *); typedef bool (*rewind_feeder_t)(ALLEGRO_AUDIO_STREAM *); typedef bool (*seek_feeder_t)(ALLEGRO_AUDIO_STREAM *, double); typedef double (*get_feeder_position_t)(ALLEGRO_AUDIO_STREAM *); typedef double (*get_feeder_length_t)(ALLEGRO_AUDIO_STREAM *); typedef bool (*set_feeder_loop_t)(ALLEGRO_AUDIO_STREAM *, double, double); struct ALLEGRO_AUDIO_STREAM { ALLEGRO_SAMPLE_INSTANCE spl; /* ALLEGRO_AUDIO_STREAM is derived from * ALLEGRO_SAMPLE_INSTANCE. */ unsigned int buf_count; /* The stream buffer is divided into a number of * fragments; this is the number of fragments. */ void *main_buffer; /* Pointer to a single buffer big enough to hold all * the fragments. Each fragment has additional samples * at the start for linear/cubic interpolation. */ void **pending_bufs; void **used_bufs; /* Arrays of offsets into the main_buffer. * The arrays are each 'buf_count' long. * * 'pending_bufs' holds pointers to fragments supplied * by the user which are yet to be handed off to the * audio driver. * * 'used_bufs' holds pointers to fragments which * have been sent to the audio driver and so are * ready to receive new data. */ volatile bool is_draining; /* Set to true if sample data is not going to be passed * to the stream any more. The stream must change its * playing state to false after all buffers have been * played. */ ALLEGRO_THREAD *feed_thread; volatile bool quit_feed_thread; unload_feeder_t unload_feeder; rewind_feeder_t rewind_feeder; seek_feeder_t seek_feeder; get_feeder_position_t get_feeder_position; get_feeder_length_t get_feeder_length; set_feeder_loop_t set_feeder_loop; stream_callback_t feeder; /* If ALLEGRO_AUDIO_STREAM has been created by * al_load_audio_stream(), the stream will be fed * by a thread using the 'feeder' callback. Such * streams don't need to be fed by the user. */ void *extra; /* Extra data for use by the flac/vorbis addons. */ }; bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream); typedef void (*postprocess_callback_t)(void *buf, unsigned int samples, void *userdata); /* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. Certain internal functions and * pointers may take either object type, and such things are explicitly noted. * This is never exposed to the user, though. The sample object's read method * will be set to a different function that will call the read method of all * attached streams (which may be a sample, or another mixer). */ struct ALLEGRO_MIXER { ALLEGRO_SAMPLE_INSTANCE ss; /* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. */ ALLEGRO_MIXER_QUALITY quality; postprocess_callback_t postprocess_callback; void *pp_callback_userdata; _AL_VECTOR streams; /* Vector of ALLEGRO_SAMPLE_INSTANCE*. Holds the list of * streams being mixed together. */ }; extern void _al_kcm_mixer_rejig_sample_matrix(ALLEGRO_MIXER *mixer, ALLEGRO_SAMPLE_INSTANCE *spl); extern void _al_kcm_mixer_read(void *source, void **buf, unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); typedef enum { ALLEGRO_NO_ERROR = 0, ALLEGRO_INVALID_PARAM = 1, ALLEGRO_INVALID_OBJECT = 2, ALLEGRO_GENERIC_ERROR = 255 } AL_ERROR_ENUM; extern void _al_set_error(int error, char* string); /* Supposedly internal */ ALLEGRO_KCM_AUDIO_FUNC(int, _al_kcm_get_silence, (ALLEGRO_AUDIO_DEPTH depth)); ALLEGRO_KCM_AUDIO_FUNC(void*, _al_kcm_feed_stream, (ALLEGRO_THREAD *self, void *vstream)); /* Helper to emit an event that the stream has got a buffer ready to be refilled. */ void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream); void _al_kcm_init_destructors(void); void _al_kcm_shutdown_destructors(void); void _al_kcm_register_destructor(void *object, void (*func)(void*)); void _al_kcm_unregister_destructor(void *object); void _al_kcm_foreach_destructor( void (*callback)(void *object, void (*func)(void *), void *udata), void *userdata); ALLEGRO_KCM_AUDIO_FUNC(void, _al_kcm_shutdown_default_mixer, (void)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, _al_count_to_channel_conf, (int num_channels)); ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, _al_word_size_to_depth_conf, (int word_size)); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_instance.c0000644000175000001440000003411012101033341017544 0ustar tjadenusers/** * Originally digi.c from allegro wiki * Original authors: KC/Milan * * Converted to allegro5 by Ryan Dickie */ /* Title: Sample Instance functions */ #include #include #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" static void maybe_lock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_lock_mutex(mutex); } } static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_unlock_mutex(mutex); } } /* _al_kcm_stream_set_mutex: * This function sets a sample's mutex pointer to the specified value. It is * ALLEGRO_MIXER aware, and will recursively set any attached streams' mutex * to the same value. */ void _al_kcm_stream_set_mutex(ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MUTEX *mutex) { ASSERT(stream); if (stream->mutex == mutex) return; stream->mutex = mutex; /* If this is a mixer, we need to make sure all the attached streams also * set the same mutex. */ if (stream->is_mixer) { ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)stream; int i; for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); ALLEGRO_SAMPLE_INSTANCE *spl = *slot; _al_kcm_stream_set_mutex(spl, mutex); } } } /* stream_free: * This function is ALLEGRO_MIXER aware and frees the memory associated with * the sample or mixer, and detaches any attached streams or mixers. */ static void stream_free(ALLEGRO_SAMPLE_INSTANCE *spl) { if (spl) { /* Make sure we free the mixer buffer and de-reference the attached * streams if this is a mixer stream. */ if (spl->is_mixer) { ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)spl; int i; _al_kcm_stream_set_mutex(&mixer->ss, NULL); for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); ALLEGRO_SAMPLE_INSTANCE *spl = *slot; spl->parent.u.ptr = NULL; } _al_vector_free(&mixer->streams); if (spl->spl_data.buffer.ptr) { ASSERT(spl->spl_data.free_buf); al_free(spl->spl_data.buffer.ptr); spl->spl_data.buffer.ptr = NULL; } spl->spl_data.free_buf = false; } ASSERT(! spl->spl_data.free_buf); al_free(spl); } } /* _al_kcm_detach_from_parent: * This detaches the sample, stream, or mixer from anything it may be attached * to. */ void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl) { ALLEGRO_MIXER *mixer; int i; if (!spl || !spl->parent.u.ptr) return; if (spl->parent.is_voice) { al_detach_voice(spl->parent.u.voice); return; } mixer = spl->parent.u.mixer; /* Search through the streams and check for this one */ for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); if (*slot == spl) { maybe_lock_mutex(mixer->ss.mutex); _al_vector_delete_at(&mixer->streams, i); spl->parent.u.mixer = NULL; _al_kcm_stream_set_mutex(spl, NULL); spl->spl_read = NULL; maybe_unlock_mutex(mixer->ss.mutex); break; } } al_free(spl->matrix); spl->matrix = NULL; } /* Function: al_create_sample_instance */ ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data) { ALLEGRO_SAMPLE_INSTANCE *spl; spl = al_calloc(1, sizeof(*spl)); if (!spl) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating sample object"); return NULL; } if (sample_data) { spl->spl_data = *sample_data; } spl->spl_data.free_buf = false; spl->loop = ALLEGRO_PLAYMODE_ONCE; spl->speed = 1.0f; spl->gain = 1.0f; spl->pan = 0.0f; spl->pos = 0; spl->loop_start = 0; spl->loop_end = sample_data ? sample_data->len : 0; spl->step = 0; spl->matrix = NULL; spl->is_mixer = false; spl->spl_read = NULL; spl->mutex = NULL; spl->parent.u.ptr = NULL; _al_kcm_register_destructor(spl, (void (*)(void *)) al_destroy_sample_instance); return spl; } /* This function is ALLEGRO_MIXER aware */ /* Function: al_destroy_sample_instance */ void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) { _al_kcm_destroy_sample(spl, true); } /* Internal function: _al_kcm_destroy_sample */ void _al_kcm_destroy_sample(ALLEGRO_SAMPLE_INSTANCE *spl, bool unregister) { if (spl) { if (unregister) { _al_kcm_unregister_destructor(spl); } _al_kcm_detach_from_parent(spl); stream_free(spl); } } /* Function: al_play_sample_instance */ bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return al_set_sample_instance_playing(spl, true); } /* Function: al_stop_sample_instance */ bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return al_set_sample_instance_playing(spl, false); } /* Function: al_get_sample_instance_frequency */ unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->spl_data.frequency; } /* Function: al_get_sample_instance_length */ unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->spl_data.len; } /* Function: al_get_sample_instance_position */ unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); if (spl->parent.u.ptr && spl->parent.is_voice) { ALLEGRO_VOICE *voice = spl->parent.u.voice; return al_get_voice_position(voice); } return spl->pos; } /* Function: al_get_sample_instance_speed */ float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->speed; } /* Function: al_get_sample_instance_gain */ float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->gain; } /* Function: al_get_sample_instance_pan */ float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->pan; } /* Function: al_get_sample_instance_time */ float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return (float)(spl->spl_data.len) / (float)spl->spl_data.frequency; } /* Function: al_get_sample_instance_depth */ ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->spl_data.depth; } /* Function: al_get_sample_instance_channels */ ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels( const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->spl_data.chan_conf; } /* Function: al_get_sample_instance_playmode */ ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return spl->loop; } /* Function: al_get_sample_instance_playing */ bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); if (spl->parent.u.ptr && spl->parent.is_voice) { ALLEGRO_VOICE *voice = spl->parent.u.voice; return al_get_voice_playing(voice); } return spl->is_playing; } /* Function: al_get_sample_instance_attached */ bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return (spl->parent.u.ptr != NULL); } /* Function: al_set_sample_instance_position */ bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val) { ASSERT(spl); if (spl->parent.u.ptr && spl->parent.is_voice) { ALLEGRO_VOICE *voice = spl->parent.u.voice; if (!al_set_voice_position(voice, val)) return false; } else { maybe_lock_mutex(spl->mutex); spl->pos = val; maybe_unlock_mutex(spl->mutex); } return true; } /* Function: al_set_sample_instance_length */ bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val) { ASSERT(spl); if (spl->is_playing) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to change the length of a playing sample"); return false; } spl->spl_data.len = val; return true; } /* Function: al_set_sample_instance_speed */ bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val) { ASSERT(spl); if (fabsf(val) < (1.0f/64.0f)) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to set zero speed"); return false; } if (spl->parent.u.ptr && spl->parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set voice playback speed"); return false; } spl->speed = val; if (spl->parent.u.mixer) { ALLEGRO_MIXER *mixer = spl->parent.u.mixer; maybe_lock_mutex(spl->mutex); spl->step = (spl->spl_data.frequency) * spl->speed; spl->step_denom = mixer->ss.spl_data.frequency; /* Don't wanna be trapped with a step value of 0 */ if (spl->step == 0) { if (spl->speed > 0.0f) spl->step = 1; else spl->step = -1; } maybe_unlock_mutex(spl->mutex); } return true; } /* Function: al_set_sample_instance_gain */ bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val) { ASSERT(spl); if (spl->parent.u.ptr && spl->parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set gain of sample attached to voice"); return false; } if (spl->gain != val) { spl->gain = val; /* If attached to a mixer already, need to recompute the sample * matrix to take into account the gain. */ if (spl->parent.u.mixer) { ALLEGRO_MIXER *mixer = spl->parent.u.mixer; maybe_lock_mutex(spl->mutex); _al_kcm_mixer_rejig_sample_matrix(mixer, spl); maybe_unlock_mutex(spl->mutex); } } return true; } /* Function: al_set_sample_instance_pan */ bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val) { ASSERT(spl); if (spl->parent.u.ptr && spl->parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set panning of sample attached to voice"); return false; } if (val != ALLEGRO_AUDIO_PAN_NONE && (val < -1.0 || val > 1.0)) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Invalid pan value"); return false; } if (spl->pan != val) { spl->pan = val; /* If attached to a mixer already, need to recompute the sample * matrix to take into account the panning. */ if (spl->parent.u.mixer) { ALLEGRO_MIXER *mixer = spl->parent.u.mixer; maybe_lock_mutex(spl->mutex); _al_kcm_mixer_rejig_sample_matrix(mixer, spl); maybe_unlock_mutex(spl->mutex); } } return true; } /* Function: al_set_sample_instance_playmode */ bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_PLAYMODE val) { ASSERT(spl); if (val < ALLEGRO_PLAYMODE_ONCE || val > ALLEGRO_PLAYMODE_BIDIR) { _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid loop mode"); return false; } maybe_lock_mutex(spl->mutex); spl->loop = val; if (spl->loop != ALLEGRO_PLAYMODE_ONCE) { if (spl->pos < spl->loop_start) spl->pos = spl->loop_start; else if (spl->pos > spl->loop_end-1) spl->pos = spl->loop_end-1; } maybe_unlock_mutex(spl->mutex); return true; } /* Function: al_set_sample_instance_playing */ bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val) { ASSERT(spl); if (!spl->parent.u.ptr) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Sample has no parent"); return false; } if (!spl->spl_data.buffer.ptr) { _al_set_error(ALLEGRO_INVALID_OBJECT, "Sample has no data"); return false; } if (spl->parent.is_voice) { /* parent is voice */ ALLEGRO_VOICE *voice = spl->parent.u.voice; return al_set_voice_playing(voice, val); } /* parent is mixer */ maybe_lock_mutex(spl->mutex); spl->is_playing = val; if (!val) spl->pos = 0; maybe_unlock_mutex(spl->mutex); return true; } /* Function: al_detach_sample_instance */ bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); _al_kcm_detach_from_parent(spl); ASSERT(spl->spl_read == NULL); return true; } /* Function: al_set_sample */ bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data) { sample_parent_t old_parent; bool need_reattach; ASSERT(spl); /* Stop the sample if it is playing. */ if (spl->is_playing) { if (!al_set_sample_instance_playing(spl, false)) { /* Shouldn't happen. */ ASSERT(false); return false; } } if (!data) { if (spl->parent.u.ptr) { _al_kcm_detach_from_parent(spl); } spl->spl_data.buffer.ptr = NULL; return true; } /* Have data. */ need_reattach = false; if (spl->parent.u.ptr != NULL) { if (spl->spl_data.frequency != data->frequency || spl->spl_data.depth != data->depth || spl->spl_data.chan_conf != data->chan_conf) { old_parent = spl->parent; need_reattach = true; _al_kcm_detach_from_parent(spl); } } spl->spl_data = *data; spl->spl_data.free_buf = false; spl->pos = 0; spl->loop_start = 0; spl->loop_end = data->len; /* Should we reset the loop mode? */ if (need_reattach) { if (old_parent.is_voice) { if (!al_attach_sample_instance_to_voice(spl, old_parent.u.voice)) { spl->spl_data.buffer.ptr = NULL; return false; } } else { if (!al_attach_sample_instance_to_mixer(spl, old_parent.u.mixer)) { spl->spl_data.buffer.ptr = NULL; return false; } } } return true; } /* Function: al_get_sample */ ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl) { ASSERT(spl); return &(spl->spl_data); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/openal.c0000644000175000001440000004621012031446260016402 0ustar tjadenusers/* * updated for 4.9 inclusion by Ryan Dickie * Originally done by KC/Milan */ #include #include #include "allegro5/allegro.h" #if defined(ALLEGRO_MACOSX) || defined(ALLEGRO_IPHONE) #include #include #else /* ALLEGRO_MACOSX */ #include #include #endif /* ALLEGRO_MACOSX */ #include "allegro5/internal/aintern_audio.h" ALLEGRO_DEBUG_CHANNEL("openal") /* OpenAL vars */ static ALCdevice *openal_dev; static ALCcontext *openal_context; /* TODO: make these configurable */ static const size_t preferred_frag_size = 1024; static const ALuint preferred_buf_count = 4; static const char *openal_get_err_str(ALenum err) { switch (err) { case AL_NO_ERROR: return "There is no OpenAL error"; case AL_INVALID_NAME: return "A bad name (ID) was passed to OpenAL"; case AL_INVALID_ENUM: return "An invalid enum was passed to OpenAL"; case AL_INVALID_VALUE: return "An Invalid enum was passed to OpenAL"; case AL_INVALID_OPERATION: return "The requestion operation is invalid"; case AL_OUT_OF_MEMORY: return "OpenAL ran out of memory"; default: return "Unknown error"; } } static const char *alc_get_err_str(ALCenum err) { switch (err) { case ALC_NO_ERROR: return "There is no OpenAL error"; case ALC_INVALID_DEVICE: return "A bad device was passed to OpenAL"; case ALC_INVALID_CONTEXT: return "An bad context was passed to OpenAL"; case ALC_INVALID_ENUM: return "An Invalid enum was passed to OpenAL"; case ALC_INVALID_VALUE: return "The requestion operation is invalid"; case ALC_OUT_OF_MEMORY: return "OpenAL ran out of memory"; default: return "Unknown error"; } } /* The open method starts up the driver and should lock the device, using the previously set paramters, or defaults. It shouldn't need to start sending audio data to the device yet, however. */ static int _openal_open(void) { ALenum openal_err; ALCenum alc_err; ALLEGRO_INFO("Starting OpenAL\n"); /* clear the error state */ openal_err = alGetError(); /* pick default device. always a good choice */ openal_dev = alcOpenDevice(NULL); alc_err = ALC_NO_ERROR; if (!openal_dev || (alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { ALLEGRO_ERROR("Could not open audio device: %s\n", alc_get_err_str(alc_err)); return 1; } openal_context = alcCreateContext(openal_dev, NULL); alc_err = ALC_NO_ERROR; if (!openal_context || (alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { ALLEGRO_ERROR("Could not create current device context: %s\n", alc_get_err_str(alc_err)); return 1; } alcMakeContextCurrent(openal_context); #if !defined ALLEGRO_IPHONE if ((alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { ALLEGRO_ERROR("Could not make context current: %s\n", alc_get_err_str(alc_err)); return 1; } alDistanceModel(AL_NONE); if ((openal_err = alGetError()) != AL_NO_ERROR) { ALLEGRO_ERROR("Could not set distance model: %s\n", openal_get_err_str(openal_err)); return 1; } #endif ALLEGRO_DEBUG("Vendor: %s\n", alGetString(AL_VENDOR)); ALLEGRO_DEBUG("Version: %s\n", alGetString(AL_VERSION)); ALLEGRO_DEBUG("Renderer: %s\n", alGetString(AL_RENDERER)); ALLEGRO_DEBUG("Extensions: %s\n", alGetString(AL_EXTENSIONS)); return 0; } /* The close method should close the device, freeing any resources, and allow other processes to use the device */ static void _openal_close(void) { /* clear error states */ alGetError(); alcGetError(openal_dev); /* remove traces from openal */ alcMakeContextCurrent(NULL); alcDestroyContext(openal_context); alcCloseDevice(openal_dev); /* reset the pointers to NULL */ openal_context = NULL; openal_dev = NULL; } /* Custom struct to hold voice information OpenAL needs */ /* TODO: review */ typedef struct ALLEGRO_AL_DATA { ALuint *buffers; size_t num_buffers; ALuint buffer_size; ALuint source; ALuint format; ALLEGRO_THREAD *thread; bool stopped; } ALLEGRO_AL_DATA; /* Custom routine which runs in another thread to periodically check if OpenAL wants more data for a stream */ /* TODO: review */ static void *_openal_update(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*) arg; ALLEGRO_AL_DATA *ex_data = (ALLEGRO_AL_DATA*)voice->extra; unsigned int i, samples_per_update; unsigned int bytes_per_sample; const void *data; void *silence; /* Streams should not be set to looping */ alSourcei(ex_data->source, AL_LOOPING, AL_FALSE); silence = al_calloc(1, ex_data->buffer_size); if (ex_data->format == AL_FORMAT_STEREO8 || ex_data->format == AL_FORMAT_MONO8) { memset(silence, 0x80, ex_data->buffer_size); } for (i = 0; i < ex_data->num_buffers; i++) { alBufferData(ex_data->buffers[i], ex_data->format, silence, ex_data->buffer_size, voice->frequency); } alSourceQueueBuffers(ex_data->source, ex_data->num_buffers, ex_data->buffers); alSourcePlay(ex_data->source); switch (ex_data->format) { case AL_FORMAT_STEREO16: bytes_per_sample = 4; break; case AL_FORMAT_STEREO8: case AL_FORMAT_MONO16: bytes_per_sample = 2; break; default: bytes_per_sample = 1; break; } samples_per_update = ex_data->buffer_size / bytes_per_sample; data = silence; while (!al_get_thread_should_stop(self)) { ALint status = 0; alGetSourcei(ex_data->source, AL_BUFFERS_PROCESSED, &status); if (status <= 0) { /* FIXME what is this for ? */ al_rest(0.001); continue; } while (--status >= 0) { ALuint buffer; data = _al_voice_update(voice, &samples_per_update); if (data == NULL) data = silence; alSourceUnqueueBuffers(ex_data->source, 1, &buffer); alBufferData(buffer, ex_data->format, data, samples_per_update * bytes_per_sample, voice->frequency); alSourceQueueBuffers(ex_data->source, 1, &buffer); } alGetSourcei(ex_data->source, AL_SOURCE_STATE, &status); if (status == AL_STOPPED) { alSourcePlay(ex_data->source); } } alSourceStop(ex_data->source); al_free(silence); ex_data->stopped = true; al_broadcast_cond(voice->cond); return NULL; } /* The load_voice method loads a sample into the driver's memory. The voice's 'streaming' field will be set to false for these voices, and it's 'buffer_size' field will be the total length in bytes of the sample data. The voice's attached sample's looping mode should be honored, and loading must fail if it cannot be. */ static int _openal_load_voice(ALLEGRO_VOICE *voice, const void *data) { ALLEGRO_AL_DATA *ex_data = voice->extra; ALenum openal_err; if (voice->attached_stream->loop != ALLEGRO_PLAYMODE_ONCE && voice->attached_stream->loop != ALLEGRO_PLAYMODE_LOOP) { return 1; } ex_data->buffer_size = voice->buffer_size; if (!ex_data->buffer_size) { ALLEGRO_ERROR("Voice buffer and data buffer size mismatch\n"); return 1; } ex_data->num_buffers = 1; alGenSources(1, &ex_data->source); if ((openal_err = alGetError()) != AL_NO_ERROR) { ALLEGRO_ERROR("Could not generate (voice) source: %s\n", openal_get_err_str(openal_err)); return 1; } ex_data->buffers = al_malloc(sizeof(ALuint) * ex_data->num_buffers); if (!ex_data->buffers) { alDeleteSources(1, &ex_data->source); ALLEGRO_ERROR("Could not allocate voice buffer memory\n"); return 1; } alGenBuffers(ex_data->num_buffers, ex_data->buffers); if ((openal_err = alGetError()) != AL_NO_ERROR) { alDeleteSources(1, &ex_data->source); al_free(ex_data->buffers); ex_data->buffers = NULL; ALLEGRO_ERROR("Could not generate (voice) buffer: %s\n", openal_get_err_str(openal_err)); return 1; } /* copies data into a buffer */ alBufferData(ex_data->buffers[0], ex_data->format, data, ex_data->buffer_size, voice->frequency); /* sets the buffer */ alSourcei(ex_data->source, AL_BUFFER, ex_data->buffers[0]); /* Loop / no loop? */ alSourcei(ex_data->source, AL_LOOPING, (voice->attached_stream->loop != ALLEGRO_PLAYMODE_ONCE)); /* make sure the volume is on */ alSourcef(ex_data->source, AL_GAIN, 1.0f); if ((openal_err = alGetError()) != AL_NO_ERROR) { alDeleteSources(1, &ex_data->source); alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); al_free(ex_data->buffers); ex_data->buffers = NULL; ALLEGRO_ERROR("Could not attach voice source: %s\n", openal_get_err_str(openal_err)); return 1; } return 0; } /* The unload_voice method unloads a sample previously loaded with load_voice. This method should not be called on a streaming voice. */ static void _openal_unload_voice(ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; alDeleteSources(1, &ex_data->source); alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); al_free(ex_data->buffers); ex_data->buffers = NULL; alGetError(); /* required! */ } /* The start_voice should, surprise, start the voice. For streaming voices, it should start polling the device and call _al_voice_update for audio data. For non-streaming voices, it should resume playing from the last set position */ static int _openal_start_voice(ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; ALenum openal_err; /* playing a sample instead of a stream */ if (!voice->is_streaming) { alSourcePlay(ex_data->source); if ((openal_err = alGetError()) != AL_NO_ERROR) { ALLEGRO_ERROR("Could not start voice: %s\n", openal_get_err_str(openal_err)); return 1; } ALLEGRO_INFO("Starting voice\n"); return 0; } { ex_data->buffer_size = voice->buffer_size; if (!ex_data->buffer_size) { switch (ex_data->format) { case AL_FORMAT_STEREO16: ex_data->buffer_size = preferred_frag_size * 4; break; case AL_FORMAT_STEREO8: case AL_FORMAT_MONO16: ex_data->buffer_size = preferred_frag_size * 2; break; default: ex_data->buffer_size = preferred_frag_size; break; } } ex_data->num_buffers = voice->num_buffers; if (!ex_data->num_buffers) ex_data->num_buffers = preferred_buf_count; alGenSources(1, &ex_data->source); if (alGetError() != AL_NO_ERROR) return 1; ex_data->buffers = al_malloc(sizeof(ALuint) * ex_data->num_buffers); if (!ex_data->buffers) { alDeleteSources(1, &ex_data->source); return 1; } alGenBuffers(ex_data->num_buffers, ex_data->buffers); if (alGetError() != AL_NO_ERROR) { alDeleteSources(1, &ex_data->source); al_free(ex_data->buffers); ex_data->buffers = NULL; return 1; } alSourcef(ex_data->source, AL_GAIN, 1.0f); if (alGetError() != AL_NO_ERROR) { alDeleteSources(1, &ex_data->source); alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); al_free(ex_data->buffers); ex_data->buffers = NULL; return 1; } ex_data->stopped = false; ex_data->thread = al_create_thread(_openal_update, (void *)voice); al_start_thread(ex_data->thread); } ALLEGRO_INFO("Starting voice\n"); return 0; } /* The stop_voice method should stop playback. For non-streaming voices, it should leave the data loaded, and reset the voice position to 0. */ static int _openal_stop_voice(ALLEGRO_VOICE* voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; ALenum openal_err; if (!ex_data->buffers) { ALLEGRO_WARN("Trying to stop empty voice buffer\n"); return 1; } /* if playing a sample */ if (!voice->is_streaming) { alSourceStop(ex_data->source); if ((openal_err = alGetError()) != AL_NO_ERROR) { ALLEGRO_ERROR("Could not stop voice: %s\n", openal_get_err_str(openal_err)); return 1; } return 0; } if (ex_data->thread) { al_set_thread_should_stop(ex_data->thread); while (!ex_data->stopped) { al_wait_cond(voice->cond, voice->mutex); } al_join_thread(ex_data->thread, NULL); ex_data->thread = NULL; ex_data->stopped = false; } alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); al_free(ex_data->buffers); ex_data->buffers = NULL; alDeleteSources(1, &ex_data->source); alGetError(); /* required! */ return 0; } /* The voice_is_playing method should only be called on non-streaming sources, and should return true if the voice is playing */ static bool _openal_voice_is_playing(const ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; ALint status; if (!ex_data) return false; alGetSourcei(ex_data->source, AL_SOURCE_STATE, &status); return (status == AL_PLAYING); } /* The allocate_voice method should grab a voice from the system, and allocate any data common to streaming and non-streaming sources. */ static int _openal_allocate_voice(ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data; /* OpenAL doesn't support very much! */ switch (voice->depth) { case ALLEGRO_AUDIO_DEPTH_UINT8: /* format supported */ break; case ALLEGRO_AUDIO_DEPTH_INT8: ALLEGRO_WARN("OpenAL requires 8-bit data to be unsigned\n"); return 1; case ALLEGRO_AUDIO_DEPTH_UINT16: ALLEGRO_WARN("OpenAL requires 16-bit data to be signed\n"); return 1; case ALLEGRO_AUDIO_DEPTH_INT16: /* format supported */ break; case ALLEGRO_AUDIO_DEPTH_UINT24: ALLEGRO_WARN("OpenAL does not support 24-bit data\n"); return 1; case ALLEGRO_AUDIO_DEPTH_INT24: ALLEGRO_WARN("OpenAL does not support 24-bit data\n"); return 1; case ALLEGRO_AUDIO_DEPTH_FLOAT32: ALLEGRO_WARN("OpenAL does not support 32-bit floating data\n"); return 1; default: ALLEGRO_WARN("Cannot allocate unknown voice depth\n"); return 1; } ex_data = al_calloc(1, sizeof(*ex_data)); if (!ex_data) { ALLEGRO_ERROR("Could not allocate voice data memory\n"); return 1; } switch (voice->chan_conf) { case ALLEGRO_CHANNEL_CONF_1: /* format supported */ if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) ex_data->format = AL_FORMAT_MONO8; else ex_data->format = AL_FORMAT_MONO16; break; case ALLEGRO_CHANNEL_CONF_2: /* format supported */ if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) ex_data->format = AL_FORMAT_STEREO8; else ex_data->format = AL_FORMAT_STEREO16; break; case ALLEGRO_CHANNEL_CONF_3: ALLEGRO_ERROR("OpenAL does not support voice with 3 channel configuration\n"); al_free(ex_data); return 1; case ALLEGRO_CHANNEL_CONF_4: ex_data->format = alGetEnumValue("AL_FORMAT_QUAD16"); if (ex_data->format) { ALLEGRO_ERROR("OpenAL cannot allocate voice with 4.0 channel configuration\n"); al_free(ex_data); return 1; } if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) { ALLEGRO_ERROR("OpenAL requires 16-bit signed data for 4 channel configuration\n"); al_free(ex_data); return 1; } /* else it is supported */ break; case ALLEGRO_CHANNEL_CONF_5_1: ex_data->format = alGetEnumValue("AL_FORMAT_51CHN_16"); if (!ex_data->format) { ALLEGRO_ERROR("Cannot allocate voice with 5.1 channel configuration\n"); al_free(ex_data); return 1; } if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { ALLEGRO_ERROR("5.1 channel requires 16-bit signed data\n"); al_free(ex_data); return 1; } /* else it is supported */ break; case ALLEGRO_CHANNEL_CONF_6_1: ex_data->format = alGetEnumValue("AL_FORMAT_61CHN_16"); if (!ex_data->format) { ALLEGRO_ERROR("Cannot allocate voice with 6.1 channel configuration\n"); al_free(ex_data); return 1; } if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { ALLEGRO_ERROR("6.1 channel requires 16-bit signed data\n"); al_free(ex_data); return 1; } /* else it is supported */ break; case ALLEGRO_CHANNEL_CONF_7_1: ex_data->format = alGetEnumValue("AL_FORMAT_71CHN_16"); if (!ex_data->format) { ALLEGRO_ERROR("Cannot allocate voice with 7.1 channel configuration\n"); al_free(ex_data); return 1; } if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { ALLEGRO_ERROR("7.1 channel requires 16-bit signed data\n"); al_free(ex_data); return 1; } /* else it is supported */ break; default: ALLEGRO_ERROR("Cannot allocate voice with unknown channel configuration\n"); al_free(ex_data); return 1; } voice->extra = ex_data; ex_data->thread = NULL; ex_data->stopped = false; return 0; } /* The deallocate_voice method should free the resources for the given voice, but still retain a hold on the device. The voice should be stopped and unloaded by the time this is called */ static void _openal_deallocate_voice(ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; ASSERT(ex_data->thread == NULL); (void)ex_data; al_free(voice->extra); voice->extra = NULL; } /* The get_voice_position method should return the current sample position of the voice (sample_pos = byte_pos / (depth/8) / channels). This should never be called on a streaming voice. */ static unsigned int _openal_get_voice_position(const ALLEGRO_VOICE *voice) { ALLEGRO_AL_DATA *ex_data = voice->extra; ALint pos; alGetSourcei(ex_data->source, AL_SAMPLE_OFFSET, &pos); if (alGetError() != AL_NO_ERROR) return 0; return pos; } /* The set_voice_position method should set the voice's playback position, given the value in samples. This should never be called on a streaming voice. */ static int _openal_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) { ALLEGRO_AL_DATA *ex_data = voice->extra; alSourcei(ex_data->source, AL_SAMPLE_OFFSET, val); if (alGetError() != AL_NO_ERROR) return 1; return 0; } ALLEGRO_AUDIO_DRIVER _al_kcm_openal_driver = { "OpenAL", _openal_open, _openal_close, _openal_allocate_voice, _openal_deallocate_voice, _openal_load_voice, _openal_unload_voice, _openal_start_voice, _openal_stop_voice, _openal_voice_is_playing, _openal_get_voice_position, _openal_set_voice_position, }; /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_stream.c0000644000175000001440000004666612101331126017260 0ustar tjadenusers/** * Originally digi.c from allegro wiki * Original authors: KC/Milan * * Converted to allegro5 by Ryan Dickie */ /* Title: Stream functions */ #include #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_audio_cfg.h" ALLEGRO_DEBUG_CHANNEL("audio") /* * The highest quality interpolator is a cubic interpolator requiring * four sample points. In the streaming case we lag the true sample * position by three. */ #define MAX_LAG (3) static void maybe_lock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_lock_mutex(mutex); } } static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { al_unlock_mutex(mutex); } } /* Function: al_create_audio_stream */ ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count, unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) { ALLEGRO_AUDIO_STREAM *stream; unsigned long bytes_per_sample; unsigned long bytes_per_frag_buf; size_t i; if (!fragment_count) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to create stream with no buffers"); return NULL; } if (!frag_samples) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to create stream with no buffer size"); return NULL; } if (!freq) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to create stream with no frequency"); return NULL; } bytes_per_sample = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); bytes_per_frag_buf = frag_samples * bytes_per_sample; stream = al_calloc(1, sizeof(*stream)); if (!stream) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating stream object"); return NULL; } stream->spl.is_playing = true; stream->is_draining = false; stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONCE; stream->spl.spl_data.depth = depth; stream->spl.spl_data.chan_conf = chan_conf; stream->spl.spl_data.frequency = freq; stream->spl.speed = 1.0f; stream->spl.gain = 1.0f; stream->spl.pan = 0.0f; stream->spl.step = 0; stream->spl.pos = frag_samples; stream->spl.spl_data.len = stream->spl.pos; stream->buf_count = fragment_count; stream->used_bufs = al_calloc(1, fragment_count * sizeof(void *) * 2); if (!stream->used_bufs) { al_free(stream->used_bufs); al_free(stream); _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating stream buffer pointers"); return NULL; } stream->pending_bufs = stream->used_bufs + fragment_count; /* The main_buffer holds all the buffer fragments in contiguous memory. * To support interpolation across buffer fragments, we allocate extra * MAX_LAG samples at the start of each buffer fragment, to hold the * last few sample values which came before that fragment. */ stream->main_buffer = al_calloc(1, (MAX_LAG * bytes_per_sample + bytes_per_frag_buf) * fragment_count); if (!stream->main_buffer) { al_free(stream->used_bufs); al_free(stream); _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating stream buffer"); return NULL; } for (i = 0; i < fragment_count; i++) { stream->pending_bufs[i] = (char *) stream->main_buffer + i * (MAX_LAG*bytes_per_sample + bytes_per_frag_buf) + MAX_LAG*bytes_per_sample; } al_init_user_event_source(&stream->spl.es); /* This can lead to deadlocks on shutdown, hence we don't do it. */ /* _al_kcm_register_destructor(stream, (void (*)(void *)) al_destroy_audio_stream); */ return stream; } /* Function: al_destroy_audio_stream */ void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream) { if (stream) { if (stream->feed_thread) { stream->unload_feeder(stream); } /* See commented out call to _al_kcm_register_destructor. */ /* _al_kcm_unregister_destructor(stream); */ _al_kcm_detach_from_parent(&stream->spl); al_destroy_user_event_source(&stream->spl.es); al_free(stream->main_buffer); al_free(stream->used_bufs); al_free(stream); } } /* Function: al_drain_audio_stream */ void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream) { bool playing; if (!al_get_audio_stream_attached(stream)) { al_set_audio_stream_playing(stream, false); return; } stream->is_draining = true; do { al_rest(0.01); playing = al_get_audio_stream_playing(stream); } while (playing); stream->is_draining = false; } /* Function: al_get_audio_stream_frequency */ unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.spl_data.frequency; } /* Function: al_get_audio_stream_length */ unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.spl_data.len; } /* Function: al_get_audio_stream_fragments */ unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->buf_count; } /* Function: al_get_available_audio_stream_fragments */ unsigned int al_get_available_audio_stream_fragments( const ALLEGRO_AUDIO_STREAM *stream) { unsigned int i; ASSERT(stream); for (i = 0; i < stream->buf_count && stream->used_bufs[i]; i++) ; return i; } /* Function: al_get_audio_stream_speed */ float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.speed; } /* Function: al_get_audio_stream_gain */ float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.gain; } /* Function: al_get_audio_stream_pan */ float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.pan; } /* Function: al_get_audio_stream_channels */ ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels( const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.spl_data.chan_conf; } /* Function: al_get_audio_stream_depth */ ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth( const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.spl_data.depth; } /* Function: al_get_audio_stream_playmode */ ALLEGRO_PLAYMODE al_get_audio_stream_playmode( const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.loop; } /* Function: al_get_audio_stream_playing */ bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return stream->spl.is_playing; } /* Function: al_get_audio_stream_attached */ bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); return (stream->spl.parent.u.ptr != NULL); } /* Function: al_get_audio_stream_fragment */ void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream) { size_t i; void *fragment; ASSERT(stream); maybe_lock_mutex(stream->spl.mutex); if (!stream->used_bufs[0]) { /* No free fragments are available. */ fragment = NULL; } else { fragment = stream->used_bufs[0]; for (i = 0; i < stream->buf_count-1 && stream->used_bufs[i]; i++) { stream->used_bufs[i] = stream->used_bufs[i+1]; } stream->used_bufs[i] = NULL; } maybe_unlock_mutex(stream->spl.mutex); return fragment; } /* Function: al_set_audio_stream_speed */ bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val) { ASSERT(stream); if (val <= 0.0f) { _al_set_error(ALLEGRO_INVALID_PARAM, "Attempted to set stream speed to a zero or negative value"); return false; } if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set voice playback speed"); return false; } stream->spl.speed = val; if (stream->spl.parent.u.mixer) { ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; maybe_lock_mutex(stream->spl.mutex); stream->spl.step = (stream->spl.spl_data.frequency) * stream->spl.speed; stream->spl.step_denom = mixer->ss.spl_data.frequency; /* Don't wanna be trapped with a step value of 0 */ if (stream->spl.step == 0) { stream->spl.step = 1; } maybe_unlock_mutex(stream->spl.mutex); } return true; } /* Function: al_set_audio_stream_gain */ bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val) { ASSERT(stream); if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set gain of stream attached to voice"); return false; } if (stream->spl.gain != val) { stream->spl.gain = val; /* If attached to a mixer already, need to recompute the sample * matrix to take into account the gain. */ if (stream->spl.parent.u.mixer) { ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; maybe_lock_mutex(stream->spl.mutex); _al_kcm_mixer_rejig_sample_matrix(mixer, &stream->spl); maybe_unlock_mutex(stream->spl.mutex); } } return true; } /* Function: al_set_audio_stream_pan */ bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val) { ASSERT(stream); if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Could not set gain of stream attached to voice"); return false; } if (val != ALLEGRO_AUDIO_PAN_NONE && (val < -1.0 || val > 1.0)) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Invalid pan value"); return false; } if (stream->spl.pan != val) { stream->spl.pan = val; /* If attached to a mixer already, need to recompute the sample * matrix to take into account the panning. */ if (stream->spl.parent.u.mixer) { ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; maybe_lock_mutex(stream->spl.mutex); _al_kcm_mixer_rejig_sample_matrix(mixer, &stream->spl); maybe_unlock_mutex(stream->spl.mutex); } } return true; } /* Function: al_set_audio_stream_playmode */ bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_PLAYMODE val) { ASSERT(stream); if (val == ALLEGRO_PLAYMODE_ONCE) { stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONCE; return true; } else if (val == ALLEGRO_PLAYMODE_LOOP) { /* Only streams creating by al_load_audio_stream() support * looping. */ if (!stream->feeder) return false; stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONEDIR; return true; } // XXX _al_set_error return false; } /* Function: al_set_audio_stream_playing */ bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val) { ASSERT(stream); if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { ALLEGRO_VOICE *voice = stream->spl.parent.u.voice; bool rc; if (val == stream->spl.is_playing) { return true; } rc = _al_kcm_set_voice_playing(voice, val); if (rc) { stream->spl.is_playing = val; } return rc; } stream->spl.is_playing = val; if (!val) { maybe_lock_mutex(stream->spl.mutex); stream->spl.pos = stream->spl.spl_data.len; maybe_unlock_mutex(stream->spl.mutex); } return true; } /* Function: al_detach_audio_stream */ bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream) { ASSERT(stream); _al_kcm_detach_from_parent(&stream->spl); ASSERT(stream->spl.spl_read == NULL); return !al_get_audio_stream_attached(stream); } /* Function: al_set_audio_stream_fragment */ bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val) { size_t i; bool ret; ASSERT(stream); maybe_lock_mutex(stream->spl.mutex); for (i = 0; i < stream->buf_count && stream->pending_bufs[i] ; i++) ; if (i < stream->buf_count) { stream->pending_bufs[i] = val; ret = true; } else { _al_set_error(ALLEGRO_INVALID_OBJECT, "Attempted to set a stream buffer with a full pending list"); ret = false; } maybe_unlock_mutex(stream->spl.mutex); return ret; } /* _al_kcm_refill_stream: * Called by the mixer when the current buffer has been used up. It should * point to the next pending buffer and reset the sample position. * Returns true if the next buffer is available and set up. * Otherwise returns false. */ bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream) { ALLEGRO_SAMPLE_INSTANCE *spl = &stream->spl; void *old_buf = spl->spl_data.buffer.ptr; void *new_buf; size_t i; if (old_buf) { /* Slide the buffers down one position and put the * completed buffer into the used array to be refilled. */ for (i = 0; i < stream->buf_count-1 && stream->pending_bufs[i]; i++) { stream->pending_bufs[i] = stream->pending_bufs[i+1]; } stream->pending_bufs[i] = NULL; for (i = 0; stream->used_bufs[i]; i++) ; stream->used_bufs[i] = old_buf; } new_buf = stream->pending_bufs[0]; stream->spl.spl_data.buffer.ptr = new_buf; if (!new_buf) { ALLEGRO_WARN("Out of buffers\n"); return false; } /* Copy the last MAX_LAG sample values to the front of the new buffer * for interpolation. */ if (old_buf) { const int bytes_per_sample = al_get_channel_count(spl->spl_data.chan_conf) * al_get_audio_depth_size(spl->spl_data.depth); memcpy( (char *) new_buf - bytes_per_sample * MAX_LAG, (char *) old_buf + bytes_per_sample * (spl->pos-MAX_LAG), bytes_per_sample * MAX_LAG); } stream->spl.pos = 0; return true; } /* _al_kcm_feed_stream: * A routine running in another thread that feeds the stream buffers as * neccesary, usually getting data from some file reader backend. */ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream) { ALLEGRO_AUDIO_STREAM *stream = vstream; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; (void)self; ALLEGRO_DEBUG("Stream feeder thread started.\n"); queue = al_create_event_queue(); al_register_event_source(queue, &stream->spl.es); stream->quit_feed_thread = false; while (!stream->quit_feed_thread) { char *fragment; ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT && !stream->is_draining) { unsigned long bytes; unsigned long bytes_written; fragment = al_get_audio_stream_fragment(stream); if (!fragment) { /* This is not an error. */ continue; } bytes = (stream->spl.spl_data.len) * al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth); maybe_lock_mutex(stream->spl.mutex); bytes_written = stream->feeder(stream, fragment, bytes); maybe_unlock_mutex(stream->spl.mutex); /* In case it reaches the end of the stream source, stream feeder will * fill the remaining space with silence. If we should loop, rewind the * stream and override the silence with the beginning. * In extreme cases we need to repeat it multiple times. */ while (bytes_written < bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { size_t bw; al_rewind_audio_stream(stream); maybe_lock_mutex(stream->spl.mutex); bw = stream->feeder(stream, fragment + bytes_written, bytes - bytes_written); bytes_written += bw; maybe_unlock_mutex(stream->spl.mutex); } if (!al_set_audio_stream_fragment(stream, fragment)) { ALLEGRO_ERROR("Error setting stream buffer.\n"); continue; } /* The streaming source doesn't feed any more, drain buffers and quit. */ if (bytes_written != bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE) { al_drain_audio_stream(stream); stream->quit_feed_thread = true; } } else if (event.type == _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE) { stream->quit_feed_thread = true; } } event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FINISHED; event.user.timestamp = al_get_time(); al_emit_user_event(&stream->spl.es, &event, NULL); al_destroy_event_queue(queue); ALLEGRO_DEBUG("Stream feeder thread finished.\n"); return NULL; } void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream) { /* Emit one event for each stream fragment available right now. * * There may already be an event corresponding to an available fragment in * some event queue, but there's nothing we can do about that. Streams may * be added and removed from queues, events may be lost by the user, etc. * so it would be dangerous to assume that each fragment event would be * responded to, once and exactly once. * * Having said that, event queues are empty in the steady state so it is * relatively rare that this situation occurs. */ int count = al_get_available_audio_stream_fragments(stream); while (count--) { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT; event.user.timestamp = al_get_time(); al_emit_user_event(&stream->spl.es, &event, NULL); } } /* Function: al_rewind_audio_stream */ bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream) { bool ret; if (stream->rewind_feeder) { maybe_lock_mutex(stream->spl.mutex); ret = stream->rewind_feeder(stream); maybe_unlock_mutex(stream->spl.mutex); return ret; } return false; } /* Function: al_seek_audio_stream_secs */ bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time) { bool ret; if (stream->seek_feeder) { maybe_lock_mutex(stream->spl.mutex); ret = stream->seek_feeder(stream, time); maybe_unlock_mutex(stream->spl.mutex); return ret; } return false; } /* Function: al_get_audio_stream_position_secs */ double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream) { double ret; if (stream->get_feeder_position) { maybe_lock_mutex(stream->spl.mutex); ret = stream->get_feeder_position(stream); maybe_unlock_mutex(stream->spl.mutex); return ret; } return 0.0; } /* Function: al_get_audio_stream_length_secs */ double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream) { double ret; if (stream->get_feeder_length) { maybe_lock_mutex(stream->spl.mutex); ret = stream->get_feeder_length(stream); maybe_unlock_mutex(stream->spl.mutex); return ret; } return 0.0; } /* Function: al_set_audio_stream_loop_secs */ bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream, double start, double end) { bool ret; if (start >= end) return false; if (stream->set_feeder_loop) { maybe_lock_mutex(stream->spl.mutex); ret = stream->set_feeder_loop(stream, start, end); maybe_unlock_mutex(stream->spl.mutex); return ret; } return false; } /* Function: al_get_audio_stream_event_source */ ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source( ALLEGRO_AUDIO_STREAM *stream) { return &stream->spl.es; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/audio/kcm_sample.c0000644000175000001440000002704511771525101017246 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Sample audio interface. * * By Peter Wang. * * See LICENSE.txt for copyright information. */ /* Title: Sample audio interface */ #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_vector.h" ALLEGRO_DEBUG_CHANNEL("audio") static ALLEGRO_VOICE *allegro_voice = NULL; static ALLEGRO_MIXER *allegro_mixer = NULL; static ALLEGRO_MIXER *default_mixer = NULL; static _AL_VECTOR auto_samples = _AL_VECTOR_INITIALIZER(ALLEGRO_SAMPLE_INSTANCE *); static _AL_VECTOR auto_sample_ids = _AL_VECTOR_INITIALIZER(int); static bool create_default_mixer(void); static bool do_play_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop); static void free_sample_vector(void); static int string_to_depth(const char *s) { // FIXME: fill in the rest if (!_al_stricmp(s, "int16")) { return ALLEGRO_AUDIO_DEPTH_INT16; } else { return ALLEGRO_AUDIO_DEPTH_FLOAT32; } } /* Creates the default voice and mixer if they haven't been created yet. */ static bool create_default_mixer(void) { int voice_frequency = 44100; int voice_depth = ALLEGRO_AUDIO_DEPTH_INT16; int mixer_frequency = 44100; int mixer_depth = ALLEGRO_AUDIO_DEPTH_FLOAT32; ALLEGRO_CONFIG *config = al_get_system_config(); if (config) { const char *p; p = al_get_config_value(config, "audio", "primary_voice_frequency"); if (p && p[0] != '\0') { voice_frequency = atoi(p); } p = al_get_config_value(config, "audio", "primary_mixer_frequency"); if (p && p[0] != '\0') { mixer_frequency = atoi(p); } p = al_get_config_value(config, "audio", "primary_voice_depth"); if (p && p[0] != '\0') { voice_depth = string_to_depth(p); } p = al_get_config_value(config, "audio", "primary_mixer_depth"); if (p && p[0] != '\0') { mixer_depth = string_to_depth(p); } } if (!allegro_voice) { allegro_voice = al_create_voice(voice_frequency, voice_depth, ALLEGRO_CHANNEL_CONF_2); if (!allegro_voice) { ALLEGRO_ERROR("al_create_voice failed\n"); goto Error; } } if (!allegro_mixer) { allegro_mixer = al_create_mixer(mixer_frequency, mixer_depth, ALLEGRO_CHANNEL_CONF_2); if (!allegro_mixer) { ALLEGRO_ERROR("al_create_voice failed\n"); goto Error; } } if (!al_attach_mixer_to_voice(allegro_mixer, allegro_voice)) { ALLEGRO_ERROR("al_attach_mixer_to_voice failed\n"); goto Error; } return true; Error: if (allegro_mixer) { al_destroy_mixer(allegro_mixer); allegro_mixer = NULL; } if (allegro_voice) { al_destroy_voice(allegro_voice); allegro_voice = NULL; } return false; } /* Function: al_create_sample */ ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf) { ALLEGRO_SAMPLE *spl; ASSERT(buf); if (!freq) { _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid sample frequency"); return NULL; } spl = al_calloc(1, sizeof(*spl)); if (!spl) { _al_set_error(ALLEGRO_GENERIC_ERROR, "Out of memory allocating sample data object"); return NULL; } spl->depth = depth; spl->chan_conf = chan_conf; spl->frequency = freq; spl->len = samples; spl->buffer.ptr = buf; spl->free_buf = free_buf; _al_kcm_register_destructor(spl, (void (*)(void *)) al_destroy_sample); return spl; } /* Stop any sample instances which are still playing a sample buffer which * is about to be destroyed. */ static void stop_sample_instances_helper(void *object, void (*func)(void *), void *userdata) { ALLEGRO_SAMPLE_INSTANCE *splinst = object; /* This is ugly. */ if (func == (void (*)(void *)) al_destroy_sample_instance && al_get_sample_data(al_get_sample(splinst)) == userdata && al_get_sample_instance_playing(splinst)) { al_stop_sample_instance(splinst); } } /* Function: al_destroy_sample */ void al_destroy_sample(ALLEGRO_SAMPLE *spl) { if (spl) { _al_kcm_foreach_destructor(stop_sample_instances_helper, al_get_sample_data(spl)); _al_kcm_unregister_destructor(spl); if (spl->free_buf && spl->buffer.ptr) { al_free(spl->buffer.ptr); } spl->buffer.ptr = NULL; spl->free_buf = false; al_free(spl); } } /* Function: al_reserve_samples */ bool al_reserve_samples(int reserve_samples) { int i; int current_samples_count = (int) _al_vector_size(&auto_samples); ASSERT(reserve_samples >= 0); /* If no default mixer has been set by the user, then create a voice * and a mixer, and set them to be the default one for use with * al_play_sample(). */ if (default_mixer == NULL) { if (!al_restore_default_mixer()) goto Error; } if (current_samples_count < reserve_samples) { /* We need to reserve more samples than currently are reserved. */ for (i = 0; i < reserve_samples - current_samples_count; i++) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_alloc_back(&auto_samples); int *id = _al_vector_alloc_back(&auto_sample_ids); *id = 0; *slot = al_create_sample_instance(NULL); if (!*slot) { ALLEGRO_ERROR("al_create_sample failed\n"); goto Error; } if (!al_attach_sample_instance_to_mixer(*slot, default_mixer)) { ALLEGRO_ERROR("al_attach_mixer_to_sample failed\n"); goto Error; } } } else if (current_samples_count > reserve_samples) { /* We need to reserve fewer samples than currently are reserved. */ while (current_samples_count-- > reserve_samples) { _al_vector_delete_at(&auto_samples, current_samples_count); _al_vector_delete_at(&auto_sample_ids, current_samples_count); } } return true; Error: free_sample_vector(); return false; } /* Function: al_get_default_mixer */ ALLEGRO_MIXER *al_get_default_mixer(void) { return default_mixer; } /* Function: al_set_default_mixer */ bool al_set_default_mixer(ALLEGRO_MIXER *mixer) { ASSERT(mixer != NULL); if (mixer != default_mixer) { int i; default_mixer = mixer; /* Destroy all current sample instances, recreate them, and * attach them to the new mixer */ for (i = 0; i < (int) _al_vector_size(&auto_samples); i++) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&auto_samples, i); int *id = _al_vector_ref(&auto_sample_ids, i); *id = 0; al_destroy_sample_instance(*slot); *slot = al_create_sample_instance(NULL); if (!*slot) { ALLEGRO_ERROR("al_create_sample failed\n"); goto Error; } if (!al_attach_sample_instance_to_mixer(*slot, default_mixer)) { ALLEGRO_ERROR("al_attach_mixer_to_sample failed\n"); goto Error; } } } return true; Error: free_sample_vector(); default_mixer = NULL; return false; } /* Function: al_restore_default_mixer */ bool al_restore_default_mixer(void) { if (!create_default_mixer()) return false; if (!al_set_default_mixer(allegro_mixer)) return false; return true; } /* Function: al_play_sample */ bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id) { static int next_id = 0; unsigned int i; ASSERT(spl); if (ret_id != NULL) { ret_id->_id = -1; ret_id->_index = 0; } for (i = 0; i < _al_vector_size(&auto_samples); i++) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&auto_samples, i); ALLEGRO_SAMPLE_INSTANCE *splinst = (*slot); if (!al_get_sample_instance_playing(splinst)) { int *id = _al_vector_ref(&auto_sample_ids, i); if (!do_play_sample(splinst, spl, gain, pan, speed, loop)) break; if (ret_id != NULL) { ret_id->_index = (int) i; ret_id->_id = *id = ++next_id; } return true; } } return false; } static bool do_play_sample(ALLEGRO_SAMPLE_INSTANCE *splinst, ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop) { if (!al_set_sample(splinst, spl)) { ALLEGRO_ERROR("al_set_sample failed\n"); return false; } if (!al_set_sample_instance_gain(splinst, gain) || !al_set_sample_instance_pan(splinst, pan) || !al_set_sample_instance_speed(splinst, speed) || !al_set_sample_instance_playmode(splinst, loop)) { return false; } if (!al_play_sample_instance(splinst)) { ALLEGRO_ERROR("al_play_sample_instance failed\n"); return false; } return true; } /* Function: al_stop_sample */ void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id) { int *id; ASSERT(spl_id->_id != -1); ASSERT(spl_id->_index < (int) _al_vector_size(&auto_samples)); ASSERT(spl_id->_index < (int) _al_vector_size(&auto_sample_ids)); id = _al_vector_ref(&auto_sample_ids, spl_id->_index); if (*id == spl_id->_id) { ALLEGRO_SAMPLE_INSTANCE **slot, *spl; slot = _al_vector_ref(&auto_samples, spl_id->_index); spl = (*slot); al_stop_sample_instance(spl); } } /* Function: al_stop_samples */ void al_stop_samples(void) { unsigned int i; for (i = 0; i < _al_vector_size(&auto_samples); i++) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&auto_samples, i); ALLEGRO_SAMPLE_INSTANCE *spl = (*slot); al_stop_sample_instance(spl); } } /* Function: al_get_sample_frequency */ unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl) { ASSERT(spl); return spl->frequency; } /* Function: al_get_sample_length */ unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl) { ASSERT(spl); return spl->len; } /* Function: al_get_sample_depth */ ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl) { ASSERT(spl); return spl->depth; } /* Function: al_get_sample_channels */ ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl) { ASSERT(spl); return spl->chan_conf; } /* Function: al_get_sample_data */ void *al_get_sample_data(const ALLEGRO_SAMPLE *spl) { ASSERT(spl); return spl->buffer.ptr; } /* Destroy all sample instances, and frees the associated vectors. */ static void free_sample_vector(void) { int j; for (j = 0; j < (int) _al_vector_size(&auto_samples); j++) { ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&auto_samples, j); al_destroy_sample_instance(*slot); } _al_vector_free(&auto_samples); _al_vector_free(&auto_sample_ids); } void _al_kcm_shutdown_default_mixer(void) { free_sample_vector(); al_destroy_mixer(allegro_mixer); al_destroy_voice(allegro_voice); allegro_mixer = NULL; allegro_voice = NULL; default_mixer = NULL; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/0000755000175000001440000000000012157230737016472 5ustar tjadenusersallegro-5.0.10/addons/native_dialog/gtk_msgbox.c0000644000175000001440000001042512104442472020775 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GTK native dialog implementation. * * See LICENSE.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "gtk_dialog.h" typedef struct { ALLEGRO_DISPLAY *display; ALLEGRO_NATIVE_DIALOG *dialog; } Msg; /* Note: the message box code cannot assume that Allegro is installed. */ static void msgbox_destroy(GtkWidget *w, gpointer data) { ALLEGRO_NATIVE_DIALOG *nd = data; (void)w; ASSERT(nd->async_queue); g_async_queue_push(nd->async_queue, ACK_CLOSED); } static void msgbox_response(GtkDialog *dialog, gint response_id, gpointer user_data) { ALLEGRO_NATIVE_DIALOG *nd = (void *)user_data; (void)dialog; switch (response_id) { case GTK_RESPONSE_DELETE_EVENT: nd->mb_pressed_button = 0; break; case GTK_RESPONSE_YES: case GTK_RESPONSE_OK: nd->mb_pressed_button = 1; break; case GTK_RESPONSE_NO: case GTK_RESPONSE_CANCEL: nd->mb_pressed_button = 2; break; default: nd->mb_pressed_button = response_id; } } /* [gtk thread] */ static gboolean create_native_message_box(gpointer data) { Msg *msg = data; ALLEGRO_DISPLAY *display = msg->display; ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; GtkWidget *window; /* Create a new file selection widget */ GtkMessageType type = GTK_MESSAGE_INFO; GtkButtonsType buttons = GTK_BUTTONS_OK; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type = GTK_MESSAGE_WARNING; if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type = GTK_MESSAGE_ERROR; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) buttons = GTK_BUTTONS_YES_NO; if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) buttons = GTK_BUTTONS_OK_CANCEL; if (fd->mb_buttons) buttons = GTK_BUTTONS_NONE; window = gtk_message_dialog_new(NULL, 0, type, buttons, "%s", al_cstr(fd->mb_heading)); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(window), "%s", al_cstr(fd->mb_text)); _al_gtk_make_transient(display, window); if (fd->mb_buttons) { int i = 1; int pos = 0; while (1) { int next = al_ustr_find_chr(fd->mb_buttons, pos, '|'); int pos2 = next; if (next == -1) pos2 = al_ustr_size(fd->mb_buttons); ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *button_text; button_text = al_ref_ustr(&info, fd->mb_buttons, pos, pos2); pos = pos2 + 1; char buffer[256]; al_ustr_to_buffer(button_text, buffer, sizeof buffer); gtk_dialog_add_button(GTK_DIALOG(window), buffer, i++); if (next == -1) break; } } gtk_window_set_title(GTK_WINDOW(window), al_cstr(fd->title)); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(msgbox_destroy), fd); g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(msgbox_response), fd); g_signal_connect_swapped(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), window); gtk_widget_show(window); return FALSE; } /* [user thread] */ int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { Msg msg; if (!_al_gtk_ensure_thread()) return 0; /* "cancelled" */ fd->async_queue = g_async_queue_new(); msg.display = display; msg.dialog = fd; g_timeout_add(0, create_native_message_box, &msg); /* Wait for a signal that the window is closed. */ while (g_async_queue_pop(fd->async_queue) != ACK_CLOSED) ; g_async_queue_unref(fd->async_queue); fd->async_queue = NULL; return fd->mb_pressed_button; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/CMakeLists.txt0000644000175000001440000000534412104442472021231 0ustar tjadenusersset(NATIVE_DIALOG_INCLUDE_FILES allegro5/allegro_native_dialog.h) set_our_header_properties(${NATIVE_DIALOG_INCLUDE_FILES}) set(NATIVE_DIALOG_SOURCES dialog.c textlog.c ) set(GTK_NATIVE_DIALOG_SOURCES gtk_dialog.c gtk_filesel.c gtk_msgbox.c gtk_textlog.c gtk_thread.c ) if(APPLE AND NOT IPHONE) list(APPEND NATIVE_DIALOG_SOURCES osx_dialog.m) set(ALLEGRO_CFG_NATIVE_DIALOG_OSX 1) set(SUPPORT_NATIVE_DIALOG 1) endif(APPLE AND NOT IPHONE) if(APPLE AND IPHONE) list(APPEND NATIVE_DIALOG_SOURCES iphone_dialog.m) set(ALLEGRO_CFG_NATIVE_DIALOG_IPHONE 1) set(SUPPORT_NATIVE_DIALOG 1) endif(APPLE AND IPHONE) if(WIN32) list(APPEND NATIVE_DIALOG_SOURCES win_dialog.c) set(ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS 1) set(SUPPORT_NATIVE_DIALOG 1) endif(WIN32) if(NOT SUPPORT_NATIVE_DIALOG AND NOT GP2XWIZ AND NOT IPHONE) pkg_check_modules(GTK gtk+-2.0) pkg_check_modules(GT gthread-2.0) if(GTK_FOUND AND GT_FOUND) list(APPEND NATIVE_DIALOG_SOURCES ${GTK_NATIVE_DIALOG_SOURCES}) include_directories(SYSTEM ${GTK_INCLUDE_DIRS}) # For example, on Windows, GTK+ requires gcc -mms-bitfields (MinGW). foreach(arg ${GTK_CFLAGS}) set(GTK_CFLAGS_STRING "${GTK_CFLAGS_STRING} ${arg}") endforeach(arg) # STRICT_WARN will cause gcc to warn about a function prototype in # gtkitemfactory.h so disable that warning explicitly. if(COMPILER_GCC) set(GTK_CFLAGS_STRING "${GTK_CFLAGS_STRING} -Wno-strict-prototypes") endif(COMPILER_GCC) set_source_files_properties( ${GTK_NATIVE_DIALOG_SOURCES} PROPERTIES COMPILE_FLAGS "${GTK_CFLAGS_STRING}" ) set(NATIVE_DIALOG_LIBRARIES ${GTK_LIBRARIES} ${GT_LIBRARIES}) set(ALLEGRO_CFG_NATIVE_DIALOG_GTK 1) set(SUPPORT_NATIVE_DIALOG 1) endif(GTK_FOUND AND GT_FOUND) endif() if(SUPPORT_NATIVE_DIALOG) configure_file( allegro5/internal/aintern_native_dialog_cfg.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/internal/aintern_native_dialog_cfg.h ) # Note: allegro_dialog NOT allegro_native_dialog. add_our_library(allegro_dialog "${NATIVE_DIALOG_SOURCES};${NATIVE_DIALOG_INCLUDE_FILES}" "-DALLEGRO_NATIVE_DIALOG_SRC" "${NATIVE_DIALOG_LIBRARIES};${ALLEGRO_LINK_WITH}" ) # Note: allegro_dialog NOT allegro_native_dialog. set_our_framework_properties(allegro_dialog AllegroDialog-${ALLEGRO_SOVERSION}) install_our_library(allegro_dialog) install_our_headers(${NATIVE_DIALOG_INCLUDE_FILES}) set(SUPPORT_NATIVE_DIALOG 1 PARENT_SCOPE) set(NATIVE_DIALOG_LINK_WITH allegro_dialog PARENT_SCOPE) endif(SUPPORT_NATIVE_DIALOG) # vim: set sts=4 sw=4 et: allegro-5.0.10/addons/native_dialog/gtk_dialog.h0000644000175000001440000000052712104442472020744 0ustar tjadenusers#ifndef __al_included_gtk_dialog_h #define __al_included_gtk_dialog_h #define ACK_OK ((void *)0x1111) #define ACK_ERROR ((void *)0x2222) #define ACK_OPENED ((void *)0x3333) #define ACK_CLOSED ((void *)0x4444) void _al_gtk_make_transient(ALLEGRO_DISPLAY *display, GtkWidget *window); bool _al_gtk_ensure_thread(void); #endif allegro-5.0.10/addons/native_dialog/iphone_dialog.m0000644000175000001440000000553212104442472021447 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include #include "allegro5/internal/aintern_iphone.h" /* In 5.1 this is exposed but not in 5.0 */ UIView *_al_iphone_get_view(void); bool _al_init_native_dialog_addon(void) { return true; } void _al_shutdown_native_dialog_addon(void) { } bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { (void)display; (void)fd; return false; } @interface AlertDelegate : NSObject { ALLEGRO_MUTEX *mutex; ALLEGRO_COND *button_pressed; } @property ALLEGRO_MUTEX *mutex; @property ALLEGRO_COND *button_pressed; @end @implementation AlertDelegate @synthesize mutex; @synthesize button_pressed; - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)bindex { (void)alert; (void)bindex; al_lock_mutex(mutex); al_signal_cond(button_pressed); al_unlock_mutex(mutex); } -(void) createAlert:(id)alert { [_al_iphone_get_view() addSubview:alert]; [alert show]; [alert release]; } @end int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *nd) { (void)display; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; NSString *title = [NSString stringWithUTF8String:al_cstr(nd->title)]; NSString *heading = [NSString stringWithUTF8String:al_cstr(nd->mb_heading)]; NSString *text = [NSString stringWithUTF8String:al_cstr(nd->mb_text)]; NSString *ok = [NSString stringWithUTF8String:"Ok"]; NSString *message = [NSString stringWithFormat:@"%@\n\n%@", heading, text]; AlertDelegate *delegate = [[AlertDelegate alloc]init]; delegate.mutex = al_create_mutex(); delegate.button_pressed = al_create_cond(); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:delegate cancelButtonTitle:ok otherButtonTitles:nil]; [delegate performSelectorOnMainThread:@selector(createAlert:) withObject:alert waitUntilDone:YES]; al_lock_mutex(delegate.mutex); al_wait_cond(delegate.button_pressed, delegate.mutex); al_unlock_mutex(delegate.mutex); al_destroy_cond(delegate.button_pressed); al_destroy_mutex(delegate.mutex); [delegate release]; [pool drain]; return 0; } bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { (void)textlog; return false; } void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { (void) textlog; } void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { (void) textlog; } allegro-5.0.10/addons/native_dialog/textlog.c0000644000175000001440000001112111655353002020311 0ustar tjadenusers#include #include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "allegro5/internal/aintern_native_dialog_cfg.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_system.h" /* The GTK implementation does not require an extra thread. * The Windows and OSX implementations do. */ #if defined(ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS) || defined(ALLEGRO_CFG_NATIVE_DIALOG_OSX) #define TEXT_LOG_EXTRA_THREAD true #else #define TEXT_LOG_EXTRA_THREAD false #endif /* This will only return when the text window is closed. */ static void *text_log_thread_proc(ALLEGRO_THREAD *thread, void *arg) { ALLEGRO_NATIVE_DIALOG *textlog = arg; if (!_al_open_native_text_log(textlog)) { al_lock_mutex(textlog->tl_text_mutex); textlog->tl_init_error = true; al_signal_cond(textlog->tl_text_cond); al_unlock_mutex(textlog->tl_text_mutex); } return thread; } /* Function: al_open_native_text_log */ ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags) { ALLEGRO_NATIVE_DIALOG *textlog = NULL; /* Avoid warnings when log windows are unimplemented. */ (void)title; (void)flags; textlog = al_calloc(1, sizeof *textlog); textlog->title = al_ustr_new(title); textlog->flags = flags; if (TEXT_LOG_EXTRA_THREAD) { textlog->tl_thread = al_create_thread(text_log_thread_proc, textlog); } textlog->tl_text_cond = al_create_cond(); textlog->tl_text_mutex = al_create_mutex(); textlog->tl_pending_text = al_ustr_new(""); al_init_user_event_source(&textlog->tl_events); textlog->tl_init_error = false; textlog->tl_done = false; if (TEXT_LOG_EXTRA_THREAD) { /* Unlike the other dialogs, this one never blocks as the intended * use case is a log window running in the background for debugging * purposes when no console can be used. Therefore we have it run * in a separate thread. */ al_start_thread(textlog->tl_thread); al_lock_mutex(textlog->tl_text_mutex); while (!textlog->tl_done && !textlog->tl_init_error) { al_wait_cond(textlog->tl_text_cond, textlog->tl_text_mutex); } al_unlock_mutex(textlog->tl_text_mutex); } else { textlog->tl_init_error = !_al_open_native_text_log(textlog); } if (textlog->tl_init_error) { al_close_native_text_log((ALLEGRO_TEXTLOG *)textlog); return NULL; } _al_register_destructor(_al_dtor_list, textlog, (void (*)(void *))al_close_native_text_log); return (ALLEGRO_TEXTLOG *)textlog; } /* Function: al_close_native_text_log */ void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog) { ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; if (!dialog) return; if (!dialog->tl_init_error) { dialog->tl_done = false; if (TEXT_LOG_EXTRA_THREAD) { al_lock_mutex(dialog->tl_text_mutex); _al_close_native_text_log(dialog); while (!dialog->tl_done) { al_wait_cond(dialog->tl_text_cond, dialog->tl_text_mutex); } } else { _al_close_native_text_log(dialog); al_lock_mutex(dialog->tl_text_mutex); } _al_unregister_destructor(_al_dtor_list, dialog); } al_ustr_free(dialog->title); al_ustr_free(dialog->tl_pending_text); al_destroy_user_event_source(&dialog->tl_events); al_unlock_mutex(dialog->tl_text_mutex); if (TEXT_LOG_EXTRA_THREAD) { al_destroy_thread(dialog->tl_thread); } al_destroy_cond(dialog->tl_text_cond); al_destroy_mutex(dialog->tl_text_mutex); al_free(dialog); } /* Function: al_append_native_text_log */ void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog, char const *format, ...) { ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; va_list args; /* Fall back to printf if no window. */ if (!dialog) { va_start(args, format); vprintf(format, args); va_end(args); return; } al_lock_mutex(dialog->tl_text_mutex); /* We could optimise the case where format="%s". */ va_start(args, format); al_ustr_vappendf(dialog->tl_pending_text, format, args); va_end(args); _al_append_native_text_log(dialog); al_unlock_mutex(dialog->tl_text_mutex); } /* Function: al_get_native_text_log_event_source */ ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source( ALLEGRO_TEXTLOG *textlog) { ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; ASSERT(dialog); return &dialog->tl_events; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/gtk_filesel.c0000644000175000001440000000665612104442472021134 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GTK native dialog implementation. * * See LICENSE.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "gtk_dialog.h" typedef struct { ALLEGRO_DISPLAY *display; ALLEGRO_NATIVE_DIALOG *dialog; } Msg; static void filesel_destroy(GtkWidget *w, gpointer data) { ALLEGRO_NATIVE_DIALOG *nd = data; (void)w; ASSERT(nd->async_queue); g_async_queue_push(nd->async_queue, ACK_CLOSED); } static void filesel_ok(GtkWidget *w, GtkFileSelection *fs) { ALLEGRO_NATIVE_DIALOG *fc; fc = g_object_get_data(G_OBJECT(w), "ALLEGRO_NATIVE_DIALOG"); gchar **paths = gtk_file_selection_get_selections(fs); int n = 0, i; while (paths[n]) { n++; } fc->fc_path_count = n; fc->fc_paths = al_malloc(n * sizeof(void *)); for (i = 0; i < n; i++) fc->fc_paths[i] = al_create_path(paths[i]); g_strfreev(paths); } /* [nd_gtk thread] */ static gboolean create_native_file_dialog(gpointer data) { Msg *msg = data; ALLEGRO_DISPLAY *display = msg->display; ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; GtkWidget *window; /* Create a new file selection widget */ window = gtk_file_selection_new(al_cstr(fd->title)); _al_gtk_make_transient(display, window); /* Connect the destroy signal */ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(filesel_destroy), fd); /* Connect the ok_button */ g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", G_CALLBACK(filesel_ok), (gpointer) window); /* Connect both buttons to gtk_widget_destroy */ g_signal_connect_swapped(GTK_FILE_SELECTION(window)->ok_button, "clicked", G_CALLBACK(gtk_widget_destroy), window); g_signal_connect_swapped(GTK_FILE_SELECTION(window)->cancel_button, "clicked", G_CALLBACK(gtk_widget_destroy), window); g_object_set_data(G_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "ALLEGRO_NATIVE_DIALOG", fd); if (fd->fc_initial_path) { gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), al_path_cstr(fd->fc_initial_path, '/')); } if (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(window), true); gtk_widget_show(window); return FALSE; } /* [user thread] */ bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { Msg msg; if (!_al_gtk_ensure_thread()) return false; fd->async_queue = g_async_queue_new(); msg.display = display; msg.dialog = fd; g_timeout_add(0, create_native_file_dialog, &msg); /* Wait for a signal that the window is closed. */ while (g_async_queue_pop(fd->async_queue) != ACK_CLOSED) ; g_async_queue_unref(fd->async_queue); fd->async_queue = NULL; return true; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/gtk_thread.c0000644000175000001440000000522512104442472020747 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "allegro5/internal/aintern_native_dialog_cfg.h" #include "gtk_dialog.h" #include "allegro5/internal/aintern_vector.h" ALLEGRO_DEBUG_CHANNEL("gtk") /* GTK is not thread safe. We launch a single thread which runs the GTK main * loop, and it is the only thread which calls into GTK. (g_timeout_add may be * called from other threads without locking.) * * We used to attempt to use gdk_threads_enter/gdk_threads_leave but hit * some problems with deadlocks so switched to this. */ // G_STATIC_MUTEX_INIT causes a warning about a missing initializer, so if we // have version 2.32 or newer don't use it to avoid the warning. #if GLIB_CHECK_VERSION(2, 32, 0) #define NEWER_GLIB 1 #else #define NEWER_GLIB 0 #endif #if NEWER_GLIB static GMutex nd_gtk_mutex; static void nd_gtk_lock(void) { g_mutex_lock(&nd_gtk_mutex); } static void nd_gtk_unlock(void) { g_mutex_unlock(&nd_gtk_mutex); } #else static GStaticMutex nd_gtk_mutex = G_STATIC_MUTEX_INIT; static void nd_gtk_lock(void) { g_static_mutex_lock(&nd_gtk_mutex); } static void nd_gtk_unlock(void) { g_static_mutex_unlock(&nd_gtk_mutex); } #endif static GThread *nd_gtk_thread = NULL; static void *nd_gtk_thread_func(void *data) { GAsyncQueue *queue = data; ALLEGRO_DEBUG("GLIB %d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); g_async_queue_push(queue, ACK_OK); gtk_main(); ALLEGRO_INFO("GTK stopped.\n"); return NULL; } bool _al_gtk_ensure_thread(void) { bool ok = true; #if !NEWER_GLIB if (!g_thread_supported()) g_thread_init(NULL); #endif /* al_init_native_dialog_addon() didn't always exist so GTK might not have * been initialised. gtk_init_check knows if it's been initialised already * so we can just call it again. */ { int argc = 0; char **argv = NULL; if (!gtk_init_check(&argc, &argv)) { ALLEGRO_ERROR("gtk_init_check failed\n"); return false; } } nd_gtk_lock(); if (!nd_gtk_thread) { GAsyncQueue *queue = g_async_queue_new(); #if NEWER_GLIB nd_gtk_thread = g_thread_new("gtk thread", nd_gtk_thread_func, queue); #else bool joinable = FALSE; nd_gtk_thread = g_thread_create(nd_gtk_thread_func, queue, joinable, NULL); #endif if (!nd_gtk_thread) { ok = false; } else { ok = (g_async_queue_pop(queue) == ACK_OK); } g_async_queue_unref(queue); } nd_gtk_unlock(); return ok; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/gtk_textlog.c0000644000175000001440000001344512104442472021171 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GTK native dialog implementation. * * See LICENSE.txt for copyright information. */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "gtk_dialog.h" typedef struct { ALLEGRO_NATIVE_DIALOG *dialog; } Msg; static void emit_close_event(ALLEGRO_NATIVE_DIALOG *textlog, bool keypress) { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; event.user.timestamp = al_get_time(); event.user.data1 = (intptr_t)textlog; event.user.data2 = (intptr_t)keypress; al_emit_user_event(&textlog->tl_events, &event, NULL); } static gboolean textlog_delete(GtkWidget *w, GdkEvent *gevent, gpointer userdata) { ALLEGRO_NATIVE_DIALOG *textlog = userdata; (void)w; (void)gevent; if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { emit_close_event(textlog, false); } /* Don't close the window. */ return TRUE; } static gboolean textlog_key_press(GtkWidget *w, GdkEventKey *gevent, gpointer userdata) { ALLEGRO_NATIVE_DIALOG *textlog = userdata; (void)w; if (gevent->keyval == GDK_Escape) { emit_close_event(textlog, true); } return FALSE; } static void textlog_destroy(GtkWidget *w, gpointer data) { ALLEGRO_NATIVE_DIALOG *nd = data; (void)w; ASSERT(nd->async_queue); g_async_queue_push(nd->async_queue, ACK_CLOSED); } /* [gtk thread] */ static gboolean create_native_text_log(gpointer data) { Msg *msg = data; ALLEGRO_NATIVE_DIALOG *textlog = msg->dialog; /* Create a new text log window. */ GtkWidget *top = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(top), 640, 480); gtk_window_set_title(GTK_WINDOW(top), al_cstr(textlog->title)); if (textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE) { gtk_window_set_deletable(GTK_WINDOW(top), false); } else { g_signal_connect(G_OBJECT(top), "key-press-event", G_CALLBACK(textlog_key_press), textlog); } g_signal_connect(G_OBJECT(top), "delete-event", G_CALLBACK(textlog_delete), textlog); g_signal_connect(G_OBJECT(top), "destroy", G_CALLBACK(textlog_destroy), textlog); GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(top), scroll); GtkWidget *view = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(view), false); if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) { PangoFontDescription *font_desc; font_desc = pango_font_description_from_string("Monospace"); gtk_widget_modify_font(view, font_desc); pango_font_description_free(font_desc); } gtk_container_add(GTK_CONTAINER(scroll), view); gtk_widget_show(view); gtk_widget_show(scroll); gtk_widget_show(top); textlog->window = top; textlog->tl_textview = view; ASSERT(textlog->async_queue); g_async_queue_push(textlog->async_queue, ACK_OPENED); return FALSE; } /* [user thread] */ bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { Msg msg; if (!_al_gtk_ensure_thread()) { textlog->tl_init_error = true; return false; } textlog->async_queue = g_async_queue_new(); msg.dialog = textlog; g_timeout_add(0, create_native_text_log, &msg); while (g_async_queue_pop(textlog->async_queue) != ACK_OPENED) ; return true; } /* [gtk thread] */ static gboolean do_append_native_text_log(gpointer data) { ALLEGRO_NATIVE_DIALOG *textlog = data; al_lock_mutex(textlog->tl_text_mutex); GtkTextView *tv = GTK_TEXT_VIEW(textlog->tl_textview); GtkTextBuffer *buffer = gtk_text_view_get_buffer(tv); GtkTextIter iter; GtkTextMark *mark; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert(buffer, &iter, al_cstr(textlog->tl_pending_text), -1); mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textlog->tl_textview), mark); gtk_text_buffer_delete_mark(buffer, mark); al_ustr_truncate(textlog->tl_pending_text, 0); textlog->tl_have_pending = false; al_unlock_mutex(textlog->tl_text_mutex); return FALSE; } /* [user thread] */ void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { if (textlog->tl_have_pending) return; textlog->tl_have_pending = true; gdk_threads_add_timeout(100, do_append_native_text_log, textlog); } /* [gtk thread] */ static gboolean do_close_native_text_log(gpointer data) { ALLEGRO_NATIVE_DIALOG *textlog = data; /* Delay closing until appends are completed. */ if (textlog->tl_have_pending) { return TRUE; } /* This causes the GTK window as well as all of its children to * be freed. Further it will call the destroy function which we * connected to the destroy signal which in turn causes our * gtk thread to quit. */ gtk_widget_destroy(textlog->window); return FALSE; } /* [user thread] */ void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { gdk_threads_add_timeout(0, do_close_native_text_log, textlog); while (g_async_queue_pop(textlog->async_queue) != ACK_CLOSED) ; g_async_queue_unref(textlog->async_queue); textlog->async_queue = NULL; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/gtk_dialog.c0000644000175000001440000000273312104442472020740 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #include "allegro5/internal/aintern_native_dialog_cfg.h" #include "allegro5/internal/aintern_xdisplay.h" #include "gtk_dialog.h" ALLEGRO_DEBUG_CHANNEL("gtk_dialog") bool _al_init_native_dialog_addon(void) { int argc = 0; char **argv = NULL; if (!gtk_init_check(&argc, &argv)) { ALLEGRO_ERROR("gtk_init_check failed\n"); return false; } return true; } void _al_shutdown_native_dialog_addon(void) { } static void really_make_transient(GtkWidget *window, ALLEGRO_DISPLAY_XGLX *glx) { GdkDisplay *gdk = gdk_drawable_get_display(GDK_DRAWABLE(window->window)); GdkWindow *parent = gdk_window_lookup_for_display(gdk, glx->window); if (!parent) parent = gdk_window_foreign_new_for_display(gdk, glx->window); gdk_window_set_transient_for(window->window, parent); } static void realized(GtkWidget *window, gpointer data) { really_make_transient(window, (void *)data); } void _al_gtk_make_transient(ALLEGRO_DISPLAY *display, GtkWidget *window) { /* Set the current display window (if any) as the parent of the dialog. */ ALLEGRO_DISPLAY_XGLX *glx = (void *)display; if (glx) { if (!GTK_WIDGET_REALIZED(window)) g_signal_connect(window, "realize", G_CALLBACK(realized), (void *)glx); else really_make_transient(window, glx); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/allegro5/0000755000175000001440000000000012157230736020203 5ustar tjadenusersallegro-5.0.10/addons/native_dialog/allegro5/allegro_native_dialog.h0000644000175000001440000000623412066452512024670 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_native_dialog_h #define __al_included_allegro5_allegro_native_dialog_h #include "allegro5/allegro.h" #ifdef __cplusplus extern "C" { #endif #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_NATIVE_DIALOG_SRC #define _ALLEGRO_DIALOG_DLL __declspec(dllexport) #else #define _ALLEGRO_DIALOG_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_DIALOG_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_DIALOG_FUNC(type, name, args) _ALLEGRO_DIALOG_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_DIALOG_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_DIALOG_FUNC(type, name, args) extern _ALLEGRO_DIALOG_DLL type name args #else #define ALLEGRO_DIALOG_FUNC AL_FUNC #endif /* Type: ALLEGRO_FILECHOOSER */ typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER; /* Type: ALLEGRO_TEXTLOG */ typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG; ALLEGRO_DIALOG_FUNC(bool, al_init_native_dialog_addon, (void)); ALLEGRO_DIALOG_FUNC(void, al_shutdown_native_dialog_addon, (void)); ALLEGRO_DIALOG_FUNC(ALLEGRO_FILECHOOSER *, al_create_native_file_dialog, (char const *initial_path, char const *title, char const *patterns, int mode)); ALLEGRO_DIALOG_FUNC(bool, al_show_native_file_dialog, (ALLEGRO_DISPLAY *display, ALLEGRO_FILECHOOSER *dialog)); ALLEGRO_DIALOG_FUNC(int, al_get_native_file_dialog_count, (const ALLEGRO_FILECHOOSER *dialog)); ALLEGRO_DIALOG_FUNC(const char *, al_get_native_file_dialog_path, (const ALLEGRO_FILECHOOSER *dialog, size_t index)); ALLEGRO_DIALOG_FUNC(void, al_destroy_native_file_dialog, (ALLEGRO_FILECHOOSER *dialog)); ALLEGRO_DIALOG_FUNC(int, al_show_native_message_box, (ALLEGRO_DISPLAY *display, char const *title, char const *heading, char const *text, char const *buttons, int flags)); ALLEGRO_DIALOG_FUNC(ALLEGRO_TEXTLOG *, al_open_native_text_log, (char const *title, int flags)); ALLEGRO_DIALOG_FUNC(void, al_close_native_text_log, (ALLEGRO_TEXTLOG *textlog)); ALLEGRO_DIALOG_FUNC(void, al_append_native_text_log, (ALLEGRO_TEXTLOG *textlog, char const *format, ...)); ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_native_text_log_event_source, (ALLEGRO_TEXTLOG *textlog)); ALLEGRO_DIALOG_FUNC(uint32_t, al_get_allegro_native_dialog_version, (void)); enum { ALLEGRO_FILECHOOSER_FILE_MUST_EXIST = 1, ALLEGRO_FILECHOOSER_SAVE = 2, ALLEGRO_FILECHOOSER_FOLDER = 4, ALLEGRO_FILECHOOSER_PICTURES = 8, ALLEGRO_FILECHOOSER_SHOW_HIDDEN = 16, ALLEGRO_FILECHOOSER_MULTIPLE = 32 }; enum { ALLEGRO_MESSAGEBOX_WARN = 1<<0, ALLEGRO_MESSAGEBOX_ERROR = 1<<1, ALLEGRO_MESSAGEBOX_OK_CANCEL = 1<<2, ALLEGRO_MESSAGEBOX_YES_NO = 1<<3, ALLEGRO_MESSAGEBOX_QUESTION = 1<<4 }; enum { ALLEGRO_TEXTLOG_NO_CLOSE = 1<<0, ALLEGRO_TEXTLOG_MONOSPACE = 1<<1 }; enum { ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE = 600 }; #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/allegro5/internal/0000755000175000001440000000000012157230736022017 5ustar tjadenusersallegro-5.0.10/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake0000644000175000001440000000020511417072504030403 0ustar tjadenusers#cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_GTK #cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_OSX #cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS allegro-5.0.10/addons/native_dialog/allegro5/internal/aintern_native_dialog.h0000644000175000001440000000277312104442472026520 0ustar tjadenusers#ifndef __al_included_allegro_aintern_native_dialog_h #define __al_included_allegro_aintern_native_dialog_h typedef struct ALLEGRO_NATIVE_DIALOG ALLEGRO_NATIVE_DIALOG; /* We could use different structs for the different dialogs. But why * bother. */ struct ALLEGRO_NATIVE_DIALOG { ALLEGRO_USTR *title; int flags; /* Only used by file chooser. */ ALLEGRO_PATH *fc_initial_path; size_t fc_path_count; ALLEGRO_PATH **fc_paths; ALLEGRO_USTR *fc_patterns; /* Only used by message box. */ ALLEGRO_USTR *mb_heading; ALLEGRO_USTR *mb_text; ALLEGRO_USTR *mb_buttons; int mb_pressed_button; /* Only used by text log. */ ALLEGRO_THREAD *tl_thread; ALLEGRO_COND *tl_text_cond; ALLEGRO_MUTEX *tl_text_mutex; ALLEGRO_USTR *tl_pending_text; bool tl_init_error; bool tl_done; bool tl_have_pending; ALLEGRO_EVENT_SOURCE tl_events; void *tl_textview; /* Only used by platform implementations. */ bool is_active; void *window; void *async_queue; }; extern bool _al_init_native_dialog_addon(void); extern void _al_shutdown_native_dialog_addon(void); extern bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd); extern int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd); extern bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); extern void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); extern void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); #endif allegro-5.0.10/addons/native_dialog/dialog.c0000644000175000001440000000756412125160224020075 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_native_dialog.h" #include "allegro5/internal/aintern_system.h" ALLEGRO_DEBUG_CHANNEL("native_dialog") static bool inited_addon = false; /* Function: al_init_native_dialog_addon */ bool al_init_native_dialog_addon(void) { if (!inited_addon) { if (!_al_init_native_dialog_addon()) { ALLEGRO_ERROR("_al_init_native_dialog_addon failed.\n"); return false; } inited_addon = true; _al_add_exit_func(al_shutdown_native_dialog_addon, "al_shutdown_native_dialog_addon"); } return true; } /* Function: al_shutdown_native_dialog_addon */ void al_shutdown_native_dialog_addon(void) { if (inited_addon) { _al_shutdown_native_dialog_addon(); inited_addon = false; } } /* Function: al_create_native_file_dialog */ ALLEGRO_FILECHOOSER *al_create_native_file_dialog( char const *initial_path, char const *title, char const *patterns, int mode) { ALLEGRO_NATIVE_DIALOG *fc; fc = al_calloc(1, sizeof *fc); if (initial_path) { fc->fc_initial_path = al_create_path(initial_path); } fc->title = al_ustr_new(title); fc->fc_patterns = al_ustr_new(patterns); fc->flags = mode; _al_register_destructor(_al_dtor_list, fc, (void (*)(void *))al_destroy_native_file_dialog); return (ALLEGRO_FILECHOOSER *)fc; } /* Function: al_show_native_file_dialog */ bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_FILECHOOSER *dialog) { ALLEGRO_NATIVE_DIALOG *fd = (ALLEGRO_NATIVE_DIALOG *)dialog; return _al_show_native_file_dialog(display, fd); } /* Function: al_get_native_file_dialog_count */ int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog) { const ALLEGRO_NATIVE_DIALOG *fc = (const ALLEGRO_NATIVE_DIALOG *)dialog; return fc->fc_path_count; } /* Function: al_get_native_file_dialog_path */ const char *al_get_native_file_dialog_path( const ALLEGRO_FILECHOOSER *dialog, size_t i) { const ALLEGRO_NATIVE_DIALOG *fc = (const ALLEGRO_NATIVE_DIALOG *)dialog; if (i < fc->fc_path_count) return al_path_cstr(fc->fc_paths[i], ALLEGRO_NATIVE_PATH_SEP); return NULL; } /* Function: al_destroy_native_file_dialog */ void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog) { ALLEGRO_NATIVE_DIALOG *fd = (ALLEGRO_NATIVE_DIALOG *)dialog; size_t i; if (!fd) return; _al_unregister_destructor(_al_dtor_list, fd); al_ustr_free(fd->title); al_destroy_path(fd->fc_initial_path); for (i = 0; i < fd->fc_path_count; i++) { al_destroy_path(fd->fc_paths[i]); } al_free(fd->fc_paths); al_ustr_free(fd->fc_patterns); al_free(fd); } /* Function: al_show_native_message_box */ int al_show_native_message_box(ALLEGRO_DISPLAY *display, char const *title, char const *heading, char const *text, char const *buttons, int flags) { ALLEGRO_NATIVE_DIALOG *fc; int r; /* Note: the message box code cannot assume that Allegro is installed. * al_malloc and ustr functions are okay (with the assumption that the * user doesn't change the memory management functions in another thread * while this message box is open). */ fc = al_calloc(1, sizeof *fc); fc->title = al_ustr_new(title); fc->mb_heading = al_ustr_new(heading); fc->mb_text = al_ustr_new(text); fc->mb_buttons = al_ustr_new(buttons); fc->flags = flags; r = _al_show_native_message_box(display, fc); al_ustr_free(fc->title); al_ustr_free(fc->mb_heading); al_ustr_free(fc->mb_text); al_ustr_free(fc->mb_buttons); al_free(fc); return r; } /* Function: al_get_allegro_native_dialog_version */ uint32_t al_get_allegro_native_dialog_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/win_dialog.c0000644000175000001440000004354312104442472020754 0ustar tjadenusers/* Each of these files implements the same, for different GUI toolkits: * * dialog.c - code shared between all platforms * gtk_dialog.c - GTK file open dialog * osx_dialog.m - OSX file open dialog * qt_dialog.cpp - Qt file open dialog * win_dialog.c - Windows file open dialog * */ #include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_native_dialog.h" #include "allegro5/platform/aintwin.h" #include "allegro5/allegro_windows.h" /* We use RichEdit by default. */ #include #include // for folder selector ALLEGRO_DEBUG_CHANNEL("win_dialog") /* Reference count for shared resources. */ static int wlog_count = 0; /* Handle of RichEdit module */ static void *wlog_rich_edit_module = 0; /* Name of the edit control. Depend on system resources. */ static wchar_t* wlog_edit_control = L"EDIT"; /* True if output support unicode */ static bool wlog_unicode = false; bool _al_init_native_dialog_addon(void) { return true; } void _al_shutdown_native_dialog_addon(void) { } static bool select_folder(ALLEGRO_DISPLAY_WIN *win_display, ALLEGRO_NATIVE_DIALOG *fd) { BROWSEINFO folderinfo; LPCITEMIDLIST pidl; char buf[MAX_PATH] = ""; char dbuf[MAX_PATH] = ""; folderinfo.hwndOwner = win_display->window; folderinfo.pidlRoot = NULL; folderinfo.pszDisplayName = dbuf; folderinfo.lpszTitle = al_cstr(fd->title); folderinfo.ulFlags = 0; folderinfo.lpfn = NULL; pidl = SHBrowseForFolder(&folderinfo); if (pidl) { SHGetPathFromIDList(pidl, buf); fd->fc_path_count = 1; fd->fc_paths = al_malloc(sizeof(void *)); fd->fc_paths[0] = al_create_path(buf); return true; } return false; } static ALLEGRO_USTR *create_filter_string(const ALLEGRO_USTR *patterns) { ALLEGRO_USTR *filter = al_ustr_new(""); bool filter_all = false; int start, end; if (0 == strcmp(al_cstr(patterns), "*.*")) { filter_all = true; } else { al_ustr_append_cstr(filter, "All Supported Files"); al_ustr_append_chr(filter, '\0'); start = al_ustr_size(filter); al_ustr_append(filter, patterns); /* Remove all instances of "*.*", which will be added separately. */ for (;;) { int pos = al_ustr_find_cstr(filter, start, "*.*;"); if (pos == -1) break; if (pos == start || al_ustr_get(filter, pos - 1) == ';') { filter_all = true; al_ustr_remove_range(filter, pos, pos + 4); start = pos; } else { start = pos + 4; } } while (al_ustr_has_suffix_cstr(filter, ";*.*")) { filter_all = true; end = al_ustr_size(filter); al_ustr_remove_range(filter, end - 4, end); } al_ustr_append_chr(filter, '\0'); } if (filter_all) { al_ustr_append_cstr(filter, "All Files"); al_ustr_append_chr(filter, '\0'); al_ustr_append_cstr(filter, "*.*"); al_ustr_append_chr(filter, '\0'); } al_ustr_append_chr(filter, '\0'); return filter; } static int skip_nul_terminated_string(char *s) { int i = 0; while (s[i]) i++; return i+1; } bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { OPENFILENAME ofn; ALLEGRO_DISPLAY_WIN *win_display; int flags = 0; bool ret; char buf[4096] = ""; ALLEGRO_USTR *filter_string = NULL; win_display = (ALLEGRO_DISPLAY_WIN *)display; if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) { return select_folder(win_display, fd); } /* Selecting a file. */ memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = (win_display) ? win_display->window : NULL; /* Create filter string. */ if (fd->fc_patterns) { filter_string = create_filter_string(fd->fc_patterns); ofn.lpstrFilter = al_cstr(filter_string); } else { /* List all files by default. */ ofn.lpstrFilter = "All Files\0*.*\0\0"; } ofn.lpstrFile = buf; ofn.nMaxFile = sizeof(buf); if (fd->fc_initial_path) { ofn.lpstrInitialDir = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP); } if (fd->title) ofn.lpstrTitle = al_cstr(fd->title); flags |= OFN_NOCHANGEDIR | OFN_EXPLORER; if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) { flags |= OFN_OVERWRITEPROMPT; } else { flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0; } flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0; flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN ofn.Flags = flags; if (flags & OFN_OVERWRITEPROMPT) { ret = GetSaveFileName(&ofn); } else { ret = GetOpenFileName(&ofn); } al_ustr_free(filter_string); if (!ret) { DWORD err = GetLastError(); if (err != ERROR_SUCCESS) { char buf[1000]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL); ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", buf); } return false; } if (flags & OFN_ALLOWMULTISELECT) { int i; /* Count number of file names in buf. */ fd->fc_path_count = 0; i = skip_nul_terminated_string(buf); while (1) { if (buf[i] == '\0') { fd->fc_path_count++; if (buf[i+1] == '\0') break; } i++; } } else { fd->fc_path_count = 1; } if (fd->fc_path_count == 1) { fd->fc_paths = al_malloc(sizeof(void *)); fd->fc_paths[0] = al_create_path(buf); } else { int i, p; /* If multiple files were selected, the first string in buf is the * directory name, followed by each of the file names terminated by NUL. */ fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *)); i = skip_nul_terminated_string(buf); for (p = 0; p < (int)fd->fc_path_count; p++) { fd->fc_paths[p] = al_create_path_for_directory(buf); al_set_path_filename(fd->fc_paths[p], buf+i); i += skip_nul_terminated_string(buf+i); } } return true; } int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { UINT type = 0; int result; uint16_t *wide_text, *wide_title; size_t text_len, title_len; /* Note: the message box code cannot assume that Allegro is installed. */ if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type |= MB_ICONQUESTION; else if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type |= MB_ICONWARNING; else if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type |= MB_ICONERROR; else type |= MB_ICONINFORMATION; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type |= MB_YESNO; else if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) type |= MB_OKCANCEL; /* heading + text are combined together */ if (al_ustr_size(fd->mb_heading)) al_ustr_append_cstr(fd->mb_heading, "\n\n"); al_ustr_append(fd->mb_heading, fd->mb_text); text_len = al_ustr_size_utf16(fd->mb_heading); title_len = al_ustr_size_utf16(fd->title); wide_text = al_malloc(text_len + 1); if (!wide_text) return 0; wide_title = al_malloc(title_len + 1); if (!wide_title) { al_free(wide_text); return 0; } al_ustr_encode_utf16(fd->mb_heading, wide_text, text_len); al_ustr_encode_utf16(fd->title, wide_title, title_len); result = MessageBoxW(al_get_win_window_handle(display), (LPCWSTR) wide_text, (LPCWSTR) wide_title, type); al_free(wide_text); al_free(wide_title); if (result == IDYES || result == IDOK) return 1; else return 0; } /* Emit close event. */ static void wlog_emit_close_event(ALLEGRO_NATIVE_DIALOG *textlog, bool keypress) { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; event.user.timestamp = al_get_time(); event.user.data1 = (intptr_t)textlog; event.user.data2 = (intptr_t)keypress; al_emit_user_event(&textlog->tl_events, &event, NULL); } /* Output message to ANSI log. */ static void wlog_do_append_native_text_log_ansi(ALLEGRO_NATIVE_DIALOG *textlog) { int index; index = GetWindowTextLength(textlog->tl_textview); SendMessageA(textlog->tl_textview, EM_SETSEL, (WPARAM)index, (LPARAM)index); SendMessageA(textlog->tl_textview, EM_REPLACESEL, 0, (LPARAM)al_cstr(textlog->tl_pending_text)); al_ustr_truncate(textlog->tl_pending_text, 0); textlog->tl_have_pending = false; } /* Output message to Unicode log. */ static void wlog_do_append_native_text_log_unicode(ALLEGRO_NATIVE_DIALOG *textlog) { #define BUFFER_SIZE 512 bool flush; int index, ch, next; static WCHAR buffer[BUFFER_SIZE + 1] = { 0 }; index = GetWindowTextLength(textlog->tl_textview); SendMessageW(textlog->tl_textview, EM_SETSEL, (WPARAM)index, (LPARAM)index); next = 0; index = 0; flush = false; while ((ch = al_ustr_get_next(textlog->tl_pending_text, &next)) >= 0) { buffer[index] = (WCHAR)ch; flush = true; index++; if ((index % BUFFER_SIZE) == 0) { buffer[BUFFER_SIZE] = L'\0'; SendMessageW(textlog->tl_textview, EM_REPLACESEL, 0, (LPARAM)buffer); flush = false; index = 0; } } if (flush) { buffer[index] = L'\0'; SendMessageW(textlog->tl_textview, EM_REPLACESEL, 0, (LPARAM)buffer); } al_ustr_truncate(textlog->tl_pending_text, 0); textlog->tl_have_pending = false; } /* General function to output log message. */ static void wlog_do_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { if (wlog_unicode) { wlog_do_append_native_text_log_unicode(textlog); } else { wlog_do_append_native_text_log_ansi(textlog); } SendMessage(textlog->tl_textview, WM_VSCROLL, SB_BOTTOM, 0); } /* Text log window callback. */ static LRESULT CALLBACK wlog_text_log_callback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CREATESTRUCT* create_struct; ALLEGRO_NATIVE_DIALOG* textlog = (ALLEGRO_NATIVE_DIALOG*)GetWindowLongPtr(hWnd, GWLP_USERDATA); switch (uMsg) { case WM_CREATE: /* Set user data for window, so we will be able to retieve text log structure any time */ create_struct = (CREATESTRUCT*)lParam; SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)create_struct->lpCreateParams); break; case WM_CLOSE: if (textlog->is_active) { if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { wlog_emit_close_event(textlog, false); } return 0; } break; case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) { wlog_emit_close_event(textlog, true); } break; case WM_MOVE: InvalidateRect(hWnd, NULL, FALSE); break; case WM_SIZE: /* Match text log size to parent client area */ if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) { RECT client_rect; GetClientRect(hWnd, &client_rect); MoveWindow(textlog->tl_textview, client_rect.left, client_rect.top, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, TRUE); } break; case WM_USER: al_lock_mutex(textlog->tl_text_mutex); wlog_do_append_native_text_log(textlog); al_unlock_mutex(textlog->tl_text_mutex); break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } /* We hold textlog->tl_text_mutex. */ static bool open_native_text_log_inner(ALLEGRO_NATIVE_DIALOG *textlog) { LPCSTR font_name; HWND hWnd; HWND hLog; RECT client_rect; HFONT hFont; MSG msg; BOOL ret; /* Create text log window. */ hWnd = CreateWindowA("Allegro Text Log", al_cstr(textlog->title), WS_CAPTION | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, (HINSTANCE)GetModuleHandle(NULL), textlog); if (!hWnd) { ALLEGRO_ERROR("CreateWindowA failed\n"); return false; } /* Get client area of the log window. */ GetClientRect(hWnd, &client_rect); /* Create edit control. */ hLog = CreateWindowW(wlog_edit_control, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_READONLY, client_rect.left, client_rect.top, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, hWnd, NULL, (HINSTANCE)GetModuleHandle(NULL), NULL); if (!hLog) { ALLEGRO_ERROR("CreateWindowW failed\n"); DestroyWindow(hWnd); return false; } /* Enable double-buffering. */ SetWindowLong(hLog, GWL_EXSTYLE, GetWindowLong(hLog, GWL_EXSTYLE) | 0x02000000L/*WS_EX_COMPOSITED*/); /* Select font name. */ if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) font_name = "Courier New"; else font_name = "Arial"; /* Create font and set font. */ hFont = CreateFont(-11, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH, font_name); /* Assign font to the text log. */ if (hFont) { SendMessage(hLog, WM_SETFONT, (WPARAM)hFont, 0); } /* We are ready to show our window. */ ShowWindow(hWnd, SW_NORMAL); /* Save handles for future use. */ textlog->window = hWnd; textlog->tl_textview = hLog; textlog->is_active = true; /* Now notify al_show_native_textlog that the text log is ready. */ textlog->tl_done = true; al_signal_cond(textlog->tl_text_cond); al_unlock_mutex(textlog->tl_text_mutex); /* Process messages. */ while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) { if (ret != -1 && msg.message != WM_QUIT) { /* Intercept child window key down messages. Needed to track * hit of ESCAPE key while text log have focus. */ if (msg.hwnd != textlog->window && msg.message == WM_KEYDOWN) { PostMessage(textlog->window, WM_KEYDOWN, msg.wParam, msg.lParam); } TranslateMessage(&msg); DispatchMessage(&msg); } else break; } /* Close window. Should be already closed, this is just sanity. */ if (IsWindow(textlog->window)) { DestroyWindow(textlog->window); } /* Release font. We don't want to leave any garbage. */ DeleteObject(hFont); /* Notify everyone that we're gone. */ al_lock_mutex(textlog->tl_text_mutex); textlog->tl_done = true; al_signal_cond(textlog->tl_text_cond); return true; } bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { WNDCLASSA text_log_class; bool rc; al_lock_mutex(textlog->tl_text_mutex); /* Note: the class registration and rich edit module loading are not * implemented in a thread-safe manner (pretty unlikely). */ /* Prepare text log class info. */ if (wlog_count == 0) { ALLEGRO_DEBUG("Register text log class\n"); memset(&text_log_class, 0, sizeof(text_log_class)); text_log_class.hInstance = (HINSTANCE)GetModuleHandle(NULL); text_log_class.lpszClassName = "Allegro Text Log"; text_log_class.lpfnWndProc = wlog_text_log_callback; text_log_class.hIcon = NULL; text_log_class.hCursor = NULL; text_log_class.lpszMenuName = NULL; text_log_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); if (RegisterClassA(&text_log_class) == 0) { /* Failure, window class is a basis and we do not have one. */ ALLEGRO_ERROR("RegisterClassA failed\n"); al_unlock_mutex(textlog->tl_text_mutex); return false; } } /* Load RichEdit control. */ if (wlog_count == 0) { ALLEGRO_DEBUG("Load rich edit module\n"); ALLEGRO_ASSERT(!wlog_rich_edit_module); if ((wlog_rich_edit_module = _al_open_library("msftedit.dll"))) { /* 4.1 and emulation of 3.0, 2.0, 1.0 */ wlog_edit_control = L"RICHEDIT50W"; /*MSFTEDIT_CLASS*/ wlog_unicode = true; } else if ((wlog_rich_edit_module = _al_open_library("riched20.dll"))) { /* 3.0, 2.0 */ wlog_edit_control = L"RichEdit20W"; /*RICHEDIT_CLASS*/ wlog_unicode = true; } else if ((wlog_rich_edit_module = _al_open_library("riched32.dll"))) { /* 1.0 */ wlog_edit_control = L"RichEdit"; /*RICHEDIT_CLASS*/ wlog_unicode = false; } else { wlog_edit_control = L"EDIT"; wlog_unicode = false; } } wlog_count++; ALLEGRO_DEBUG("wlog_count = %d\n", wlog_count); rc = open_native_text_log_inner(textlog); wlog_count--; ALLEGRO_DEBUG("wlog_count = %d\n", wlog_count); /* Release RichEdit module. */ if (wlog_count == 0 && wlog_rich_edit_module) { ALLEGRO_DEBUG("Unload rich edit module\n"); _al_close_library(wlog_rich_edit_module); wlog_rich_edit_module = NULL; } /* Unregister window class. */ if (wlog_count == 0) { ALLEGRO_DEBUG("Unregister text log class\n"); UnregisterClassA("Allegro Text Log", (HINSTANCE)GetModuleHandle(NULL)); } al_unlock_mutex(textlog->tl_text_mutex); return rc; } void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { /* Just deactivate text log and send bye, bye message. */ if (IsWindow(textlog->window)) { textlog->is_active = false; PostMessage(textlog->window, WM_CLOSE, 0, 0); } } void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { if (textlog->tl_have_pending) return; textlog->tl_have_pending = true; /* Post text as user message. This guarantees that the whole processing will * take place on text log thread. */ if (IsWindow(textlog->window)) { PostMessage(textlog->window, WM_USER, (WPARAM)textlog, 0); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/native_dialog/osx_dialog.m0000644000175000001440000002724012104442472020776 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_native_dialog.h" #include "allegro5/internal/aintern_native_dialog.h" #import bool _al_init_native_dialog_addon(void) { return true; } void _al_shutdown_native_dialog_addon(void) { } /* We need to run the dialog box on the main thread because AppKit is not * re-entrant and running it from another thread can cause unpredictable * crashes. * We use a dedicated class for this and simply forward the call. * The textbox is apparently fine the way it is. */ @interface FileDialog : NSObject +(void) show : (NSValue *)param; @end @implementation FileDialog +(void) show : (NSValue *) param { ALLEGRO_NATIVE_DIALOG *fd = [param pointerValue]; int mode = fd->flags; NSString *directory, *filename; /* Set initial directory to pass to the file selector */ if (fd->fc_initial_path) { ALLEGRO_PATH *initial_directory = al_clone_path(fd->fc_initial_path); /* Strip filename from path */ al_set_path_filename(initial_directory, NULL); /* Convert path and filename to NSString objects */ directory = [NSString stringWithUTF8String: al_path_cstr(initial_directory, '/')]; filename = [NSString stringWithUTF8String: al_get_path_filename(fd->fc_initial_path)]; al_destroy_path(initial_directory); } else { directory = nil; filename = nil; } /* We need slightly different code for SAVE and LOAD dialog boxes, which * are handled by slightly different classes. * Actually, NSOpenPanel inherits from NSSavePanel, so we can possibly * avoid some code cuplication here... */ if (mode & ALLEGRO_FILECHOOSER_SAVE) { // Save dialog NSSavePanel *panel = [NSSavePanel savePanel]; /* Set file save dialog box options */ [panel setCanCreateDirectories: YES]; [panel setCanSelectHiddenExtension: YES]; [panel setAllowsOtherFileTypes: YES]; /* Open dialog box */ if ([panel runModalForDirectory:directory file:filename] == NSOKButton) { /* NOTE: at first glance, it looks as if this code might leak * memory, but in fact it doesn't: the string returned by * UTF8String is freed automatically when it goes out of scope * (according to the UTF8String docs anyway). */ const char *s = [[panel filename] UTF8String]; fd->fc_path_count = 1; fd->fc_paths = al_malloc(fd->fc_path_count * sizeof *fd->fc_paths); fd->fc_paths[0] = al_create_path(s); } } else { // Open dialog NSOpenPanel *panel = [NSOpenPanel openPanel]; /* Set file selection box options */ if (mode & ALLEGRO_FILECHOOSER_FOLDER) { [panel setCanChooseFiles: NO]; [panel setCanChooseDirectories: YES]; } else { [panel setCanChooseFiles: YES]; [panel setCanChooseDirectories: NO]; } [panel setResolvesAliases:YES]; if (mode & ALLEGRO_FILECHOOSER_MULTIPLE) [panel setAllowsMultipleSelection: YES]; else [panel setAllowsMultipleSelection: NO]; /* Open dialog box */ if ([panel runModalForDirectory:directory file:filename] == NSOKButton) { size_t i; fd->fc_path_count = [[panel filenames] count]; fd->fc_paths = al_malloc(fd->fc_path_count * sizeof *fd->fc_paths); for (i = 0; i < fd->fc_path_count; i++) { /* NOTE: at first glance, it looks as if this code might leak * memory, but in fact it doesn't: the string returned by * UTF8String is freed automatically when it goes out of scope * (according to the UTF8String docs anyway). */ const char *s = [[[panel filenames] objectAtIndex: i] UTF8String]; fd->fc_paths[i] = al_create_path(s); } } } } @end /* Wrapper to run NSAlert on main thread */ @interface NSAlertWrapper : NSObject { @public int retval; } -(void) go : (NSAlert *)param; @end @implementation NSAlertWrapper -(void) go : (NSAlert *) param { retval = [param runModal]; } @end bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { (void)display; /* Since this function may be called from a separate thread (our own * example program does this), we need to setup a release pool, or we * get memory leaks. */ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [FileDialog performSelectorOnMainThread: @selector(show:) withObject: [NSValue valueWithPointer:fd] waitUntilDone: YES]; [pool drain]; _al_osx_clear_mouse_state(); return true; } int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { unsigned i; (void)display; /* Note: the message box code cannot assume that Allegro is installed. */ /* Since this might be run from a separate thread, we setup * release pool, or we get memory leaks */ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSString* button_text; NSArray* buttons; NSAlert* box = [[NSAlert alloc] init]; NSAlertStyle style; [box autorelease]; if (fd->mb_buttons == NULL) { button_text = @"OK"; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) button_text = @"Yes|No"; if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) button_text = @"OK|Cancel"; } else { button_text = [NSString stringWithUTF8String: al_cstr(fd->mb_buttons)]; } style = NSWarningAlertStyle; buttons = [button_text componentsSeparatedByString: @"|"]; [box setMessageText:[NSString stringWithUTF8String: al_cstr(fd->title)]]; [box setInformativeText:[NSString stringWithUTF8String: al_cstr(fd->mb_text)]]; [box setAlertStyle: style]; for (i = 0; i < [buttons count]; ++i) [box addButtonWithTitle: [buttons objectAtIndex: i]]; NSAlertWrapper *wrap = [[NSAlertWrapper alloc] init]; [wrap performSelectorOnMainThread: @selector(go:) withObject: box waitUntilDone: YES]; fd->mb_pressed_button = wrap->retval + 1 - NSAlertFirstButtonReturn; [wrap release]; [pool drain]; _al_osx_clear_mouse_state(); return fd->mb_pressed_button; } #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 @interface LogView : NSTextView #else @interface LogView : NSTextView #endif { @public ALLEGRO_NATIVE_DIALOG *textlog; } - (void)keyDown: (NSEvent*)event; - (BOOL)windowShouldClose: (id)sender; - (void)emitCloseEventWithKeypress: (BOOL)keypress; + (void)appendText: (NSValue*)param; @end @implementation LogView - (void)keyDown: (NSEvent*)event { if (([event keyCode] == 0x35) || // Escape (([event keyCode] == 0x0D) && ([event modifierFlags] & NSCommandKeyMask))) { // Command+W [[self window] close]; [self emitCloseEventWithKeypress: YES]; } else { [super keyDown: event]; } } - (BOOL)windowShouldClose: (id)sender { (void)sender; if (self->textlog->is_active) { if (!(self->textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { [self emitCloseEventWithKeypress: NO]; } } return YES; } - (void)emitCloseEventWithKeypress: (BOOL)keypress { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; event.user.timestamp = al_get_time(); event.user.data1 = (intptr_t)self->textlog; event.user.data2 = (intptr_t)keypress; al_emit_user_event(&self->textlog->tl_events, &event, NULL); } + (void)appendText: (NSValue*)param { ALLEGRO_NATIVE_DIALOG *textlog = (ALLEGRO_NATIVE_DIALOG*)[param pointerValue]; al_lock_mutex(textlog->tl_text_mutex); if (textlog->is_active) { LogView *view = (LogView *)textlog->tl_textview; NSString *text = [[NSString alloc] initWithUTF8String: al_cstr(textlog->tl_pending_text)]; NSRange range = NSMakeRange([[view string] length], 0); [view setEditable: YES]; [view setSelectedRange: range]; [view insertText: text]; [view setEditable: NO]; [text release]; al_ustr_truncate(textlog->tl_pending_text, 0); textlog->tl_have_pending = false; } al_unlock_mutex(textlog->tl_text_mutex); } @end bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; al_lock_mutex(textlog->tl_text_mutex); NSRect rect = NSMakeRect(0, 0, 640, 480); NSWindow *win = [NSWindow alloc]; int adapter = al_get_new_display_adapter(); NSScreen *screen; unsigned int mask = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask; if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) mask |= NSClosableWindowMask; if ((adapter >= 0) && (adapter < al_get_num_video_adapters())) { screen = [[NSScreen screens] objectAtIndex: adapter]; } else { screen = [NSScreen mainScreen]; } [win initWithContentRect: rect styleMask: mask backing: NSBackingStoreBuffered defer: NO screen: screen]; [win setReleasedWhenClosed: NO]; [win setTitle: @"Allegro Text Log"]; [win setMinSize: NSMakeSize(128, 128)]; NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: rect]; [scrollView setHasHorizontalScroller: YES]; [scrollView setHasVerticalScroller: YES]; [scrollView setAutohidesScrollers: YES]; [scrollView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [[scrollView contentView] setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [[scrollView contentView] setAutoresizesSubviews: YES]; rect = [[scrollView contentView] frame]; LogView *view = [[LogView alloc] initWithFrame: rect]; view->textlog = textlog; [view setHorizontallyResizable: YES]; [view setVerticallyResizable: YES]; [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; [[view textContainer] setContainerSize: NSMakeSize(rect.size.width, 1000000)]; [[view textContainer] setWidthTracksTextView: NO]; [view setTextColor: [NSColor grayColor]]; if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) [view setFont: [NSFont userFixedPitchFontOfSize: 0]]; [view setEditable: NO]; [scrollView setDocumentView: view]; [[win contentView] addSubview: scrollView]; [scrollView release]; [win setDelegate: view]; [win orderFront: nil]; /* Save handles for future use. */ textlog->window = win; textlog->tl_textview = view; textlog->is_active = true; /* Now notify al_show_native_textlog that the text log is ready. */ textlog->tl_done = true; al_signal_cond(textlog->tl_text_cond); al_unlock_mutex(textlog->tl_text_mutex); while ([win isVisible]) { al_rest(0.05); } al_lock_mutex(textlog->tl_text_mutex); _al_close_native_text_log(textlog); al_unlock_mutex(textlog->tl_text_mutex); [pool drain]; return true; } void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *win = (NSWindow *)textlog->window; if ([win isVisible]) { [win close]; } /* Notify everyone that we're gone. */ textlog->is_active = false; textlog->tl_done = true; al_signal_cond(textlog->tl_text_cond); [pool drain]; } void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (textlog->tl_have_pending) { [pool drain]; return; } textlog->tl_have_pending = true; [LogView performSelectorOnMainThread: @selector(appendText:) withObject: [NSValue valueWithPointer: textlog] waitUntilDone: NO]; [pool drain]; } allegro-5.0.10/addons/physfs/0000755000175000001440000000000012157230737015201 5ustar tjadenusersallegro-5.0.10/addons/physfs/CMakeLists.txt0000644000175000001440000000146111776304737017753 0ustar tjadenusersinclude_directories(SYSTEM ${PHYSFS_INCLUDE_DIR}) set(PHYSFS_SOURCES a5_physfs.c a5_physfs_dir.c) set(PHYSFS_INCLUDE_FILES allegro5/allegro_physfs.h) #set *_INCLUDE_DIRECTORIES for add_addon (so monolith build will find files) set(PHYSFS_INCLUDE_DIRECTORIES ${PHYSFS_INCLUDE_DIR}) set_our_header_properties(${PHYSFS_INCLUDE_FILES}) add_our_library(allegro_physfs "${PHYSFS_SOURCES};${PHYSFS_INCLUDE_FILES}" "-DALLEGRO_PHYSFS_SRC" "${ALLEGRO_LINK_WITH};${PHYSFS_LIBRARIES}" ) set_our_framework_properties(allegro_physfs AllegroPhysfs-${ALLEGRO_SOVERSION}) install_our_library(allegro_physfs) install_our_headers(${PHYSFS_INCLUDE_FILES}) set(PHYSFS_LINK_WITH allegro_physfs PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/physfs/a5_physfs_dir.c0000644000175000001440000001171611621646113020104 0ustar tjadenusers/* * Filesystem driver for the PhysFS addon. * * By Elias Pschernig. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_physfs.h" #include "allegro_physfs_intern.h" #if defined(ENOTSUP) #define NOTSUP ENOTSUP #elif defined(ENOSYS) #define NOTSUP ENOSYS #else #define NOTSUP EINVAL #endif typedef struct ALLEGRO_FS_ENTRY_PHYSFS ALLEGRO_FS_ENTRY_PHYSFS; struct ALLEGRO_FS_ENTRY_PHYSFS { ALLEGRO_FS_ENTRY fs_entry; /* must be first */ ALLEGRO_PATH *path; const char *path_cstr; /* For directory listing. */ char **file_list; char **file_list_pos; bool is_dir_open; }; /* forward declaration */ static const ALLEGRO_FS_INTERFACE fs_phys_vtable; static ALLEGRO_FS_ENTRY *fs_phys_create_entry(const char *path) { ALLEGRO_FS_ENTRY_PHYSFS *e; e = al_calloc(1, sizeof *e); e->fs_entry.vtable = &fs_phys_vtable; e->path = al_create_path(path); e->path_cstr = al_path_cstr(e->path, '/'); return &e->fs_entry; } static char *fs_phys_get_current_directory(void) { char *s = al_malloc(2); if (s) { s[0] = '/'; s[1] = '\0'; } return s; } static bool fs_phys_change_directory(const char *path) { (void)path; al_set_errno(NOTSUP); return false; } static bool fs_phys_filename_exists(const char *path) { return PHYSFS_exists(path) != 0; } static bool fs_phys_remove_filename(const char *path) { return PHYSFS_delete(path) != 0; } static bool fs_phys_make_directory(const char *path) { return PHYSFS_mkdir(path) != 0; } static const char *fs_phys_entry_name(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; return al_path_cstr(e->path, '/'); } static bool fs_phys_update_entry(ALLEGRO_FS_ENTRY *fse) { (void)fse; return true; } static off_t fs_phys_entry_size(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; PHYSFS_file *f = PHYSFS_openRead(e->path_cstr); if (f) { off_t s = PHYSFS_fileLength(f); PHYSFS_close(f); return s; } return 0; } static uint32_t fs_phys_entry_mode(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; uint32_t mode = ALLEGRO_FILEMODE_READ; if (PHYSFS_isDirectory(e->path_cstr)) mode |= ALLEGRO_FILEMODE_ISDIR | ALLEGRO_FILEMODE_EXECUTE; else mode |= ALLEGRO_FILEMODE_ISFILE; return mode; } static time_t fs_phys_entry_mtime(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; return PHYSFS_getLastModTime(e->path_cstr); } static bool fs_phys_entry_exists(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; return PHYSFS_exists(e->path_cstr) != 0; } static bool fs_phys_remove_entry(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; return PHYSFS_delete(e->path_cstr) != 0; } static bool fs_phys_open_directory(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; e->file_list = PHYSFS_enumerateFiles(e->path_cstr); e->file_list_pos = e->file_list; e->is_dir_open = true; return true; } static ALLEGRO_FS_ENTRY *fs_phys_read_directory(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; ALLEGRO_FS_ENTRY *next; ALLEGRO_USTR *tmp; if (!e->file_list_pos) return NULL; if (!*e->file_list_pos) return NULL; tmp = al_ustr_new(e->path_cstr); if (al_ustr_length(tmp) > 0) al_ustr_append_chr(tmp, '/'); al_ustr_append_cstr(tmp, *e->file_list_pos); next = fs_phys_create_entry(al_cstr(tmp)); al_ustr_free(tmp); e->file_list_pos++; return next; } static bool fs_phys_close_directory(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; PHYSFS_freeList(e->file_list); e->file_list = NULL; e->is_dir_open = false; return true; } static void fs_phys_destroy_entry(ALLEGRO_FS_ENTRY *fse) { ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; if (e->is_dir_open) fs_phys_close_directory(fse); al_destroy_path(e->path); al_free(e); } static ALLEGRO_FILE *fs_phys_open_file(ALLEGRO_FS_ENTRY *fse, const char *mode) { return al_fopen_interface(_al_get_phys_vtable(), fs_phys_entry_name(fse), mode); } static const ALLEGRO_FS_INTERFACE fs_phys_vtable = { fs_phys_create_entry, fs_phys_destroy_entry, fs_phys_entry_name, fs_phys_update_entry, fs_phys_entry_mode, fs_phys_entry_mtime, fs_phys_entry_mtime, fs_phys_entry_mtime, fs_phys_entry_size, fs_phys_entry_exists, fs_phys_remove_entry, fs_phys_open_directory, fs_phys_read_directory, fs_phys_close_directory, fs_phys_filename_exists, fs_phys_remove_filename, fs_phys_get_current_directory, fs_phys_change_directory, fs_phys_make_directory, fs_phys_open_file }; void _al_set_physfs_fs_interface(void) { al_set_fs_interface(&fs_phys_vtable); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/physfs/allegro_physfs_intern.h0000644000175000001440000000033111505637062021745 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_physfs_intern_h #define __al_included_allegro5_allegro_physfs_intern_h void _al_set_physfs_fs_interface(void); const ALLEGRO_FILE_INTERFACE *_al_get_phys_vtable(void); #endif allegro-5.0.10/addons/physfs/allegro5/0000755000175000001440000000000012157230737016713 5ustar tjadenusersallegro-5.0.10/addons/physfs/allegro5/allegro_physfs.h0000644000175000001440000000211511426530515022077 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_physfs_h #define __al_included_allegro5_allegro_physfs_h #include "allegro5/allegro.h" #ifdef __cplusplus extern "C" { #endif #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_PHYSFS_SRC #define _ALLEGRO_PHYSFS_DLL __declspec(dllexport) #else #define _ALLEGRO_PHYSFS_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_PHYSFS_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_PHYSFS_FUNC(type, name, args) _ALLEGRO_PHYSFS_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern _ALLEGRO_PHYSFS_DLL type name args #else #define ALLEGRO_PHYSFS_FUNC AL_FUNC #endif ALLEGRO_PHYSFS_FUNC(void, al_set_physfs_file_interface, (void)); ALLEGRO_PHYSFS_FUNC(uint32_t, al_get_allegro_physfs_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/physfs/a5_physfs.c0000644000175000001440000001174011520366613017245 0ustar tjadenusers/* * PhysicsFS addon for Allegro. * * By Peter Wang. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_physfs.h" #include "allegro_physfs_intern.h" typedef struct ALLEGRO_FILE_PHYSFS ALLEGRO_FILE_PHYSFS; struct ALLEGRO_FILE_PHYSFS { PHYSFS_file *phys; bool error_indicator; }; /* forward declaration */ static const ALLEGRO_FILE_INTERFACE file_phys_vtable; const ALLEGRO_FILE_INTERFACE *_al_get_phys_vtable(void) { return &file_phys_vtable; } #define streq(a, b) (0 == strcmp(a, b)) static ALLEGRO_FILE_PHYSFS *cast_stream(ALLEGRO_FILE *f) { return (ALLEGRO_FILE_PHYSFS *)al_get_file_userdata(f); } static void phys_set_errno(ALLEGRO_FILE_PHYSFS *fp) { /* It might be worth mapping some common error strings from * PHYSFS_getLastError() onto errno values. There are no guarantees, * though. */ al_set_errno(-1); if (fp) { fp->error_indicator = true; } } static void *file_phys_fopen(const char *filename, const char *mode) { PHYSFS_file *phys; ALLEGRO_FILE_PHYSFS *fp; /* XXX handle '+' modes */ /* It might be worth adding a function to parse mode strings, to be * shared amongst these kinds of addons. */ if (streq(mode, "r") || streq(mode, "rb")) phys = PHYSFS_openRead(filename); else if (streq(mode, "w") || streq(mode, "wb")) phys = PHYSFS_openWrite(filename); else if (streq(mode, "a") || streq(mode, "ab")) phys = PHYSFS_openAppend(filename); else phys = NULL; if (!phys) { phys_set_errno(NULL); return NULL; } fp = al_malloc(sizeof(*fp)); if (!fp) { al_set_errno(ENOMEM); PHYSFS_close(phys); return NULL; } fp->phys = phys; fp->error_indicator = false; return fp; } static void file_phys_fclose(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_close(fp->phys); al_free(fp); } static size_t file_phys_fread(ALLEGRO_FILE *f, void *buf, size_t buf_size) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_sint64 n; if (buf_size == 0) return 0; n = PHYSFS_read(fp->phys, buf, 1, buf_size); if (n < 0) { phys_set_errno(fp); return 0; } return n; } static size_t file_phys_fwrite(ALLEGRO_FILE *f, const void *buf, size_t buf_size) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_sint64 n; n = PHYSFS_write(fp->phys, buf, 1, buf_size); if (n < 0) { phys_set_errno(fp); return 0; } return n; } static bool file_phys_fflush(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); if (!PHYSFS_flush(fp->phys)) { phys_set_errno(fp); return false; } return true; } static int64_t file_phys_ftell(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_sint64 n; n = PHYSFS_tell(fp->phys); if (n < 0) { phys_set_errno(fp); return -1; } return n; } static bool file_phys_seek(ALLEGRO_FILE *f, int64_t offset, int whence) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_sint64 base; switch (whence) { case ALLEGRO_SEEK_SET: base = 0; break; case ALLEGRO_SEEK_CUR: base = PHYSFS_tell(fp->phys); if (base < 0) { phys_set_errno(fp); return false; } break; case ALLEGRO_SEEK_END: base = PHYSFS_fileLength(fp->phys); if (base < 0) { phys_set_errno(fp); return false; } break; default: al_set_errno(EINVAL); return false; } if (!PHYSFS_seek(fp->phys, base + offset)) { phys_set_errno(fp); return false; } return true; } static bool file_phys_feof(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); return PHYSFS_eof(fp->phys); } static bool file_phys_ferror(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); return fp->error_indicator; } static void file_phys_fclearerr(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); fp->error_indicator = false; /* PhysicsFS doesn't provide a way to clear the EOF indicator. */ } static off_t file_phys_fsize(ALLEGRO_FILE *f) { ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); PHYSFS_sint64 n; n = PHYSFS_fileLength(fp->phys); if (n < 0) { phys_set_errno(fp); return -1; } return n; } static const ALLEGRO_FILE_INTERFACE file_phys_vtable = { file_phys_fopen, file_phys_fclose, file_phys_fread, file_phys_fwrite, file_phys_fflush, file_phys_ftell, file_phys_seek, file_phys_feof, file_phys_ferror, file_phys_fclearerr, NULL, /* ungetc */ file_phys_fsize }; /* Function: al_set_physfs_file_interface */ void al_set_physfs_file_interface(void) { al_set_new_file_interface(&file_phys_vtable); _al_set_physfs_fs_interface(); } /* Function: al_get_allegro_physfs_version */ uint32_t al_get_allegro_physfs_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/ttf/0000755000175000001440000000000012157230737014462 5ustar tjadenusersallegro-5.0.10/addons/ttf/CMakeLists.txt0000644000175000001440000000175111436051274017222 0ustar tjadenusersinclude_directories(../font) include_directories(SYSTEM ${FREETYPE_INCLUDE_DIRS}) set(TTF_SOURCES ttf.c) set(TTF_INCLUDE_FILES allegro5/allegro_ttf.h) set_our_header_properties(${TTF_INCLUDE_FILES}) configure_file( allegro5/internal/aintern_ttf_cfg.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/internal/aintern_ttf_cfg.h ) # FREETYPE_LIBRARIES should include zlib automatically if statically linking, # but it doesn't. find_package(ZLIB) if(ZLIB_FOUND AND NOT IPHONE) list(APPEND FREETYPE_LIBRARIES ${ZLIB_LIBRARIES}) endif() add_our_library(allegro_ttf "${TTF_SOURCES};${TTF_INCLUDE_FILES}" "-DALLEGRO_TTF_SRC" "${FONT_LINK_WITH};${FREETYPE_LIBRARIES}" ) set_our_framework_properties(allegro_ttf AllegroTTF-${ALLEGRO_SOVERSION}) install_our_library(allegro_ttf) install_our_headers(${TTF_INCLUDE_FILES}) set(TTF_LINK_WITH allegro_ttf PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/ttf/ttf.c0000644000175000001440000005536712123474405015436 0ustar tjadenusers#include "allegro5/allegro.h" #ifdef ALLEGRO_CFG_OPENGL #include "allegro5/allegro_opengl.h" #endif #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/allegro_ttf.h" #include "allegro5/internal/aintern_ttf_cfg.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_system.h" #include #include FT_FREETYPE_H #include ALLEGRO_DEBUG_CHANNEL("font") /* Some low-end drivers enable automatic S3TC compression, which * requires glTexSubImage2D to only work on multiples of aligned * 4x4 pixel blocks with some buggy OpenGL drivers. * There's not much we can do about that in general - if the user * locks a portion of a bitmap not conformin to this it will fail * with such a driver. * * However in many programs this is no problem at all safe for rendering * glyphs and simply aligning to 4 pixels here fixes it. */ #define ALIGN_TO_4_PIXEL #define RANGE_SIZE 128 typedef struct REGION { short x; short y; short w; short h; } REGION; typedef struct ALLEGRO_TTF_GLYPH_DATA { ALLEGRO_BITMAP *page_bitmap; REGION region; short offset_x; short offset_y; short advance; } ALLEGRO_TTF_GLYPH_DATA; typedef struct ALLEGRO_TTF_GLYPH_RANGE { int32_t range_start; ALLEGRO_TTF_GLYPH_DATA *glyphs; /* [RANGE_SIZE] */ } ALLEGRO_TTF_GLYPH_RANGE; typedef struct ALLEGRO_TTF_FONT_DATA { FT_Face face; int flags; bool no_premultiply_alpha; _AL_VECTOR glyph_ranges; /* sorted array of of ALLEGRO_TTF_GLYPH_RANGE */ _AL_VECTOR page_bitmaps; /* of ALLEGRO_BITMAP pointers */ int page_pos_x; int page_pos_y; int page_line_height; REGION lock_rect; ALLEGRO_LOCKED_REGION *page_lr; FT_StreamRec stream; ALLEGRO_FILE *file; unsigned long base_offset; unsigned long offset; int bitmap_format; int bitmap_flags; } ALLEGRO_TTF_FONT_DATA; /* globals */ static bool ttf_inited; static FT_Library ft; static ALLEGRO_FONT_VTABLE vt; static INLINE int align4(int x) { #ifdef ALIGN_TO_4_PIXEL return (x + 3) & ~3; #else return x; #endif } static ALLEGRO_TTF_GLYPH_DATA *get_glyph(ALLEGRO_TTF_FONT_DATA *data, int ft_index) { ALLEGRO_TTF_GLYPH_RANGE *range; int32_t range_start; int lo, hi, mid; range_start = ft_index - (ft_index % RANGE_SIZE); /* Binary search for the range. */ lo = 0; hi = _al_vector_size(&data->glyph_ranges); mid = (hi + lo)/2; range = NULL; while (lo < hi) { ALLEGRO_TTF_GLYPH_RANGE *r = _al_vector_ref(&data->glyph_ranges, mid); if (r->range_start == range_start) { range = r; break; } else if (r->range_start < range_start) { lo = mid + 1; } else { hi = mid; } mid = (hi + lo)/2; } if (!range) { range = _al_vector_alloc_mid(&data->glyph_ranges, mid); range->range_start = range_start; range->glyphs = al_calloc(RANGE_SIZE, sizeof(ALLEGRO_TTF_GLYPH_DATA)); } return &range->glyphs[ft_index - range_start]; } static void unlock_current_page(ALLEGRO_TTF_FONT_DATA *data) { if (data->page_lr) { ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps); ASSERT(al_is_bitmap_locked(*back)); al_unlock_bitmap(*back); data->page_lr = NULL; } } // FIXME: Add a special case for when a single glyph rendering won't fit // into 256x256 pixels. static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data) { ALLEGRO_BITMAP **back; ALLEGRO_BITMAP *page; ALLEGRO_STATE state; unlock_current_page(data); /* The bitmap will be destroyed when the parent font is destroyed so * it is not safe to register a destructor for it. */ _al_push_destructor_owner(); al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(data->bitmap_format); al_set_new_bitmap_flags(data->bitmap_flags); page = al_create_bitmap(256, 256); al_restore_state(&state); _al_pop_destructor_owner(); back = _al_vector_alloc_back(&data->page_bitmaps); *back = page; /* Sometimes OpenGL will partly sample texels from the border of * glyphs. So we better clear the texture to transparency. * XXX This is very slow and avoidable with some effort. */ al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_hold_bitmap_drawing(false); al_set_target_bitmap(*back); al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); al_restore_state(&state); data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; return page; } static unsigned char *alloc_glyph_region(ALLEGRO_TTF_FONT_DATA *data, int ft_index, int w, int h, bool new, ALLEGRO_TTF_GLYPH_DATA *glyph, bool lock_more) { ALLEGRO_BITMAP *page; bool relock; int w4, h4; if (_al_vector_is_empty(&data->page_bitmaps) || new) { page = push_new_page(data); relock = true; } else { ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps); page = *back; relock = !data->page_lr; } w4 = align4(w); h4 = align4(h); ALLEGRO_DEBUG("Glyph %d: %dx%d (%dx%d)%s\n", ft_index, w, h, w4, h4, new ? " new" : ""); if (data->page_pos_x + w4 > al_get_bitmap_width(page)) { data->page_pos_y += data->page_line_height; data->page_pos_y = align4(data->page_pos_y); data->page_pos_x = 0; data->page_line_height = 0; relock = true; } if (data->page_pos_y + h4 > al_get_bitmap_height(page)) { return alloc_glyph_region(data, ft_index, w, h, true, glyph, lock_more); } glyph->page_bitmap = page; glyph->region.x = data->page_pos_x; glyph->region.y = data->page_pos_y; glyph->region.w = w; glyph->region.h = h; data->page_pos_x = align4(data->page_pos_x + w4); if (h > data->page_line_height) { data->page_line_height = h4; relock = true; } if (relock) { char *ptr; int n; unlock_current_page(data); data->lock_rect.x = glyph->region.x; data->lock_rect.y = glyph->region.y; /* Do we lock up to the right edge in anticipation of caching more * glyphs, or just enough for the current glyph? */ if (lock_more) { data->lock_rect.w = al_get_bitmap_width(page) - data->lock_rect.x; data->lock_rect.h = data->page_line_height; } else { data->lock_rect.w = w4; data->lock_rect.h = h4; } data->page_lr = al_lock_bitmap_region(page, data->lock_rect.x, data->lock_rect.y, data->lock_rect.w, data->lock_rect.h, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); /* Clear the data so we don't get garbage when using filtering * FIXME We could clear just the border but I'm not convinced that * would be faster (yet) */ ptr = data->page_lr->data; n = data->lock_rect.h * data->page_lr->pitch; if (n < 0) { ptr += n - data->page_lr->pitch; n = -n; } memset(ptr, 0, n); } ASSERT(data->page_lr); /* Copy a displaced pointer for the glyph. */ return (unsigned char *)data->page_lr->data + ((glyph->region.y + 1) - data->lock_rect.y) * data->page_lr->pitch + ((glyph->region.x + 1) - data->lock_rect.x) * sizeof(int32_t); } static void copy_glyph_mono(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, unsigned char *glyph_data) { int pitch = font_data->page_lr->pitch; int x, y; for (y = 0; y < face->glyph->bitmap.rows; y++) { unsigned char const *ptr = face->glyph->bitmap.buffer + face->glyph->bitmap.pitch * y; unsigned char *dptr = glyph_data + pitch * y; int bit = 0; if (font_data->no_premultiply_alpha) { for (x = 0; x < face->glyph->bitmap.width; x++) { unsigned char set = ((*ptr >> (7-bit)) & 1) ? 255 : 0; *dptr++ = 255; *dptr++ = 255; *dptr++ = 255; *dptr++ = set; bit = (bit + 1) & 7; if (bit == 0) { ptr++; } } } else { for (x = 0; x < face->glyph->bitmap.width; x++) { unsigned char set = ((*ptr >> (7-bit)) & 1) ? 255 : 0; *dptr++ = set; *dptr++ = set; *dptr++ = set; *dptr++ = set; bit = (bit + 1) & 7; if (bit == 0) { ptr++; } } } } } static void copy_glyph_color(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, unsigned char *glyph_data) { int pitch = font_data->page_lr->pitch; int x, y; for (y = 0; y < face->glyph->bitmap.rows; y++) { unsigned char const *ptr = face->glyph->bitmap.buffer + face->glyph->bitmap.pitch * y; unsigned char *dptr = glyph_data + pitch * y; if (font_data->no_premultiply_alpha) { for (x = 0; x < face->glyph->bitmap.width; x++) { unsigned char c = *ptr; *dptr++ = 255; *dptr++ = 255; *dptr++ = 255; *dptr++ = c; ptr++; } } else { for (x = 0; x < face->glyph->bitmap.width; x++) { unsigned char c = *ptr; *dptr++ = c; *dptr++ = c; *dptr++ = c; *dptr++ = c; ptr++; } } } } /* NOTE: this function may disable the bitmap hold drawing state * and leave the current page bitmap locked. */ static void cache_glyph(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, int ft_index, ALLEGRO_TTF_GLYPH_DATA *glyph, bool lock_more) { FT_Int32 ft_load_flags; FT_Error e; int w, h; unsigned char *glyph_data; if (glyph->page_bitmap || glyph->region.x < 0) return; // FIXME: make this a config setting? FT_LOAD_FORCE_AUTOHINT // FIXME: Investigate why some fonts don't work without the // NO_BITMAP flags. Supposedly using that flag makes small sizes // look bad so ideally we would not used it. ft_load_flags = FT_LOAD_RENDER | FT_LOAD_NO_BITMAP; if (font_data->flags & ALLEGRO_TTF_MONOCHROME) ft_load_flags |= FT_LOAD_TARGET_MONO; if (font_data->flags & ALLEGRO_TTF_NO_AUTOHINT) ft_load_flags |= FT_LOAD_NO_AUTOHINT; e = FT_Load_Glyph(face, ft_index, ft_load_flags); if (e) { ALLEGRO_WARN("Failed loading glyph %d from.\n", ft_index); } glyph->offset_x = face->glyph->bitmap_left; glyph->offset_y = (face->size->metrics.ascender >> 6) - face->glyph->bitmap_top; glyph->advance = face->glyph->advance.x >> 6; w = face->glyph->bitmap.width; h = face->glyph->bitmap.rows; if (w == 0 || h == 0) { /* Mark this glyph so we won't try to cache it next time. */ glyph->region.x = -1; glyph->region.y = -1; ALLEGRO_DEBUG("Glyph %d has zero size.\n", ft_index); return; } /* Each glyph has a 1-pixel border all around. Note: The border is kept * even against the outer bitmap edge, to ensure consistent rendering. */ glyph_data = alloc_glyph_region(font_data, ft_index, w + 2, h + 2, false, glyph, lock_more); if (font_data->flags & ALLEGRO_TTF_MONOCHROME) copy_glyph_mono(font_data, face, glyph_data); else copy_glyph_color(font_data, face, glyph_data); if (!lock_more) { unlock_current_page(font_data); } } static int get_kerning(ALLEGRO_TTF_FONT_DATA const *data, FT_Face face, int prev_ft_index, int ft_index) { /* Do kerning? */ if (!(data->flags & ALLEGRO_TTF_NO_KERNING) && prev_ft_index != -1) { FT_Vector delta; FT_Get_Kerning(face, prev_ft_index, ft_index, FT_KERNING_DEFAULT, &delta); return delta.x >> 6; } return 0; } static int render_glyph(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, int prev_ft_index, int ft_index, float xpos, float ypos) { ALLEGRO_TTF_FONT_DATA *data = f->data; FT_Face face = data->face; ALLEGRO_TTF_GLYPH_DATA *glyph = get_glyph(data, ft_index); int advance = 0; /* We don't try to cache all glyphs in a pre-pass before drawing them. * While that would indeed save us making separate texture uploads, it * implies two passes over a string even in the common case when all glyphs * are already cached. This turns out to have an measureable impact on * performance. */ cache_glyph(data, face, ft_index, glyph, false); advance += get_kerning(data, face, prev_ft_index, ft_index); if (glyph->page_bitmap) { /* Each glyph has a 1-pixel border all around. */ al_draw_tinted_bitmap_region(glyph->page_bitmap, color, glyph->region.x + 1, glyph->region.y + 1, glyph->region.w - 2, glyph->region.h - 2, xpos + glyph->offset_x + advance, ypos + glyph->offset_y, 0); } else if (glyph->region.x > 0) { ALLEGRO_ERROR("Glyph %d not on any page.\n", ft_index); } advance += glyph->advance; return advance; } static int ttf_font_height(ALLEGRO_FONT const *f) { ASSERT(f); return f->height; } static int ttf_font_ascent(ALLEGRO_FONT const *f) { ALLEGRO_TTF_FONT_DATA *data; FT_Face face; ASSERT(f); data = f->data; face = data->face; return face->size->metrics.ascender >> 6; } static int ttf_font_descent(ALLEGRO_FONT const *f) { ALLEGRO_TTF_FONT_DATA *data; FT_Face face; ASSERT(f); data = f->data; face = data->face; return (-face->size->metrics.descender) >> 6; } static int ttf_render_char(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, int ch, float xpos, float ypos) { /* Unused method. */ ASSERT(false); (void)f; (void)color; (void)ch; (void)xpos; (void)ypos; return 0; } static int ttf_char_length(ALLEGRO_FONT const *f, int ch) { /* Unused method. */ ASSERT(false); (void)f; (void)ch; return 0; } static int ttf_render(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, const ALLEGRO_USTR *text, float x, float y) { ALLEGRO_TTF_FONT_DATA *data = f->data; FT_Face face = data->face; int pos = 0; int advance = 0; int prev_ft_index = -1; int32_t ch; bool hold; hold = al_is_bitmap_drawing_held(); al_hold_bitmap_drawing(true); while ((ch = al_ustr_get_next(text, &pos)) >= 0) { int ft_index = FT_Get_Char_Index(face, ch); advance += render_glyph(f, color, prev_ft_index, ft_index, x + advance, y); prev_ft_index = ft_index; } al_hold_bitmap_drawing(hold); return advance; } static int ttf_text_length(ALLEGRO_FONT const *f, const ALLEGRO_USTR *text) { ALLEGRO_TTF_FONT_DATA *data = f->data; FT_Face face = data->face; int pos = 0; int prev_ft_index = -1; int x = 0; int32_t ch; while ((ch = al_ustr_get_next(text, &pos)) >= 0) { int ft_index = FT_Get_Char_Index(face, ch); ALLEGRO_TTF_GLYPH_DATA *glyph = get_glyph(data, ft_index); cache_glyph(data, face, ft_index, glyph, true); x += get_kerning(data, face, prev_ft_index, ft_index); x += glyph->advance; prev_ft_index = ft_index; } unlock_current_page(data); return x; } static void ttf_get_text_dimensions(ALLEGRO_FONT const *f, ALLEGRO_USTR const *text, int *bbx, int *bby, int *bbw, int *bbh) { ALLEGRO_TTF_FONT_DATA *data = f->data; FT_Face face = data->face; int end; int pos = 0; int prev_ft_index = -1; bool first = true; int x = 0; int32_t ch; end = al_ustr_size(text); *bbx = 0; while ((ch = al_ustr_get_next(text, &pos)) >= 0) { int ft_index = FT_Get_Char_Index(face, ch); ALLEGRO_TTF_GLYPH_DATA *glyph = get_glyph(data, ft_index); cache_glyph(data, face, ft_index, glyph, true); if (pos == end) { x += glyph->offset_x + glyph->region.w; } else { x += get_kerning(data, face, prev_ft_index, ft_index); x += glyph->advance; } if (first) { *bbx = glyph->offset_x; first = false; } prev_ft_index = ft_index; } *bby = 0; // FIXME *bbw = x - *bbx; *bbh = f->height; // FIXME, we want the bounding box! unlock_current_page(data); } #ifdef DEBUG_CACHE #include "allegro5/allegro_image.h" static void debug_cache(ALLEGRO_FONT *f) { ALLEGRO_TTF_FONT_DATA *data = f->data; _AL_VECTOR *v = &data->page_bitmaps; static int j = 0; int i; al_init_image_addon(); for (i = 0; i < (int)_al_vector_size(v); i++) { ALLEGRO_BITMAP **bmp = _al_vector_ref(v, i); ALLEGRO_USTR *u = al_ustr_newf("font%d.png", j++); al_save_bitmap(al_cstr(u), *bmp); al_ustr_free(u); } } #endif static void ttf_destroy(ALLEGRO_FONT *f) { ALLEGRO_TTF_FONT_DATA *data = f->data; int i; unlock_current_page(data); #ifdef DEBUG_CACHE debug_cache(f); #endif FT_Done_Face(data->face); for (i = _al_vector_size(&data->glyph_ranges) - 1; i >= 0; i--) { ALLEGRO_TTF_GLYPH_RANGE *range = _al_vector_ref(&data->glyph_ranges, i); al_free(range->glyphs); } _al_vector_free(&data->glyph_ranges); for (i = _al_vector_size(&data->page_bitmaps) - 1; i >= 0; i--) { ALLEGRO_BITMAP **bmp = _al_vector_ref(&data->page_bitmaps, i); al_destroy_bitmap(*bmp); } _al_vector_free(&data->page_bitmaps); al_free(data); al_free(f); } static unsigned long ftread(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { ALLEGRO_TTF_FONT_DATA *data = stream->pathname.pointer; unsigned long bytes; if (count == 0) return 0; if (offset != data->offset) al_fseek(data->file, data->base_offset + offset, ALLEGRO_SEEK_SET); bytes = al_fread(data->file, buffer, count); data->offset = offset + bytes; return bytes; } static void ftclose(FT_Stream stream) { ALLEGRO_TTF_FONT_DATA *data = stream->pathname.pointer; al_fclose(data->file); data->file = NULL; } /* Function: al_load_ttf_font_f */ ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file, char const *filename, int size, int flags) { return al_load_ttf_font_stretch_f(file, filename, 0, size, flags); } /* Function: al_load_ttf_font_stretch_f */ ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file, char const *filename, int w, int h, int flags) { FT_Face face; ALLEGRO_TTF_FONT_DATA *data; ALLEGRO_FONT *f; ALLEGRO_PATH *path; FT_Open_Args args; int result; data = al_calloc(1, sizeof *data); data->stream.read = ftread; data->stream.close = ftclose; data->stream.pathname.pointer = data; data->base_offset = al_ftell(file); data->stream.size = al_fsize(file); data->file = file; data->bitmap_format = al_get_new_bitmap_format(); data->bitmap_flags = al_get_new_bitmap_flags(); memset(&args, 0, sizeof args); args.flags = FT_OPEN_STREAM; args.stream = &data->stream; if ((result = FT_Open_Face(ft, &args, 0, &face)) != 0) { ALLEGRO_ERROR("Reading %s failed. Freetype error code %d\n", filename, result); // Note: Freetype already closed the file for us. al_free(data); return NULL; } // FIXME: The below doesn't use Allegro's streaming. /* Small hack for Type1 fonts which store kerning information in * a separate file - and we try to guess the name of that file. */ path = al_create_path(filename); if (!strcmp(al_get_path_extension(path), ".pfa")) { const char *helper; ALLEGRO_DEBUG("Type1 font assumed for %s.\n", filename); al_set_path_extension(path, ".afm"); helper = al_path_cstr(path, '/'); FT_Attach_File(face, helper); ALLEGRO_DEBUG("Guessed afm file %s.\n", helper); al_set_path_extension(path, ".tfm"); helper = al_path_cstr(path, '/'); FT_Attach_File(face, helper); ALLEGRO_DEBUG("Guessed tfm file %s.\n", helper); } al_destroy_path(path); if (h > 0) { FT_Set_Pixel_Sizes(face, w, h); } else { /* Set the "real dimension" of the font to be the passed size, * in pixels. */ FT_Size_RequestRec req; ASSERT(w <= 0); ASSERT(h <= 0); req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; req.width = (-w) << 6; req.height = (-h) << 6; req.horiResolution = 0; req.vertResolution = 0; FT_Request_Size(face, &req); } ALLEGRO_DEBUG("Font %s loaded with pixel size %d x %d.\n", filename, w, h); ALLEGRO_DEBUG(" ascent=%.1f, descent=%.1f, height=%.1f\n", face->size->metrics.ascender / 64.0, face->size->metrics.descender / 64.0, face->size->metrics.height / 64.0); data->face = face; data->flags = flags; data->no_premultiply_alpha = (al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); _al_vector_init(&data->glyph_ranges, sizeof(ALLEGRO_TTF_GLYPH_RANGE)); _al_vector_init(&data->page_bitmaps, sizeof(ALLEGRO_BITMAP*)); f = al_malloc(sizeof *f); f->height = face->size->metrics.height >> 6; f->vtable = &vt; f->data = data; _al_register_destructor(_al_dtor_list, f, (void (*)(void *))al_destroy_font); return f; } /* Function: al_load_ttf_font */ ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags) { return al_load_ttf_font_stretch(filename, 0, size, flags); } /* Function: al_load_ttf_font_stretch */ ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h, int flags) { ALLEGRO_FILE *f; ALLEGRO_FONT *font; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; /* The file handle is owned by the function and the file is usually only * closed when the font is destroyed, in case Freetype has to load data * at a later time. */ font = al_load_ttf_font_stretch_f(f, filename, w, h, flags); return font; } /* Function: al_init_ttf_addon */ bool al_init_ttf_addon(void) { if (ttf_inited) { ALLEGRO_WARN("TTF addon already initialised.\n"); return true; } FT_Init_FreeType(&ft); vt.font_height = ttf_font_height; vt.font_ascent = ttf_font_ascent; vt.font_descent = ttf_font_descent; vt.char_length = ttf_char_length; vt.text_length = ttf_text_length; vt.render_char = ttf_render_char; vt.render = ttf_render; vt.destroy = ttf_destroy; vt.get_text_dimensions = ttf_get_text_dimensions; al_register_font_loader(".ttf", al_load_ttf_font); /* Can't fail right now - in the future we might dynamically load * the FreeType DLL here and/or initialize FreeType (which both * could fail and would cause a false return). */ ttf_inited = true; return ttf_inited; } /* Function: al_shutdown_ttf_addon */ void al_shutdown_ttf_addon(void) { if (!ttf_inited) { ALLEGRO_ERROR("TTF addon not initialised.\n"); return; } al_register_font_loader(".ttf", NULL); FT_Done_FreeType(ft); ttf_inited = false; } /* Function: al_get_allegro_ttf_version */ uint32_t al_get_allegro_ttf_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/ttf/allegro5/0000755000175000001440000000000012157230737016174 5ustar tjadenusersallegro-5.0.10/addons/ttf/allegro5/allegro_ttf.h0000644000175000001440000000324211721436703020645 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_ttf_h #define __al_included_allegro5_allegro_ttf_h #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #ifdef __cplusplus extern "C" { #endif #define ALLEGRO_TTF_NO_KERNING 1 #define ALLEGRO_TTF_MONOCHROME 2 #define ALLEGRO_TTF_NO_AUTOHINT 4 #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_TTF_SRC #define _ALLEGRO_TTF_DLL __declspec(dllexport) #else #define _ALLEGRO_TTF_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_TTF_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_TTF_FUNC(type, name, args) _ALLEGRO_TTF_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_TTF_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_TTF_FUNC(type, name, args) extern _ALLEGRO_TTF_DLL type name args #else #define ALLEGRO_TTF_FUNC AL_FUNC #endif ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font, (char const *filename, int size, int flags)); ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_f, (ALLEGRO_FILE *file, char const *filename, int size, int flags)); ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch, (char const *filename, int w, int h, int flags)); ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch_f, (ALLEGRO_FILE *file, char const *filename, int w, int h, int flags)); ALLEGRO_TTF_FUNC(bool, al_init_ttf_addon, (void)); ALLEGRO_TTF_FUNC(void, al_shutdown_ttf_addon, (void)); ALLEGRO_TTF_FUNC(uint32_t, al_get_allegro_ttf_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/ttf/allegro5/internal/0000755000175000001440000000000012157230515020002 5ustar tjadenusersallegro-5.0.10/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake0000644000175000001440000000004611054541666024375 0ustar tjadenusers#cmakedefine ALLEGRO_CFG_TTF_FREETYPE allegro-5.0.10/addons/memfile/0000755000175000001440000000000012157230737015303 5ustar tjadenusersallegro-5.0.10/addons/memfile/memfile.c0000644000175000001440000000736311520367161017071 0ustar tjadenusers#include #include "allegro5/allegro_memfile.h" typedef struct ALLEGRO_FILE_MEMFILE ALLEGRO_FILE_MEMFILE; struct ALLEGRO_FILE_MEMFILE { bool readable; bool writable; bool eof; int64_t size; int64_t pos; char *mem; }; static void memfile_fclose(ALLEGRO_FILE *fp) { al_free(al_get_file_userdata(fp)); } static size_t memfile_fread(ALLEGRO_FILE *fp, void *ptr, size_t size) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); size_t n = 0; if (!mf->readable) { al_set_errno(EPERM); return 0; } if (mf->size - mf->pos < (int64_t)size) { /* partial read */ n = mf->size - mf->pos; mf->eof = true; } else { n = size; } memcpy(ptr, mf->mem + mf->pos, n); mf->pos += n; return n; } static size_t memfile_fwrite(ALLEGRO_FILE *fp, const void *ptr, size_t size) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); size_t n; if (!mf->writable) { al_set_errno(EPERM); return 0; } if (mf->size - mf->pos < (int64_t)size) { /* partial write */ n = mf->size - mf->pos; mf->eof = true; } else { n = size; } memcpy(mf->mem + mf->pos, ptr, n); mf->pos += n; return n; } static bool memfile_fflush(ALLEGRO_FILE *fp) { (void)fp; return true; } static int64_t memfile_ftell(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->pos; } static bool memfile_fseek(ALLEGRO_FILE *fp, int64_t offset, int whence) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); int64_t pos = mf->pos; switch (whence) { case ALLEGRO_SEEK_SET: pos = offset; break; case ALLEGRO_SEEK_CUR: pos = mf->pos + offset; break; case ALLEGRO_SEEK_END: pos = mf->size + offset; break; } if (pos >= mf->size) pos = mf->size; else if (pos < 0) pos = 0; mf->pos = pos; mf->eof = false; return true; } /* doesn't quite match up to stdio here, an feof after a seek will return false, even if it seeks past the end of the file */ static bool memfile_feof(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->eof; } static bool memfile_ferror(ALLEGRO_FILE *fp) { (void)fp; return false; } static void memfile_fclearerr(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); mf->eof = false; } static off_t memfile_fsize(ALLEGRO_FILE *fp) { ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); return mf->size; } static struct ALLEGRO_FILE_INTERFACE memfile_vtable = { NULL, /* open */ memfile_fclose, memfile_fread, memfile_fwrite, memfile_fflush, memfile_ftell, memfile_fseek, memfile_feof, memfile_ferror, memfile_fclearerr, NULL, /* ungetc */ memfile_fsize }; /* Function: al_open_memfile */ ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode) { ALLEGRO_FILE *memfile; ALLEGRO_FILE_MEMFILE *userdata = NULL; ASSERT(mem); ASSERT(size > 0); userdata = al_malloc(sizeof(ALLEGRO_FILE_MEMFILE)); if (!userdata) { al_set_errno(ENOMEM); return NULL; } memset(userdata, 0, sizeof(*userdata)); userdata->size = size; userdata->pos = 0; userdata->mem = mem; userdata->readable = strchr(mode, 'r') || strchr(mode, 'R'); userdata->writable = strchr(mode, 'w') || strchr(mode, 'W'); memfile = al_create_file_handle(&memfile_vtable, userdata); if (!memfile) { al_free(userdata); } return memfile; } /* Function: al_get_allegro_memfile_version */ uint32_t al_get_allegro_memfile_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/memfile/CMakeLists.txt0000644000175000001440000000114311505637161020040 0ustar tjadenusers set(MEMFILE_SOURCES memfile.c) set(MEMFILE_INCLUDE_FILES allegro5/allegro_memfile.h) set_our_header_properties(${MEMFILE_INCLUDE_FILES}) add_our_library(allegro_memfile "${MEMFILE_SOURCES};${MEMFILE_INCLUDE_FILES}" "-DALLEGRO_MEMFILE_SRC" "${ALLEGRO_LINK_WITH}" ) set_our_framework_properties(allegro_memfile AllegroMemfile-${ALLEGRO_SOVERSION}) install_our_library(allegro_memfile) install_our_headers(${MEMFILE_INCLUDE_FILES}) set(MEMFILE_LINK_WITH allegro_memfile PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/memfile/allegro5/0000755000175000001440000000000012157230737017015 5ustar tjadenusersallegro-5.0.10/addons/memfile/allegro5/allegro_memfile.h0000644000175000001440000000215511505637161022312 0ustar tjadenusers#ifndef __al_included_allegro5_memfile_h #define __al_included_allegro5_memfile_h #include "allegro5/allegro.h" #ifdef __cplusplus extern "C" { #endif #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_MEMFILE_SRC #define _ALLEGRO_MEMFILE_DLL __declspec(dllexport) #else #define _ALLEGRO_MEMFILE_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_MEMFILE_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_MEMFILE_FUNC(type, name, args) _ALLEGRO_MEMFILE_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern _ALLEGRO_MEMFILE_DLL type name args #else #define ALLEGRO_MEMFILE_FUNC AL_FUNC #endif ALLEGRO_MEMFILE_FUNC(ALLEGRO_FILE *, al_open_memfile, (void *mem, int64_t size, const char *mode)); ALLEGRO_MEMFILE_FUNC(uint32_t, al_get_allegro_memfile_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/color/0000755000175000001440000000000012157230737015003 5ustar tjadenusersallegro-5.0.10/addons/color/CMakeLists.txt0000644000175000001440000000112111345165711017533 0ustar tjadenusersset(COLOR_SOURCES color.c) set(COLOR_INCLUDE_FILES allegro5/allegro_color.h ) set_our_header_properties(${COLOR_INCLUDE_FILES}) add_our_library(allegro_color "${COLOR_SOURCES};${COLOR_INCLUDE_FILES}" "-DALLEGRO_COLOR_SRC" "${ALLEGRO_LINK_WITH}" ) set_our_framework_properties(allegro_color AllegroColor-${ALLEGRO_SOVERSION}) install_our_library(allegro_color) install_our_headers(${COLOR_INCLUDE_FILES}) set(COLOR_LINK_WITH allegro_color PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/color/color.c0000644000175000001440000003442612135477603016277 0ustar tjadenusers/* Addon which allows converting between different color * representations. Included are: * - HSV (like A4) * - names (mostly X11 color names, except where CSS redefines them) * - HSL (the "better" HSV) * - CMYK (a bit like the opposite of RGB) * - YUV (the Y channel is quite useful for creating grayscale pictures) */ #include "allegro5/allegro.h" #include "allegro5/allegro_color.h" #include #include typedef struct { char const *name; int r, g, b; } ColorName; /* Taken from http://www.w3.org/TR/2010/PR-css3-color-20101028/#svg-color * This must be sorted correctly for binary search. */ static ColorName _al_color_names[] = { {"aliceblue", 0xf0, 0xf8, 0xff}, {"antiquewhite", 0xfa, 0xeb, 0xd7}, {"aqua", 0x00, 0xff, 0xff}, {"aquamarine", 0x7f, 0xff, 0xd4}, {"azure", 0xf0, 0xff, 0xff}, {"beige", 0xf5, 0xf5, 0xdc}, {"bisque", 0xff, 0xe4, 0xc4}, {"black", 0x00, 0x00, 0x00}, {"blanchedalmond", 0xff, 0xeb, 0xcd}, {"blue", 0x00, 0x00, 0xff}, {"blueviolet", 0x8a, 0x2b, 0xe2}, {"brown", 0xa5, 0x2a, 0x2a}, {"burlywood", 0xde, 0xb8, 0x87}, {"cadetblue", 0x5f, 0x9e, 0xa0}, {"chartreuse", 0x7f, 0xff, 0x00}, {"chocolate", 0xd2, 0x69, 0x1e}, {"coral", 0xff, 0x7f, 0x50}, {"cornflowerblue", 0x64, 0x95, 0xed}, {"cornsilk", 0xff, 0xf8, 0xdc}, {"crimson", 0xdc, 0x14, 0x3c}, {"cyan", 0x00, 0xff, 0xff}, {"darkblue", 0x00, 0x00, 0x8b}, {"darkcyan", 0x00, 0x8b, 0x8b}, {"darkgoldenrod", 0xb8, 0x86, 0x0b}, {"darkgray", 0xa9, 0xa9, 0xa9}, {"darkgreen", 0x00, 0x64, 0x00}, {"darkgrey", 0xa9, 0xa9, 0xa9}, {"darkkhaki", 0xbd, 0xb7, 0x6b}, {"darkmagenta", 0x8b, 0x00, 0x8b}, {"darkolivegreen", 0x55, 0x6b, 0x2f}, {"darkorange", 0xff, 0x8c, 0x00}, {"darkorchid", 0x99, 0x32, 0xcc}, {"darkred", 0x8b, 0x00, 0x00}, {"darksalmon", 0xe9, 0x96, 0x7a}, {"darkseagreen", 0x8f, 0xbc, 0x8f}, {"darkslateblue", 0x48, 0x3d, 0x8b}, {"darkslategray", 0x2f, 0x4f, 0x4f}, {"darkslategrey", 0x2f, 0x4f, 0x4f}, {"darkturquoise", 0x00, 0xce, 0xd1}, {"darkviolet", 0x94, 0x00, 0xd3}, {"deeppink", 0xff, 0x14, 0x93}, {"deepskyblue", 0x00, 0xbf, 0xff}, {"dimgray", 0x69, 0x69, 0x69}, {"dimgrey", 0x69, 0x69, 0x69}, {"dodgerblue", 0x1e, 0x90, 0xff}, {"firebrick", 0xb2, 0x22, 0x22}, {"floralwhite", 0xff, 0xfa, 0xf0}, {"forestgreen", 0x22, 0x8b, 0x22}, {"fuchsia", 0xff, 0x00, 0xff}, {"gainsboro", 0xdc, 0xdc, 0xdc}, {"ghostwhite", 0xf8, 0xf8, 0xff}, {"gold", 0xff, 0xd7, 0x00}, {"goldenrod", 0xda, 0xa5, 0x20}, {"gray", 0x80, 0x80, 0x80}, {"green", 0x00, 0x80, 0x00}, {"greenyellow", 0xad, 0xff, 0x2f}, {"grey", 0x80, 0x80, 0x80}, {"honeydew", 0xf0, 0xff, 0xf0}, {"hotpink", 0xff, 0x69, 0xb4}, {"indianred", 0xcd, 0x5c, 0x5c}, {"indigo", 0x4b, 0x00, 0x82}, {"ivory", 0xff, 0xff, 0xf0}, {"khaki", 0xf0, 0xe6, 0x8c}, {"lavender", 0xe6, 0xe6, 0xfa}, {"lavenderblush", 0xff, 0xf0, 0xf5}, {"lawngreen", 0x7c, 0xfc, 0x00}, {"lemonchiffon", 0xff, 0xfa, 0xcd}, {"lightblue", 0xad, 0xd8, 0xe6}, {"lightcoral", 0xf0, 0x80, 0x80}, {"lightcyan", 0xe0, 0xff, 0xff}, {"lightgoldenrodyellow", 0xfa, 0xfa, 0xd2}, {"lightgray", 0xd3, 0xd3, 0xd3}, {"lightgreen", 0x90, 0xee, 0x90}, {"lightgrey", 0xd3, 0xd3, 0xd3}, {"lightpink", 0xff, 0xb6, 0xc1}, {"lightsalmon", 0xff, 0xa0, 0x7a}, {"lightseagreen", 0x20, 0xb2, 0xaa}, {"lightskyblue", 0x87, 0xce, 0xfa}, {"lightslategray", 0x77, 0x88, 0x99}, {"lightslategrey", 0x77, 0x88, 0x99}, {"lightsteelblue", 0xb0, 0xc4, 0xde}, {"lightyellow", 0xff, 0xff, 0xe0}, {"lime", 0x00, 0xff, 0x00}, {"limegreen", 0x32, 0xcd, 0x32}, {"linen", 0xfa, 0xf0, 0xe6}, {"magenta", 0xff, 0x00, 0xff}, {"maroon", 0x80, 0x00, 0x00}, {"mediumaquamarine", 0x66, 0xcd, 0xaa}, {"mediumblue", 0x00, 0x00, 0xcd}, {"mediumorchid", 0xba, 0x55, 0xd3}, {"mediumpurple", 0x93, 0x70, 0xdb}, {"mediumseagreen", 0x3c, 0xb3, 0x71}, {"mediumslateblue", 0x7b, 0x68, 0xee}, {"mediumspringgreen", 0x00, 0xfa, 0x9a}, {"mediumturquoise", 0x48, 0xd1, 0xcc}, {"mediumvioletred", 0xc7, 0x15, 0x85}, {"midnightblue", 0x19, 0x19, 0x70}, {"mintcream", 0xf5, 0xff, 0xfa}, {"mistyrose", 0xff, 0xe4, 0xe1}, {"moccasin", 0xff, 0xe4, 0xb5}, {"navajowhite", 0xff, 0xde, 0xad}, {"navy", 0x00, 0x00, 0x80}, {"oldlace", 0xfd, 0xf5, 0xe6}, {"olive", 0x80, 0x80, 0x00}, {"olivedrab", 0x6b, 0x8e, 0x23}, {"orange", 0xff, 0xa5, 0x00}, {"orangered", 0xff, 0x45, 0x00}, {"orchid", 0xda, 0x70, 0xd6}, {"palegoldenrod", 0xee, 0xe8, 0xaa}, {"palegreen", 0x98, 0xfb, 0x98}, {"paleturquoise", 0xaf, 0xee, 0xee}, {"palevioletred", 0xdb, 0x70, 0x93}, {"papayawhip", 0xff, 0xef, 0xd5}, {"peachpuff", 0xff, 0xda, 0xb9}, {"peru", 0xcd, 0x85, 0x3f}, {"pink", 0xff, 0xc0, 0xcb}, {"plum", 0xdd, 0xa0, 0xdd}, {"powderblue", 0xb0, 0xe0, 0xe6}, {"purple", 0x80, 0x00, 0x80}, {"purwablue", 0x9b, 0xe1, 0xff}, {"red", 0xff, 0x00, 0x00}, {"rosybrown", 0xbc, 0x8f, 0x8f}, {"royalblue", 0x41, 0x69, 0xe1}, {"saddlebrown", 0x8b, 0x45, 0x13}, {"salmon", 0xfa, 0x80, 0x72}, {"sandybrown", 0xf4, 0xa4, 0x60}, {"seagreen", 0x2e, 0x8b, 0x57}, {"seashell", 0xff, 0xf5, 0xee}, {"sienna", 0xa0, 0x52, 0x2d}, {"silver", 0xc0, 0xc0, 0xc0}, {"skyblue", 0x87, 0xce, 0xeb}, {"slateblue", 0x6a, 0x5a, 0xcd}, {"slategray", 0x70, 0x80, 0x90}, {"slategrey", 0x70, 0x80, 0x90}, {"snow", 0xff, 0xfa, 0xfa}, {"springgreen", 0x00, 0xff, 0x7f}, {"steelblue", 0x46, 0x82, 0xb4}, {"tan", 0xd2, 0xb4, 0x8c}, {"teal", 0x00, 0x80, 0x80}, {"thistle", 0xd8, 0xbf, 0xd8}, {"tomato", 0xff, 0x63, 0x47}, {"turquoise", 0x40, 0xe0, 0xd0}, {"violet", 0xee, 0x82, 0xee}, {"wheat", 0xf5, 0xde, 0xb3}, {"white", 0xff, 0xff, 0xff}, {"whitesmoke", 0xf5, 0xf5, 0xf5}, {"yellow", 0xff, 0xff, 0x00}, {"yellowgreen", 0x9a, 0xcd, 0x32}, }; #define NUM_COLORS (sizeof(_al_color_names) / sizeof(ColorName)) static void assert_sorted_names(void) { /* In debug mode, check once that the array is sorted. */ #ifdef DEBUGMODE static bool done = false; unsigned i; if (!done) { for (i = 1; i < NUM_COLORS; i++) { ASSERT(strcmp(_al_color_names[i-1].name, _al_color_names[i].name) < 0); } done = true; } #endif } static int compare(const void *va, const void *vb) { char const *ca = va; ColorName const *cb = vb; return strcmp(ca, cb->name); } /* Function: al_color_name_to_rgb */ bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b) { void *result; assert_sorted_names(); result = bsearch(name, _al_color_names, NUM_COLORS, sizeof(ColorName), compare); if (result) { ColorName *c = result; *r = c->r / 255.0; *g = c->g / 255.0; *b = c->b / 255.0; return true; } return false; } /* Function: al_color_rgb_to_name */ char const *al_color_rgb_to_name(float r, float g, float b) { int i; int ir = r * 255; int ig = g * 255; int ib = b * 255; int n = NUM_COLORS; int min = n, mind = 0; /* Could optimize this, right now it does linear search. */ for (i = 0; i < n; i++) { int dr = _al_color_names[i].r - ir; int dg = _al_color_names[i].g - ig; int db = _al_color_names[i].b - ib; int d = dr * dr + dg * dg + db * db; if (min == n || d < mind) { min = i; mind = d; } } return _al_color_names[min].name; } /* Function: al_color_name */ ALLEGRO_COLOR al_color_name(char const *name) { float r, g, b; if (al_color_name_to_rgb(name, &r, &g, &b)) return al_map_rgb_f(r, g, b); else return al_map_rgb_f(0, 0, 0); } /* Function: al_color_hsv_to_rgb */ void al_color_hsv_to_rgb(float hue, float saturation, float value, float *red, float *green, float *blue) { int d; float e, a, b, c; hue = fmodf(hue, 360); if (hue < 0) hue += 360; d = hue / 60; e = hue / 60 - d; a = value * (1 - saturation); b = value * (1 - e * saturation); c = value * (1 - (1 - e) * saturation); switch (d) { default: case 0: *red = value, *green = c, *blue = a; return; case 1: *red = b, *green = value, *blue = a; return; case 2: *red = a, *green = value, *blue = c; return; case 3: *red = a, *green = b, *blue = value; return; case 4: *red = c, *green = a, *blue = value; return; case 5: *red = value, *green = a, *blue = b; return; } } /* Function: al_color_rgb_to_hsv */ void al_color_rgb_to_hsv(float red, float green, float blue, float *hue, float *saturation, float *value) { float a, b, c, d; if (red > green) { if (red > blue) { if (green > blue) a = red, b = green - blue, c = blue, d = 0; else a = red, b = green - blue, c = green, d = 0; } else { a = blue, b = red - green, c = green, d = 4; } } else { if (red > blue) a = green, b = blue - red, c = blue, d = 2; else if (green > blue) a = green, b = blue - red, c = red, d = 2; else a = blue, b = red - green, c = red, d = 4; } if (a == c) { *hue = 0; } else { *hue = 60 * (d + b / (a - c)); if (*hue < 0) *hue += 360; if (*hue > 360) *hue -= 360; } if (a == 0) *saturation = 0; else *saturation = (a - c) / a; *value = a; } /* Function: al_color_hsv */ ALLEGRO_COLOR al_color_hsv(float h, float s, float v) { float r, g, b; al_color_hsv_to_rgb(h, s, v, &r, &g, &b); return al_map_rgb_f(r, g, b); } static float hsl_to_rgb_helper(float x, float a, float b) { if (x < 0) x += 1; if (x > 1) x -= 1; if (x * 6 < 1) return b + (a - b) * 6 * x; if (x * 6 < 3) return a; if (x * 6 < 4) return b + (a - b) * (4.0 - 6.0 * x); return b; } /* Function: al_color_hsl_to_rgb */ void al_color_hsl_to_rgb(float hue, float saturation, float lightness, float *red, float *green, float *blue) { float a, b, h; hue = fmodf(hue, 360); if (hue < 0) hue += 360; h = hue / 360; if (lightness < 0.5) a = lightness + lightness * saturation; else a = lightness + saturation - lightness * saturation; b = lightness * 2 - a; *red = hsl_to_rgb_helper(h + 1.0 / 3.0, a, b); *green = hsl_to_rgb_helper(h, a, b); *blue = hsl_to_rgb_helper(h - 1.0 / 3.0, a, b); } /* Function: al_color_rgb_to_hsl */ void al_color_rgb_to_hsl(float red, float green, float blue, float *hue, float *saturation, float *lightness) { float a, b, c, d; if (red > green) { if (red > blue) { if (green > blue) a = red, b = green - blue, c = blue, d = 0; else a = red, b = green - blue, c = green, d = 0; } else { a = blue, b = red - green, c = green, d = 4; } } else { if (red > blue) a = green, b = blue - red, c = blue, d = 2; else if (green > blue) a = green, b = blue - red, c = red, d = 2; else a = blue, b = red - green, c = red, d = 4; } if (a == c) { *hue = 0; } else { *hue = 60 * (d + b / (a - c)); if (*hue < 0) *hue += 360; } if (a == c) *saturation = 0; else if (a + c < 1) *saturation = (a - c) / (a + c); else *saturation = (a - c) / (2 - a - c); *lightness = (a + c) / 2; } /* Function: al_color_hsl */ ALLEGRO_COLOR al_color_hsl(float h, float s, float l) { float r, g, b; al_color_hsl_to_rgb(h, s, l, &r, &g, &b); return al_map_rgb_f(r, g, b); } /* Function: al_color_cmyk_to_rgb */ void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow, float key, float *red, float *green, float *blue) { float max = 1 - key; *red = max - cyan * max; *green = max - magenta * max; *blue = max - yellow * max; } /* Function: al_color_rgb_to_cmyk */ void al_color_rgb_to_cmyk(float red, float green, float blue, float *cyan, float *magenta, float *yellow, float *key) { float max = red; if (green > max) max = green; if (blue > max) max = blue; *key = 1 - max; if (max > 0) { *cyan = (max - red) / max; *magenta = (max - green) / max; *yellow = (max - blue) / max; } else { *cyan = *magenta = *yellow = 0; } } /* Function: al_color_cmyk */ ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k) { float r, g, b; al_color_cmyk_to_rgb(c, m, y, k, &r, &g, &b); return al_map_rgb_f(r, g, b); } /* Function: al_color_yuv_to_rgb */ void al_color_yuv_to_rgb(float y, float u, float v, float *red, float *green, float *blue) { /* Translate range 0..1 to actual range. */ u = 0.436 * (u * 2 - 1); v = 0.615 * (v * 2 - 1); *red = y + v * 1.13983; *green = y + u * -0.39465 + v * -0.58060; *blue = y + u * 2.03211; } /* Function: al_color_rgb_to_yuv */ void al_color_rgb_to_yuv(float red, float green, float blue, float *y, float *u, float *v) { *y = red * 0.299 + green * 0.587 + blue * 0.114; *u = red * -0.14713 + green * -0.28886 + blue * 0.436; *v = red * 0.615 + green * -0.51499 + blue * -0.10001; /* Normalize chroma components into 0..1 range. */ *u = (*u / 0.436 + 1) * 0.5; *v = (*v / 0.615 + 1) * 0.5; } /* Function: al_color_yuv */ ALLEGRO_COLOR al_color_yuv(float y, float u, float v) { float r, g, b; al_color_yuv_to_rgb(y, u, v, &r, &g, &b); return al_map_rgb_f(r, g, b); } /* Function: al_color_rgb_to_html */ void al_color_rgb_to_html(float red, float green, float blue, char *string) { sprintf(string, "#%02x%02x%02x", (int)(red * 255), (int)(green * 255), (int)(blue * 255)); } /* Function: al_color_html_to_rgb */ void al_color_html_to_rgb(char const *string, float *red, float *green, float *blue) { char const *ptr = string; long rgb; if (*ptr == '#') ptr++; rgb = strtol(ptr, NULL, 16); *red = (rgb >> 16) / 255.0; *green = ((rgb >> 8) & 255) / 255.0; *blue = (rgb & 255) / 255.0; } /* Function: al_color_html */ ALLEGRO_COLOR al_color_html(char const *string) { float r, g, b; al_color_html_to_rgb(string, &r, &g, &b); return al_map_rgb_f(r, g, b); } /* Function: al_get_allegro_color_version */ uint32_t al_get_allegro_color_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/color/allegro5/0000755000175000001440000000000012157230737016515 5ustar tjadenusersallegro-5.0.10/addons/color/allegro5/allegro_color.h0000644000175000001440000000561711426530105021510 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_color_h #define __al_included_allegro5_allegro_color_h #include "allegro5/allegro.h" #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_COLOR_SRC #define _ALLEGRO_COLOR_DLL __declspec(dllexport) #else #define _ALLEGRO_COLOR_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_COLOR_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_COLOR_FUNC(type, name, args) _ALLEGRO_COLOR_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_COLOR_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_COLOR_FUNC(type, name, args) extern _ALLEGRO_COLOR_DLL type name args #else #define ALLEGRO_COLOR_FUNC AL_FUNC #endif #ifdef __cplusplus extern "C" { #endif ALLEGRO_COLOR_FUNC(uint32_t, al_get_allegro_color_version, (void)); ALLEGRO_COLOR_FUNC(void, al_color_hsv_to_rgb, (float hue, float saturation, float value, float *red, float *green, float *blue)); ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsl, (float red, float green, float blue, float *hue, float *saturation, float *lightness)); ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsv, (float red, float green, float blue, float *hue, float *saturation, float *value)); ALLEGRO_COLOR_FUNC(void, al_color_hsl_to_rgb, (float hue, float saturation, float lightness, float *red, float *green, float *blue)); ALLEGRO_COLOR_FUNC(bool, al_color_name_to_rgb, (char const *name, float *r, float *g, float *b)); ALLEGRO_COLOR_FUNC(const char*, al_color_rgb_to_name, (float r, float g, float b)); ALLEGRO_COLOR_FUNC(void, al_color_cmyk_to_rgb, (float cyan, float magenta, float yellow, float key, float *red, float *green, float *blue)); ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_cmyk, (float red, float green, float blue, float *cyan, float *magenta, float *yellow, float *key)); ALLEGRO_COLOR_FUNC(void, al_color_yuv_to_rgb, (float y, float u, float v, float *red, float *green, float *blue)); ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_yuv, (float red, float green, float blue, float *y, float *u, float *v)); ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_html, (float red, float green, float blue, char *string)); ALLEGRO_COLOR_FUNC(void, al_color_html_to_rgb, (char const *string, float *red, float *green, float *blue)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_yuv, (float y, float u, float v)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_cmyk, (float c, float m, float y, float k)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsl, (float h, float s, float l)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsv, (float h, float s, float v)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_name, (char const *name)); ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_html, (char const *string)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/image/0000755000175000001440000000000012157230737014747 5ustar tjadenusersallegro-5.0.10/addons/image/macosx.m0000644000175000001440000002067312102566154016422 0ustar tjadenusers#import #import #import #include "allegro5/allegro.h" #include "allegro5/fshook.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 typedef float CGFloat; #endif ALLEGRO_DEBUG_CHANNEL("OSXIIO") // Just to make sure it's never al_malloc. #define apple_malloc malloc static ALLEGRO_BITMAP *really_load_image(char *buffer, int size) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; ALLEGRO_BITMAP *bmp = NULL; void *pixels = NULL; /* Note: buffer is now owned (and later freed) by the data object. */ NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:buffer length:size]; NSImage *image = [[NSImage alloc] initWithData:nsdata]; [nsdata release]; bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); if (!image) goto done; /* Get the image representations */ NSArray *reps = [image representations]; NSImageRep *image_rep = [reps objectAtIndex: 0]; if (!image_rep) { [image release]; goto done; } /* Get the actual size in pixels from the representation */ unsigned char *data[5]; // TODO: We should check it really is a bitmap representation. NSBitmapImageRep *bitmap_rep = (NSBitmapImageRep *)image_rep; [bitmap_rep getBitmapDataPlanes:data]; pixels = data[0]; int w = [image_rep pixelsWide]; int h = [image_rep pixelsHigh]; int bits = [bitmap_rep bitsPerPixel]; int samples = bits / 8; ALLEGRO_DEBUG("Read image of size %dx%dx%d\n", w, h, bits); /* Then create a bitmap out of the memory buffer. */ bmp = al_create_bitmap(w, h); if (bmp) { ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); int i, j; { for (i = 0; i < h; i++) { uint8_t *data_row = lock->data + lock->pitch * i; uint8_t *source_row = pixels + w * samples * i; if (samples == 4) { if (premul) { for (j = 0; j < w; j++) { int r, g, b, a; r = source_row[j * 4 + 0]; g = source_row[j * 4 + 1]; b = source_row[j * 4 + 2]; a = source_row[j * 4 + 3]; data_row[j * 4 + 0] = r * a / 255; data_row[j * 4 + 1] = g * a / 255; data_row[j * 4 + 2] = b * a / 255; data_row[j * 4 + 3] = a; } } else memcpy(data_row, source_row, w * 4); } else if (samples == 3) { for (j = 0; j < w; j++) { data_row[j * 4 + 0] = source_row[j * 3 + 0]; data_row[j * 4 + 1] = source_row[j * 3 + 1]; data_row[j * 4 + 2] = source_row[j * 3 + 2]; data_row[j * 4 + 3] = 255; } } else if (samples == 2) { for (j = 0; j < w; j++) { int a = data_row[j * 4 + 3] = source_row[j * 2 + 1]; if (!premul) a = 255; data_row[j * 4 + 0] = source_row[j * 2 + 0] * a / 255; data_row[j * 4 + 1] = source_row[j * 2 + 0] * a / 255; data_row[j * 4 + 2] = source_row[j * 2 + 0] * a / 255; } } else if (samples == 1) { for (j = 0; j < w; j++) { data_row[j * 4 + 0] = source_row[j]; data_row[j * 4 + 1] = source_row[j]; data_row[j * 4 + 2] = source_row[j]; data_row[j * 4 + 3] = 255; } } } } al_unlock_bitmap(bmp); } [image release]; done: [pool drain]; return bmp; } static ALLEGRO_BITMAP *_al_osx_load_image_f(ALLEGRO_FILE *f) { ALLEGRO_BITMAP *bmp; ASSERT(f); int64_t size = al_fsize(f); if (size <= 0) { // TODO: Read from stream until we have the whole image return NULL; } /* Note: This *MUST* be the Apple malloc and not any wrapper, as the * buffer will be owned and freed by the NSData object not us. */ void *buffer = apple_malloc(size); al_fread(f, buffer, size); /* Really load the image now. */ bmp = really_load_image(buffer, size); return bmp; } static ALLEGRO_BITMAP *_al_osx_load_image(const char *filename) { ALLEGRO_FILE *fp; ALLEGRO_BITMAP *bmp; ASSERT(filename); ALLEGRO_DEBUG("Using native loader to read %s\n", filename); fp = al_fopen(filename, "rb"); if (!fp) return NULL; bmp = _al_osx_load_image_f(fp); al_fclose(fp); return bmp; } extern NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp); bool _al_osx_save_image_f(ALLEGRO_FILE *f, const char *ident, ALLEGRO_BITMAP *bmp) { NSBitmapImageFileType type; if (!strcmp(ident, ".bmp")) { type = NSBMPFileType; } else if (!strcmp(ident, ".jpg") || !strcmp(ident, ".jpeg")) { type = NSJPEGFileType; } else if (!strcmp(ident, ".gif")) { type = NSGIFFileType; } else if (!strcmp(ident, ".tif") || !strcmp(ident, ".tiff")) { type = NSTIFFFileType; } else if (!strcmp(ident, ".png")) { type = NSPNGFileType; } else { return false; } NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; NSImage *image = NSImageFromAllegroBitmap(bmp); NSArray *reps = [image representations]; NSData *nsdata = [NSBitmapImageRep representationOfImageRepsInArray: reps usingType: type properties: nil]; size_t size = (size_t)[nsdata length]; bool ret = al_fwrite(f, [nsdata bytes], size) == size; [image release]; [pool drain]; return ret; } bool _al_osx_save_image(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *fp; bool ret = false; fp = al_fopen(filename, "wb"); if (fp) { ALLEGRO_PATH *path = al_create_path(filename); if (path) { ret = _al_osx_save_image_f(fp, al_get_path_extension(path), bmp); al_destroy_path(path); } al_fclose(fp); } return ret; } bool _al_osx_save_png_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_osx_save_image_f(f, ".png", bmp); } bool _al_osx_save_jpg_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_osx_save_image_f(f, ".jpg", bmp); } bool _al_osx_save_tif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_osx_save_image_f(f, ".tif", bmp); } bool _al_osx_save_gif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_osx_save_image_f(f, ".gif", bmp); } bool _al_osx_register_image_loader(void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; bool success = false; int num_types; int i; /* Get a list of all supported image types */ NSArray *file_types = [NSImage imageFileTypes]; num_types = [file_types count]; for (i = 0; i < num_types; i++) { NSString *str = @"."; NSString *type_str = [str stringByAppendingString: [file_types objectAtIndex: i]]; const char *s = [type_str UTF8String]; /* Skip image types Allegro supports built-in */ if (!_al_stricmp(s, ".tga") || !_al_stricmp(s, ".bmp") || !_al_stricmp(s, ".pcx")) { continue; } /* Unload previous loader, if any */ al_register_bitmap_loader(s, NULL); al_register_bitmap_loader_f(s, NULL); ALLEGRO_DEBUG("Registering native loader for bitmap type %s\n", s); success |= al_register_bitmap_loader(s, _al_osx_load_image); success |= al_register_bitmap_loader_f(s, _al_osx_load_image_f); } char const *extensions[] = { ".tif", ".tiff", ".gif", ".png", ".jpg", ".jpeg", NULL }; for (i = 0; extensions[i]; i++) { ALLEGRO_DEBUG("Registering native saver for bitmap type %s\n", extensions[i]); success |= al_register_bitmap_saver(extensions[i], _al_osx_save_image); } success |= al_register_bitmap_saver_f(".tif", _al_osx_save_tif_f); success |= al_register_bitmap_saver_f(".tiff", _al_osx_save_tif_f); success |= al_register_bitmap_saver_f(".gif", _al_osx_save_gif_f); success |= al_register_bitmap_saver_f(".png", _al_osx_save_png_f); success |= al_register_bitmap_saver_f(".jpg", _al_osx_save_jpg_f); success |= al_register_bitmap_saver_f(".jpeg", _al_osx_save_jpg_f); [pool drain]; return success; } allegro-5.0.10/addons/image/CMakeLists.txt0000644000175000001440000001215012115511363017475 0ustar tjadenusersoption(WANT_NATIVE_IMAGE_LOADER "Enable the native platform image loader (if available)" on) set(IMAGE_SOURCES bmp.c iio.c pcx.c tga.c) set(IMAGE_INCLUDE_FILES allegro5/allegro_image.h) set_our_header_properties(${IMAGE_INCLUDE_FILES}) # Accumulate these. set(IMAGE_LIBRARIES) set(IMAGE_DEFINES) # ALLEGRO_CFG_IIO_HAVE_* are the available libraries. # ALLEGRO_CFG_IIO_SUPPORT_* are the supported formats. # First look for native libraries and mark any supported image # type as found, so that the associated third party libraries # don't need to be used. if(WANT_NATIVE_IMAGE_LOADER) set(ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER 1) if(WIN32) find_package(GDIPLUS) if(GDIPLUS_FOUND) set(CMAKE_REQUIRED_DEFINITIONS -DGDIPLUS_LOWERCASE=${GDIPLUS_LOWERCASE}) set(CMAKE_REQUIRED_INCLUDES ${GDIPLUS_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${GDIPLUS_LIBRARY}) check_cxx_source_compiles(" #include #include #if GDIPLUS_LOWERCASE #include #else #include #endif using namespace Gdiplus; int main(void) { int pf = PixelFormat32bppARGB; return 0; } " SUPPORT_GDIPLUS) endif(GDIPLUS_FOUND) if(SUPPORT_GDIPLUS) set(ALLEGRO_CFG_IIO_HAVE_GDIPLUS 1) set(ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H ${GDIPLUS_LOWERCASE}) set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) list(APPEND IMAGE_SOURCES gdiplus.cpp) list(APPEND IMAGE_LIBRARIES ${GDIPLUS_LIBRARIES}) if(MINGW) list(APPEND IMAGE_LIBRARIES uuid) endif(MINGW) list(APPEND IMAGE_DEFINES ${GDIPLUS_DEFINITIONS}) include_directories(SYSTEM ${GDIPLUS_INCLUDE_DIR}) else(SUPPORT_GDIPLUS) message("WARNING: cannot use GDI+. Will try other libraries.") endif(SUPPORT_GDIPLUS) endif(WIN32) if (MACOSX) set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) list(APPEND IMAGE_SOURCES macosx.m) endif(MACOSX) if(IPHONE) list(APPEND IMAGE_SOURCES iphone.m) endif(IPHONE) endif(WANT_NATIVE_IMAGE_LOADER) # Now look for third party libraries to handle the unsupported formats if(WANT_IMAGE_PNG AND NOT ALLEGRO_CFG_IIO_SUPPORT_PNG) find_package(PNG) if(PNG_FOUND) # HAVE_PNG means libpng is available (and should be used) set(ALLEGRO_CFG_IIO_HAVE_PNG 1) set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) list(APPEND IMAGE_SOURCES png.c) list(APPEND IMAGE_LIBRARIES ${PNG_LIBRARIES}) list(APPEND IMAGE_DEFINES ${PNG_DEFINITIONS}) include_directories(SYSTEM ${PNG_INCLUDE_DIR}) else(PNG_FOUND) message("WARNING: libpng not found, disabling support") endif(PNG_FOUND) endif(WANT_IMAGE_PNG AND NOT ALLEGRO_CFG_IIO_SUPPORT_PNG) if(WANT_IMAGE_JPG AND NOT ALLEGRO_CFG_IIO_SUPPORT_JPG) find_package(JPEG) if(JPEG_FOUND AND MINGW) set(CMAKE_REQUIRED_INCLUDES ${JPEG_INCLUDE_DIR}) check_c_source_compiles(" #include #include #include #include int main(void) { return 0; }" JPEG_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(SUPPORT_JPEG ${JPEG_COMPILES}) else() set(SUPPORT_JPEG ${JPEG_FOUND}) endif() if(SUPPORT_JPEG) # HAVE_JPG means libjpeg is available (and should be used) set(ALLEGRO_CFG_IIO_HAVE_JPG 1) set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) list(APPEND IMAGE_SOURCES jpg.c) list(APPEND IMAGE_LIBRARIES ${JPEG_LIBRARIES}) list(APPEND IMAGE_DEFINES ${JPEG_DEFINITIONS}) list(APPEND IMAGE_INCLUDE_DIRECTORIES ${JPEG_INCLUDE_DIR}) include_directories(SYSTEM ${JPEG_INCLUDE_DIR}) else() if(MINGW AND JPEG_FOUND AND NOT JPEG_COMPILES) message("WARNING: libjpeg found but the headers appear to " "conflict with your MinGW headers, so disabling support. " "Try a later version.") else() message("WARNING: libjpeg not found, disabling support") endif() endif() endif(WANT_IMAGE_JPG AND NOT ALLEGRO_CFG_IIO_SUPPORT_JPG) configure_file( allegro5/internal/aintern_image_cfg.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/internal/aintern_image_cfg.h ) add_our_library(allegro_image "${IMAGE_SOURCES};${IMAGE_INCLUDE_FILES}" "-DALLEGRO_IIO_SRC" "${ALLEGRO_LINK_WITH};${IMAGE_LIBRARIES}" ) set_our_framework_properties(allegro_image AllegroImage-${ALLEGRO_SOVERSION}) install_our_library(allegro_image) install_our_headers(${IMAGE_INCLUDE_FILES}) set(IMAGE_LINK_WITH allegro_image PARENT_SCOPE) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/image/tga.c0000644000175000001440000003425611771523147015701 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * TGA reader. * * By Tim Gunn. * * RLE support added by Michal Mertl and Salvador Eduardo Tropea. * * Palette reading improved by Peter Wang. * * Big-endian support added by Eric Botcazou. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_image.h" #include "allegro5/internal/aintern_pixels.h" #include "iio.h" /* raw_tga_read8: * Helper for reading 256-color raw data from TGA files. */ static INLINE unsigned char *raw_tga_read8(unsigned char *b, int w, ALLEGRO_FILE *f) { return b + al_fread(f, b, w); } /* rle_tga_read8: * Helper for reading 256-color RLE data from TGA files. */ static void rle_tga_read8(unsigned char *b, int w, ALLEGRO_FILE *f) { int value, count, c = 0; do { count = al_fgetc(f); if (count & 0x80) { /* run-length packet */ count = (count & 0x7F) + 1; c += count; value = al_fgetc(f); while (count--) *b++ = value; } else { /* raw packet */ count++; c += count; b = raw_tga_read8(b, count, f); } } while (c < w); } /* single_tga_read32: * Helper for reading a single 32-bit data from TGA files. */ static INLINE int32_t single_tga_read32(ALLEGRO_FILE *f) { return al_fread32le(f); } /* raw_tga_read32: * Helper for reading 32-bit raw data from TGA files. */ static unsigned int *raw_tga_read32(unsigned int *b, int w, ALLEGRO_FILE *f) { while (w--) *b++ = single_tga_read32(f); return b; } /* rle_tga_read32: * Helper for reading 32-bit RLE data from TGA files. */ static void rle_tga_read32(unsigned int *b, int w, ALLEGRO_FILE *f) { int color, count, c = 0; do { count = al_fgetc(f); if (count & 0x80) { /* run-length packet */ count = (count & 0x7F) + 1; c += count; color = single_tga_read32(f); while (count--) *b++ = color; } else { /* raw packet */ count++; c += count; b = raw_tga_read32(b, count, f); } } while (c < w); } /* single_tga_read24: * Helper for reading a single 24-bit data from TGA files. */ static INLINE void single_tga_read24(ALLEGRO_FILE *f, unsigned char color[3]) { al_fread(f, color, 3); } /* raw_tga_read24: * Helper for reading 24-bit raw data from TGA files. */ static unsigned char *raw_tga_read24(unsigned char *b, int w, ALLEGRO_FILE *f) { while (w--) { single_tga_read24(f, b); b += 3; } return b; } /* rle_tga_read24: * Helper for reading 24-bit RLE data from TGA files. */ static void rle_tga_read24(unsigned char *b, int w, ALLEGRO_FILE *f) { int count, c = 0; unsigned char color[3]; do { count = al_fgetc(f); if (count & 0x80) { /* run-length packet */ count = (count & 0x7F) + 1; c += count; single_tga_read24(f, color); while (count--) { b[0] = color[0]; b[1] = color[1]; b[2] = color[2]; b += 3; } } else { /* raw packet */ count++; c += count; b = raw_tga_read24(b, count, f); } } while (c < w); } /* single_tga_read16: * Helper for reading a single 16-bit data from TGA files. */ static INLINE int single_tga_read16(ALLEGRO_FILE *f) { return al_fread16le(f); } /* raw_tga_read16: * Helper for reading 16-bit raw data from TGA files. */ static unsigned short *raw_tga_read16(unsigned short *b, int w, ALLEGRO_FILE *f) { while (w--) *b++ = single_tga_read16(f); return b; } /* rle_tga_read16: * Helper for reading 16-bit RLE data from TGA files. */ static void rle_tga_read16(unsigned short *b, int w, ALLEGRO_FILE *f) { int color, count, c = 0; do { count = al_fgetc(f); if (count & 0x80) { /* run-length packet */ count = (count & 0x7F) + 1; c += count; color = single_tga_read16(f); while (count--) *b++ = color; } else { /* raw packet */ count++; c += count; b = raw_tga_read16(b, count, f); } } while (c < w); } /* Like load_tga, but starts loading from the current place in the ALLEGRO_FILE * specified. If successful the offset into the file will be left just after * the image data. If unsuccessful the offset into the file is unspecified, * i.e. you must either reset the offset to some known place or close the * packfile. The packfile is not closed by this function. */ ALLEGRO_BITMAP *_al_load_tga_f(ALLEGRO_FILE *f) { unsigned char image_id[256], image_palette[256][3]; unsigned char id_length, palette_type, image_type, palette_entry_size; unsigned char bpp, descriptor_bits; short unsigned int palette_colors; short unsigned int image_width, image_height; bool left_to_right; bool top_to_bottom; unsigned int c, i; int y; int compressed; ALLEGRO_BITMAP *bmp; ALLEGRO_LOCKED_REGION *lr; unsigned char *buf; bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); ASSERT(f); id_length = al_fgetc(f); palette_type = al_fgetc(f); image_type = al_fgetc(f); al_fread16le(f); /* first_color */ palette_colors = al_fread16le(f); palette_entry_size = al_fgetc(f); al_fread16le(f); /* left */ al_fread16le(f); /* top */ image_width = al_fread16le(f); image_height = al_fread16le(f); bpp = al_fgetc(f); descriptor_bits = al_fgetc(f); left_to_right = !(descriptor_bits & (1 << 4)); top_to_bottom = (descriptor_bits & (1 << 5)); al_fread(f, image_id, id_length); if (palette_type == 1) { for (i = 0; i < palette_colors; i++) { switch (palette_entry_size) { case 16: c = al_fread16le(f); image_palette[i][0] = (c & 0x1F) << 3; image_palette[i][1] = ((c >> 5) & 0x1F) << 3; image_palette[i][2] = ((c >> 10) & 0x1F) << 3; break; case 24: case 32: image_palette[i][0] = al_fgetc(f); image_palette[i][1] = al_fgetc(f); image_palette[i][2] = al_fgetc(f); if (palette_entry_size == 32) al_fgetc(f); break; } } } else if (palette_type != 0) { return NULL; } /* Image type: * 0 = no image data * 1 = uncompressed color mapped * 2 = uncompressed true color * 3 = grayscale * 9 = RLE color mapped * 10 = RLE true color * 11 = RLE grayscale */ compressed = (image_type & 8); image_type &= 7; if ((image_type < 1) || (image_type > 3)) { return NULL; } switch (image_type) { case 1: /* paletted image */ if ((palette_type != 1) || (bpp != 8)) { return NULL; } break; case 2: /* truecolor image */ if ((palette_type == 0) && ((bpp == 15) || (bpp == 16))) { bpp = 15; } else if ((palette_type == 0) && ((bpp == 24) || (bpp == 32))) { } else { return NULL; } break; case 3: /* grayscale image */ if ((palette_type != 0) || (bpp != 8)) { return NULL; } for (i=0; i<256; i++) { image_palette[i][0] = i; image_palette[i][1] = i; image_palette[i][2] = i; } break; default: return NULL; } bmp = al_create_bitmap(image_width, image_height); if (!bmp) { return NULL; } al_set_errno(0); lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); if (!lr) { al_destroy_bitmap(bmp); return NULL; } /* bpp + 1 accounts for 15 bpp. */ buf = al_malloc(image_width * ((bpp + 1) / 8)); if (!buf) { al_unlock_bitmap(bmp); al_destroy_bitmap(bmp); return NULL; } for (y = 0; y < image_height; y++) { int true_y = (top_to_bottom) ? y : (image_height - 1 - y); switch (image_type) { case 1: case 3: if (compressed) rle_tga_read8(buf, image_width, f); else raw_tga_read8(buf, image_width, f); for (i = 0; i < image_width; i++) { int true_x = (left_to_right) ? i : (image_width - 1 - i); int pix = buf[i]; unsigned char *dest = (unsigned char *)lr->data + lr->pitch*true_y + true_x*4; dest[0] = image_palette[pix][2]; dest[1] = image_palette[pix][1]; dest[2] = image_palette[pix][0]; dest[3] = 255; } break; case 2: if (bpp == 32) { if (compressed) rle_tga_read32((unsigned int *)buf, image_width, f); else raw_tga_read32((unsigned int *)buf, image_width, f); for (i = 0; i < image_width; i++) { int true_x = (left_to_right) ? i : (image_width - 1 - i); unsigned char *dest = (unsigned char *)lr->data + lr->pitch*true_y + true_x*4; #ifdef ALLEGRO_BIG_ENDIAN int a = buf[i * 4 + 0]; int r = buf[i * 4 + 1]; int g = buf[i * 4 + 2]; int b = buf[i * 4 + 3]; #else int b = buf[i * 4 + 0]; int g = buf[i * 4 + 1]; int r = buf[i * 4 + 2]; int a = buf[i * 4 + 3]; #endif if (premul) { r = r * a / 255; g = g * a / 255; b = b * a / 255; } dest[0] = r; dest[1] = g; dest[2] = b; dest[3] = a; } } else if (bpp == 24) { if (compressed) rle_tga_read24(buf, image_width, f); else raw_tga_read24(buf, image_width, f); for (i = 0; i < image_width; i++) { int true_x = (left_to_right) ? i : (image_width - 1 - i); int b = buf[i * 3 + 0]; int g = buf[i * 3 + 1]; int r = buf[i * 3 + 2]; unsigned char *dest = (unsigned char *)lr->data + lr->pitch*true_y + true_x*4; dest[0] = r; dest[1] = g; dest[2] = b; dest[3] = 255; } } else { if (compressed) rle_tga_read16((unsigned short *)buf, image_width, f); else raw_tga_read16((unsigned short *)buf, image_width, f); for (i = 0; i < image_width; i++) { int true_x = (left_to_right) ? i : (image_width - 1 - i); int pix = *((unsigned short *)(buf + i * 2)); int r = _al_rgb_scale_5[(pix >> 10)]; int g = _al_rgb_scale_5[(pix >> 5) & 0x1F]; int b = _al_rgb_scale_5[(pix & 0x1F)]; unsigned char *dest = (unsigned char *)lr->data + lr->pitch*true_y + true_x*4; dest[0] = r; dest[1] = g; dest[2] = b; dest[3] = 255; } } break; } } al_free(buf); al_unlock_bitmap(bmp); if (al_get_errno()) { al_destroy_bitmap(bmp); return NULL; } return bmp; } /* Like save_tga but writes into the ALLEGRO_FILE given instead of a new file. * The packfile is not closed after writing is completed. On success the * offset into the file is left after the TGA file just written. On failure * the offset is left at the end of whatever incomplete data was written. */ bool _al_save_tga_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { int x, y; int w, h; ASSERT(f); ASSERT(bmp); al_set_errno(0); w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); al_fputc(f, 0); /* id length (no id saved) */ al_fputc(f, 0); /* palette type */ al_fputc(f, 2); /* image type */ al_fwrite16le(f, 0); /* first colour */ al_fwrite16le(f, 0); /* number of colours */ al_fputc(f, 0); /* palette entry size */ al_fwrite16le(f, 0); /* left */ al_fwrite16le(f, 0); /* top */ al_fwrite16le(f, w); /* width */ al_fwrite16le(f, h); /* height */ al_fputc(f, 32); /* bits per pixel */ al_fputc(f, 8); /* descriptor (bottom to top, 8-bit alpha) */ al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); for (y = h - 1; y >= 0; y--) { for (x = 0; x < w; x++) { ALLEGRO_COLOR c = al_get_pixel(bmp, x, y); unsigned char r, g, b, a; al_unmap_rgba(c, &r, &g, &b, &a); al_fputc(f, b); al_fputc(f, g); al_fputc(f, r); al_fputc(f, a); } } al_unlock_bitmap(bmp); return al_get_errno() ? false : true; } ALLEGRO_BITMAP *_al_load_tga(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_BITMAP *bmp; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; bmp = _al_load_tga_f(f); al_fclose(f); return bmp; } bool _al_save_tga(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *f; bool ret; ASSERT(filename); f = al_fopen(filename, "wb"); if (!f) return false; ret = _al_save_tga_f(f, bmp); al_fclose(f); return ret; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/gdiplus.cpp0000644000175000001440000002662212130233035017113 0ustar tjadenusers#include #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_convert.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" #ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H #include #else #include #endif /* Needed with the MinGW w32api-3.15 headers. */ using namespace Gdiplus; #ifndef _MSC_VER #define __uuidof(x) (IID_ ## x) #endif static bool gdiplus_inited = false; static ULONG_PTR gdiplusToken = 0; /* Source: * http://msdn.microsoft.com/en-us/library/ms533843%28VS.85%29.aspx */ static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; Gdiplus::GetImageEncodersSize(&num, &size); if (size == 0) { return -1; } pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(al_malloc(size)); if (pImageCodecInfo == NULL) { return -1; } GetImageEncoders(num, size, pImageCodecInfo); for (UINT j = 0; j < num; ++j) { if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0) { *pClsid = pImageCodecInfo[j].Clsid; al_free(pImageCodecInfo); return j; } } al_free(pImageCodecInfo); return -1; } /* A wrapper around an already opened ALLEGRO_FILE* pointer */ class AllegroWindowsStream : public IStream { long refCount; ALLEGRO_FILE *fp; public: /* Create a stream from an open file handle */ AllegroWindowsStream(ALLEGRO_FILE *fp) : refCount(1), fp(fp) { this->fp = fp; } virtual ~AllegroWindowsStream() { } /* IUnknown */ virtual ULONG STDMETHODCALLTYPE AddRef(void) { return (ULONG) InterlockedIncrement(&refCount); } virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) { if (iid == __uuidof(IUnknown) || iid == __uuidof(ISequentialStream) || iid == __uuidof(IStream)) { *ppvObject = static_cast(this); AddRef(); return S_OK; } else { return E_NOINTERFACE; } } virtual ULONG STDMETHODCALLTYPE Release(void) { ULONG ret = InterlockedDecrement(&refCount); if (ret == 0) { delete this; return 0; } return ret; } /* ISequentialStream */ virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead) { size_t read = al_fread(fp, pv, cb); if (pcbRead) { *pcbRead = read; } return read == cb ? S_OK : S_FALSE; } virtual HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten) { size_t written = al_fwrite(fp, pv, cb); if (pcbWritten) { *pcbWritten = written; } return written == cb ? S_OK : STG_E_CANTSAVE; } /* IStream */ virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { ALLEGRO_SEEK o; if (dwOrigin == STREAM_SEEK_SET) { o = ALLEGRO_SEEK_SET; } else if (dwOrigin == STREAM_SEEK_CUR) { o = ALLEGRO_SEEK_CUR; } else { o = ALLEGRO_SEEK_END; } bool ret = al_fseek(fp, dlibMove.QuadPart, o); if (plibNewPosition) { int64_t pos = al_ftell(fp); if (pos == -1) { return STG_E_INVALIDFUNCTION; } plibNewPosition->QuadPart = pos; } return ret ? S_OK : STG_E_INVALIDFUNCTION; } /* The GDI+ image I/O methods need to know the file size */ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag) { (void) grfStatFlag; memset(pstatstg, 0, sizeof(*pstatstg)); pstatstg->type = STGTY_STREAM; pstatstg->cbSize.QuadPart = al_fsize(fp); return S_OK; } /* The following IStream methods aren't needed */ virtual HRESULT STDMETHODCALLTYPE Clone(IStream **ppstm) { (void) ppstm; return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags) { (void) grfCommitFlags; return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE CopyTo (IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) { (void) pstm; (void) cb; (void) pcbRead; (void) pcbWritten; return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { (void) libOffset; (void) cb; (void) dwLockType; return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE Revert() { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize) { (void) libNewSize; return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { (void) libOffset; (void) cb; (void) dwLockType; return E_NOTIMPL; } }; static void load_non_indexed_data(Gdiplus::Bitmap *gdi_bmp, ALLEGRO_BITMAP *a_bmp, uint32_t w, uint32_t h, bool premul) { Gdiplus::BitmapData *gdi_lock = new Gdiplus::BitmapData(); Gdiplus::Rect rect(0, 0, w, h); if (!gdi_bmp->LockBits(&rect, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, gdi_lock)) { ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap(a_bmp, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY); if (a_lock) { unsigned char *in = (unsigned char *)gdi_lock->Scan0; unsigned char *out = (unsigned char *)a_lock->data; if (premul) { int in_inc = gdi_lock->Stride - (w*4); int out_inc = a_lock->pitch - (w*4); for (unsigned int y = 0; y < h; y++) { for (unsigned int x = 0; x < w; x++) { unsigned char r, g, b, a; b = *in++; g = *in++; r = *in++; a = *in++; b = b * a / 255; g = g * a / 255; r = r * a / 255; *out++ = b; *out++ = g; *out++ = r; *out++ = a; } in += in_inc; out += out_inc; } } else { if (gdi_lock->Stride == a_lock->pitch) { memcpy(out, in, h * gdi_lock->Stride); } else { uint32_t rows = h; while (rows--) { memcpy(out, in, w * 4); in += gdi_lock->Stride; out += a_lock->pitch; } } } al_unlock_bitmap(a_bmp); } gdi_bmp->UnlockBits(gdi_lock); } delete gdi_lock; } ALLEGRO_BITMAP *_al_load_gdiplus_bitmap_f(ALLEGRO_FILE *fp) { AllegroWindowsStream *s = new AllegroWindowsStream(fp); if (!s) { return NULL; } ALLEGRO_BITMAP *a_bmp = NULL; Gdiplus::Bitmap *gdi_bmp = Gdiplus::Bitmap::FromStream(s, false); if (gdi_bmp) { const uint32_t w = gdi_bmp->GetWidth(); const uint32_t h = gdi_bmp->GetHeight(); bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); a_bmp = al_create_bitmap(w, h); if (a_bmp) { load_non_indexed_data(gdi_bmp, a_bmp, w, h, premul); } delete gdi_bmp; } s->Release(); return a_bmp; } ALLEGRO_BITMAP *_al_load_gdiplus_bitmap(const char *filename) { ALLEGRO_BITMAP *bmp = NULL; ALLEGRO_FILE *fp; fp = al_fopen(filename, "rb"); if (fp) { bmp = _al_load_gdiplus_bitmap_f(fp); al_fclose(fp); } return bmp; } bool _al_save_gdiplus_bitmap_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_BITMAP *a_bmp) { CLSID encoder; int encoder_status = -1; if (!strcmp(ident, ".bmp")) { encoder_status = GetEncoderClsid(L"image/bmp", &encoder); } else if (!strcmp(ident, ".jpg") || !strcmp(ident, ".jpeg")) { encoder_status = GetEncoderClsid(L"image/jpeg", &encoder); } else if (!strcmp(ident, ".gif")) { encoder_status = GetEncoderClsid(L"image/gif", &encoder); } else if (!strcmp(ident, ".tif") || !strcmp(ident, ".tiff")) { encoder_status = GetEncoderClsid(L"image/tiff", &encoder); } else if (!strcmp(ident, ".png")) { encoder_status = GetEncoderClsid(L"image/png", &encoder); } if (encoder_status == -1) { return false; } AllegroWindowsStream *s = new AllegroWindowsStream(fp); if (!s) { return false; } const int w = al_get_bitmap_width(a_bmp), h = al_get_bitmap_height(a_bmp); bool ret = false; Gdiplus::Bitmap *gdi_bmp = new Gdiplus::Bitmap(w, h, PixelFormat32bppARGB); if (gdi_bmp) { Gdiplus::Rect rect(0, 0, w, h); Gdiplus::BitmapData *gdi_lock = new Gdiplus::BitmapData(); if (!gdi_bmp->LockBits(&rect, Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, gdi_lock)) { ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap( a_bmp, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_READONLY); if (a_lock) { unsigned char *in = (unsigned char *)a_lock->data; unsigned char *out = (unsigned char *)gdi_lock->Scan0; if (gdi_lock->Stride == a_lock->pitch) { memcpy(out, in, h * gdi_lock->Stride); } else { uint32_t rows = h; while (rows--) { memcpy(out, in, w * 4); in += a_lock->pitch; out += gdi_lock->Stride; } } al_unlock_bitmap(a_bmp); } gdi_bmp->UnlockBits(gdi_lock); } ret = (gdi_bmp->Save(s, &encoder, NULL) == 0); delete gdi_lock; delete gdi_bmp; } s->Release(); return ret; } bool _al_save_gdiplus_bitmap(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *fp; bool ret = false; fp = al_fopen(filename, "wb"); if (fp) { ALLEGRO_PATH *path = al_create_path(filename); if (path) { ret = _al_save_gdiplus_bitmap_f(fp, al_get_path_extension(path), bmp); al_destroy_path(path); } al_fclose(fp); } return ret; } bool _al_save_gdiplus_png_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_save_gdiplus_bitmap_f(f, ".png", bmp); } bool _al_save_gdiplus_jpg_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_save_gdiplus_bitmap_f(f, ".jpg", bmp); } bool _al_save_gdiplus_tif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_save_gdiplus_bitmap_f(f, ".tif", bmp); } bool _al_save_gdiplus_gif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { return _al_save_gdiplus_bitmap_f(f, ".gif", bmp); } bool _al_init_gdiplus() { if (!gdiplus_inited) { Gdiplus::GdiplusStartupInput gdiplusStartupInput; if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Gdiplus::Ok) { gdiplus_inited = TRUE; _al_add_exit_func(_al_shutdown_gdiplus, "_al_shutdown_gdiplus"); } } return gdiplus_inited; } void _al_shutdown_gdiplus() { if (gdiplus_inited) { Gdiplus::GdiplusShutdown(gdiplusToken); gdiplus_inited = false; } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/allegro5/0000755000175000001440000000000012157230737016461 5ustar tjadenusersallegro-5.0.10/addons/image/allegro5/allegro_image.h0000644000175000001440000000207111426530515021414 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_image_h #define __al_included_allegro5_allegro_image_h #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_IIO_SRC #define _ALLEGRO_IIO_DLL __declspec(dllexport) #else #define _ALLEGRO_IIO_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_IIO_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_IIO_FUNC(type, name, args) _ALLEGRO_IIO_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_IIO_FUNC(type, name, args) extern type name args #elif defined ALLEGRO_BCC32 #define ALLEGRO_IIO_FUNC(type, name, args) extern _ALLEGRO_IIO_DLL type name args #else #define ALLEGRO_IIO_FUNC AL_FUNC #endif #ifdef __cplusplus extern "C" { #endif ALLEGRO_IIO_FUNC(bool, al_init_image_addon, (void)); ALLEGRO_IIO_FUNC(void, al_shutdown_image_addon, (void)); ALLEGRO_IIO_FUNC(uint32_t, al_get_allegro_image_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/image/allegro5/internal/0000755000175000001440000000000012157230737020275 5ustar tjadenusersallegro-5.0.10/addons/image/allegro5/internal/aintern_image_cfg.h.cmake0000644000175000001440000000061611534666374025161 0ustar tjadenusers#cmakedefine ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER /* which libraries are present and needed? */ #cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS #cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H #cmakedefine ALLEGRO_CFG_IIO_HAVE_PNG #cmakedefine ALLEGRO_CFG_IIO_HAVE_JPG /* which formats are supported and wanted? */ #cmakedefine ALLEGRO_CFG_IIO_SUPPORT_PNG #cmakedefine ALLEGRO_CFG_IIO_SUPPORT_JPG allegro-5.0.10/addons/image/allegro5/internal/aintern_image.h0000644000175000001440000000577411520366677023273 0ustar tjadenusers#ifndef __al_included_allegro_aintern_image_h #define __al_included_allegro_aintern_image_h #include "allegro5/platform/alplatf.h" #include "allegro5/internal/aintern_image_cfg.h" #ifdef __cplusplus extern "C" { #endif #ifdef ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER #ifdef ALLEGRO_IPHONE ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_iphone_load_image, (const char *filename)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_iphone_load_image_f, (ALLEGRO_FILE *f)); #endif #ifdef ALLEGRO_MACOSX ALLEGRO_IIO_FUNC(bool, _al_osx_register_image_loader, (void)); #endif #endif ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_pcx, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_pcx, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_pcx_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_pcx_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_bmp, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_bmp, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_bmp_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_bmp_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_tga, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_tga, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_tga_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_tga_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); #ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS ALLEGRO_IIO_FUNC(bool, _al_init_gdiplus, (void)); ALLEGRO_IIO_FUNC(void, _al_shutdown_gdiplus, (void)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_gdiplus_bitmap, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_bitmap, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_gdiplus_bitmap_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_png_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_jpg_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_tif_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_gif_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); #endif /* ALLEGRO_CFG_IIO_HAVE_PNG/JPG implies that "native" loaders aren't available. */ #ifdef ALLEGRO_CFG_IIO_HAVE_PNG ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_png, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_png, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_png_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_png_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); #endif #ifdef ALLEGRO_CFG_IIO_HAVE_JPG ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_jpg, (const char *filename)); ALLEGRO_IIO_FUNC(bool, _al_save_jpg, (const char *filename, ALLEGRO_BITMAP *bmp)); ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_jpg_f, (ALLEGRO_FILE *f)); ALLEGRO_IIO_FUNC(bool, _al_save_jpg_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); #endif #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/image/iio.h0000644000175000001440000000165411426530515015701 0ustar tjadenusers#ifndef __al_included_allegro5_iio_h #define __al_included_allegro5_iio_h #include "allegro5/internal/aintern_image_cfg.h" typedef struct PalEntry { int r, g, b, a; } PalEntry; /* FIXME: Not sure if these should be made accessible. Hide them for now. */ /* _al_png_screen_gamma is slightly overloaded (sorry): * * A value of 0.0 means: Don't do any gamma correction in load_png() * and load_memory_png(). This meaning was introduced in v1.4. * * A value of -1.0 means: Use the value from the environment variable * SCREEN_GAMMA (if available), otherwise fallback to a value of 2.2 * (a good guess for PC monitors, and the value for sRGB colourspace). * This is the default. * * Otherwise, the value of _al_png_screen_gamma is taken as-is. */ extern double _al_png_screen_gamma; /* Choose zlib compression level for saving file. * Default is Z_BEST_COMPRESSION. */ extern int _al_png_compression_level; #endif allegro-5.0.10/addons/image/jpg.c0000644000175000001440000002303711724540613015674 0ustar tjadenusers/* libjpeg wrapper for Allegro 5 iio addon. * by Elias Pschernig */ #include #include #include #ifdef ALLEGRO_HAVE_STDINT_H #include #endif #define BUFFER_SIZE 4096 #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" #include #include ALLEGRO_DEBUG_CHANNEL("image") struct my_src_mgr { struct jpeg_source_mgr pub; JOCTET *buffer; ALLEGRO_FILE *fp; }; struct my_dest_mgr { struct jpeg_destination_mgr pub; JOCTET *buffer; ALLEGRO_FILE *fp; }; struct my_err_mgr { struct jpeg_error_mgr pub; jmp_buf jmpenv; }; static void init_source(j_decompress_ptr cinfo) { (void)cinfo; } static void init_destination(j_compress_ptr cinfo) { struct my_dest_mgr *dest = (void *)cinfo->dest; dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = BUFFER_SIZE; } static boolean fill_input_buffer(j_decompress_ptr cinfo) { struct my_src_mgr *src = (void *)cinfo->src; src->pub.next_input_byte = src->buffer; src->pub.bytes_in_buffer = al_fread(src->fp, src->buffer, BUFFER_SIZE); return 1; } static boolean empty_output_buffer(j_compress_ptr cinfo) { struct my_dest_mgr *dest = (void *)cinfo->dest; al_fwrite(dest->fp, dest->buffer, BUFFER_SIZE); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = BUFFER_SIZE; return 1; } static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { struct my_src_mgr *src = (void *)cinfo->src; if (num_bytes <= (long)src->pub.bytes_in_buffer) { src->pub.next_input_byte += num_bytes; src->pub.bytes_in_buffer -= num_bytes; } else { long skip = num_bytes - src->pub.bytes_in_buffer; al_fseek(src->fp, skip, ALLEGRO_SEEK_CUR); src->pub.bytes_in_buffer = 0; } } static void term_source(j_decompress_ptr cinfo) { (void)cinfo; } static void term_destination(j_compress_ptr cinfo) { struct my_dest_mgr *dest = (void *)cinfo->dest; al_fwrite(dest->fp, dest->buffer, BUFFER_SIZE - dest->pub.free_in_buffer); } static void jpeg_packfile_src(j_decompress_ptr cinfo, ALLEGRO_FILE *fp, JOCTET *buffer) { struct my_src_mgr *src; if (!cinfo->src) cinfo->src = (*cinfo->mem->alloc_small) ((void *)cinfo, JPOOL_PERMANENT, sizeof *src); src = (void *)cinfo->src; src->pub.init_source = init_source; src->pub.fill_input_buffer = fill_input_buffer; src->pub.skip_input_data = skip_input_data; src->pub.resync_to_restart = jpeg_resync_to_restart; src->pub.term_source = term_source; src->pub.bytes_in_buffer = 0; src->buffer = buffer; src->fp = fp; } static void jpeg_packfile_dest(j_compress_ptr cinfo, ALLEGRO_FILE *fp, JOCTET *buffer) { struct my_dest_mgr *dest; if (!cinfo->dest) cinfo->dest = (*cinfo->mem->alloc_small) ((void *)cinfo, JPOOL_PERMANENT, sizeof *dest); dest = (void *)cinfo->dest; dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; dest->pub.free_in_buffer = 0; dest->buffer = buffer; dest->fp = fp; } static void my_error_exit(j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; struct my_err_mgr *jerr = (void *)cinfo->err; jerr->pub.format_message(cinfo, buffer); ALLEGRO_ERROR("jpeg error: %s\n", buffer); longjmp(jerr->jmpenv, 1); } /* We keep data for load_jpg_entry_helper in a structure allocated in the * caller's stack frame to avoid problems with automatic variables being * undefined after a longjmp. */ struct load_jpg_entry_helper_data { bool error; ALLEGRO_BITMAP *bmp; JOCTET *buffer; unsigned char *row; }; static void load_jpg_entry_helper(ALLEGRO_FILE *fp, struct load_jpg_entry_helper_data *data) { struct jpeg_decompress_struct cinfo; struct my_err_mgr jerr; ALLEGRO_LOCKED_REGION *lock; int w, h, s; data->error = false; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.jmpenv) != 0) { /* Longjmp'd. */ data->error = true; goto longjmp_error; } data->buffer = al_malloc(BUFFER_SIZE); if (!data->buffer) { data->error = true; goto error; } jpeg_create_decompress(&cinfo); jpeg_packfile_src(&cinfo, fp, data->buffer); jpeg_read_header(&cinfo, true); jpeg_start_decompress(&cinfo); w = cinfo.output_width; h = cinfo.output_height; s = cinfo.output_components; /* Only one and three components make sense in a JPG file. */ if (s != 1 && s != 3) { data->error = true; ALLEGRO_ERROR("%d components makes no sense\n", s); goto error; } data->bmp = al_create_bitmap(w, h); if (!data->bmp) { data->error = true; ALLEGRO_ERROR("%dx%d bitmap creation failed\n", w, h); goto error; } /* Allegro's pixel format is endian independent, so that in * ALLEGRO_PIXEL_FORMAT_RGB_888 the lower 8 bits always hold the Blue * component. On a little endian system this is in byte 0. On a big * endian system this is in byte 2. * * libjpeg expects byte 0 to hold the Red component, byte 1 to hold the * Green component, byte 2 to hold the Blue component. Hence on little * endian systems we need the opposite format, ALLEGRO_PIXEL_FORMAT_BGR_888. */ #ifdef ALLEGRO_BIG_ENDIAN lock = al_lock_bitmap(data->bmp, ALLEGRO_PIXEL_FORMAT_RGB_888, ALLEGRO_LOCK_WRITEONLY); #else lock = al_lock_bitmap(data->bmp, ALLEGRO_PIXEL_FORMAT_BGR_888, ALLEGRO_LOCK_WRITEONLY); #endif if (s == 3) { /* Colour. */ int y; for (y = cinfo.output_scanline; y < h; y = cinfo.output_scanline) { unsigned char *out[1]; out[0] = ((unsigned char *)lock->data) + y * lock->pitch; jpeg_read_scanlines(&cinfo, (void *)out, 1); } } else if (s == 1) { /* Greyscale. */ unsigned char *in; unsigned char *out; int x, y; data->row = al_malloc(w); for (y = cinfo.output_scanline; y < h; y = cinfo.output_scanline) { jpeg_read_scanlines(&cinfo, (void *)&data->row, 1); in = data->row; out = ((unsigned char *)lock->data) + y * lock->pitch; for (x = 0; x < w; x++) { *out++ = *in; *out++ = *in; *out++ = *in; in++; } } } error: jpeg_finish_decompress(&cinfo); longjmp_error: jpeg_destroy_decompress(&cinfo); if (data->bmp) { if (al_is_bitmap_locked(data->bmp)) { al_unlock_bitmap(data->bmp); } if (data->error) { al_destroy_bitmap(data->bmp); data->bmp = NULL; } } al_free(data->buffer); al_free(data->row); } ALLEGRO_BITMAP *_al_load_jpg_f(ALLEGRO_FILE *fp) { struct load_jpg_entry_helper_data data; memset(&data, 0, sizeof(data)); load_jpg_entry_helper(fp, &data); return data.bmp; } /* See comment about load_jpg_entry_helper_data. */ struct save_jpg_entry_helper_data { bool error; JOCTET *buffer; }; static void save_jpg_entry_helper(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp, struct save_jpg_entry_helper_data *data) { struct jpeg_compress_struct cinfo; struct my_err_mgr jerr; ALLEGRO_LOCKED_REGION *lock; data->error = false; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.jmpenv)) { /* Longjmp'd. */ data->error = true; goto longjmp_error; } data->buffer = al_malloc(BUFFER_SIZE); if (!data->buffer) { data->error = true; goto error; } jpeg_create_compress(&cinfo); jpeg_packfile_dest(&cinfo, fp, data->buffer); cinfo.image_width = al_get_bitmap_width(bmp); cinfo.image_height = al_get_bitmap_height(bmp); cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_start_compress(&cinfo, 1); /* See comment in load_jpg_entry_helper. */ #ifdef ALLEGRO_BIG_ENDIAN lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGB_888, ALLEGRO_LOCK_READONLY); #else lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_BGR_888, ALLEGRO_LOCK_READONLY); #endif while (cinfo.next_scanline < cinfo.image_height) { unsigned char *row[1]; row[0] = ((unsigned char *)lock->data) + (signed)cinfo.next_scanline * lock->pitch; jpeg_write_scanlines(&cinfo, (void *)row, 1); } error: jpeg_finish_compress(&cinfo); longjmp_error: jpeg_destroy_compress(&cinfo); if (al_is_bitmap_locked(bmp)) { al_unlock_bitmap(bmp); } al_free(data->buffer); } bool _al_save_jpg_f(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp) { struct save_jpg_entry_helper_data data; memset(&data, 0, sizeof(data)); save_jpg_entry_helper(fp, bmp, &data); return !data.error; } ALLEGRO_BITMAP *_al_load_jpg(char const *filename) { ALLEGRO_FILE *fp; ALLEGRO_BITMAP *bmp; ALLEGRO_ASSERT(filename); fp = al_fopen(filename, "rb"); if (!fp) return NULL; bmp = _al_load_jpg_f(fp); al_fclose(fp); return bmp; } bool _al_save_jpg(char const *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *fp; bool result; ALLEGRO_ASSERT(filename); ALLEGRO_ASSERT(bmp); fp = al_fopen(filename, "wb"); if (!fp) { ALLEGRO_ERROR("Unable to open file %s for writing\n", filename); return false; } result = _al_save_jpg_f(fp, bmp); al_fclose(fp); return result; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/iphone.m0000644000175000001440000000750211724540613016407 0ustar tjadenusers#import #import #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" static ALLEGRO_BITMAP *really_load_image(char *buffer, int size) { /* * FIXME: We might need a more proper way of doing this, since * it could be a problem if the user calls this function from * their own thread that already has an autorelease pool. But * I'm not sure. */ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_BITMAP *bmp = NULL; void *pixels = NULL; /* Note: buffer is now owned (and later freed) by the data object. */ NSData *nsdata = [NSData dataWithBytesNoCopy:buffer length:size]; UIImage *uiimage = [UIImage imageWithData:nsdata]; int w = uiimage.size.width; int h = uiimage.size.height; bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); /* Now we need to draw the image into a memory buffer. */ pixels = al_malloc(w * h * 4); CGFloat whitePoint[3] = { 1, 1, 1 }; CGFloat blackPoint[3] = { 0, 0, 0 }; CGFloat gamma[3] = { 2.2, 2.2, 2.2 }; CGFloat matrix[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* This sets up a color space that results in identical values * as the image data itself, which is the same as the standalone * libpng loader */ CGColorSpaceRef cs = CGColorSpaceCreateCalibratedRGB( whitePoint, blackPoint, gamma, matrix ); CGContextRef context = CGBitmapContextCreate(pixels, w, h, 8, w * 4, cs, kCGImageAlphaPremultipliedLast); CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextDrawImage(context, CGRectMake(0.0, 0.0, (CGFloat)w, (CGFloat)h), uiimage.CGImage); CGContextRelease(context); CGColorSpaceRelease(cs); /* Then create a bitmap out of the memory buffer. */ bmp = al_create_bitmap(w, h); if (!bmp) goto done; ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_WRITEONLY); if (!premul) { for (int i = 0; i < h; i++) { unsigned char *src_ptr = (unsigned char *)pixels + w * 4 * i; unsigned char *dest_ptr = (unsigned char *)lock->data + lock->pitch * i; for (int x = 0; x < w; x++) { unsigned char r, g, b, a; r = *src_ptr++; g = *src_ptr++; b = *src_ptr++; a = *src_ptr++; // NOTE: avoid divide by zero by adding a fraction float alpha_mul = 255.0f / (a+0.001f); r *= alpha_mul; g *= alpha_mul; b *= alpha_mul; *dest_ptr++ = r; *dest_ptr++ = g; *dest_ptr++ = b; *dest_ptr++ = a; } } } else { for (int i = 0; i < h; i++) { memcpy(lock->data + lock->pitch * i, pixels + w * 4 * i, w * 4); } } al_unlock_bitmap(bmp); done: al_free(pixels); [pool release]; return bmp; } ALLEGRO_BITMAP *_al_iphone_load_image_f(ALLEGRO_FILE *f) { ALLEGRO_BITMAP *bmp; ALLEGRO_ASSERT(f); int64_t size = al_fsize(f); if (size <= 0) { // TODO: Read from stream until we have the whole image return NULL; } /* Note: This *MUST* be the Apple malloc and not any wrapper, as the * buffer will be owned and freed by the NSData object not us. */ void *buffer = al_malloc(size); al_fread(f, buffer, size); /* Really load the image now. */ bmp = really_load_image(buffer, size); return bmp; } ALLEGRO_BITMAP *_al_iphone_load_image(const char *filename) { ALLEGRO_FILE *fp; ALLEGRO_BITMAP *bmp; ALLEGRO_ASSERT(filename); fp = al_fopen(filename, "rb"); if (!fp) return NULL; bmp = _al_iphone_load_image_f(fp); al_fclose(fp); return bmp; } allegro-5.0.10/addons/image/bmp.c0000644000175000001440000007265011771527222015702 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * BMP reader. * * By Seymour Shlien. * * OS/2 BMP support and BMP save function by Jonas Petersen. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_convert.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" ALLEGRO_DEBUG_CHANNEL("image") #define BIT_RGB 0 #define BIT_RLE8 1 #define BIT_RLE4 2 #define BIT_BITFIELDS 3 #define OS2INFOHEADERSIZE 12 #define WININFOHEADERSIZE 40 #define WININFOHEADERSIZEV2 52 #define WININFOHEADERSIZEV3 56 #define WININFOHEADERSIZEV4 108 #define WININFOHEADERSIZEV5 124 typedef struct BMPFILEHEADER { unsigned long bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; } BMPFILEHEADER; /* Used for both OS/2 and Windows BMP. * Contains only the parameters needed to load the image */ typedef struct BMPINFOHEADER { unsigned long biWidth; signed long biHeight; unsigned short biBitCount; unsigned long biCompression; unsigned long biClrUsed; bool biHaveAlphaMask; uint32_t biAlphaMask; } BMPINFOHEADER; typedef struct WINBMPINFOHEADER { /* size: 40 */ unsigned long biWidth; signed long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; unsigned long biXPelsPerMeter; unsigned long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; } WINBMPINFOHEADER; typedef struct OS2BMPINFOHEADER { /* size: 12 */ unsigned short biWidth; unsigned short biHeight; unsigned short biPlanes; unsigned short biBitCount; } OS2BMPINFOHEADER; /* read_bmfileheader: * Reads a BMP file header and check that it has the BMP magic number. */ static int read_bmfileheader(ALLEGRO_FILE *f, BMPFILEHEADER *fileheader) { fileheader->bfType = al_fread16le(f); fileheader->bfSize = al_fread32le(f); fileheader->bfReserved1 = al_fread16le(f); fileheader->bfReserved2 = al_fread16le(f); fileheader->bfOffBits = al_fread32le(f); if (fileheader->bfType != 19778) { ALLEGRO_ERROR("Not BMP format\n"); return -1; } if (al_feof(f) || al_ferror(f)) { ALLEGRO_ERROR("Failed to read file header\n"); return -1; } return 0; } /* read_win_bminfoheader: * Reads information from a BMP file header. */ static int read_win_bminfoheader(ALLEGRO_FILE *f, BMPINFOHEADER *infoheader) { WINBMPINFOHEADER win_infoheader; win_infoheader.biWidth = al_fread32le(f); win_infoheader.biHeight = al_fread32le(f); win_infoheader.biPlanes = al_fread16le(f); win_infoheader.biBitCount = al_fread16le(f); win_infoheader.biCompression = al_fread32le(f); win_infoheader.biSizeImage = al_fread32le(f); win_infoheader.biXPelsPerMeter = al_fread32le(f); win_infoheader.biYPelsPerMeter = al_fread32le(f); win_infoheader.biClrUsed = al_fread32le(f); win_infoheader.biClrImportant = al_fread32le(f); infoheader->biWidth = win_infoheader.biWidth; infoheader->biHeight = win_infoheader.biHeight; infoheader->biBitCount = win_infoheader.biBitCount; infoheader->biCompression = win_infoheader.biCompression; infoheader->biClrUsed = win_infoheader.biClrUsed; if (al_feof(f) || al_ferror(f)) { ALLEGRO_ERROR("Failed to read file header\n"); return -1; } return 0; } /* read_os2_bminfoheader: * Reads information from an OS/2 format BMP file header. */ static int read_os2_bminfoheader(ALLEGRO_FILE *f, BMPINFOHEADER *infoheader) { OS2BMPINFOHEADER os2_infoheader; os2_infoheader.biWidth = al_fread16le(f); os2_infoheader.biHeight = al_fread16le(f); os2_infoheader.biPlanes = al_fread16le(f); os2_infoheader.biBitCount = al_fread16le(f); infoheader->biWidth = os2_infoheader.biWidth; infoheader->biHeight = os2_infoheader.biHeight; infoheader->biBitCount = os2_infoheader.biBitCount; infoheader->biCompression = BIT_RGB; infoheader->biClrUsed = 0; /* default */ if (al_feof(f) || al_ferror(f)) { ALLEGRO_ERROR("Failed to read file header\n"); return -1; } return 0; } /* read_palette: * Loads the color palette for 1,4,8 bit formats. * OS/2 bitmaps take 3 bytes per color. * Windows bitmaps take 4 bytes per color. */ static void read_palette(int ncolors, PalEntry *pal, ALLEGRO_FILE *f, int win_flag) { int i; for (i = 0; i < ncolors; i++) { pal[i].b = al_fgetc(f); pal[i].g = al_fgetc(f); pal[i].r = al_fgetc(f); if (win_flag) { al_fgetc(f); } } } /* read_1bit_line: * Support function for reading the 1 bit bitmap file format. */ static void read_1bit_line(int length, ALLEGRO_FILE *f, unsigned char *buf) { unsigned char b[32]; unsigned long n; int i, j, k; for (i = 0; i < length; i++) { j = i % 32; if (j == 0) { n = al_fread32be(f); for (k = 0; k < 32; k++) { b[31 - k] = (char)(n & 1); n = n >> 1; } } buf[i] = b[j]; } } /* read_4bit_line: * Support function for reading the 4 bit bitmap file format. */ static void read_4bit_line(int length, ALLEGRO_FILE *f, unsigned char *buf) { unsigned char b[8]; unsigned long n; int i, j, k; int temp; for (i = 0; i < length; i++) { j = i % 8; if (j == 0) { n = al_fread32le(f); for (k = 0; k < 4; k++) { temp = n & 255; b[k * 2 + 1] = temp & 15; temp = temp >> 4; b[k * 2] = temp & 15; n = n >> 8; } } buf[i] = b[j]; } } /* read_8bit_line: * Support function for reading the 8 bit bitmap file format. */ static void read_8bit_line(int length, ALLEGRO_FILE *f, unsigned char *buf) { unsigned char b[4]; unsigned long n; int i, j, k; for (i = 0; i < length; i++) { j = i % 4; if (j == 0) { n = al_fread32le(f); for (k = 0; k < 4; k++) { b[k] = (char)(n & 255); n = n >> 8; } } buf[i] = b[j]; } } /* read_16bit_line: * Support function for reading the 16 bit bitmap file format, doing * our best to convert it down to a 256 color palette. */ static void read_16bit_line(int length, ALLEGRO_FILE *f, unsigned char *data) { int i, w; unsigned char r, g, b; for (i = 0; i < length; i++) { w = al_fread16le(f); /* the format is like a 15-bpp bitmap, not 16bpp */ r = _al_rgb_scale_5[(w >> 10) & 0x1f]; g = _al_rgb_scale_5[(w >> 5) & 0x1f]; b = _al_rgb_scale_5[w & 0x1f]; data[0] = r; data[1] = g; data[2] = b; data[3] = 255; data += 4; } /* padding */ i = (i * 2) % 4; if (i != 0) { while (i++ < 4) al_fgetc(f); } } /* read_24bit_line: * Support function for reading the 24 bit bitmap file format. */ static void read_24bit_line(int length, ALLEGRO_FILE *f, unsigned char *data) { int i; unsigned char c[3]; unsigned char r, g, b; for (i = 0; i < length; i++) { al_fread(f, c, 3); r = c[2]; g = c[1]; b = c[0]; data[0] = r; data[1] = g; data[2] = b; data[3] = 255; data += 4; } /* padding */ i = (i * 3) % 4; if (i != 0) { while (i++ < 4) al_fgetc(f); } } /* read_32bit_line: * Support function for reading the 32 bit bitmap file format, * treating fourth byte as alpha. */ static void read_32bit_line(int length, ALLEGRO_FILE *f, unsigned char *data) { int i; unsigned char c[4]; unsigned char r, g, b, a; bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); for (i = 0; i < length; i++) { al_fread(f, c, 4); r = c[2]; g = c[1]; b = c[0]; a = c[3]; if (premul) { r = r * a / 255; g = g * a / 255; b = b * a / 255; } data[0] = r; data[1] = g; data[2] = b; data[3] = a; data += 4; } } /* read_bitfields_image: * For reading the bitfield compressed BMP image format. */ static void read_bitfields_image(ALLEGRO_FILE *f, const BMPINFOHEADER *infoheader, int bpp, ALLEGRO_LOCKED_REGION *lr) { int k, i, line, height, dir; int bytes_per_pixel; unsigned long buffer; int pix; height = infoheader->biHeight; line = height < 0 ? 0 : height - 1; dir = height < 0 ? 1 : -1; height = abs(height); bytes_per_pixel = (bpp + 1) / 8; for (i = 0; i < height; i++, line += dir) { unsigned char *data = (unsigned char *)lr->data + lr->pitch * line; for (k = 0; k < (int)infoheader->biWidth; k++) { al_fread(f, &buffer, bytes_per_pixel); if (bpp == 15) { if (infoheader->biAlphaMask == 0x8000) { pix = ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_8888(buffer); } else { pix = ALLEGRO_CONVERT_RGB_555_TO_ARGB_8888(buffer); } } else if (bpp == 16) { pix = ALLEGRO_CONVERT_RGB_565_TO_ARGB_8888(buffer); } else { if (infoheader->biAlphaMask == 0xFF000000) { pix = buffer; } else { pix = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_8888(buffer); } } data[2] = pix & 255; data[1] = (pix >> 8) & 255; data[0] = (pix >> 16) & 255; data[3] = (pix >> 24) & 255; data += 4; } /* padding */ k = (k * bytes_per_pixel) % 4; if (k > 0) { while (k++ < 4) al_fgetc(f); } } } /* read_RGB_image: * For reading the non-compressed BMP image format (all except 32-bit with * alpha hack). */ static void read_RGB_image(ALLEGRO_FILE *f, const BMPINFOHEADER *infoheader, PalEntry *pal, ALLEGRO_LOCKED_REGION *lr) { int i, j, line, height, dir; unsigned char *buf; unsigned char *data; height = infoheader->biHeight; line = height < 0 ? 0 : height - 1; dir = height < 0 ? 1 : -1; height = abs(height); buf = al_malloc(infoheader->biWidth); for (i = 0; i < height; i++, line += dir) { data = (unsigned char *)lr->data + lr->pitch * line; switch (infoheader->biBitCount) { case 1: read_1bit_line(infoheader->biWidth, f, buf); break; case 4: read_4bit_line(infoheader->biWidth, f, buf); break; case 8: read_8bit_line(infoheader->biWidth, f, buf); break; case 16: read_16bit_line(infoheader->biWidth, f, data); break; case 24: read_24bit_line(infoheader->biWidth, f, data); break; case 32: read_32bit_line(infoheader->biWidth, f, data); break; } if (infoheader->biBitCount <= 8) { for (j = 0; j < (int)infoheader->biWidth; j++) { data[0] = pal[buf[j]].r; data[1] = pal[buf[j]].g; data[2] = pal[buf[j]].b; data[3] = 255; data += 4; } } } al_free(buf); } /* read_RGB_image_32bit_alpha_hack: * For reading the non-compressed BMP image format (32-bit). * These are treatly specially because some programs put alpha information in * the fourth byte of each pixel, which is normally just padding (and zero). * We use a heuristic: if every pixel has zero in that fourth byte then assume * the whole image is opaque (a=255). Otherwise treat the fourth byte as an * alpha channel. * * Note that V3 headers include an alpha bit mask, which can properly indicate * the presence or absence of an alpha channel. * This hack is not required then. */ static void read_RGB_image_32bit_alpha_hack(ALLEGRO_FILE *f, const BMPINFOHEADER *infoheader, ALLEGRO_LOCKED_REGION *lr) { int i, j, line, height, dir; unsigned char *data; unsigned char r, g, b, a; unsigned char have_alpha = 0; const bool premul = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA); height = infoheader->biHeight; line = height < 0 ? 0 : height - 1; dir = height < 0 ? 1 : -1; height = abs(height); /* Read data. */ for (i = 0; i < height; i++, line += dir) { data = (unsigned char *)lr->data + lr->pitch * line; for (j = 0; j < (int)infoheader->biWidth; j++) { b = al_fgetc(f); g = al_fgetc(f); r = al_fgetc(f); a = al_fgetc(f); have_alpha |= a; data[0] = r; data[1] = g; data[2] = b; data[3] = a; data += 4; } } /* Fixup pass. */ if (!have_alpha) { for (i = 0; i < height; i++) { data = (unsigned char *)lr->data + lr->pitch * i; for (j = 0; j < (int)infoheader->biWidth; j++) { data[3] = 255; /* a */ data += 4; } } } else if (premul) { for (i = 0; i < height; i++) { data = (unsigned char *)lr->data + lr->pitch * i; for (j = 0; j < (int)infoheader->biWidth; j++) { r = data[0]; g = data[1]; b = data[2]; a = data[3]; r = r * a / 255; g = g * a / 255; b = b * a / 255; data[0] = r; data[1] = g; data[2] = b; data[3] = a; data += 4; } } } } /* read_RLE8_compressed_image: * For reading the 8 bit RLE compressed BMP image format. */ static void read_RLE8_compressed_image(ALLEGRO_FILE *f, unsigned char *buf, const BMPINFOHEADER *infoheader) { int count; unsigned char val; unsigned char val0; int j, pos, line, height, dir; int eolflag, eopicflag; eopicflag = 0; height = abs(infoheader->biHeight); line = (infoheader->biHeight < 0) ? 0 : height - 1; dir = (infoheader->biHeight < 0) ? 1 : -1; while (eopicflag == 0) { pos = 0; /* x position in bitmap */ eolflag = 0; /* end of line flag */ while ((eolflag == 0) && (eopicflag == 0)) { count = al_fgetc(f); if (count == EOF) return; if (pos + count > (int)infoheader->biWidth) { ALLEGRO_WARN("overlong compressed line\n"); count = infoheader->biWidth - pos; } val = al_fgetc(f); if (count > 0) { /* repeat pixel count times */ for (j = 0; j < count; j++) { buf[line * infoheader->biWidth + pos] = val; pos++; } } else { switch (val) { case 0: /* end of line flag */ eolflag = 1; break; case 1: /* end of picture flag */ eopicflag = 1; break; case 2: /* displace picture */ count = al_fgetc(f); if (count == EOF) return; val = al_fgetc(f); pos += count; line += dir * val; break; default: /* read in absolute mode */ for (j=0; jbiWidth + pos] = val0; pos++; } if (j % 2 == 1) val0 = al_fgetc(f); /* align on word boundary */ break; } } if (pos - 1 > (int)infoheader->biWidth) eolflag = 1; } line += dir; if (line < 0 || line >= height) eopicflag = 1; } } /* read_RLE4_compressed_image: * For reading the 4 bit RLE compressed BMP image format. */ static void read_RLE4_compressed_image(ALLEGRO_FILE *f, unsigned char *buf, const BMPINFOHEADER *infoheader) { unsigned char b[8]; int count; unsigned short val0, val; int j, k, pos, line, height, dir; int eolflag, eopicflag; eopicflag = 0; /* end of picture flag */ height = abs(infoheader->biHeight); line = (infoheader->biHeight < 0) ? 0 : height - 1; dir = (infoheader->biHeight < 0) ? 1 : -1; while (eopicflag == 0) { pos = 0; eolflag = 0; /* end of line flag */ while ((eolflag == 0) && (eopicflag == 0)) { count = al_fgetc(f); if (count == EOF) return; if (pos + count > (int)infoheader->biWidth) { ALLEGRO_WARN("overlong compressed line\n"); count = infoheader->biWidth - pos; } val = al_fgetc(f); if (count > 0) { /* repeat pixels count times */ b[1] = val & 15; b[0] = (val >> 4) & 15; for (j = 0; j < count; j++) { buf[line * infoheader->biWidth + pos] = b[j % 2]; pos++; } } else { switch (val) { case 0: /* end of line */ eolflag = 1; break; case 1: /* end of picture */ eopicflag = 1; break; case 2: /* displace image */ count = al_fgetc(f); if (count == EOF) return; val = al_fgetc(f); pos += count; line += dir * val; break; default: /* read in absolute mode */ for (j = 0; j < val; j++) { if ((j % 4) == 0) { val0 = al_fread16le(f); for (k = 0; k < 2; k++) { b[2 * k + 1] = val0 & 15; val0 = val0 >> 4; b[2 * k] = val0 & 15; val0 = val0 >> 4; } } buf[line * infoheader->biWidth + pos] = b[j % 4]; pos++; } break; } } if (pos - 1 > (int)infoheader->biWidth) eolflag = 1; } line += dir; if (line < 0 || line >= height) eopicflag = 1; } } /* alpha_mask_supported: * Return true if we support the combination of compressed, bit depth * and alpha mask. */ static bool alpha_mask_supported(int biCompression, int biBitCount, uint32_t biAlphaMask) { if (biAlphaMask == 0) { return true; } if (biCompression == BIT_RGB) { return (biBitCount == 24 && biAlphaMask == 0xff000000) || (biBitCount == 32 && biAlphaMask == 0xff000000); } if (biCompression == BIT_BITFIELDS) { return (biBitCount == 16 && biAlphaMask == 0x8000) || (biBitCount == 24 && biAlphaMask == 0xff000000) || (biBitCount == 32 && biAlphaMask == 0xff000000); } return false; } /* Like load_bmp, but starts loading from the current place in the ALLEGRO_FILE * specified. If successful the offset into the file will be left just after * the image data. If unsuccessful the offset into the file is unspecified, * i.e. you must either reset the offset to some known place or close the * packfile. The packfile is not closed by this function. */ ALLEGRO_BITMAP *_al_load_bmp_f(ALLEGRO_FILE *f) { BMPFILEHEADER fileheader; BMPINFOHEADER infoheader; ALLEGRO_BITMAP *bmp; PalEntry pal[256]; int64_t file_start; int64_t header_start; unsigned long biSize; unsigned char *buf = NULL; ALLEGRO_LOCKED_REGION *lr; int bpp; ASSERT(f); file_start = al_ftell(f); if (read_bmfileheader(f, &fileheader) != 0) { return NULL; } header_start = al_ftell(f); biSize = al_fread32le(f); if (al_feof(f) || al_ferror(f)) { ALLEGRO_ERROR("EOF or file error\n"); return NULL; } switch (biSize) { case WININFOHEADERSIZE: case WININFOHEADERSIZEV2: case WININFOHEADERSIZEV3: case WININFOHEADERSIZEV4: case WININFOHEADERSIZEV5: if (read_win_bminfoheader(f, &infoheader) != 0) { return NULL; } break; case OS2INFOHEADERSIZE: if (read_os2_bminfoheader(f, &infoheader) != 0) { return NULL; } ASSERT(infoheader.biCompression == BIT_RGB); break; default: ALLEGRO_WARN("Unsupported header size: %ld\n", biSize); return NULL; } /* End of header for OS/2 and BITMAPV2INFOHEADER (V1). */ if (biSize == OS2INFOHEADERSIZE || biSize == WININFOHEADERSIZE) { ASSERT(al_ftell(f) == header_start + (int64_t) biSize); } if ((int)infoheader.biWidth < 0) { ALLEGRO_WARN("negative width: %ld\n", infoheader.biWidth); return NULL; } if (infoheader.biBitCount == 24) bpp = 24; else if (infoheader.biBitCount == 16) bpp = 16; else if (infoheader.biBitCount == 32) bpp = 32; else bpp = 8; /* In BITMAPINFOHEADER (V1) the RGB bit masks are not part of the header. * In BITMAPV2INFOHEADER they form part of the header, but only valid when * for BITFIELDS images. */ if (infoheader.biCompression == BIT_BITFIELDS || biSize >= WININFOHEADERSIZEV2) { uint32_t redMask = al_fread32le(f); uint32_t grnMask = al_fread32le(f); uint32_t bluMask = al_fread32le(f); (void)grnMask; if (infoheader.biCompression == BIT_BITFIELDS) { if ((bluMask == 0x001f) && (redMask == 0x7C00)) bpp = 15; else if ((bluMask == 0x001f) && (redMask == 0xF800)) bpp = 16; else if ((bluMask == 0x0000FF) && (redMask == 0xFF0000)) bpp = 32; else { /* Unrecognised bit masks/depth, refuse to load. */ ALLEGRO_WARN("Unrecognised RGB masks: %x, %x, %x\n", redMask, grnMask, bluMask); return NULL; } } } /* BITMAPV3INFOHEADER and above include an Alpha bit mask. */ if (biSize < WININFOHEADERSIZEV3) { infoheader.biHaveAlphaMask = false; infoheader.biAlphaMask = 0x0; } else { infoheader.biHaveAlphaMask = true; infoheader.biAlphaMask = al_fread32le(f); if (!alpha_mask_supported(infoheader.biCompression, infoheader.biBitCount, infoheader.biAlphaMask)) { ALLEGRO_WARN( "Unsupported: compression=%ld, bit count=%d, alpha mask=%x\n", infoheader.biCompression, infoheader.biBitCount, infoheader.biAlphaMask); return NULL; } } /* End of header for BITMAPV2INFOHEADER and above. */ /* Read the palette, if any. Higher bit depth images _may_ have an optional * palette but we don't use it and don't read it. */ if (infoheader.biCompression != BIT_BITFIELDS && infoheader.biBitCount <= 8) { int win_flag = (biSize != OS2INFOHEADERSIZE); int ncolors = infoheader.biClrUsed; if (ncolors == 0) { ncolors = (1 << infoheader.biBitCount); } if (ncolors > 256) { ALLEGRO_ERROR("Too many colors: %d\n", ncolors); return NULL; } read_palette(ncolors, pal, f, win_flag); if (al_feof(f) || al_ferror(f)) { ALLEGRO_ERROR("EOF or I/O error\n"); return NULL; } } /* Skip to the pixel storage. */ if (!al_fseek(f, file_start + fileheader.bfOffBits, ALLEGRO_SEEK_SET)) { ALLEGRO_ERROR("Seek error\n"); return NULL; } bmp = al_create_bitmap(infoheader.biWidth, abs(infoheader.biHeight)); if (!bmp) { ALLEGRO_ERROR("Failed to create bitmap\n"); return NULL; } lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); if (!lr) { ALLEGRO_ERROR("Failed to lock region\n"); al_destroy_bitmap(bmp); return NULL; } if (infoheader.biCompression == BIT_RLE8 || infoheader.biCompression == BIT_RLE4) { /* Questionable but most loaders handle this, so we should. */ if (infoheader.biHeight < 0) { ALLEGRO_WARN("compressed bitmap with negative height\n"); } /* RLE decoding may skip pixels so clear the buffer first. */ buf = al_calloc(infoheader.biWidth, abs(infoheader.biHeight)); } switch (infoheader.biCompression) { case BIT_RGB: if (infoheader.biBitCount == 32 && !infoheader.biHaveAlphaMask) { read_RGB_image_32bit_alpha_hack(f, &infoheader, lr); } else { read_RGB_image(f, &infoheader, pal, lr); } break; case BIT_RLE8: read_RLE8_compressed_image(f, buf, &infoheader); break; case BIT_RLE4: read_RLE4_compressed_image(f, buf, &infoheader); break; case BIT_BITFIELDS: read_bitfields_image(f, &infoheader, bpp, lr); break; default: ALLEGRO_WARN("Unknown compression: %ld\n", infoheader.biCompression); al_unlock_bitmap(bmp); al_destroy_bitmap(bmp); bmp = NULL; break; } if (infoheader.biCompression == BIT_RLE8 || infoheader.biCompression == BIT_RLE4) { int x, y; unsigned char *data; for (y = 0; y < abs(infoheader.biHeight); y++) { data = (unsigned char *)lr->data + lr->pitch * y; for (x = 0; x < (int)infoheader.biWidth; x++) { data[0] = pal[buf[y * infoheader.biWidth + x]].r; data[1] = pal[buf[y * infoheader.biWidth + x]].g; data[2] = pal[buf[y * infoheader.biWidth + x]].b; data[3] = 255; data += 4; } } al_free(buf); } if (bmp) { al_unlock_bitmap(bmp); } return bmp; } /* Like save_bmp but writes into the ALLEGRO_FILE given instead of a new file. * The packfile is not closed after writing is completed. On success the * offset into the file is left after the TGA file just written. On failure * the offset is left at the end of whatever incomplete data was written. */ bool _al_save_bmp_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { int bfSize; int biSizeImage; int bpp; int filler; int i, j; int w, h; ALLEGRO_LOCKED_REGION *lr; ASSERT(f); ASSERT(bmp); w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); bpp = 24; filler = 3 - ((w * (bpp / 8) - 1) & 3); if (bpp == 8) { biSizeImage = (w + filler) * h; bfSize = (54 /* header */ + 256 * 4 /* palette */ + biSizeImage); /* image data */ } else { biSizeImage = (w * 3 + filler) * h; bfSize = 54 + biSizeImage; /* header + image data */ } al_set_errno(0); /* file_header */ al_fwrite16le(f, 0x4D42); /* bfType ("BM") */ al_fwrite32le(f, bfSize); /* bfSize */ al_fwrite16le(f, 0); /* bfReserved1 */ al_fwrite16le(f, 0); /* bfReserved2 */ if (bpp == 8) /* bfOffBits */ al_fwrite32le(f, 54 + 256 * 4); else al_fwrite32le(f, 54); /* info_header */ al_fwrite32le(f, 40); /* biSize */ al_fwrite32le(f, w); /* biWidth */ al_fwrite32le(f, h); /* biHeight */ al_fwrite16le(f, 1); /* biPlanes */ al_fwrite16le(f, bpp); /* biBitCount */ al_fwrite32le(f, 0); /* biCompression */ al_fwrite32le(f, biSizeImage); /* biSizeImage */ al_fwrite32le(f, 0xB12); /* biXPelsPerMeter (0xB12 = 72 dpi) */ al_fwrite32le(f, 0xB12); /* biYPelsPerMeter */ al_fwrite32le(f, 0); /* biClrUsed */ al_fwrite32le(f, 0); /* biClrImportant */ /* Don't really need the alpha channel, just the _LE. * Note that there exist 32-bit BMPs now so we could try to save those. */ lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY); /* image data */ for (i = h - 1; i >= 0; i--) { unsigned char *data = (unsigned char *)lr->data + i * lr->pitch; for (j = 0; j < w; j++) { unsigned char r = data[0]; unsigned char g = data[1]; unsigned char b = data[2]; data += 4; al_fputc(f, b); al_fputc(f, g); al_fputc(f, r); } for (j = 0; j < filler; j++) al_fputc(f, 0); } al_unlock_bitmap(bmp); return al_get_errno() ? false : true; } ALLEGRO_BITMAP *_al_load_bmp(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_BITMAP *bmp; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; bmp = _al_load_bmp_f(f); al_fclose(f); return bmp; } bool _al_save_bmp(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *f; bool ret; ASSERT(filename); f = al_fopen(filename, "wb"); if (!f) return false; ret = _al_save_bmp_f(f, bmp); al_fclose(f); return ret; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/iio.c0000644000175000001440000001010012125160224015647 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_image.h" #include "allegro5/internal/aintern_image_cfg.h" /* globals */ static bool iio_inited = false; /* Function: al_init_image_addon */ bool al_init_image_addon(void) { int success; if (iio_inited) return true; success = 0; success |= al_register_bitmap_loader(".pcx", _al_load_pcx); success |= al_register_bitmap_saver(".pcx", _al_save_pcx); success |= al_register_bitmap_loader_f(".pcx", _al_load_pcx_f); success |= al_register_bitmap_saver_f(".pcx", _al_save_pcx_f); success |= al_register_bitmap_loader(".bmp", _al_load_bmp); success |= al_register_bitmap_saver(".bmp", _al_save_bmp); success |= al_register_bitmap_loader_f(".bmp", _al_load_bmp_f); success |= al_register_bitmap_saver_f(".bmp", _al_save_bmp_f); success |= al_register_bitmap_loader(".tga", _al_load_tga); success |= al_register_bitmap_saver(".tga", _al_save_tga); success |= al_register_bitmap_loader_f(".tga", _al_load_tga_f); success |= al_register_bitmap_saver_f(".tga", _al_save_tga_f); /* ALLEGRO_CFG_IIO_HAVE_* is sufficient to know that the library should be used. i.e., ALLEGRO_CFG_IIO_HAVE_GDIPLUS and ALLEGRO_CFG_IIO_HAVE_PNG will never both be set. */ #ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS { char const *extensions[] = {".tif", ".tiff", ".jpg", ".jpeg", ".gif", ".png", NULL}; int i; if (_al_init_gdiplus()) { for (i = 0; extensions[i]; i++) { success |= al_register_bitmap_loader(extensions[i], _al_load_gdiplus_bitmap); success |= al_register_bitmap_loader_f(extensions[i], _al_load_gdiplus_bitmap_f); success |= al_register_bitmap_saver(extensions[i], _al_save_gdiplus_bitmap); } success |= al_register_bitmap_saver_f(".tif", _al_save_gdiplus_tif_f); success |= al_register_bitmap_saver_f(".tiff", _al_save_gdiplus_tif_f); success |= al_register_bitmap_saver_f(".gif", _al_save_gdiplus_gif_f); success |= al_register_bitmap_saver_f(".png", _al_save_gdiplus_png_f); success |= al_register_bitmap_saver_f(".jpg", _al_save_gdiplus_jpg_f); success |= al_register_bitmap_saver_f(".jpeg", _al_save_gdiplus_jpg_f); } } #endif #ifdef ALLEGRO_CFG_IIO_HAVE_PNG success |= al_register_bitmap_loader(".png", _al_load_png); success |= al_register_bitmap_saver(".png", _al_save_png); success |= al_register_bitmap_loader_f(".png", _al_load_png_f); success |= al_register_bitmap_saver_f(".png", _al_save_png_f); #endif #ifdef ALLEGRO_CFG_IIO_HAVE_JPG success |= al_register_bitmap_loader(".jpg", _al_load_jpg); success |= al_register_bitmap_saver(".jpg", _al_save_jpg); success |= al_register_bitmap_loader_f(".jpg", _al_load_jpg_f); success |= al_register_bitmap_saver_f(".jpg", _al_save_jpg_f); success |= al_register_bitmap_loader(".jpeg", _al_load_jpg); success |= al_register_bitmap_saver(".jpeg", _al_save_jpg); success |= al_register_bitmap_loader_f(".jpeg", _al_load_jpg_f); success |= al_register_bitmap_saver_f(".jpeg", _al_save_jpg_f); #endif #ifdef ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER #ifdef ALLEGRO_IPHONE { char const *extensions[] = {".tif", ".tiff", ".jpg", ".jpeg", ".gif", ".png", ".BMPf", ".ico", ".cur", ".xbm", NULL}; int i; for (i = 0; extensions[i]; i++) { success |= al_register_bitmap_loader(extensions[i], _al_iphone_load_image); success |= al_register_bitmap_loader_f(extensions[i], _al_iphone_load_image_f); } } #endif #ifdef ALLEGRO_MACOSX success |= _al_osx_register_image_loader(); #endif #endif if (success) iio_inited = true; _al_add_exit_func(al_shutdown_image_addon, "al_shutdown_image_addon"); return success; } /* Function: al_shutdown_image_addon */ void al_shutdown_image_addon(void) { iio_inited = false; } /* Function: al_get_allegro_image_version */ uint32_t al_get_allegro_image_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/pcx.c0000644000175000001440000001453211721435126015705 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" ALLEGRO_BITMAP *_al_load_pcx_f(ALLEGRO_FILE *f) { ALLEGRO_BITMAP *b; int c; int width, height; int bpp, bytes_per_line; int x, xx, y; char ch; ALLEGRO_LOCKED_REGION *lr; unsigned char *buf; PalEntry pal[256]; ASSERT(f); al_fgetc(f); /* skip manufacturer ID */ al_fgetc(f); /* skip version flag */ al_fgetc(f); /* skip encoding flag */ if (al_fgetc(f) != 8) { /* we like 8 bit color planes */ return NULL; } width = -(al_fread16le(f)); /* xmin */ height = -(al_fread16le(f)); /* ymin */ width += al_fread16le(f) + 1; /* xmax */ height += al_fread16le(f) + 1; /* ymax */ al_fread32le(f); /* skip DPI values */ for (c = 0; c < 16 * 3; c++) { /* skip the 16 color palette */ al_fgetc(f); } al_fgetc(f); bpp = al_fgetc(f) * 8; /* how many color planes? */ if ((bpp != 8) && (bpp != 24)) { return NULL; } bytes_per_line = al_fread16le(f); for (c = 0; c < 60; c++) /* skip some more junk */ al_fgetc(f); if (al_feof(f) || al_ferror(f)) { return NULL; } b = al_create_bitmap(width, height); if (!b) { return NULL; } al_set_errno(0); if (bpp == 8) { /* The palette comes after the image data. We need to to keep the * whole image in a temporary buffer before mapping the final colours. */ buf = (unsigned char *)al_malloc(bytes_per_line * height); } else { /* We can read one line at a time. */ buf = (unsigned char *)al_malloc(bytes_per_line * 3); } lr = al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); if (!lr) { al_free(buf); return NULL; } xx = 0; /* index into buf, only for bpp = 8 */ for (y = 0; y < height; y++) { /* read RLE encoded PCX data */ x = 0; while (x < bytes_per_line * bpp / 8) { ch = al_fgetc(f); if ((ch & 0xC0) == 0xC0) { /* a run */ c = (ch & 0x3F); ch = al_fgetc(f); } else { c = 1; /* single pixel */ } if (bpp == 8) { while (c--) { if (x < width) /* ignore padding */ buf[xx++] = ch; x++; } } else { while (c--) { if (x < width * 3) /* ignore padding */ buf[x] = ch; x++; } } } if (bpp == 24) { char *dest = (char*)lr->data + y*lr->pitch; for (x = 0; x < width; x++) { dest[x*4 ] = buf[x]; dest[x*4 + 1] = buf[x + width]; dest[x*4 + 2] = buf[x + width * 2]; dest[x*4 + 3] = 255; } } } if (bpp == 8) { /* look for a 256 color palette */ while ((c = al_fgetc(f)) != EOF) { if (c == 12) { for (c = 0; c < 256; c++) { pal[c].r = al_fgetc(f); pal[c].g = al_fgetc(f); pal[c].b = al_fgetc(f); } break; } } for (y = 0; y < height; y++) { char *dest = (char*)lr->data + y*lr->pitch; for (x = 0; x < width; x++) { int index = buf[y * width + x]; dest[x*4 ] = pal[index].r; dest[x*4 + 1] = pal[index].g; dest[x*4 + 2] = pal[index].b; dest[x*4 + 3] = 255; } } } al_unlock_bitmap(b); al_free(buf); if (al_get_errno()) { al_destroy_bitmap(b); return NULL; } return b; } /* Function: al_save_pcx_f */ bool _al_save_pcx_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) { int c; int x, y; int i; int w, h; unsigned char *buf; ASSERT(f); ASSERT(bmp); al_set_errno(0); w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); al_fputc(f, 10); /* manufacturer */ al_fputc(f, 5); /* version */ al_fputc(f, 1); /* run length encoding */ al_fputc(f, 8); /* 8 bits per pixel */ al_fwrite16le(f, 0); /* xmin */ al_fwrite16le(f, 0); /* ymin */ al_fwrite16le(f, w - 1); /* xmax */ al_fwrite16le(f, h - 1); /* ymax */ al_fwrite16le(f, 320); /* HDpi */ al_fwrite16le(f, 200); /* VDpi */ for (c = 0; c < 16 * 3; c++) { al_fputc(f, 0); } al_fputc(f, 0); /* reserved */ al_fputc(f, 3); /* color planes */ al_fwrite16le(f, w); /* number of bytes per scanline */ al_fwrite16le(f, 1); /* color palette */ al_fwrite16le(f, w); /* hscreen size */ al_fwrite16le(f, h); /* vscreen size */ for (c = 0; c < 54; c++) /* filler */ al_fputc(f, 0); buf = al_malloc(w * 3); al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); for (y = 0; y < h; y++) { /* for each scanline... */ for (x = 0; x < w; x++) { ALLEGRO_COLOR c = al_get_pixel(bmp, x, y); unsigned char r, g, b; al_unmap_rgb(c, &r, &g, &b); buf[x] = r; buf[x + w] = g; buf[x + w * 2] = b; } for (i = 0; i < 3; i++) { int color; int count; x = 0; for (;;) { count = 0; color = buf[x + w * i]; do { count++; x++; } while ((count < 63) && (x < w) && (color == buf[x + w * i])); al_fputc(f, count | 0xC0); al_fputc(f, color); if (x >= w) break; } } } al_free(buf); al_unlock_bitmap(bmp); if (al_get_errno()) return false; else return true; } ALLEGRO_BITMAP *_al_load_pcx(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_BITMAP *bmp; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; bmp = _al_load_pcx_f(f); al_fclose(f); return bmp; } bool _al_save_pcx(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *f; bool ret; ASSERT(filename); f = al_fopen(filename, "wb"); if (!f) return false; ret = _al_save_pcx_f(f, bmp); al_fclose(f); return ret; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/image/png.c0000644000175000001440000003663212076662370015713 0ustar tjadenusers/* loadpng, Allegro wrapper routines for libpng * by Peter Wang (tjaden@users.sf.net). */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/internal/aintern_image.h" #include "iio.h" ALLEGRO_DEBUG_CHANNEL("image") double _al_png_screen_gamma = -1.0; int _al_png_compression_level = Z_BEST_COMPRESSION; /* get_gamma: * Get screen gamma value one of three ways. */ static double get_gamma(void) { if (_al_png_screen_gamma == -1.0) { /* Use the environment variable if available. * 2.2 is a good guess for PC monitors. * 1.1 is good for my laptop. */ const char *gamma_str = getenv("SCREEN_GAMMA"); return (gamma_str) ? atof(gamma_str) : 2.2; } return _al_png_screen_gamma; } static void user_error_fn(png_structp png_ptr, png_const_charp message) { jmp_buf *jmpbuf = (jmp_buf *)png_get_error_ptr(png_ptr); ALLEGRO_DEBUG("PNG error: %s\n", message); longjmp(*jmpbuf, 1); } /***************************************************************************** * Loading routines ****************************************************************************/ /* read_data: * Custom read function to use Allegro packfile routines, * rather than C streams (so we can read from datafiles!) */ static void read_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { ALLEGRO_FILE *f = (ALLEGRO_FILE *)png_get_io_ptr(png_ptr); if ((png_uint_32) al_fread(f, data, length) != length) png_error(png_ptr, "read error (loadpng calling al_fs_entry_read)"); } /* check_if_png: * Check if input file is really PNG format. */ #define PNG_BYTES_TO_CHECK 4 static int check_if_png(ALLEGRO_FILE *fp) { unsigned char buf[PNG_BYTES_TO_CHECK]; ALLEGRO_ASSERT(fp); if (al_fread(fp, buf, PNG_BYTES_TO_CHECK) != PNG_BYTES_TO_CHECK) return 0; return (png_sig_cmp(buf, (png_size_t) 0, PNG_BYTES_TO_CHECK) == 0); } /* really_load_png: * Worker routine, used by load_png and load_memory_png. */ static ALLEGRO_BITMAP *really_load_png(png_structp png_ptr, png_infop info_ptr, int flags) { ALLEGRO_BITMAP *bmp; png_uint_32 width, height, rowbytes, real_rowbytes; int bit_depth, color_type, interlace_type; double image_gamma, screen_gamma; int intent; int bpp; int number_passes, pass; int num_trans = 0; PalEntry pal[256]; png_bytep trans; ALLEGRO_LOCKED_REGION *lock; unsigned char *buf; unsigned char *dest; bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); ALLEGRO_ASSERT(png_ptr && info_ptr); /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) png_set_expand(png_ptr); /* Adds a full alpha channel if there is transparency information * in a tRNS chunk. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { if (!(color_type & PNG_COLOR_MASK_PALETTE)) png_set_tRNS_to_alpha(png_ptr); png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); } /* Convert 16-bits per colour component to 8-bits per colour component. */ if (bit_depth == 16) png_set_strip_16(png_ptr); /* Convert grayscale to RGB triplets */ if ((color_type == PNG_COLOR_TYPE_GRAY) || (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) png_set_gray_to_rgb(png_ptr); /* Optionally, tell libpng to handle the gamma correction for us. */ if (_al_png_screen_gamma != 0.0) { screen_gamma = get_gamma(); if (png_get_sRGB(png_ptr, info_ptr, &intent)) png_set_gamma(png_ptr, screen_gamma, 0.45455); else { if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) png_set_gamma(png_ptr, screen_gamma, image_gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); } } /* Turn on interlace handling. */ number_passes = png_set_interlace_handling(png_ptr); /* Call to gamma correct and add the background to the palette * and update info structure. */ png_read_update_info(png_ptr, info_ptr); /* Palettes. */ if (color_type & PNG_COLOR_MASK_PALETTE) { int num_palette, i; png_colorp palette; if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { /* We don't actually dither, we just copy the palette. */ for (i = 0; ((i < num_palette) && (i < 256)); i++) { pal[i].r = palette[i].red; pal[i].g = palette[i].green; pal[i].b = palette[i].blue; } for (; i < 256; i++) pal[i].r = pal[i].g = pal[i].b = 0; } } rowbytes = png_get_rowbytes(png_ptr, info_ptr); /* Allocate the memory to hold the image using the fields of info_ptr. */ bpp = rowbytes * 8 / width; /* Allegro cannot handle less than 8 bpp. */ if (bpp < 8) bpp = 8; if ((bpp == 24) || (bpp == 32)) { #ifdef ALLEGRO_BIG_ENDIAN png_set_bgr(png_ptr); png_set_swap_alpha(png_ptr); #endif } bmp = al_create_bitmap(width, height); if (!bmp) { ALLEGRO_ERROR("al_create_bitmap failed while loading PNG.\n"); return NULL; } // TODO: can this be different from rowbytes? real_rowbytes = ((bpp + 7) / 8) * width; if (interlace_type == PNG_INTERLACE_ADAM7) buf = al_malloc(real_rowbytes * height); else buf = al_malloc(real_rowbytes); lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); /* Read the image, one line at a time (easier to debug!) */ for (pass = 0; pass < number_passes; pass++) { png_uint_32 y; unsigned int i; unsigned char *ptr; dest = lock->data; for (y = 0; y < height; y++) { unsigned char *dest_row_start = dest; /* For interlaced pictures, the row needs to be initialized with * the contents of the previous pass. */ if (interlace_type == PNG_INTERLACE_ADAM7) ptr = buf + y * real_rowbytes; else ptr = buf; png_read_row(png_ptr, NULL, ptr); switch (bpp) { case 8: if (color_type & PNG_COLOR_MASK_PALETTE) { for (i = 0; i < width; i++) { int pix = ptr[0]; int ti; ptr++; dest[0] = pal[pix].r; dest[1] = pal[pix].g; dest[2] = pal[pix].b; dest[3] = 255; for (ti = 0; ti < num_trans; ti++) { if (trans[ti] == pix) { dest[0] = dest[1] = dest[2] = dest[3] = 0; break; } } dest += 4; } } else { for (i = 0; i < width; i++) { int pix = ptr[0]; ptr++; *(dest++) = pix; *(dest++) = pix; *(dest++) = pix; *(dest++) = 255; } } break; case 24: for (i = 0; i < width; i++) { uint32_t pix = READ3BYTES(ptr); ptr += 3; *(dest++) = pix & 0xff; *(dest++) = (pix >> 8) & 0xff; *(dest++) = (pix >> 16) & 0xff; *(dest++) = 255; } break; case 32: for (i = 0; i < width; i++) { uint32_t pix = bmp_read32(ptr); int r = pix & 0xff; int g = (pix >> 8) & 0xff; int b = (pix >> 16) & 0xff; int a = (pix >> 24) & 0xff; ptr += 4; if (premul) { r = r * a / 255; g = g * a / 255; b = b * a / 255; } *(dest++) = r; *(dest++) = g; *(dest++) = b; *(dest++) = a; } break; default: ALLEGRO_ASSERT(bpp == 8 || bpp == 24 || bpp == 32); break; } dest = dest_row_start + lock->pitch; } } al_unlock_bitmap(bmp); al_free(buf); /* Read rest of file, and get additional chunks in info_ptr. */ png_read_end(png_ptr, info_ptr); return bmp; } /* Load a PNG file from disk, doing colour coversion if required. */ static ALLEGRO_BITMAP *load_png_f(ALLEGRO_FILE *fp, int flags) { jmp_buf jmpbuf; ALLEGRO_BITMAP *bmp; png_structp png_ptr; png_infop info_ptr; ALLEGRO_ASSERT(fp); if (!check_if_png(fp)) { ALLEGRO_ERROR("Not a png.\n"); return NULL; } /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL); if (!png_ptr) { ALLEGRO_ERROR("png_ptr == NULL\n"); return NULL; } /* Allocate/initialize the memory for image information. */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); ALLEGRO_ERROR("png_create_info_struct failed\n"); return NULL; } /* Set error handling. */ if (setjmp(jmpbuf)) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); /* If we get here, we had a problem reading the file */ ALLEGRO_ERROR("Error reading PNG file\n"); return NULL; } png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL); /* Use Allegro packfile routines. */ png_set_read_fn(png_ptr, fp, (png_rw_ptr) read_data); /* We have already read some of the signature. */ png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); /* Really load the image now. */ bmp = really_load_png(png_ptr, info_ptr, flags); /* Clean up after the read, and free any memory allocated. */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); return bmp; } ALLEGRO_BITMAP *_al_load_png_f(ALLEGRO_FILE *fp) { return load_png_f(fp, al_get_new_bitmap_flags()); } ALLEGRO_BITMAP *_al_load_png(const char *filename) { ALLEGRO_FILE *fp; ALLEGRO_BITMAP *bmp; ALLEGRO_ASSERT(filename); fp = al_fopen(filename, "rb"); if (!fp) return NULL; bmp = _al_load_png_f(fp); al_fclose(fp); return bmp; } /***************************************************************************** * Saving routines ****************************************************************************/ /* write_data: * Custom write function to use Allegro packfile routines, * rather than C streams. */ static void write_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { ALLEGRO_FILE *f = (ALLEGRO_FILE *)png_get_io_ptr(png_ptr); if ((png_uint_32) al_fwrite(f, data, length) != length) png_error(png_ptr, "write error (loadpng calling al_fs_entry_write)"); } /* Don't think Allegro has any problem with buffering * (rather, Allegro provides no way to flush packfiles). */ static void flush_data(png_structp png_ptr) { (void)png_ptr; } /* save_rgba: * Core save routine for 32 bpp images. */ static int save_rgba(png_structp png_ptr, ALLEGRO_BITMAP *bmp) { const int bmp_h = al_get_bitmap_height(bmp); ALLEGRO_LOCKED_REGION *lock; int y; lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY); if (!lock) return 0; for (y = 0; y < bmp_h; y++) { unsigned char *p = (unsigned char *)lock->data + lock->pitch * y; png_write_row(png_ptr, p); } al_unlock_bitmap(bmp); return 1; } /* Writes a non-interlaced, no-frills PNG, taking the usual save_xyz * parameters. Returns non-zero on error. */ bool _al_save_png_f(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp) { jmp_buf jmpbuf; png_structp png_ptr = NULL; png_infop info_ptr = NULL; int colour_type; /* Create and initialize the png_struct with the * desired error handler functions. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL); if (!png_ptr) goto Error; /* Allocate/initialize the image information data. */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) goto Error; /* Set error handling. */ if (setjmp(jmpbuf)) { goto Error; } png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL); /* Use packfile routines. */ png_set_write_fn(png_ptr, fp, (png_rw_ptr) write_data, flush_data); /* Set the image information here. Width and height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. */ colour_type = PNG_COLOR_TYPE_RGB_ALPHA; /* Set compression level. */ png_set_compression_level(png_ptr, _al_png_compression_level); png_set_IHDR(png_ptr, info_ptr, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), 8, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* Optionally write comments into the image ... Nah. */ /* Write the file header information. */ png_write_info(png_ptr, info_ptr); /* Once we write out the header, the compression type on the text * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again * at the end. */ if (!save_rgba(png_ptr, bmp)) goto Error; png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); return true; Error: if (png_ptr) { if (info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); else png_destroy_write_struct(&png_ptr, NULL); } return false; } bool _al_save_png(const char *filename, ALLEGRO_BITMAP *bmp) { ALLEGRO_FILE *fp; bool result; ALLEGRO_ASSERT(filename); ALLEGRO_ASSERT(bmp); fp = al_fopen(filename, "wb"); if (!fp) { ALLEGRO_ERROR("Unable to open file %s for writing\n", filename); return false; } result = _al_save_png_f(fp, bmp); al_fclose(fp); return result; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/main/0000755000175000001440000000000012157230737014611 5ustar tjadenusersallegro-5.0.10/addons/main/generic_main.c0000644000175000001440000000025311344727506017377 0ustar tjadenusers/* Empty file */ /* * MSVC will not generate an empty .lib file */ #ifdef _MSC_VER #include __declspec(dllexport) void _al_make_a_lib() { exit(1); } #endif allegro-5.0.10/addons/main/CMakeLists.txt0000644000175000001440000000103611433551140017337 0ustar tjadenusersif(MACOSX) set(SOURCES osx_main.m) set(SUPPORT_ALLEGRO_MAIN 1) endif(MACOSX) if(NOT SUPPORT_ALLEGRO_MAIN) set(SOURCES generic_main.c) set(SUPPORT_ALLEGRO_MAIN 1) endif(NOT SUPPORT_ALLEGRO_MAIN) add_our_library(allegro_main "${SOURCES}" "-DALLEGRO_SRC" "${ALLEGRO_LINK_WITH}" ) set_our_framework_properties(allegro_main AllegroMain-${ALLEGRO_SOVERSION}) install_our_library(allegro_main) set(SUPPORT_ALLEGRO_MAIN 1 PARENT_SCOPE) set(ALLEGRO_MAIN_LINK_WITH allegro_main PARENT_SCOPE) # vim: set sts=4 sw=4 et: allegro-5.0.10/addons/main/osx_main.m0000644000175000001440000000216711426530105016600 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * main() function replacement for MacOS X. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintosx.h" #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif #undef main extern int _al_mangled_main(int, char **); /* main: * Replacement for main function. */ int main(int argc, char *argv[]) { _al_osx_run_main(argc, argv, _al_mangled_main); return 0; } /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* c-file-style: "linux" */ /* End: */ allegro-5.0.10/addons/font/0000755000175000001440000000000012157230737014633 5ustar tjadenusersallegro-5.0.10/addons/font/CMakeLists.txt0000644000175000001440000000112511775014264017372 0ustar tjadenusersset(FONT_SOURCES font.c fontbmp.c stdfont.c text.c) set(FONT_INCLUDE_FILES allegro5/allegro_font.h) set_our_header_properties(${FONT_INCLUDE_FILES}) add_our_library(allegro_font "${FONT_SOURCES};${FONT_INCLUDE_FILES}" "-DALLEGRO_FONT_SRC" "${ALLEGRO_LINK_WITH}" ) set_our_framework_properties(allegro_font AllegroFont-${ALLEGRO_SOVERSION}) install_our_library(allegro_font) install_our_headers(${FONT_INCLUDE_FILES}) set(FONT_LINK_WITH allegro_font PARENT_SCOPE) #-----------------------------------------------------------------------------# # vim: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/font/text.c0000644000175000001440000002030312101033341015736 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Text drawing routines. * * By Shawn Hargreaves. * * textout_justify() by Seymour Shlien. * * Laurence Withers added the textout_ex() function family. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_system.h" /* If you call this, you're probably making a mistake. */ /* #define strlen(s) __are_you_sure__ */ /* Removed the above define since some compilers seem to use some * preprocessor magic when calling strcmp() that inserts a call to strlen. * There might be a better way to do this. */ /* Text usually looks best when aligned to pixels - * but if x is 0.5 it may very well end up at an integer * position if the current transformation scales by 2 or * translated x by 0.5. So we simply apply the transformation, * round to nearest integer, and backtransform that. */ static void align_to_integer_pixel_inner( ALLEGRO_TRANSFORM const *fwd, ALLEGRO_TRANSFORM const *inv, float *x, float *y) { al_transform_coordinates(fwd, x, y); *x = floorf(*x + 0.5f); *y = floorf(*y + 0.5f); al_transform_coordinates(inv, x, y); } static void align_to_integer_pixel(float *x, float *y) { ALLEGRO_TRANSFORM const *fwd; ALLEGRO_TRANSFORM inv; fwd = al_get_current_transform(); al_copy_transform(&inv, fwd); al_invert_transform(&inv); align_to_integer_pixel_inner(fwd, &inv, x, y); } /* Function: al_draw_ustr */ void al_draw_ustr(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, const ALLEGRO_USTR *ustr) { ASSERT(font); ASSERT(ustr); if (flags & ALLEGRO_ALIGN_CENTRE) { /* Use integer division to avoid introducing a fractional * component to an integer x value. */ x -= font->vtable->text_length(font, ustr) / 2; } else if (flags & ALLEGRO_ALIGN_RIGHT) { x -= font->vtable->text_length(font, ustr); } if (flags & ALLEGRO_ALIGN_INTEGER) align_to_integer_pixel(&x, &y); font->vtable->render(font, color, ustr, x, y); } /* Function: al_draw_text */ void al_draw_text(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text) { ALLEGRO_USTR_INFO info; ASSERT(text); al_draw_ustr(font, color, x, y, flags, al_ref_cstr(&info, text)); } /* Function: al_draw_justified_ustr */ void al_draw_justified_ustr(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, const ALLEGRO_USTR *ustr) { const char *whitespace = " \t\n\r"; ALLEGRO_USTR_INFO word_info; const ALLEGRO_USTR *word; int pos1, pos2; int minlen; int num_words; int space; float fleft, finc; int advance; ALLEGRO_TRANSFORM const *fwd = NULL; ALLEGRO_TRANSFORM inv; ASSERT(font); /* count words and measure min length (without spaces) */ num_words = 0; minlen = 0; pos1 = 0; for (;;) { pos1 = al_ustr_find_cset_cstr(ustr, pos1, whitespace); if (pos1 == -1) break; pos2 = al_ustr_find_set_cstr(ustr, pos1, whitespace); if (pos2 == -1) pos2 = al_ustr_size(ustr); word = al_ref_ustr(&word_info, ustr, pos1, pos2); minlen += font->vtable->text_length(font, word); num_words++; pos1 = pos2; } /* amount of room for space between words */ space = x2 - x1 - minlen; if ((space <= 0) || (space > diff) || (num_words < 2)) { /* can't justify */ if (flags & ALLEGRO_ALIGN_INTEGER) align_to_integer_pixel(&x1, &y); font->vtable->render(font, color, ustr, x1, y); return; } /* distribute space left evenly between words */ fleft = (float)x1; finc = (float)space / (float)(num_words-1); pos1 = 0; if (flags & ALLEGRO_ALIGN_INTEGER) { fwd = al_get_current_transform(); al_copy_transform(&inv, fwd); al_invert_transform(&inv); } for (;;) { pos1 = al_ustr_find_cset_cstr(ustr, pos1, whitespace); if (pos1 == -1) break; pos2 = al_ustr_find_set_cstr(ustr, pos1, whitespace); if (pos2 == -1) pos2 = al_ustr_size(ustr); word = al_ref_ustr(&word_info, ustr, pos1, pos2); if (flags & ALLEGRO_ALIGN_INTEGER) { float drawx = fleft; float drawy = y; align_to_integer_pixel_inner(fwd, &inv, &drawx, &drawy); advance = font->vtable->render(font, color, word, drawx, drawy); } else { advance = font->vtable->render(font, color, word, fleft, y); } fleft += advance + finc; pos1 = pos2; } } /* Function: al_draw_justified_text */ void al_draw_justified_text(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, const char *text) { ALLEGRO_USTR_INFO info; ASSERT(text); al_draw_justified_ustr(font, color, x1, x2, y, diff, flags, al_ref_cstr(&info, text)); } /* Function: al_draw_textf */ void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, const char *format, ...) { ALLEGRO_USTR *buf; va_list ap; const char *s; ASSERT(font); ASSERT(format); /* Fast path for common case. */ if (0 == strcmp(format, "%s")) { va_start(ap, format); s = va_arg(ap, const char *); al_draw_text(font, color, x, y, flags, s); va_end(ap); return; } va_start(ap, format); buf = al_ustr_new(""); al_ustr_vappendf(buf, format, ap); va_end(ap); al_draw_text(font, color, x, y, flags, al_cstr(buf)); al_ustr_free(buf); } /* Function: al_draw_justified_textf */ void al_draw_justified_textf(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, const char *format, ...) { ALLEGRO_USTR *buf; va_list ap; ASSERT(f); ASSERT(format); va_start(ap, format); buf = al_ustr_new(""); al_ustr_vappendf(buf, format, ap); va_end(ap); al_draw_justified_text(f, color, x1, x2, y, diff, flags, al_cstr(buf)); al_ustr_free(buf); } /* Function: al_get_ustr_width */ int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr) { ASSERT(f); ASSERT(ustr); return f->vtable->text_length(f, ustr); } /* Function: al_get_text_width */ int al_get_text_width(const ALLEGRO_FONT *f, const char *str) { ALLEGRO_USTR_INFO str_info; const ALLEGRO_USTR *ustr; ASSERT(f); ASSERT(str); ustr = al_ref_cstr(&str_info, str); return f->vtable->text_length(f, ustr); } /* Function: al_get_font_line_height */ int al_get_font_line_height(const ALLEGRO_FONT *f) { ASSERT(f); return f->vtable->font_height(f); } /* Function: al_get_font_ascent */ int al_get_font_ascent(const ALLEGRO_FONT *f) { ASSERT(f); return f->vtable->font_ascent(f); } /* Function: al_get_font_descent */ int al_get_font_descent(const ALLEGRO_FONT *f) { ASSERT(f); return f->vtable->font_descent(f); } /* Function: al_get_ustr_dimensions */ void al_get_ustr_dimensions(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr, int *bbx, int *bby, int *bbw, int *bbh) { ASSERT(f); ASSERT(ustr); f->vtable->get_text_dimensions(f, ustr, bbx, bby, bbw, bbh); } /* Function: al_get_text_dimensions */ void al_get_text_dimensions(const ALLEGRO_FONT *f, char const *text, int *bbx, int *bby, int *bbw, int *bbh) { ALLEGRO_USTR_INFO info; ASSERT(f); ASSERT(text); f->vtable->get_text_dimensions(f, al_ref_cstr(&info, text), bbx, bby, bbw, bbh); } /* Function: al_destroy_font */ void al_destroy_font(ALLEGRO_FONT *f) { if (!f) return; _al_unregister_destructor(_al_dtor_list, f); f->vtable->destroy(f); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/font/font.c0000644000175000001440000002222312125160224015732 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_vector.h" #include "font.h" ALLEGRO_DEBUG_CHANNEL("font") typedef struct { ALLEGRO_USTR *extension; ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags); } FONT_HANDLER; /* globals */ static bool font_inited = false; static _AL_VECTOR font_handlers; /* al_font_404_character: * This is what we render missing glyphs as. */ static int al_font_404_character = '^'; /* font_height: * (mono and color vtable entry) * Returns the height, in pixels of the font. */ static int font_height(const ALLEGRO_FONT *f) { ASSERT(f); return f->height; } static int font_ascent(const ALLEGRO_FONT *f) { return font_height(f); } static int font_descent(const ALLEGRO_FONT *f) { (void)f; return 0; } /* length: * (mono and color vtable entry) * Returns the length, in pixels, of a string as rendered in a font. */ static int length(const ALLEGRO_FONT* f, const ALLEGRO_USTR *text) { int ch = 0, w = 0; int pos = 0; ASSERT(f); while ((ch = al_ustr_get_next(text, &pos)) >= 0) { w += f->vtable->char_length(f, ch); } return w; } static void color_get_text_dimensions(ALLEGRO_FONT const *f, const ALLEGRO_USTR *text, int *bbx, int *bby, int *bbw, int *bbh) { /* Dummy implementation - for A4-style bitmap fonts the bounding * box of text is its width and line-height. */ int h = al_get_font_line_height(f); if (bbx) *bbx = 0; if (bby) *bby = 0; if (bbw) *bbw = length(f, text); if (bbh) *bbh = h; } static ALLEGRO_FONT_COLOR_DATA *_al_font_find_page( ALLEGRO_FONT_COLOR_DATA *cf, int ch) { while (cf) { if (ch >= cf->begin && ch < cf->end) return cf; cf = cf->next; } return NULL; } /* _color_find_glyph: * Helper for color vtable entries, below. */ static ALLEGRO_BITMAP* _al_font_color_find_glyph(const ALLEGRO_FONT* f, int ch) { ALLEGRO_FONT_COLOR_DATA* cf = (ALLEGRO_FONT_COLOR_DATA*)(f->data); cf = _al_font_find_page(cf, ch); if (cf) { return cf->bitmaps[ch - cf->begin]; } /* if we don't find the character, then search for the missing glyph, but don't get stuck in a loop. */ if (ch != al_font_404_character) return _al_font_color_find_glyph(f, al_font_404_character); return 0; } /* color_char_length: * (color vtable entry) * Returns the length of a character, in pixels, as it would be rendered * in this font. */ static int color_char_length(const ALLEGRO_FONT* f, int ch) { ALLEGRO_BITMAP* g = _al_font_color_find_glyph(f, ch); return g ? al_get_bitmap_width(g) : 0; } /* color_render_char: * (color vtable entry) * Renders a color character onto a bitmap, at the specified location, * using * the specified colors. If fg == -1, render as color, else render as * mono; if bg == -1, render as transparent, else render as opaque. * Returns the character width, in pixels. */ static int color_render_char(const ALLEGRO_FONT* f, ALLEGRO_COLOR color, int ch, float x, float y) { int w = 0; int h = f->vtable->font_height(f); ALLEGRO_BITMAP *g; g = _al_font_color_find_glyph(f, ch); if (g) { al_draw_tinted_bitmap(g, color, x, y + ((float)h - al_get_bitmap_height(g))/2.0f, 0); w = al_get_bitmap_width(g); } return w; } /* color_render: * (color vtable entry) * Renders a color font onto a bitmap, at the specified location, using * the specified colors. If fg == -1, render as color, else render as * mono; if bg == -1, render as transparent, else render as opaque. */ static int color_render(const ALLEGRO_FONT* f, ALLEGRO_COLOR color, const ALLEGRO_USTR *text, float x, float y) { int pos = 0; int advance = 0; int32_t ch; bool held = al_is_bitmap_drawing_held(); al_hold_bitmap_drawing(true); while ((ch = al_ustr_get_next(text, &pos)) >= 0) { advance += f->vtable->render_char(f, color, ch, x + advance, y); } al_hold_bitmap_drawing(held); return advance; } /* color_destroy: * (color vtable entry) * Destroys a color font. */ static void color_destroy(ALLEGRO_FONT* f) { ALLEGRO_FONT_COLOR_DATA* cf; ALLEGRO_BITMAP *glyphs = NULL; if (!f) return; cf = (ALLEGRO_FONT_COLOR_DATA*)(f->data); if (cf) glyphs = cf->glyphs; while (cf) { ALLEGRO_FONT_COLOR_DATA* next = cf->next; int i = 0; for (i = cf->begin; i < cf->end; i++) al_destroy_bitmap(cf->bitmaps[i - cf->begin]); /* Each range might point to the same bitmap. */ if (cf->glyphs != glyphs) { al_destroy_bitmap(cf->glyphs); cf->glyphs = NULL; } if (!next && cf->glyphs) al_destroy_bitmap(cf->glyphs); al_free(cf->bitmaps); al_free(cf); cf = next; } al_free(f); } /******** * vtable declarations ********/ ALLEGRO_FONT_VTABLE _al_font_vtable_color = { font_height, font_ascent, font_descent, color_char_length, length, color_render_char, color_render, color_destroy, color_get_text_dimensions, }; static void font_shutdown(void) { if (!font_inited) return; while (!_al_vector_is_empty(&font_handlers)) { FONT_HANDLER *h = _al_vector_ref_back(&font_handlers); al_ustr_free(h->extension); _al_vector_delete_at(&font_handlers, _al_vector_size(&font_handlers)-1); } _al_vector_free(&font_handlers); font_inited = false; } /* Function: al_init_font_addon */ void al_init_font_addon(void) { if (font_inited) { ALLEGRO_WARN("Font addon already initialised.\n"); return; } _al_vector_init(&font_handlers, sizeof(FONT_HANDLER)); al_register_font_loader(".bmp", _al_load_bitmap_font); al_register_font_loader(".jpg", _al_load_bitmap_font); al_register_font_loader(".pcx", _al_load_bitmap_font); al_register_font_loader(".png", _al_load_bitmap_font); al_register_font_loader(".tga", _al_load_bitmap_font); _al_add_exit_func(font_shutdown, "font_shutdown"); font_inited = true; } /* Function: al_shutdown_font_addon */ void al_shutdown_font_addon(void) { font_shutdown(); } static FONT_HANDLER *find_extension(char const *extension) { int i; /* Go backwards so a handler registered later for the same extension * has precedence. */ for (i = _al_vector_size(&font_handlers) - 1; i >= 0 ; i--) { FONT_HANDLER *handler = _al_vector_ref(&font_handlers, i); if (0 == _al_stricmp(al_cstr(handler->extension), extension)) return handler; } return NULL; } /* Function: al_register_font_loader */ bool al_register_font_loader(char const *extension, ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags)) { FONT_HANDLER *handler = find_extension(extension); if (!handler) { if (!load_font) return false; /* Nothing to remove. */ handler = _al_vector_alloc_back(&font_handlers); handler->extension = al_ustr_new(extension); } else { if (!load_font) { al_ustr_free(handler->extension); return _al_vector_find_and_delete(&font_handlers, handler); } } handler->load_font = load_font; return true; } /* Function: al_load_font */ ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags) { int i; const char *ext; FONT_HANDLER *handler; ASSERT(filename); if (!font_inited) { ALLEGRO_ERROR("Font addon not initialised.\n"); return NULL; } ext = strrchr(filename, '.'); if (!ext) return NULL; handler = find_extension(ext); if (handler) return handler->load_font(filename, size, flags); /* No handler for the extension was registered - try to load with * all registered font_handlers and see if one works. So if the user * does: * * al_init_font_addon() * al_init_ttf_addon() * * This will first try to load an unknown (let's say Type1) font file * with Freetype (and load it successfully in this case), then try * to load it as a bitmap font. */ for (i = _al_vector_size(&font_handlers) - 1; i >= 0 ; i--) { FONT_HANDLER *handler = _al_vector_ref(&font_handlers, i); ALLEGRO_FONT *try = handler->load_font(filename, size, flags); if (try) return try; } return NULL; } /* Function: al_get_allegro_font_version */ uint32_t al_get_allegro_font_version(void) { return ALLEGRO_VERSION_INT; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/addons/font/stdfont.c0000644000175000001440000005673611777543402016504 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * A builtin bitmap font using no external data. * * By Dennis Busch. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" /* Adapted from Allegro4 "font.c" (removed unnecessary height and width * information and packed them all into a single continuous array). * Contains the following ranges * * ASCII (0x0020 to 0x007F) * Latin-1 (0x00A1 to 0x00FF) * Extended-A (0x0100 to 0x017F) * Euro (0x20AC) */ static const unsigned char builtin_rom_font_8x8[] = { /* standard ASCII characters (0x20 to 0x7F) */ /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21 */ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, /* 0x22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x23 */ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, /* 0x24 */ 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, /* 0x25 */ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, /* 0x26 */ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, /* 0x27 */ 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28 */ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, /* 0x29 */ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, /* 0x2A */ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, /* 0x2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* 0x2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* 0x2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 0x2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* 0x2F */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, /* 0x30 */ 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, /* 0x31 */ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, /* 0x32 */ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, /* 0x33 */ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, /* 0x34 */ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, /* 0x35 */ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, /* 0x36 */ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, /* 0x37 */ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 0x38 */ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0x39 */ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, /* 0x3A */ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, /* 0x3B */ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, /* 0x3C */ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, /* 0x3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* 0x3E */ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, /* 0x3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* 0x40 */ 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, /* 0x41 */ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, /* 0x42 */ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, /* 0x43 */ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, /* 0x44 */ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, /* 0x45 */ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, /* 0x46 */ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, /* 0x47 */ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, /* 0x48 */ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, /* 0x49 */ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x4A */ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, /* 0x4B */ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, /* 0x4C */ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, /* 0x4D */ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, /* 0x4E */ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, /* 0x4F */ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, /* 0x50 */ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, /* 0x51 */ 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, /* 0x52 */ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, /* 0x53 */ 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, /* 0x54 */ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x55 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, /* 0x56 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, /* 0x57 */ 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, /* 0x58 */ 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, /* 0x59 */ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, /* 0x5A */ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, /* 0x5B */ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, /* 0x5C */ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, /* 0x5D */ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, /* 0x5E */ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 0x5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* 0x60 */ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x61 */ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, /* 0x62 */ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, /* 0x63 */ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, /* 0x64 */ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, /* 0x65 */ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0x66 */ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, /* 0x67 */ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x68 */ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, /* 0x69 */ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x6A */ 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, /* 0x6B */ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, /* 0x6C */ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x6D */ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, /* 0x6E */ 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, /* 0x6F */ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, /* 0x70 */ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, /* 0x71 */ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, /* 0x72 */ 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, /* 0x73 */ 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, /* 0x74 */ 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, /* 0x75 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, /* 0x76 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, /* 0x77 */ 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, /* 0x78 */ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, /* 0x79 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x7A */ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, /* 0x7B */ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, /* 0x7C */ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, /* 0x7D */ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, /* 0x7E */ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7F */ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, /* ANSI Latin-1 characters (0xA1 to 0xFF) */ /* 0xA1 */ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, /* 0xA2 */ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, /* 0xA3 */ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, /* 0xA4 */ 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, /* 0xA5 */ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30, /* 0xA6 */ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, /* 0xA7 */ 0x3E, 0x61, 0x3C, 0x66, 0x66, 0x3C, 0x86, 0x7C, /* 0xA8 */ 0x00, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA9 */ 0x7E, 0x81, 0x9D, 0xA1, 0xA1, 0x9D, 0x81, 0x7E, /* 0xAA */ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, /* 0xAB */ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, /* 0xAC */ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, /* 0xAD */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 0xAE */ 0x7E, 0x81, 0xB9, 0xA5, 0xB9, 0xA5, 0x81, 0x7E, /* 0xAF */ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB0 */ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, /* 0xB1 */ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00, /* 0xB2 */ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, /* 0xB3 */ 0x78, 0x0C, 0x38, 0x0C, 0x78, 0x00, 0x00, 0x00, /* 0xB4 */ 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB5 */ 0x00, 0x00, 0x33, 0x33, 0x66, 0x7E, 0xC0, 0x80, /* 0xB6 */ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, /* 0xB7 */ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /* 0xB8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x38, /* 0xB9 */ 0x18, 0x38, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, /* 0xBA */ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, /* 0xBB */ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, /* 0xBC */ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03, /* 0xBD */ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F, /* 0xBE */ 0xE1, 0x32, 0xE4, 0x3A, 0xF6, 0x2A, 0x5F, 0x86, /* 0xBF */ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, /* 0xC0 */ 0x18, 0x0C, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC1 */ 0x30, 0x60, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC2 */ 0x7C, 0x82, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC3 */ 0x76, 0xDC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC4 */ 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC5 */ 0x10, 0x28, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0xC6 */ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, /* 0xC7 */ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, /* 0xC8 */ 0x30, 0x18, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0xC9 */ 0x0C, 0x18, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0xCA */ 0x7C, 0x82, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0xCB */ 0xC6, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0xCC */ 0x30, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, /* 0xCD */ 0x0C, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, /* 0xCE */ 0x3C, 0x42, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, /* 0xCF */ 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, /* 0xD0 */ 0xF8, 0x6C, 0x66, 0xF6, 0x66, 0x6C, 0xF8, 0x00, /* 0xD1 */ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, /* 0xD2 */ 0x30, 0x18, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xD3 */ 0x18, 0x30, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xD4 */ 0x7C, 0x82, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xD5 */ 0x76, 0xDC, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xD6 */ 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xD7 */ 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, /* 0xD8 */ 0x3A, 0x6C, 0xCE, 0xD6, 0xE6, 0x6C, 0xB8, 0x00, /* 0xD9 */ 0x60, 0x30, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xDA */ 0x18, 0x30, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xDB */ 0x7C, 0x82, 0x00, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xDC */ 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0xDD */ 0x0C, 0x18, 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x00, /* 0xDE */ 0xE0, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0xF0, /* 0xDF */ 0x78, 0xCC, 0xCC, 0xD8, 0xCC, 0xC6, 0xCC, 0x00, /* 0xE0 */ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0xE1 */ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0xE2 */ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00, /* 0xE3 */ 0x76, 0xDC, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0xE4 */ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0xE5 */ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0xE6 */ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, /* 0xE7 */ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38, /* 0xE8 */ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0xE9 */ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0xEA */ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* 0xEB */ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0xEC */ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0xED */ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0xEE */ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* 0xEF */ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0xF0 */ 0x08, 0x3C, 0x08, 0x7C, 0xCC, 0xCC, 0x78, 0x00, /* 0xF1 */ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00, /* 0xF2 */ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0xF3 */ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0xF4 */ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0xF5 */ 0x76, 0xDC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0xF6 */ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0xF7 */ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00, /* 0xF8 */ 0x00, 0x02, 0x7C, 0xCE, 0xD6, 0xE6, 0x7C, 0x80, /* 0xF9 */ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0xFA */ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0xFB */ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0xFC */ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0xFD */ 0x18, 0x30, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0xFE */ 0xF0, 0x60, 0x7C, 0x66, 0x7C, 0x60, 0xF0, 0x00, /* 0xFF */ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* Extended-A characters (0x100 to 0x17F) */ /* 0x100 */ 0xFE, 0x00, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0x101 */ 0xFC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0x102 */ 0x82, 0x7C, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, /* 0x103 */ 0xC3, 0x7E, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, /* 0x104 */ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x1C, 0x30, 0x1E, /* 0x105 */ 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x30, 0x1C, /* 0x106 */ 0x0C, 0x18, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, /* 0x107 */ 0x1C, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, /* 0x108 */ 0x7C, 0x82, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, /* 0x109 */ 0x7E, 0xC3, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, /* 0x10A */ 0x10, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, /* 0x10B */ 0x10, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, /* 0x10C */ 0x6C, 0x38, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, /* 0x10D */ 0x6C, 0x38, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, /* 0x10E */ 0x6C, 0x38, 0xF8, 0x66, 0x66, 0x66, 0xF8, 0x00, /* 0x10F */ 0xBC, 0x4C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, /* 0x110 */ 0xF8, 0x6C, 0x66, 0xF6, 0x66, 0x6C, 0xF8, 0x00, /* 0x111 */ 0x08, 0x3C, 0x08, 0x7C, 0xCC, 0xCC, 0x78, 0x00, /* 0x112 */ 0xFE, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0x113 */ 0xFC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0x114 */ 0x6C, 0x38, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0x115 */ 0x6C, 0x38, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0x116 */ 0x10, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0x117 */ 0x10, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0x118 */ 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x18, 0x30, 0x1C, /* 0x119 */ 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x38, 0x0C, /* 0x11A */ 0x6C, 0x38, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, /* 0x11B */ 0x6C, 0x38, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, /* 0x11C */ 0x7C, 0x82, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, /* 0x11D */ 0x7E, 0xC3, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x11E */ 0x82, 0x7C, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, /* 0x11F */ 0xC3, 0x7E, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x120 */ 0x10, 0x00, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, /* 0x121 */ 0x10, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x122 */ 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x18, 0x0C, 0x78, /* 0x123 */ 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0x0C, 0x38, /* 0x124 */ 0x78, 0x84, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, /* 0x125 */ 0xEE, 0x7B, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, /* 0x126 */ 0xCC, 0xFE, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, /* 0x127 */ 0xE0, 0xFE, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, /* 0x128 */ 0x76, 0xDC, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x129 */ 0x76, 0xDC, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x12A */ 0x78, 0x00, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x12B */ 0x78, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x12C */ 0x84, 0x78, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x12D */ 0xC6, 0x7C, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x12E */ 0x78, 0x30, 0x30, 0x30, 0x78, 0x18, 0x30, 0x1E, /* 0x12F */ 0x30, 0x00, 0x70, 0x30, 0x30, 0x78, 0x30, 0x1C, /* 0x130 */ 0x10, 0x00, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x131 */ 0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x132 */ 0xEE, 0x42, 0x42, 0x42, 0x52, 0x52, 0xEC, 0x00, /* 0x133 */ 0x42, 0x00, 0xC6, 0x42, 0x42, 0x42, 0xE2, 0x0C, /* 0x134 */ 0x7C, 0x82, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, /* 0x135 */ 0x7C, 0xC6, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, /* 0x136 */ 0xE6, 0x6C, 0x78, 0x6C, 0xE6, 0x30, 0x18, 0xF0, /* 0x137 */ 0xE0, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x30, 0xE0, /* 0x138 */ 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x6C, 0xE6, 0x00, /* 0x139 */ 0xF3, 0x66, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, /* 0x13A */ 0x73, 0x36, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x13B */ 0xF0, 0x60, 0x62, 0x66, 0xFE, 0x18, 0x0C, 0x78, /* 0x13C */ 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x0C, 0x38, /* 0x13D */ 0xF5, 0x66, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, /* 0x13E */ 0x75, 0x36, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x13F */ 0xF0, 0x60, 0x64, 0x60, 0x62, 0x66, 0xFE, 0x00, /* 0x140 */ 0x70, 0x30, 0x30, 0x32, 0x30, 0x30, 0x78, 0x00, /* 0x141 */ 0xF0, 0x60, 0x70, 0x60, 0xE2, 0x66, 0xFE, 0x00, /* 0x142 */ 0x70, 0x30, 0x38, 0x30, 0x70, 0x30, 0x78, 0x00, /* 0x143 */ 0x0C, 0x18, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, /* 0x144 */ 0x1C, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, /* 0x145 */ 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x30, 0x18, 0xF0, /* 0x146 */ 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x30, 0xE0, /* 0x147 */ 0x6C, 0x38, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, /* 0x148 */ 0x6C, 0x38, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, /* 0x149 */ 0xC0, 0x80, 0x5C, 0x66, 0x66, 0x66, 0x66, 0x00, /* 0x14A */ 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x0C, 0x38, /* 0x14B */ 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x0C, 0x38, /* 0x14C */ 0xFE, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x14D */ 0x00, 0xFC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0x14E */ 0x6C, 0x38, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x14F */ 0x6C, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0x150 */ 0x36, 0x6C, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x151 */ 0x36, 0x6C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, /* 0x152 */ 0x7E, 0xDA, 0x88, 0x8C, 0x88, 0xDA, 0x7E, 0x00, /* 0x153 */ 0x00, 0x00, 0x6C, 0x92, 0x9E, 0x90, 0x6C, 0x00, /* 0x154 */ 0x0C, 0x18, 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x00, /* 0x155 */ 0x0C, 0x18, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, /* 0x156 */ 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x30, 0x18, 0xF0, /* 0x157 */ 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x30, 0xE0, /* 0x158 */ 0x6C, 0x38, 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x00, /* 0x159 */ 0x6C, 0x38, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, /* 0x15A */ 0x0C, 0x18, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, /* 0x15B */ 0x0C, 0x18, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, /* 0x15C */ 0x7C, 0x82, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, /* 0x15D */ 0x7C, 0xC6, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, /* 0x15E */ 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x18, 0x0C, 0x78, /* 0x15F */ 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x0C, 0x38, /* 0x160 */ 0x6C, 0x38, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, /* 0x161 */ 0x6C, 0x38, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, /* 0x162 */ 0xFC, 0x30, 0x30, 0x30, 0x78, 0x18, 0x0C, 0x38, /* 0x163 */ 0x10, 0x30, 0xFC, 0x30, 0x34, 0x18, 0x0C, 0x38, /* 0x164 */ 0x6C, 0x38, 0xFC, 0x30, 0x30, 0x30, 0x78, 0x00, /* 0x165 */ 0x12, 0x3A, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, /* 0x166 */ 0xFC, 0xB4, 0x30, 0x30, 0xFC, 0x30, 0x78, 0x00, /* 0x167 */ 0x10, 0x30, 0xFC, 0x30, 0xFC, 0x34, 0x18, 0x00, /* 0x168 */ 0x76, 0xDC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x169 */ 0x76, 0xDC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0x16A */ 0xFE, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x16B */ 0x00, 0xFE, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0x16C */ 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x16D */ 0x6C, 0x38, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0x16E */ 0x38, 0x6C, 0xFE, 0xD6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x16F */ 0x38, 0x6C, 0x38, 0xDC, 0xCC, 0xCC, 0x7E, 0x00, /* 0x170 */ 0x36, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, /* 0x171 */ 0x36, 0x6C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, /* 0x172 */ 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x30, 0x60, 0x3C, /* 0x173 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x18, 0x0E, /* 0x174 */ 0x7C, 0x82, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, /* 0x175 */ 0x7C, 0xC6, 0x00, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, /* 0x176 */ 0x7C, 0x82, 0xCC, 0xCC, 0x78, 0x30, 0x78, 0x00, /* 0x177 */ 0x7C, 0xC6, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, /* 0x178 */ 0xCC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0x78, 0x00, /* 0x179 */ 0x0C, 0x18, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, /* 0x17A */ 0x0C, 0x18, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, /* 0x17B */ 0x10, 0x00, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, /* 0x17C */ 0x10, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, /* 0x17D */ 0x6C, 0x38, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, /* 0x17E */ 0x6C, 0x38, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, /* 0x17F */ 0x38, 0x6C, 0x64, 0xE0, 0x60, 0x60, 0xE0, 0x00, /* euro character (0x20AC) */ /* 0x20AC*/ 0x3C, 0x62, 0xF8, 0x60, 0xF8, 0x62, 0x3C, 0x00 }; /* range definitions for the above binary data */ static const int builtin_rom_font_8x8_ranges[] = { 0x00000020, 0x0000007F, 0x000000A1, 0x000000FF, 0x00000100, 0x0000017F, 0x000020AC, 0x000020AC }; static const int builtin_rom_font_8x8_ranges_count = (sizeof(builtin_rom_font_8x8_ranges) / sizeof(int)) / 2; static void put_pixel_abgr8888_le(ALLEGRO_LOCKED_REGION *region, int x, int y, uint32_t pixel) { uint32_t *target = (uint32_t *) ((uint8_t *)region->data + y * region->pitch + x * region->pixel_size); *target = pixel; } /* decodes the binary data and creates a bitmap containing the glyps from it */ static ALLEGRO_BITMAP *create_builtin_font_sheet(void) { const int glyph_count = sizeof(builtin_rom_font_8x8) / 8; const int glyphs_per_row = 32; const int alloc_rows = (glyph_count + glyphs_per_row - 1) / glyphs_per_row; ALLEGRO_STATE state; ALLEGRO_BITMAP *bmp; ALLEGRO_LOCKED_REGION *lr; int i, j, k; al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS | ALLEGRO_STATE_TARGET_BITMAP); /* putting pixels is much faster on a memory bitmap */ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); /* create bitmap onto which to render the glyphs */ bmp = al_create_bitmap(glyphs_per_row * 8 + glyphs_per_row + 1, alloc_rows * 8 + alloc_rows + 1); if (bmp) { al_set_target_bitmap(bmp); al_clear_to_color(al_map_rgba(255, 255, 0, 255)); lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READWRITE); /* decode and render glyph pixels */ for (i = 0; i < glyph_count; i++) { /* for each of the 8 lines per character */ for (j = 0; j < 8; j++) { /* decode and draw each of the 8 pixels of the current line */ for (k = 0; k < 8; k++) { bool set = (builtin_rom_font_8x8[i * 8 + j] >> (7 - k)) & 0x01; put_pixel_abgr8888_le(lr, (i % glyphs_per_row) * 9 + 1 + k, (i / glyphs_per_row) * 9 + 1 + j, set ? 0xFFFFFFFF : 0x00000000); } } } al_unlock_bitmap(bmp); } al_restore_state(&state); return bmp; } /* Function: al_create_builtin_font */ ALLEGRO_FONT *al_create_builtin_font(void) { ALLEGRO_BITMAP *bmp; ALLEGRO_FONT *font; bmp = create_builtin_font_sheet(); if (!bmp) return NULL; font = al_grab_font_from_bitmap(bmp, builtin_rom_font_8x8_ranges_count, builtin_rom_font_8x8_ranges); al_destroy_bitmap(bmp); return font; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/font/font.h0000644000175000001440000000107211431672525015751 0ustar tjadenusers#ifndef __al_included_allegro5_font_h #define __al_included_allegro5_font_h extern ALLEGRO_FONT_VTABLE _al_font_vtable_color; typedef struct ALLEGRO_FONT_COLOR_DATA { int begin, end; /* first char and one-past-the-end char */ ALLEGRO_BITMAP *glyphs; /* our glyphs */ ALLEGRO_BITMAP **bitmaps; /* sub bitmaps pointing to our glyphs */ struct ALLEGRO_FONT_COLOR_DATA *next; /* linked list structure */ } ALLEGRO_FONT_COLOR_DATA; ALLEGRO_FONT *_al_load_bitmap_font(const char *filename, int size, int flags); #endif allegro-5.0.10/addons/font/fontbmp.c0000644000175000001440000001527711777537537016477 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Read font from a bitmap. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_system.h" #include "font.h" static void font_find_character(uint32_t *data, int pitch, int bmp_w, int bmp_h, int *x, int *y, int *w, int *h) { /* The pixel at position 0/0 is used as background color. */ uint32_t c = data[0]; pitch >>= 2; /* look for top left corner of character */ while (1) { /* Reached border? */ if (*x >= bmp_w - 1) { *x = 0; (*y)++; if (*y >= bmp_h - 1) { *w = 0; *h = 0; return; } } if ( data[*x + *y * pitch] == c && data[(*x + 1) + *y * pitch] == c && data[*x + (*y + 1) * pitch] == c && data[(*x + 1) + (*y + 1) * pitch] != c) { break; } (*x)++; } /* look for right edge of character */ *w = 1; while ((*x + *w + 1 < bmp_w) && data[(*x + *w + 1) + (*y + 1) * pitch] != c) { (*w)++; } /* look for bottom edge of character */ *h = 1; while ((*y + *h + 1 < bmp_h) && data[*x + 1 + (*y + *h + 1) * pitch] != c) { (*h)++; } } /* import_bitmap_font_color: * Helper for import_bitmap_font, below. */ static int import_bitmap_font_color(uint32_t *data, int pitch, int bmp_w, int bmp_h, ALLEGRO_BITMAP **bits, ALLEGRO_BITMAP *glyphs, int num, int *import_x, int *import_y) { int w, h, i; for (i = 0; i < num; i++) { font_find_character(data, pitch, bmp_w, bmp_h, import_x, import_y, &w, &h); if (w <= 0 || h <= 0) { return -1; } else { bits[i] = al_create_sub_bitmap(glyphs, *import_x + 1, *import_y + 1, w, h); *import_x += w; } } return 0; } /* bitmap_font_count: * Helper for `import_bitmap_font', below. */ static int bitmap_font_count(ALLEGRO_BITMAP* bmp) { int x = 0, y = 0, w = 0, h = 0; int num = 0; ALLEGRO_LOCKED_REGION *lock; lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); while (1) { font_find_character(lock->data, lock->pitch, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), &x, &y, &w, &h); if (w <= 0 || h <= 0) break; num++; x += w; } al_unlock_bitmap(bmp); return num; } ALLEGRO_FONT *_al_load_bitmap_font(const char *fname, int size, int flags) { ALLEGRO_BITMAP *import_bmp; ALLEGRO_FONT *f; ALLEGRO_STATE backup; int range[2]; ASSERT(fname); (void)size; (void)flags; al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); import_bmp = al_load_bitmap(fname); al_restore_state(&backup); if (!import_bmp) return NULL; /* We assume a single unicode range, starting at the space * character. */ range[0] = 32; range[1] = 32 + bitmap_font_count(import_bmp) - 1; f = al_grab_font_from_bitmap(import_bmp, 1, range); al_destroy_bitmap(import_bmp); return f; } /* Function: al_load_bitmap_font */ ALLEGRO_FONT *al_load_bitmap_font(const char *fname) { return _al_load_bitmap_font(fname, 0, 0); } /* Function: al_grab_font_from_bitmap */ ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp, int ranges_n, const int ranges[]) { ALLEGRO_FONT *f; ALLEGRO_FONT_COLOR_DATA *cf, *prev = NULL; ALLEGRO_STATE backup; int i; ALLEGRO_COLOR mask = al_get_pixel(bmp, 0, 0); ALLEGRO_BITMAP *glyphs = NULL, *unmasked = NULL; int import_x = 0, import_y = 0; ALLEGRO_LOCKED_REGION *lock = NULL; int w, h; ASSERT(bmp); w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); f = al_calloc(1, sizeof *f); f->vtable = &_al_font_vtable_color; al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); unmasked = al_clone_bitmap(bmp); /* At least with OpenGL, texture pixels at the very border of * the glyph are sometimes partly sampled from the yellow mask * pixels. To work around this, we replace the mask with full * transparency. * And we best do it on a memory copy to avoid loading back a texture. */ al_convert_mask_to_alpha(unmasked, mask); al_restore_state(&backup); al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); // Use the users preferred format, so don't set this below! //al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); for (i = 0; i < ranges_n; i++) { int first = ranges[i * 2]; int last = ranges[i * 2 + 1]; int n = 1 + last - first; cf = al_calloc(1, sizeof(ALLEGRO_FONT_COLOR_DATA)); if (prev) prev->next = cf; else f->data = cf; cf->bitmaps = al_malloc(sizeof(ALLEGRO_BITMAP*) * n); cf->bitmaps[0] = NULL; if (!glyphs) { glyphs = al_clone_bitmap(unmasked); if (!glyphs) goto cleanup_and_fail_on_error; lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); } cf->glyphs = glyphs; if (import_bitmap_font_color(lock->data, lock->pitch, w, h, cf->bitmaps, cf->glyphs, n, &import_x, &import_y)) { goto cleanup_and_fail_on_error; } else { cf->begin = first; cf->end = last + 1; prev = cf; } } al_restore_state(&backup); cf = f->data; if (cf && cf->bitmaps[0]) f->height = al_get_bitmap_height(cf->bitmaps[0]); if (lock) al_unlock_bitmap(bmp); if (unmasked) al_destroy_bitmap(unmasked); _al_register_destructor(_al_dtor_list, f, (void (*)(void *))al_destroy_font); return f; cleanup_and_fail_on_error: if (lock) al_unlock_bitmap(bmp); al_restore_state(&backup); al_destroy_font(f); if (unmasked) al_destroy_bitmap(unmasked); return NULL; } allegro-5.0.10/addons/font/allegro5/0000755000175000001440000000000012157230737016345 5ustar tjadenusersallegro-5.0.10/addons/font/allegro5/allegro_font.h0000644000175000001440000001271112031562164021164 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_font_h #define __al_included_allegro5_allegro_font_h #include "allegro5/allegro.h" #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_FONT_SRC #define _ALLEGRO_FONT_DLL __declspec(dllexport) #else #define _ALLEGRO_FONT_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_FONT_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_FONT_FUNC(type, name, args) _ALLEGRO_FONT_DLL type __cdecl name args #define ALLEGRO_FONT_METHOD(type, name, args) type (__cdecl *name) args #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (__cdecl *name) args #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) #elif defined ALLEGRO_MINGW32 #define ALLEGRO_FONT_FUNC(type, name, args) extern type name args #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) #elif defined ALLEGRO_BCC32 #define ALLEGRO_FONT_FUNC(type, name, args) extern _ALLEGRO_FONT_DLL type name args #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) #else #define ALLEGRO_FONT_FUNC AL_FUNC #define ALLEGRO_FONT_METHOD AL_METHOD #define ALLEGRO_FONT_FUNCPTR AL_FUNCPTR #define ALLEGRO_FONT_PRINTFUNC AL_PRINTFUNC #endif #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_FONT */ typedef struct ALLEGRO_FONT ALLEGRO_FONT; typedef struct ALLEGRO_FONT_VTABLE ALLEGRO_FONT_VTABLE; struct ALLEGRO_FONT { void *data; int height; ALLEGRO_FONT_VTABLE *vtable; }; /* text- and font-related stuff */ struct ALLEGRO_FONT_VTABLE { ALLEGRO_FONT_METHOD(int, font_height, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_METHOD(int, font_ascent, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_METHOD(int, font_descent, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_METHOD(int, char_length, (const ALLEGRO_FONT *f, int ch)); ALLEGRO_FONT_METHOD(int, text_length, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *text)); ALLEGRO_FONT_METHOD(int, render_char, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, int ch, float x, float y)); ALLEGRO_FONT_METHOD(int, render, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, const ALLEGRO_USTR *text, float x, float y)); ALLEGRO_FONT_METHOD(void, destroy, (ALLEGRO_FONT *f)); ALLEGRO_FONT_METHOD(void, get_text_dimensions, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *text, int *bbx, int *bby, int *bbw, int *bbh)); }; enum { ALLEGRO_ALIGN_LEFT = 0, ALLEGRO_ALIGN_CENTRE = 1, ALLEGRO_ALIGN_CENTER = 1, ALLEGRO_ALIGN_RIGHT = 2, ALLEGRO_ALIGN_INTEGER = 4 }; ALLEGRO_FONT_FUNC(bool, al_register_font_loader, (const char *ext, ALLEGRO_FONT *(*load)(const char *filename, int size, int flags))); ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_bitmap_font, (const char *filename)); ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_font, (const char *filename, int size, int flags)); ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_grab_font_from_bitmap, (ALLEGRO_BITMAP *bmp, int n, const int ranges[])); ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_create_builtin_font, (void)); ALLEGRO_FONT_FUNC(void, al_draw_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, ALLEGRO_USTR const *ustr)); ALLEGRO_FONT_FUNC(void, al_draw_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text)); ALLEGRO_FONT_FUNC(void, al_draw_justified_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *text)); ALLEGRO_FONT_FUNC(void, al_draw_justified_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, ALLEGRO_USTR const *text)); ALLEGRO_FONT_PRINTFUNC(void, al_draw_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *format, ...), 6, 7); ALLEGRO_FONT_PRINTFUNC(void, al_draw_justified_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *format, ...), 8, 9); ALLEGRO_FONT_FUNC(int, al_get_text_width, (const ALLEGRO_FONT *f, const char *str)); ALLEGRO_FONT_FUNC(int, al_get_ustr_width, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *ustr)); ALLEGRO_FONT_FUNC(int, al_get_font_line_height, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_FUNC(int, al_get_font_ascent, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_FUNC(int, al_get_font_descent, (const ALLEGRO_FONT *f)); ALLEGRO_FONT_FUNC(void, al_destroy_font, (ALLEGRO_FONT *f)); ALLEGRO_FONT_FUNC(void, al_get_ustr_dimensions, (const ALLEGRO_FONT *f, ALLEGRO_USTR const *text, int *bbx, int *bby, int *bbw, int *bbh)); ALLEGRO_FONT_FUNC(void, al_get_text_dimensions, (const ALLEGRO_FONT *f, char const *text, int *bbx, int *bby, int *bbw, int *bbh)); ALLEGRO_FONT_FUNC(void, al_init_font_addon, (void)); ALLEGRO_FONT_FUNC(void, al_shutdown_font_addon, (void)); ALLEGRO_FONT_FUNC(uint32_t, al_get_allegro_font_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/acodec/0000755000175000001440000000000012157230737015103 5ustar tjadenusersallegro-5.0.10/addons/acodec/CMakeLists.txt0000644000175000001440000002145112060436736017646 0ustar tjadenusersinclude_directories(../audio) option(WANT_FLAC "Enable FLAC support" on) option(WANT_VORBIS "Enable Ogg Vorbis support using libvorbis" on) option(WANT_TREMOR "Enable Ogg Vorbis support using Tremor" off) option(WANT_MODAUDIO "Enable MOD Audio support" on) option(WANT_ACODEC_DYNAMIC_LOAD "Enable DLL loading in acodec (Windows)" on) #-----------------------------------------------------------------------------# set(ACODEC_INCLUDE_FILES allegro5/allegro_acodec.h ) set_our_header_properties(${ACODEC_INCLUDE_FILES}) set(ACODEC_SOURCES acodec.c wav.c helper.c ) set(ACODEC_LIBRARIES) # For dynamic loading, we want to make sure that CMake has found an import # library and not a static library. We assume that the name of the DLL to load # is the same as the import library, bar the extension. # # With MSVC, static libraries and import libraries share the same extension. # Luckily the MSVC static libraries for FLAC and Vorbis are named with a # _static suffix. # With MinGW, static libraries end with .a, and import libraries end with # .dll.a so we can tell them apart. (The regex for this is a bodge.) set(WIN32_STATIC_LIB_REGEX "_static[.]|[^l][.]a") function(get_dll_name implib dllname_var) if(MINGW) # Guess the name of dlltool from gcc. string(REGEX REPLACE "gcc.*" dlltool DLLTOOL ${CMAKE_C_COMPILER}) execute_process( COMMAND ${DLLTOOL} -I ${implib} OUTPUT_VARIABLE dllname OUTPUT_STRIP_TRAILING_WHITESPACE ) elseif(MSVC) # Not sure this is the best way. execute_process( COMMAND lib /LIST ${implib} OUTPUT_VARIABLE output ) if(output STREQUAL "") message("WARNING: Failed to execute lib /list") else() string(REGEX MATCH "[^\n]+[.]dll" dllname "${output}") endif() endif() if(NOT dllname) # Guess from the basename. get_filename_component(basename "${implib}" NAME_WE) set(dllname "${basename}.dll") endif() message(STATUS "DLL name for ${implib}: ${dllname}") set(${dllname_var} ${dllname} PARENT_SCOPE) endfunction(get_dll_name) # # FLAC # if(WANT_FLAC) find_package(FLAC) if(FLAC_FOUND) set(CMAKE_REQUIRED_INCLUDES ${FLAC_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${FLAC_LIBRARIES}) check_c_source_compiles(" #include int main(void) { FLAC__StreamDecoderInitStatus status; return 0; }" FLAC_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(FLAC_COMPILES) set(SUPPORT_FLAC 1) endif(FLAC_COMPILES) endif(FLAC_FOUND) if(NOT SUPPORT_FLAC) message("WARNING: libFLAC not found or compile test failed, disabling support.") endif(NOT SUPPORT_FLAC) endif(WANT_FLAC) if(SUPPORT_FLAC) include_directories(SYSTEM ${FLAC_INCLUDE_DIR}) set(ALLEGRO_CFG_ACODEC_FLAC 1) list(APPEND ACODEC_SOURCES flac.c) if(WIN32) option(FLAC_STATIC "Set this if linking with a static FLAC library" off) if(FLAC_STATIC) set(FLAC__NO_DLL "-DFLAC__NO_DLL") endif() if(NOT FLAC_STATIC AND FLAC_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") set(FLAC_STATIC 1) set(FLAC__NO_DLL "-DFLAC__NO_DLL") endif() if(WANT_ACODEC_DYNAMIC_LOAD) if(FLAC_STATIC) message("WARNING: Dynamic loading will be disabled for FLAC as" " static library was found: ${FLAC_LIBRARY}") else() get_dll_name(${FLAC_LIBRARY} ALLEGRO_CFG_ACODEC_FLAC_DLL) endif() endif() endif(WIN32) if(NOT ALLEGRO_CFG_ACODEC_FLAC_DLL) list(APPEND ACODEC_LIBRARIES ${FLAC_LIBRARIES}) endif() endif(SUPPORT_FLAC) # # MOD audio # if(WANT_MODAUDIO) find_package(DUMB) if(DUMB_FOUND) set(CMAKE_REQUIRED_INCLUDES ${DUMB_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${DUMB_LIBRARIES}) check_c_source_compiles(" #include int main(void) { dumb_register_stdfiles(); return 0; }" DUMB_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(DUMB_COMPILES) set(SUPPORT_MODAUDIO 1) endif(DUMB_COMPILES) endif(DUMB_FOUND) if(NOT SUPPORT_MODAUDIO) message("WARNING: libdumb not found or compile test failed, " "disabling support. ") endif(NOT SUPPORT_MODAUDIO) endif(WANT_MODAUDIO) if(SUPPORT_MODAUDIO) include_directories(SYSTEM ${DUMB_INCLUDE_DIR}) set(ALLEGRO_CFG_ACODEC_MODAUDIO 1) list(APPEND ACODEC_SOURCES modaudio.c) if(WIN32 AND WANT_ACODEC_DYNAMIC_LOAD) if(DUMB_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") message("WARNING: Dynamic loading will be disabled for DUMB" " as static library was found: ${DUMB_LIBRARY}") else() get_dll_name(${DUMB_LIBRARY} ALLEGRO_CFG_ACODEC_DUMB_DLL) endif() endif() if(NOT ALLEGRO_CFG_ACODEC_DUMB_DLL) list(APPEND ACODEC_LIBRARIES ${DUMB_LIBRARIES}) endif() endif() # # Vorbis/Tremor # if(WANT_TREMOR) find_package(Tremor) if(TREMOR_FOUND) set(CMAKE_REQUIRED_INCLUDES ${TREMOR_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${TREMOR_LIBRARIES}) check_c_source_compiles(" #include int main(void) { OggVorbis_File f; ov_info(&f, -1); return 0; }" TREMOR_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(TREMOR_COMPILES OR IPHONE) set(SUPPORT_VORBIS 1) endif(TREMOR_COMPILES OR IPHONE) endif(TREMOR_FOUND) if(NOT SUPPORT_VORBIS) message("WARNING: Tremor not found although WANT_TREMOR was specified.") else(NOT SUPPORT_VORBIS) # mimic regular libogg/libvorbis set(OGG_INCLUDE_DIR ${TREMOR_INCLUDE_DIR}) set(VORBIS_INCLUDE_DIR ) set(VORBIS_LIBRARIES ${TREMOR_LIBRARIES}) set(ALLEGRO_CFG_ACODEC_TREMOR 1) endif(NOT SUPPORT_VORBIS) elseif(WANT_VORBIS) find_package(Vorbis) if(VORBIS_FOUND) set(CMAKE_REQUIRED_INCLUDES ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) if(COMPILER_GCC) # libm is required when linking statically. set(CMAKE_REQUIRED_LIBRARIES "${VORBIS_LIBRARIES};m") else() set(CMAKE_REQUIRED_LIBRARIES "${VORBIS_LIBRARIES}") endif(COMPILER_GCC) check_c_source_compiles(" #include int main(void) { OggVorbis_File f; ov_callbacks callback; vorbis_info *v = 0; (void)v; ov_info(&f, -1); callback = OV_CALLBACKS_NOCLOSE; return 0; }" VORBIS_COMPILES) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) if(VORBIS_COMPILES) set(SUPPORT_VORBIS 1) endif(VORBIS_COMPILES) endif(VORBIS_FOUND) if(NOT SUPPORT_VORBIS) message("WARNING: libvorbis not found or compile test failed, disabling support.") endif(NOT SUPPORT_VORBIS) endif() if(SUPPORT_VORBIS) include_directories(SYSTEM ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) set(ALLEGRO_CFG_ACODEC_VORBIS 1) list(APPEND ACODEC_SOURCES ogg.c) if(WIN32 AND WANT_ACODEC_DYNAMIC_LOAD AND NOT WANT_TREMOR) if(VORBISFILE_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") message("WARNING: Dynamic loading will be disabled for Vorbis" " as static library was found: ${VORBISFILE_LIBRARY}") else() get_dll_name(${VORBISFILE_LIBRARY} ALLEGRO_CFG_ACODEC_VORBISFILE_DLL) endif() endif() if(NOT ALLEGRO_CFG_ACODEC_VORBISFILE_DLL) list(APPEND ACODEC_LIBRARIES ${VORBIS_LIBRARIES}) endif() endif(SUPPORT_VORBIS) configure_file( allegro5/internal/aintern_acodec_cfg.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/internal/aintern_acodec_cfg.h ) add_our_library(allegro_acodec "${ACODEC_SOURCES};${ACODEC_INCLUDE_FILES}" "-DALLEGRO_ACODEC_SRC ${FLAC__NO_DLL}" "${AUDIO_LINK_WITH};${ACODEC_LIBRARIES}" ) set_our_framework_properties(allegro_acodec AllegroAcodec-${ALLEGRO_SOVERSION}) install_our_library(allegro_acodec) install_our_headers(${ACODEC_INCLUDE_FILES}) set(ACODEC_LINK_WITH allegro_acodec PARENT_SCOPE) set(SUPPORT_ACODEC 1 PARENT_SCOPE) #-----------------------------------------------------------------------------# # vim: set ts=8 sts=4 sw=4 et: allegro-5.0.10/addons/acodec/modaudio.c0000644000175000001440000002614612125160224017045 0ustar tjadenusers/* * Allegro MOD reader * author: Matthew Leverton */ #include "allegro5/allegro.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_system.h" #include "acodec.h" #include "helper.h" #ifndef ALLEGRO_CFG_ACODEC_MODAUDIO #error configuration problem, ALLEGRO_CFG_ACODEC_MODAUDIO not set #endif #include #include ALLEGRO_DEBUG_CHANNEL("acodec") /* forward declarations */ static size_t modaudio_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, size_t buf_size); static bool modaudio_stream_rewind(ALLEGRO_AUDIO_STREAM *stream); static bool modaudio_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time); static double modaudio_stream_get_position(ALLEGRO_AUDIO_STREAM *stream); static double modaudio_stream_get_length(ALLEGRO_AUDIO_STREAM *stream); static bool modaudio_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end); static void modaudio_stream_close(ALLEGRO_AUDIO_STREAM *stream); typedef struct MOD_FILE { DUH *duh; DUH_SIGRENDERER *sig; ALLEGRO_FILE *fh; double length; long loop_start, loop_end; } MOD_FILE; static bool libdumb_loaded = false; /* dynamic loading support (Windows only currently) */ #ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL static void *dumb_dll = NULL; #endif static struct { long (*duh_render)(DUH_SIGRENDERER *, int, int, float, float, long, void *); long (*duh_sigrenderer_get_position)(DUH_SIGRENDERER *); void (*duh_end_sigrenderer)(DUH_SIGRENDERER *); void (*unload_duh)(DUH *); DUH_SIGRENDERER *(*duh_start_sigrenderer)(DUH *, int, int, long); DUMBFILE *(*dumbfile_open_ex)(void *, DUMBFILE_SYSTEM *); long (*duh_get_length)(DUH *); void (*dumb_exit)(void); void (*register_dumbfile_system)(DUMBFILE_SYSTEM *); DUH *(*dumb_read_it)(DUMBFILE *); DUH *(*dumb_read_xm)(DUMBFILE *); DUH *(*dumb_read_s3m)(DUMBFILE *); DUH *(*dumb_read_mod)(DUMBFILE *); } lib; /* Set up DUMB's file system */ static DUMBFILE_SYSTEM dfs, dfs_f; static void *dfs_open(const char *filename) { return al_fopen(filename, "rb"); } static int dfs_skip(void *f, long n) { return al_fseek(f, n, ALLEGRO_SEEK_CUR) ? 0 : -1; } static int dfs_getc(void *f) { return al_fgetc(f); } static long dfs_getnc(char *ptr, long n, void *f) { return al_fread(f, ptr, n); } static void dfs_close(void *f) { /* Don't actually close f here. */ (void)f; } /* Stream Functions */ static size_t modaudio_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, size_t buf_size) { MOD_FILE *const df = stream->extra; /* the mod files are stereo and 16-bit */ const int sample_size = 4; size_t written; size_t i; written = lib.duh_render(df->sig, 16, 0, 1.0, 65536.0 / 44100.0, buf_size / sample_size, data) * sample_size; /* Fill the remainder with silence */ for (i = written; i < buf_size; ++i) ((int *)data)[i] = 0x8000; /* Check to see if a loop is set */ if (df->loop_start != -1 && df->loop_end < lib.duh_sigrenderer_get_position(df->sig)) { modaudio_stream_seek(stream, df->loop_start / 65536.0); } return written; } static void modaudio_stream_close(ALLEGRO_AUDIO_STREAM *stream) { MOD_FILE *const df = stream->extra; _al_acodec_stop_feed_thread(stream); lib.duh_end_sigrenderer(df->sig); lib.unload_duh(df->duh); if (df->fh) al_fclose(df->fh); } static bool modaudio_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) { MOD_FILE *const df = stream->extra; lib.duh_end_sigrenderer(df->sig); df->sig = lib.duh_start_sigrenderer(df->duh, 0, 2, 0); return true; } static bool modaudio_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) { MOD_FILE *const df = stream->extra; lib.duh_end_sigrenderer(df->sig); df->sig = lib.duh_start_sigrenderer(df->duh, 0, 2, time * 65536); return false; } static double modaudio_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) { MOD_FILE *const df = stream->extra; return lib.duh_sigrenderer_get_position(df->sig) / 65536.0; } static double modaudio_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) { MOD_FILE *const df = stream->extra; return df->length; } static bool modaudio_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end) { MOD_FILE *const df = stream->extra; df->loop_start = start * 65536; df->loop_end = end * 65536; return true; } /* Create the Allegro stream */ static ALLEGRO_AUDIO_STREAM *mod_stream_init(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples, DUH *(loader)(DUMBFILE *)) { ALLEGRO_AUDIO_STREAM *stream; DUMBFILE *df; DUH_SIGRENDERER *sig = NULL; DUH *duh = NULL; int64_t start_pos = -1; df = lib.dumbfile_open_ex(f, &dfs_f); if (!df) return NULL; start_pos = al_ftell(f); duh = loader(df); if (!duh) { goto Error; } sig = lib.duh_start_sigrenderer(duh, 0, 2, 0); if (!sig) { goto Error; } stream = al_create_audio_stream(buffer_count, samples, 44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (stream) { MOD_FILE *mf = al_malloc(sizeof(MOD_FILE)); mf->duh = duh; mf->sig = sig; mf->fh = NULL; mf->length = lib.duh_get_length(duh) / 65536.0; if (mf->length < 0) mf->length = 0; mf->loop_start = -1; mf->loop_end = -1; stream->extra = mf; stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); stream->feeder = modaudio_stream_update; stream->unload_feeder = modaudio_stream_close; stream->rewind_feeder = modaudio_stream_rewind; stream->seek_feeder = modaudio_stream_seek; stream->get_feeder_position = modaudio_stream_get_position; stream->get_feeder_length = modaudio_stream_get_length; stream->set_feeder_loop = modaudio_stream_set_loop; al_start_thread(stream->feed_thread); } else { goto Error; } return stream; Error: if (sig) { lib.duh_end_sigrenderer(sig); } if (duh) { lib.unload_duh(duh); } /* try to return back to where we started to load */ if (start_pos != -1) al_fseek(f, start_pos, ALLEGRO_SEEK_SET); return NULL; } static void shutdown_libdumb(void) { if (libdumb_loaded) { lib.dumb_exit(); libdumb_loaded = false; } #ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL if (dumb_dll) { _al_close_library(dumb_dll); dumb_dll = NULL; } #endif } static bool init_libdumb(void) { if (libdumb_loaded) { return true; } #ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL dumb_dll = _al_open_library(ALLEGRO_CFG_ACODEC_DUMB_DLL); if (!dumb_dll) { ALLEGRO_WARN("Could not load " ALLEGRO_CFG_ACODEC_DUMB_DLL "\n"); return false; } #define INITSYM(x) \ do \ { \ lib.x = _al_import_symbol(dumb_dll, #x); \ if (lib.x == 0) { \ ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ return false; \ } \ } while(0) #else #define INITSYM(x) (lib.x = (x)) #endif _al_add_exit_func(shutdown_libdumb, "shutdown_libdumb"); memset(&lib, 0, sizeof(lib)); INITSYM(duh_render); INITSYM(duh_sigrenderer_get_position); INITSYM(duh_end_sigrenderer); INITSYM(unload_duh); INITSYM(duh_start_sigrenderer); INITSYM(dumbfile_open_ex); INITSYM(duh_get_length); INITSYM(dumb_exit); INITSYM(register_dumbfile_system); INITSYM(dumb_read_it); INITSYM(dumb_read_xm); INITSYM(dumb_read_s3m); INITSYM(dumb_read_mod); dfs.open = dfs_open; dfs.skip = dfs_skip; dfs.getc = dfs_getc; dfs.getnc = dfs_getnc; dfs.close = dfs_close; /* Set up DUMB's default I/O to go through Allegro... */ lib.register_dumbfile_system(&dfs); /* But we'll actually use them through this version: */ dfs_f = dfs; dfs_f.open = NULL; dfs_f.close = NULL; libdumb_loaded = true; return true; } ALLEGRO_AUDIO_STREAM *_al_load_mod_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_mod_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); return NULL; } ((MOD_FILE *)stream->extra)->fh = f; return stream; } ALLEGRO_AUDIO_STREAM *_al_load_it_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_it_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); return NULL; } ((MOD_FILE *)stream->extra)->fh = f; return stream; } ALLEGRO_AUDIO_STREAM *_al_load_xm_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_xm_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); return NULL; } ((MOD_FILE *)stream->extra)->fh = f; return stream; } ALLEGRO_AUDIO_STREAM *_al_load_s3m_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_s3m_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); return NULL; } ((MOD_FILE *)stream->extra)->fh = f; return stream; } ALLEGRO_AUDIO_STREAM *_al_load_mod_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples) { if (!init_libdumb()) return NULL; return mod_stream_init(f, buffer_count, samples, lib.dumb_read_mod); } ALLEGRO_AUDIO_STREAM *_al_load_it_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples) { if (!init_libdumb()) return NULL; return mod_stream_init(f, buffer_count, samples, lib.dumb_read_it); } ALLEGRO_AUDIO_STREAM *_al_load_xm_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples) { if (!init_libdumb()) return NULL; return mod_stream_init(f, buffer_count, samples, lib.dumb_read_xm); } ALLEGRO_AUDIO_STREAM *_al_load_s3m_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples) { if (!init_libdumb()) return NULL; return mod_stream_init(f, buffer_count, samples, lib.dumb_read_s3m); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/acodec/ogg.c0000644000175000001440000003211312153633152016015 0ustar tjadenusers/* * Allegro5 Ogg Vorbis reader. * Can load samples and do streaming * author: Ryan Dickie (c) 2008 */ #include "allegro5/allegro.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_system.h" #include "acodec.h" #include "helper.h" #ifndef ALLEGRO_CFG_ACODEC_VORBIS #error configuration problem, ALLEGRO_CFG_ACODEC_VORBIS not set #endif ALLEGRO_DEBUG_CHANNEL("acodec") #if defined(ALLEGRO_CFG_ACODEC_TREMOR) #include #define TREMOR 1 #else #include #endif typedef struct AL_OV_DATA AL_OV_DATA; struct AL_OV_DATA { OggVorbis_File *vf; vorbis_info *vi; ALLEGRO_FILE *file; int bitstream; double loop_start; double loop_end; }; /* dynamic loading support (Windows only currently) */ #ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL static void *ov_dll = NULL; static bool ov_virgin = true; #endif static struct { int (*ov_clear)(OggVorbis_File *); ogg_int64_t (*ov_pcm_total)(OggVorbis_File *, int); vorbis_info *(*ov_info)(OggVorbis_File *, int); #ifndef TREMOR int (*ov_open_callbacks)(void *, OggVorbis_File *, const char *, long, ov_callbacks); double (*ov_time_total)(OggVorbis_File *, int); int (*ov_time_seek_lap)(OggVorbis_File *, double); double (*ov_time_tell)(OggVorbis_File *); long (*ov_read)(OggVorbis_File *, char *, int, int, int, int, int *); #else int (*ov_open_callbacks)(void *, OggVorbis_File *, const char *, long, ov_callbacks); ogg_int64_t (*ov_time_total)(OggVorbis_File *, int); int (*ov_time_seek)(OggVorbis_File *, ogg_int64_t); ogg_int64_t (*ov_time_tell)(OggVorbis_File *); long (*ov_read)(OggVorbis_File *, char *, int, int *); #endif } lib; #ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL static void shutdown_dynlib(void) { if (ov_dll) { _al_close_library(ov_dll); ov_dll = NULL; ov_virgin = true; } } #endif static bool init_dynlib(void) { #ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL if (ov_dll) { return true; } if (!ov_virgin) { return false; } ov_virgin = false; ov_dll = _al_open_library(ALLEGRO_CFG_ACODEC_VORBISFILE_DLL); if (!ov_dll) { ALLEGRO_WARN("Could not load " ALLEGRO_CFG_ACODEC_VORBISFILE_DLL "\n"); return false; } _al_add_exit_func(shutdown_dynlib, "shutdown_dynlib"); #define INITSYM(x) \ do \ { \ lib.x = _al_import_symbol(ov_dll, #x); \ if (lib.x == 0) { \ ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ return false; \ } \ } while(0) #else #define INITSYM(x) (lib.x = (x)) #endif memset(&lib, 0, sizeof(lib)); INITSYM(ov_clear); INITSYM(ov_open_callbacks); INITSYM(ov_pcm_total); INITSYM(ov_info); #ifndef TREMOR INITSYM(ov_time_total); INITSYM(ov_time_seek_lap); INITSYM(ov_time_tell); INITSYM(ov_read); #else INITSYM(ov_time_total); INITSYM(ov_time_seek); INITSYM(ov_time_tell); INITSYM(ov_read); #endif return true; #undef INITSYM } static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *dptr) { AL_OV_DATA *ov = (AL_OV_DATA *)dptr; size_t ret = 0; ret = al_fread(ov->file, ptr, size*nmemb); return ret; } static int seek_callback(void *dptr, ogg_int64_t offset, int whence) { AL_OV_DATA *ov = (AL_OV_DATA *)dptr; switch(whence) { case SEEK_SET: whence = ALLEGRO_SEEK_SET; break; case SEEK_CUR: whence = ALLEGRO_SEEK_CUR; break; case SEEK_END: whence = ALLEGRO_SEEK_END; break; } if (!al_fseek(ov->file, offset, whence)) { return -1; } return 0; } static long tell_callback(void *dptr) { AL_OV_DATA *ov = (AL_OV_DATA *)dptr; int64_t ret = 0; ret = al_ftell(ov->file); if (ret == -1) return -1; return (long)ret; } static int close_callback(void *dptr) { /* Don't close dptr->file here. */ (void)dptr; return 0; } static ov_callbacks callbacks = { read_callback, seek_callback, close_callback, tell_callback }; ALLEGRO_SAMPLE *_al_load_ogg_vorbis(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_SAMPLE *spl; ASSERT(filename); ALLEGRO_INFO("Loading sample %s.\n", filename); f = al_fopen(filename, "rb"); if (!f) { ALLEGRO_WARN("Failed reading %s.\n", filename); return NULL; } spl = _al_load_ogg_vorbis_f(f); al_fclose(f); return spl; } ALLEGRO_SAMPLE *_al_load_ogg_vorbis_f(ALLEGRO_FILE *file) { /* Note: decoding library returns floats. I always return 16-bit (most * commonly supported). */ #ifdef ALLEGRO_LITTLE_ENDIAN const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */ #else const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */ #endif int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ int signedness = 1; /* 0 for unsigned, 1 for signed */ const int packet_size = 4096; /* suggestion for size to read at a time */ OggVorbis_File vf; vorbis_info* vi; char *buffer; long pos; ALLEGRO_SAMPLE *sample; int channels; long rate; long total_samples; int bitstream; long total_size; AL_OV_DATA ov; long read; if (!init_dynlib()) { return NULL; } ov.file = file; if (lib.ov_open_callbacks(&ov, &vf, NULL, 0, callbacks) < 0) { ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n"); return NULL; } vi = lib.ov_info(&vf, -1); channels = vi->channels; rate = vi->rate; total_samples = lib.ov_pcm_total(&vf, -1); bitstream = -1; total_size = total_samples * channels * word_size; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", total_samples); ALLEGRO_DEBUG("total_size %ld\n", total_size); buffer = al_malloc(total_size); if (!buffer) { return NULL; } pos = 0; while (pos < total_size) { const int read_size = _ALLEGRO_MIN(packet_size, total_size - pos); ASSERT(pos + read_size <= total_size); /* XXX error handling */ #ifndef TREMOR read = lib.ov_read(&vf, buffer + pos, read_size, endian, word_size, signedness, &bitstream); #else (void)endian; (void)signedness; read = lib.ov_read(&vf, buffer + pos, read_size, &bitstream); #endif pos += read; if (read == 0) break; } lib.ov_clear(&vf); sample = al_create_sample(buffer, total_samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels), true); if (!sample) { al_free(buffer); } return sample; } static bool ogg_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; if (time >= extra->loop_end) return false; #ifndef TREMOR return (lib.ov_time_seek_lap(extra->vf, time) != -1); #else return lib.ov_time_seek(extra->vf, time*1000) != -1; #endif } static bool ogg_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; return ogg_stream_seek(stream, extra->loop_start); } static double ogg_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; #ifndef TREMOR return lib.ov_time_tell(extra->vf); #else return lib.ov_time_tell(extra->vf)/1000.0; #endif } static double ogg_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; #ifndef TREMOR double ret = lib.ov_time_total(extra->vf, -1); #else double ret = lib.ov_time_total(extra->vf, -1)/1000.0; #endif return ret; } static bool ogg_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; extra->loop_start = start; extra->loop_end = end; return true; } /* To be called when stream is destroyed */ static void ogg_stream_close(ALLEGRO_AUDIO_STREAM *stream) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; _al_acodec_stop_feed_thread(stream); al_fclose(extra->file); lib.ov_clear(extra->vf); al_free(extra->vf); al_free(extra); stream->extra = NULL; } static size_t ogg_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, size_t buf_size) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; #ifdef ALLEGRO_LITTLE_ENDIAN const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */ #else const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */ #endif const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ const int signedness = 1; /* 0 for unsigned, 1 for signed */ unsigned long pos = 0; int read_length = buf_size; #ifndef TREMOR double ctime = lib.ov_time_tell(extra->vf); #else double ctime = lib.ov_time_tell(extra->vf)/1000.0; #endif double rate = extra->vi->rate; double btime = ((double)buf_size / ((double)word_size * (double)extra->vi->channels)) / rate; unsigned long read; if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { if (ctime + btime > extra->loop_end) { read_length = (extra->loop_end - ctime) * rate * (double)word_size * (double)extra->vi->channels; if (read_length < 0) return 0; read_length += read_length % word_size; } } while (pos < (unsigned long)read_length) { #ifndef TREMOR read = lib.ov_read(extra->vf, (char *)data + pos, read_length - pos, endian, word_size, signedness, &extra->bitstream); #else (void)endian; (void)signedness; read = lib.ov_read(extra->vf, (char *)data + pos, read_length - pos, &extra->bitstream); #endif pos += read; /* If nothing read then now to silence from here to the end. */ if (read == 0) { int silence = _al_kcm_get_silence(stream->spl.spl_data.depth); memset((char *)data + pos, silence, buf_size - pos); /* return the number of usefull byes written */ return pos; } } return pos; } ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); ALLEGRO_INFO("Loading stream %s.\n", filename); f = al_fopen(filename, "rb"); if (!f) { ALLEGRO_WARN("Failed reading %s.\n", filename); return NULL; } stream = _al_load_ogg_vorbis_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); } return stream; } ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE *file, size_t buffer_count, unsigned int samples) { const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ OggVorbis_File* vf; vorbis_info* vi; int channels; long rate; long total_samples; long total_size; AL_OV_DATA* extra; ALLEGRO_AUDIO_STREAM* stream; if (!init_dynlib()) { return NULL; } extra = al_malloc(sizeof(AL_OV_DATA)); if (extra == NULL) { ALLEGRO_ERROR("Failed to allocate AL_OV_DATA struct.\n"); return NULL; } extra->file = file; vf = al_malloc(sizeof(OggVorbis_File)); if (lib.ov_open_callbacks(extra, vf, NULL, 0, callbacks) < 0) { ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n"); return NULL; } extra->vf = vf; vi = lib.ov_info(vf, -1); channels = vi->channels; rate = vi->rate; total_samples = lib.ov_pcm_total(vf, -1); total_size = total_samples * channels * word_size; extra->vi = vi; extra->bitstream = -1; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", total_samples); ALLEGRO_DEBUG("total_size %ld\n", total_size); stream = al_create_audio_stream(buffer_count, samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels)); if (!stream) { lib.ov_clear(vf); al_free(vf); return NULL; } stream->extra = extra; extra->loop_start = 0.0; extra->loop_end = ogg_stream_get_length(stream); stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); stream->quit_feed_thread = false; stream->feeder = ogg_stream_update; stream->rewind_feeder = ogg_stream_rewind; stream->seek_feeder = ogg_stream_seek; stream->get_feeder_position = ogg_stream_get_position; stream->get_feeder_length = ogg_stream_get_length; stream->set_feeder_loop = ogg_stream_set_loop; stream->unload_feeder = ogg_stream_close; al_start_thread(stream->feed_thread); return stream; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/acodec/flac.c0000644000175000001440000004320212060462364016151 0ustar tjadenusers/* * Allegro FLAC reader * author: Ryan Dickie, (c) 2008 * streaming support by Elias Pschernig */ #include "allegro5/allegro.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_system.h" #include "acodec.h" #include "helper.h" #ifndef ALLEGRO_CFG_ACODEC_FLAC #error configuration problem, ALLEGRO_CFG_ACODEC_FLAC not set #endif #include #include ALLEGRO_DEBUG_CHANNEL("acodec") typedef struct FLACFILE { FLAC__StreamDecoder *decoder; double sample_rate; int sample_size; int channels; /* The file buffer. */ uint64_t buffer_pos, buffer_size; char *buffer; /* Number of samples in the complete FLAC. */ uint64_t total_samples; /* Sample position one past last decoded sample. */ uint64_t decoded_samples; /* Sample position one past last streamed sample. */ uint64_t streamed_samples; ALLEGRO_FILE *fh; uint64_t loop_start, loop_end; /* in samples */ } FLACFILE; /* dynamic loading support (Windows only currently) */ #ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL static void *flac_dll = NULL; static bool flac_virgin = true; #endif static struct { FLAC__StreamDecoder *(*FLAC__stream_decoder_new)(void); void (*FLAC__stream_decoder_delete)(FLAC__StreamDecoder *decoder); FLAC__StreamDecoderInitStatus (*FLAC__stream_decoder_init_stream)( FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback read_callback, FLAC__StreamDecoderSeekCallback seek_callback, FLAC__StreamDecoderTellCallback tell_callback, FLAC__StreamDecoderLengthCallback length_callback, FLAC__StreamDecoderEofCallback eof_callback, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data); FLAC__bool (*FLAC__stream_decoder_process_single)(FLAC__StreamDecoder *decoder); FLAC__bool (*FLAC__stream_decoder_process_until_end_of_metadata)(FLAC__StreamDecoder *decoder); FLAC__bool (*FLAC__stream_decoder_process_until_end_of_stream)(FLAC__StreamDecoder *decoder); FLAC__bool (*FLAC__stream_decoder_seek_absolute)(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); FLAC__bool (*FLAC__stream_decoder_flush)(FLAC__StreamDecoder *decoder); FLAC__bool (*FLAC__stream_decoder_finish)(FLAC__StreamDecoder *decoder); } lib; #ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL static void shutdown_dynlib(void) { if (flac_dll) { _al_close_library(flac_dll); flac_dll = NULL; flac_virgin = true; } } #endif static bool init_dynlib(void) { #ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL if (flac_dll) { return true; } if (!flac_virgin) { return false; } flac_virgin = false; flac_dll = _al_open_library(ALLEGRO_CFG_ACODEC_FLAC_DLL); if (!flac_dll) { ALLEGRO_WARN("Could not load " ALLEGRO_CFG_ACODEC_FLAC_DLL "\n"); return false; } _al_add_exit_func(shutdown_dynlib, "shutdown_dynlib"); #define INITSYM(x) \ do \ { \ lib.x = _al_import_symbol(flac_dll, #x); \ if (lib.x == 0) { \ ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ return false; \ } \ } while(0) #else #define INITSYM(x) (lib.x = (x)) #endif memset(&lib, 0, sizeof(lib)); INITSYM(FLAC__stream_decoder_new); INITSYM(FLAC__stream_decoder_delete); INITSYM(FLAC__stream_decoder_init_stream); INITSYM(FLAC__stream_decoder_process_single); INITSYM(FLAC__stream_decoder_process_until_end_of_metadata); INITSYM(FLAC__stream_decoder_process_until_end_of_stream); INITSYM(FLAC__stream_decoder_seek_absolute); INITSYM(FLAC__stream_decoder_flush); INITSYM(FLAC__stream_decoder_finish); return true; #undef INITSYM } static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *dptr) { FLACFILE *ff = (FLACFILE *)dptr; ALLEGRO_FILE *fh = ff->fh; (void)decoder; if (*bytes > 0) { *bytes = al_fread(fh, buffer, *bytes); if (al_ferror(fh)) return FLAC__STREAM_DECODER_READ_STATUS_ABORT; else if (*bytes == 0) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; else return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } else return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } static FLAC__StreamDecoderSeekStatus seek_callback( const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *dptr) { FLACFILE *ff = (FLACFILE *)dptr; ALLEGRO_FILE *fh = ff->fh; (void)decoder; if (!al_fseek(fh, absolute_byte_offset, ALLEGRO_SEEK_SET)) return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; else return FLAC__STREAM_DECODER_SEEK_STATUS_OK; } static FLAC__StreamDecoderTellStatus tell_callback( const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *dptr) { FLACFILE *ff = (FLACFILE *)dptr; ALLEGRO_FILE *fh = ff->fh; int64_t pos = 0; (void)decoder; pos = al_ftell(fh); if (pos == -1) return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; *absolute_byte_offset = (FLAC__uint64)pos; return FLAC__STREAM_DECODER_TELL_STATUS_OK; } static FLAC__StreamDecoderLengthStatus length_callback( const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *dptr) { FLACFILE *ff = (FLACFILE *)dptr; ALLEGRO_FILE *fh = ff->fh; (void)decoder; /* XXX check error */ *stream_length = (FLAC__uint64)al_fsize(fh); return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *dptr) { FLACFILE *ff = (FLACFILE *)dptr; ALLEGRO_FILE *fh = ff->fh; (void)decoder; if (al_feof(fh)) return true; return false; } static void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { FLACFILE *out = (FLACFILE *)client_data; (void)decoder; if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { out->total_samples = metadata->data.stream_info.total_samples; out->sample_rate = metadata->data.stream_info.sample_rate; out->channels = metadata->data.stream_info.channels; out->sample_size = metadata->data.stream_info.bits_per_sample / 8; } } static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { (void)decoder; (void)client_data; #ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL (void)status; ALLEGRO_ERROR("Got FLAC error callback\n"); /* lazy */ #else ALLEGRO_ERROR("Got FLAC error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]); #endif } static FLAC__StreamDecoderWriteStatus write_callback( const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { FLACFILE *ff = (FLACFILE *) client_data; long len = frame->header.blocksize; long bytes = len * ff->channels * ff->sample_size; FLAC__uint8 *buf8; FLAC__int16 *buf16; float *buf32; int sample_index; int channel_index; int out_index; if (ff->buffer_pos + bytes > ff->buffer_size) { ff->buffer = al_realloc(ff->buffer, ff->buffer_pos + bytes); ff->buffer_size = ff->buffer_pos + bytes; } /* FLAC returns FLAC__int32 and I need to convert it to my own format. */ buf8 = (FLAC__uint8 *) (ff->buffer + ff->buffer_pos); buf16 = (FLAC__int16 *) buf8; buf32 = (float *) buf8; (void)decoder; (void)client_data; /* Flatten the array */ /* TODO: test this array flattening process on 5.1 and higher flac files */ out_index = 0; switch (ff->sample_size) { case 1: for (sample_index = 0; sample_index < len; sample_index++) { for (channel_index = 0; channel_index < ff->channels; channel_index++) { buf8[out_index++] = (FLAC__uint8) buffer[channel_index][sample_index]; } } break; case 2: for (sample_index = 0; sample_index < len; sample_index++) { for (channel_index = 0; channel_index < ff->channels; channel_index++) { buf16[out_index++] = (FLAC__int16) buffer[channel_index][sample_index]; } } break; case 3: for (sample_index = 0; sample_index < len; sample_index++) { for (channel_index = 0; channel_index < ff->channels; channel_index++) { /* Little endian */ /* FIXME: does this work? I only have 16-bit sound card mixer * garbages for other 24-bit codecs too. */ buf8[out_index++] = (FLAC__uint8) (buffer[channel_index][sample_index] & 0xFF); buf8[out_index++] = (FLAC__uint8) ((buffer[channel_index][sample_index] & 0xFF00) >> 8); buf8[out_index++] = (FLAC__uint8) ((buffer[channel_index][sample_index] & 0xFF0000) >> 16); } } break; case 4: for (sample_index = 0; sample_index < len; sample_index++) { for (channel_index = 0; channel_index < ff->channels; channel_index++) { buf32[out_index++] = (float) buffer[channel_index][sample_index]; } } break; default: /* Word_size not supported. */ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } ff->decoded_samples += len; ff->buffer_pos += bytes; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } static void flac_close(FLACFILE *ff) { lib.FLAC__stream_decoder_finish(ff->decoder); lib.FLAC__stream_decoder_delete(ff->decoder); /* Don't close ff->fh here. */ al_free(ff); } /* In seconds. */ static double flac_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) { FLACFILE *ff = (FLACFILE *)stream->extra; return ff->streamed_samples / ff->sample_rate; } /* * Updates 'stream' with the next chunk of data. * Returns the actual number of bytes written. */ static size_t flac_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, size_t buf_size) { int bytes_per_sample; uint64_t wanted_samples; uint64_t read_samples; size_t written_bytes = 0; size_t read_bytes; FLACFILE *ff = (FLACFILE *)stream->extra; bytes_per_sample = ff->sample_size * ff->channels; wanted_samples = buf_size / bytes_per_sample; if (ff->streamed_samples + wanted_samples > ff->loop_end) { if (ff->loop_end > ff->streamed_samples) wanted_samples = ff->loop_end - ff->streamed_samples; else return 0; } while (wanted_samples > 0) { read_samples = ff->decoded_samples - ff->streamed_samples; /* If the buffer size is small, we shouldn't read a new frame or our * buffer keeps growing - so only refill when needed. */ if (!read_samples) { if (!lib.FLAC__stream_decoder_process_single(ff->decoder)) break; read_samples = ff->decoded_samples - ff->streamed_samples; if (!read_samples) { break; } } if (read_samples > wanted_samples) read_samples = wanted_samples; ff->streamed_samples += read_samples; wanted_samples -= read_samples; read_bytes = read_samples * bytes_per_sample; /* Copy data from the FLAC file buffer to the stream buffer. */ memcpy((uint8_t *)data + written_bytes, ff->buffer, read_bytes); /* Make room in the FLACFILE buffer. */ memmove(ff->buffer, ff->buffer + read_bytes, ff->buffer_pos - read_bytes); ff->buffer_pos -= read_bytes; written_bytes += read_bytes; } return written_bytes; } /* Called from al_destroy_audio_stream. */ static void flac_stream_close(ALLEGRO_AUDIO_STREAM *stream) { FLACFILE *ff = stream->extra; _al_acodec_stop_feed_thread(stream); al_fclose(ff->fh); flac_close(ff); } static bool real_seek(ALLEGRO_AUDIO_STREAM *stream, uint64_t sample) { FLACFILE *ff = stream->extra; /* We use ff->streamed_samples as the exact sample position for looping and * returning the position. Therefore we also use it as reference position * when seeking - that is, we call flush below to make the FLAC decoder * discard any additional samples it may have buffered already. * */ lib.FLAC__stream_decoder_flush(ff->decoder); lib.FLAC__stream_decoder_seek_absolute(ff->decoder, sample); ff->buffer_pos = 0; ff->streamed_samples = sample; ff->decoded_samples = sample; return true; } static bool flac_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) { FLACFILE *ff = stream->extra; uint64_t sample = time * ff->sample_rate; return real_seek(stream, sample); } static bool flac_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) { FLACFILE *ff = stream->extra; return real_seek(stream, ff->loop_start); } static double flac_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) { FLACFILE *ff = stream->extra; return ff->total_samples / ff->sample_rate; } static bool flac_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end) { FLACFILE *ff = stream->extra; ff->loop_start = start * ff->sample_rate; ff->loop_end = end * ff->sample_rate; return true; } static FLACFILE *flac_open(ALLEGRO_FILE* f) { FLACFILE *ff; FLAC__StreamDecoderInitStatus init_status; if (!init_dynlib()) { return NULL; } ff = al_calloc(1, sizeof *ff); ff->decoder = lib.FLAC__stream_decoder_new(); if (!ff->decoder) { ALLEGRO_ERROR("Error allocating FLAC decoder\n"); goto error; } ff->fh = f; if (!ff->fh) { ALLEGRO_ERROR("Error opening FLAC file\n"); goto error; } init_status = lib.FLAC__stream_decoder_init_stream(ff->decoder, read_callback, seek_callback, tell_callback, length_callback, eof_callback, write_callback, metadata_callback, error_callback, ff); if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { #ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL ALLEGRO_ERROR("Error initializing FLAC decoder\n"); /* lazy */ #else ALLEGRO_ERROR("Error initializing FLAC decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]); #endif goto error; } lib.FLAC__stream_decoder_process_until_end_of_metadata(ff->decoder); if (ff->sample_size == 0) { ALLEGRO_ERROR("Error: don't support sub 8-bit sizes\n"); goto error; } ALLEGRO_INFO("Loaded FLAC sample with properties:\n"); ALLEGRO_INFO(" channels %d\n", ff->channels); ALLEGRO_INFO(" sample_size %d\n", ff->sample_size); ALLEGRO_INFO(" rate %.f\n", ff->sample_rate); ALLEGRO_INFO(" total_samples %ld\n", (long) ff->total_samples); return ff; error: if (ff) { if (ff->decoder) lib.FLAC__stream_decoder_delete(ff->decoder); al_free(ff); } return NULL; } ALLEGRO_SAMPLE *_al_load_flac(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_SAMPLE *spl; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; spl = _al_load_flac_f(f); al_fclose(f); return spl; } ALLEGRO_SAMPLE *_al_load_flac_f(ALLEGRO_FILE *f) { ALLEGRO_SAMPLE *sample; FLACFILE *ff; ff = flac_open(f); if (!ff) { return NULL; } ff->buffer_size = ff->total_samples * ff->channels * ff->sample_size; ff->buffer = al_malloc(ff->buffer_size); lib.FLAC__stream_decoder_process_until_end_of_stream(ff->decoder); sample = al_create_sample(ff->buffer, ff->total_samples, ff->sample_rate, _al_word_size_to_depth_conf(ff->sample_size), _al_count_to_channel_conf(ff->channels), true); if (!sample) { al_free(ff->buffer); } flac_close(ff); return sample; } ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_flac_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); } return stream; } ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream_f(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples) { ALLEGRO_AUDIO_STREAM *stream; FLACFILE *ff; ff = flac_open(f); if (!ff) { return NULL; } stream = al_create_audio_stream(buffer_count, samples, ff->sample_rate, _al_word_size_to_depth_conf(ff->sample_size), _al_count_to_channel_conf(ff->channels)); if (stream) { stream->extra = ff; ff->loop_start = 0; ff->loop_end = ff->total_samples; stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); stream->feeder = flac_stream_update; stream->unload_feeder = flac_stream_close; stream->rewind_feeder = flac_stream_rewind; stream->seek_feeder = flac_stream_seek; stream->get_feeder_position = flac_stream_get_position; stream->get_feeder_length = flac_stream_get_length; stream->set_feeder_loop = flac_stream_set_loop; al_start_thread(stream->feed_thread); } else { al_fclose(ff->fh); flac_close(ff); } return stream; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/acodec/acodec.h0000644000175000001440000000444011362515001016457 0ustar tjadenusers#ifndef __al_included_acodec_acodec_h #define __al_included_acodec_acodec_h #include "allegro5/internal/aintern_acodec_cfg.h" ALLEGRO_SAMPLE *_al_load_wav(const char *filename); ALLEGRO_SAMPLE *_al_load_wav_f(ALLEGRO_FILE *fp); ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream_f(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples); bool _al_save_wav(const char *filename, ALLEGRO_SAMPLE *spl); bool _al_save_wav_f(ALLEGRO_FILE *pf, ALLEGRO_SAMPLE *spl); #ifdef ALLEGRO_CFG_ACODEC_FLAC ALLEGRO_SAMPLE *_al_load_flac(const char *filename); ALLEGRO_SAMPLE *_al_load_flac_f(ALLEGRO_FILE *f); ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream_f(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples); #endif #ifdef ALLEGRO_CFG_ACODEC_MODAUDIO ALLEGRO_AUDIO_STREAM *_al_load_mod_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_it_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_xm_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_s3m_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_mod_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_it_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_xm_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_s3m_audio_stream_f(ALLEGRO_FILE *f, size_t buffer_count, unsigned int samples); #endif #ifdef ALLEGRO_CFG_ACODEC_VORBIS ALLEGRO_SAMPLE *_al_load_ogg_vorbis(const char *filename); ALLEGRO_SAMPLE *_al_load_ogg_vorbis_f(ALLEGRO_FILE *file); ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream(const char *filename, size_t buffer_count, unsigned int samples); ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE* file, size_t buffer_count, unsigned int samples); #endif #endif allegro-5.0.10/addons/acodec/acodec.c0000644000175000001440000000417711362515001016461 0ustar tjadenusers#include "allegro5/allegro_acodec.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_acodec_cfg.h" #include "acodec.h" /* Function: al_get_allegro_acodec_version */ uint32_t al_get_allegro_acodec_version(void) { return ALLEGRO_VERSION_INT; } /* Function: al_init_acodec_addon */ bool al_init_acodec_addon(void) { bool ret = true; ret &= al_register_sample_loader(".wav", _al_load_wav); ret &= al_register_sample_saver(".wav", _al_save_wav); ret &= al_register_audio_stream_loader(".wav", _al_load_wav_audio_stream); ret &= al_register_sample_loader_f(".wav", _al_load_wav_f); ret &= al_register_sample_saver_f(".wav", _al_save_wav_f); ret &= al_register_audio_stream_loader_f(".wav", _al_load_wav_audio_stream_f); #ifdef ALLEGRO_CFG_ACODEC_FLAC ret &= al_register_sample_loader(".flac", _al_load_flac); ret &= al_register_audio_stream_loader(".flac", _al_load_flac_audio_stream); ret &= al_register_sample_loader_f(".flac", _al_load_flac_f); ret &= al_register_audio_stream_loader_f(".flac", _al_load_flac_audio_stream_f); #endif #ifdef ALLEGRO_CFG_ACODEC_MODAUDIO ret &= al_register_audio_stream_loader(".xm", _al_load_xm_audio_stream); ret &= al_register_audio_stream_loader_f(".xm", _al_load_xm_audio_stream_f); ret &= al_register_audio_stream_loader(".it", _al_load_it_audio_stream); ret &= al_register_audio_stream_loader_f(".it", _al_load_it_audio_stream_f); ret &= al_register_audio_stream_loader(".mod", _al_load_mod_audio_stream); ret &= al_register_audio_stream_loader_f(".mod", _al_load_mod_audio_stream_f); ret &= al_register_audio_stream_loader(".s3m", _al_load_s3m_audio_stream); ret &= al_register_audio_stream_loader_f(".s3m", _al_load_s3m_audio_stream_f); #endif #ifdef ALLEGRO_CFG_ACODEC_VORBIS ret &= al_register_sample_loader(".ogg", _al_load_ogg_vorbis); ret &= al_register_audio_stream_loader(".ogg", _al_load_ogg_vorbis_audio_stream); ret &= al_register_sample_loader_f(".ogg", _al_load_ogg_vorbis_f); ret &= al_register_audio_stream_loader_f(".ogg", _al_load_ogg_vorbis_audio_stream_f); #endif return ret; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/acodec/wav.c0000644000175000001440000003060112060462364016040 0ustar tjadenusers/* * Allegro5 WAV reader * author: Matthew Leverton */ #include #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern_audio.h" #include "acodec.h" #include "helper.h" ALLEGRO_DEBUG_CHANNEL("wav") typedef struct WAVFILE { ALLEGRO_FILE *f; size_t dpos; /* the starting position of the data chunk */ int freq; /* e.g., 44100 */ short bits; /* 8 (unsigned char) or 16 (signed short) */ short channels; /* 1 (mono) or 2 (stereo) */ int sample_size; /* channels * bits/8 */ int samples; /* # of samples. size = samples * sample_size */ double loop_start; double loop_end; } WAVFILE; /* wav_open: * Opens f and prepares a WAVFILE struct with the WAV format info. * On a successful return, the ALLEGRO_FILE is at the beginning of the sample data. * returns the WAVFILE on success, or NULL on failure. */ static WAVFILE *wav_open(ALLEGRO_FILE *f) { WAVFILE *wavfile = NULL; char buffer[12]; if (!f) goto wav_open_error; /* prepare default values */ wavfile = al_malloc(sizeof(WAVFILE)); if (!wavfile) { return NULL; } wavfile->f = f; wavfile->freq = 22050; wavfile->bits = 8; wavfile->channels = 1; /* check the header */ if (al_fread(f, buffer, 12) != 12) goto wav_open_error; if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4)) goto wav_open_error; /* Read as many leading fmt chunks as exist, then read until a data chunk * is found. */ while (true) { int length = 0; short pcm = 0; if (al_fread(f, buffer, 4) != 4) goto wav_open_error; /* check to see if it's a fmt chunk */ if (!memcmp(buffer, "fmt ", 4)) { length = al_fread32le(f); if (length < 16) goto wav_open_error; /* should be 1 for PCM data */ pcm = al_fread16le(f); if (pcm != 1) goto wav_open_error; /* mono or stereo data */ wavfile->channels = al_fread16le(f); if ((wavfile->channels != 1) && (wavfile->channels != 2)) goto wav_open_error; /* sample frequency */ wavfile->freq = al_fread32le(f); /* skip six bytes */ al_fseek(f, 6, ALLEGRO_SEEK_CUR); /* 8 or 16 bit data? */ wavfile->bits = al_fread16le(f); if ((wavfile->bits != 8) && (wavfile->bits != 16)) goto wav_open_error; /* Skip remainder of chunk */ length -= 16; if (length > 0) al_fseek(f, length, ALLEGRO_SEEK_CUR); } else { if (!memcmp(buffer, "data", 4)) break; ALLEGRO_INFO("Ignoring chunk: %c%c%c%c\n", buffer[0], buffer[1], buffer[2], buffer[3]); length = al_fread32le(f); al_fseek(f, length, ALLEGRO_SEEK_CUR); } } /* find out how many samples exist */ wavfile->samples = al_fread32le(f); if (wavfile->channels == 2) { wavfile->samples = (wavfile->samples + 1) / 2; } if (wavfile->bits == 16) { wavfile->samples /= 2; } wavfile->sample_size = wavfile->channels * wavfile->bits / 8; wavfile->dpos = al_ftell(f); return wavfile; wav_open_error: if (wavfile) al_free(wavfile); return NULL; } /* wav_read: * Reads up to 'samples' number of samples from the wav ALLEGRO_FILE into 'data'. * Returns the actual number of samples written to 'data'. */ static size_t wav_read(WAVFILE *wavfile, void *data, size_t samples) { size_t bytes_read; ASSERT(wavfile); bytes_read = al_fread(wavfile->f, data, samples * wavfile->sample_size); /* PCM data in RIFF WAV files is little endian. * PCM data in RIFX WAV files is big endian (which we don't support). */ #ifdef ALLEGRO_BIG_ENDIAN if (wavfile->bits == 16) { uint8_t *p = data; const uint8_t *const end = p + bytes_read - 1; /* in case bytes_read is not even */ /* swap high/low bytes */ while (p < end) { uint8_t *const q = p + 1; const uint8_t tmp = *p; *p = *q; *q = tmp; p = q; } } #endif return bytes_read / wavfile->sample_size; } /* wav_close: * Closes the ALLEGRO_FILE and frees the WAVFILE struct. */ static void wav_close(WAVFILE *wavfile) { ASSERT(wavfile); al_free(wavfile); } static bool wav_stream_seek(ALLEGRO_AUDIO_STREAM * stream, double time) { WAVFILE *wavfile = (WAVFILE *) stream->extra; int align = (wavfile->bits / 8) * wavfile->channels; unsigned long cpos = time * (double)(wavfile->freq * (wavfile->bits / 8) * wavfile->channels); if (time >= wavfile->loop_end) return false; cpos += cpos % align; return (al_fseek(wavfile->f, wavfile->dpos + cpos, ALLEGRO_SEEK_SET) != -1); } /* wav_stream_rewind: * Rewinds 'stream' to the beginning of the data chunk. * Returns true on success, false on failure. */ static bool wav_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) { WAVFILE *wavfile = (WAVFILE *) stream->extra; return wav_stream_seek(stream, wavfile->loop_start); } static double wav_stream_get_position(ALLEGRO_AUDIO_STREAM * stream) { WAVFILE *wavfile = (WAVFILE *) stream->extra; double samples_per = (double)((wavfile->bits / 8) * wavfile->channels) * (double)(wavfile->freq); return ((double)(al_ftell(wavfile->f) - wavfile->dpos) / samples_per); } static double wav_stream_get_length(ALLEGRO_AUDIO_STREAM * stream) { WAVFILE *wavfile = (WAVFILE *) stream->extra; double total_time = (double)(wavfile->samples) / (double)(wavfile->freq); return total_time; } static bool wav_stream_set_loop(ALLEGRO_AUDIO_STREAM * stream, double start, double end) { WAVFILE *wavfile = (WAVFILE *) stream->extra; wavfile->loop_start = start; wavfile->loop_end = end; return true; } /* wav_stream_update: * Updates 'stream' with the next chunk of data. * Returns the actual number of bytes written. */ static size_t wav_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, size_t buf_size) { int bytes_per_sample, samples, samples_read; double ctime, btime; WAVFILE *wavfile = (WAVFILE *) stream->extra; bytes_per_sample = (wavfile->bits / 8) * wavfile->channels; ctime = wav_stream_get_position(stream); btime = ((double)buf_size / (double)bytes_per_sample) / (double)(wavfile->freq); if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR && ctime + btime > wavfile->loop_end) { samples = ((wavfile->loop_end - ctime) * (double)(wavfile->freq)); } else { samples = buf_size / bytes_per_sample; } if (samples < 0) return 0; samples_read = wav_read(wavfile, data, samples); return samples_read * bytes_per_sample; } /* wav_stream_close: * Closes the 'stream'. */ static void wav_stream_close(ALLEGRO_AUDIO_STREAM *stream) { WAVFILE *wavfile = (WAVFILE *) stream->extra; _al_acodec_stop_feed_thread(stream); al_fclose(wavfile->f); wav_close(wavfile); stream->extra = NULL; stream->feed_thread = NULL; } /* _al_load_wav: * Reads a RIFF WAV format sample ALLEGRO_FILE, returning an ALLEGRO_SAMPLE * structure, or NULL on error. */ ALLEGRO_SAMPLE *_al_load_wav(const char *filename) { ALLEGRO_FILE *f; ALLEGRO_SAMPLE *spl; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; spl = _al_load_wav_f(f); al_fclose(f); return spl; } ALLEGRO_SAMPLE *_al_load_wav_f(ALLEGRO_FILE *fp) { WAVFILE *wavfile = wav_open(fp); ALLEGRO_SAMPLE *spl = NULL; if (wavfile) { size_t n = (wavfile->bits / 8) * wavfile->channels * wavfile->samples; char *data = al_malloc(n); if (data) { spl = al_create_sample(data, wavfile->samples, wavfile->freq, _al_word_size_to_depth_conf(wavfile->bits / 8), _al_count_to_channel_conf(wavfile->channels), true); if (spl) { memset(data, 0, n); wav_read(wavfile, data, wavfile->samples); } else { al_free(data); } } wav_close(wavfile); } return spl; } /* _al_load_wav_audio_stream: */ ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) { ALLEGRO_FILE *f; ALLEGRO_AUDIO_STREAM *stream; ASSERT(filename); f = al_fopen(filename, "rb"); if (!f) return NULL; stream = _al_load_wav_audio_stream_f(f, buffer_count, samples); if (!stream) { al_fclose(f); } return stream; } /* _al_load_wav_audio_stream_f: */ ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream_f(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples) { WAVFILE* wavfile; ALLEGRO_AUDIO_STREAM* stream; wavfile = wav_open(f); if (wavfile == NULL) return NULL; stream = al_create_audio_stream(buffer_count, samples, wavfile->freq, _al_word_size_to_depth_conf(wavfile->bits / 8), _al_count_to_channel_conf(wavfile->channels)); if (stream) { stream->extra = wavfile; wavfile->loop_start = 0.0; wavfile->loop_end = wav_stream_get_length(stream); stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); stream->feeder = wav_stream_update; stream->unload_feeder = wav_stream_close; stream->rewind_feeder = wav_stream_rewind; stream->seek_feeder = wav_stream_seek; stream->get_feeder_position = wav_stream_get_position; stream->get_feeder_length = wav_stream_get_length; stream->set_feeder_loop = wav_stream_set_loop; al_start_thread(stream->feed_thread); } else { wav_close(wavfile); } return stream; } /* _al_save_wav: * Writes a sample into a wav ALLEGRO_FILE. * Returns true on success, false on error. */ bool _al_save_wav(const char *filename, ALLEGRO_SAMPLE *spl) { ALLEGRO_FILE *pf = al_fopen(filename, "wb"); if (pf) { bool rv = _al_save_wav_f(pf, spl); al_fclose(pf); return rv; } return false; } /* _al_save_wav_f: * Writes a sample into a wav packfile. * Returns true on success, false on error. */ bool _al_save_wav_f(ALLEGRO_FILE *pf, ALLEGRO_SAMPLE *spl) { size_t channels, bits; size_t data_size; size_t samples; size_t i, n; ASSERT(spl); ASSERT(pf); /* XXX: makes use of ALLEGRO_SAMPLE internals */ channels = (spl->chan_conf >> 4) + (spl->chan_conf & 0xF); bits = (spl->depth == ALLEGRO_AUDIO_DEPTH_INT8 || spl->depth == ALLEGRO_AUDIO_DEPTH_UINT8) ? 8 : 16; if (channels < 1 || channels > 2) return false; samples = spl->len; data_size = samples * channels * bits / 8; n = samples * channels; al_fputs(pf, "RIFF"); al_fwrite32le(pf, 36 + data_size); al_fputs(pf, "WAVE"); al_fputs(pf, "fmt "); al_fwrite32le(pf, 16); al_fwrite16le(pf, 1); al_fwrite16le(pf, channels); al_fwrite32le(pf, spl->frequency); al_fwrite32le(pf, spl->frequency * channels * bits / 8); al_fwrite16le(pf, channels * bits / 8); al_fwrite16le(pf, bits); al_fputs(pf, "data"); al_fwrite32le(pf, data_size); if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT8) { al_fwrite(pf, spl->buffer.u8, samples * channels); } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT16) { al_fwrite(pf, spl->buffer.s16, samples * channels * 2); } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT8) { int8_t *data = spl->buffer.s8; for (i = 0; i < samples; ++i) { al_fputc(pf, *data++ + 0x80); } } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { uint16_t *data = spl->buffer.u16; for (i = 0; i < n; ++i) { al_fwrite16le(pf, *data++ - 0x8000); } } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT24) { int32_t *data = spl->buffer.s24; for (i = 0; i < n; ++i) { const int v = ((float)(*data++ + 0x800000) / 0x7FFFFF) * 0x7FFF - 0x8000; al_fwrite16le(pf, v); } } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT24) { uint32_t *data = spl->buffer.u24; for (i = 0; i < n; ++i) { const int v = ((float)(*data++) / 0x7FFFFF) * 0x7FFF - 0x8000; al_fwrite16le(pf, v); } } else if (spl->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) { float *data = spl->buffer.f32; for (i = 0; i < n; ++i) { al_fwrite16le(pf, *data * 0x7FFF); data++; } } else { ALLEGRO_ERROR("Unknown audio depth (%d) when saving wav ALLEGRO_FILE.\n", spl->depth); return false; } return true; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/addons/acodec/allegro5/0000755000175000001440000000000012157230737016615 5ustar tjadenusersallegro-5.0.10/addons/acodec/allegro5/allegro_acodec.h0000644000175000001440000000172211426530515021706 0ustar tjadenusers#ifndef __al_included_allegro5_allegro_acodec_h #define __al_included_allegro5_allegro_acodec_h #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #ifdef __cplusplus extern "C" { #endif #if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_ACODEC_SRC #define _ALLEGRO_ACODEC_DLL __declspec(dllexport) #else #define _ALLEGRO_ACODEC_DLL __declspec(dllimport) #endif #else #define _ALLEGRO_ACODEC_DLL #endif #endif #if defined ALLEGRO_MSVC #define ALLEGRO_ACODEC_FUNC(type, name, args) _ALLEGRO_ACODEC_DLL type __cdecl name args #elif defined ALLEGRO_MINGW32 #define ALLEGRO_ACODEC_FUNC(type, name, args) extern type name args #else #define ALLEGRO_ACODEC_FUNC AL_FUNC #endif ALLEGRO_ACODEC_FUNC(bool, al_init_acodec_addon, (void)); ALLEGRO_ACODEC_FUNC(uint32_t, al_get_allegro_acodec_version, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/addons/acodec/allegro5/internal/0000755000175000001440000000000012157230515020423 5ustar tjadenusersallegro-5.0.10/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake0000644000175000001440000000067611534666254025454 0ustar tjadenusers#cmakedefine ALLEGRO_CFG_ACODEC_FLAC #cmakedefine ALLEGRO_CFG_ACODEC_MODAUDIO #cmakedefine ALLEGRO_CFG_ACODEC_VORBIS #cmakedefine ALLEGRO_CFG_ACODEC_TREMOR /* Define if the library should be loaded dynamically. */ #cmakedefine ALLEGRO_CFG_ACODEC_FLAC_DLL "@ALLEGRO_CFG_ACODEC_FLAC_DLL@" #cmakedefine ALLEGRO_CFG_ACODEC_DUMB_DLL "@ALLEGRO_CFG_ACODEC_DUMB_DLL@" #cmakedefine ALLEGRO_CFG_ACODEC_VORBISFILE_DLL "@ALLEGRO_CFG_ACODEC_VORBISFILE_DLL@" allegro-5.0.10/addons/acodec/helper.c0000644000175000001440000000110012061076500016504 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_audio.h" #include "allegro5/internal/aintern_system.h" #include "helper.h" void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream) { ALLEGRO_EVENT quit_event; quit_event.type = _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE; al_emit_user_event(al_get_audio_stream_event_source(stream), &quit_event, NULL); al_join_thread(stream->feed_thread, NULL); al_destroy_thread(stream->feed_thread); stream->feed_thread = NULL; } allegro-5.0.10/addons/acodec/helper.h0000644000175000001440000000022512060462364016526 0ustar tjadenusers#ifndef __al_included_acodec_helper_h #define __al_included_acodec_helper_h void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream); #endif allegro-5.0.10/src/0000755000175000001440000000000012157230741013177 5ustar tjadenusersallegro-5.0.10/src/math.c0000644000175000001440000004220311433100616014266 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Fixed point math routines and lookup tables. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #ifdef ALLEGRO_MSVC #define hypotf(x, y) _hypotf((x), (y)) #endif al_fixed _al_fix_cos_tbl[512] = { /* precalculated fixed point (16.16) cosines for a full circle (0-255) */ 65536L, 65531L, 65516L, 65492L, 65457L, 65413L, 65358L, 65294L, 65220L, 65137L, 65043L, 64940L, 64827L, 64704L, 64571L, 64429L, 64277L, 64115L, 63944L, 63763L, 63572L, 63372L, 63162L, 62943L, 62714L, 62476L, 62228L, 61971L, 61705L, 61429L, 61145L, 60851L, 60547L, 60235L, 59914L, 59583L, 59244L, 58896L, 58538L, 58172L, 57798L, 57414L, 57022L, 56621L, 56212L, 55794L, 55368L, 54934L, 54491L, 54040L, 53581L, 53114L, 52639L, 52156L, 51665L, 51166L, 50660L, 50146L, 49624L, 49095L, 48559L, 48015L, 47464L, 46906L, 46341L, 45769L, 45190L, 44604L, 44011L, 43412L, 42806L, 42194L, 41576L, 40951L, 40320L, 39683L, 39040L, 38391L, 37736L, 37076L, 36410L, 35738L, 35062L, 34380L, 33692L, 33000L, 32303L, 31600L, 30893L, 30182L, 29466L, 28745L, 28020L, 27291L, 26558L, 25821L, 25080L, 24335L, 23586L, 22834L, 22078L, 21320L, 20557L, 19792L, 19024L, 18253L, 17479L, 16703L, 15924L, 15143L, 14359L, 13573L, 12785L, 11996L, 11204L, 10411L, 9616L, 8820L, 8022L, 7224L, 6424L, 5623L, 4821L, 4019L, 3216L, 2412L, 1608L, 804L, 0L, -804L, -1608L, -2412L, -3216L, -4019L, -4821L, -5623L, -6424L, -7224L, -8022L, -8820L, -9616L, -10411L, -11204L, -11996L, -12785L, -13573L, -14359L, -15143L, -15924L, -16703L, -17479L, -18253L, -19024L, -19792L, -20557L, -21320L, -22078L, -22834L, -23586L, -24335L, -25080L, -25821L, -26558L, -27291L, -28020L, -28745L, -29466L, -30182L, -30893L, -31600L, -32303L, -33000L, -33692L, -34380L, -35062L, -35738L, -36410L, -37076L, -37736L, -38391L, -39040L, -39683L, -40320L, -40951L, -41576L, -42194L, -42806L, -43412L, -44011L, -44604L, -45190L, -45769L, -46341L, -46906L, -47464L, -48015L, -48559L, -49095L, -49624L, -50146L, -50660L, -51166L, -51665L, -52156L, -52639L, -53114L, -53581L, -54040L, -54491L, -54934L, -55368L, -55794L, -56212L, -56621L, -57022L, -57414L, -57798L, -58172L, -58538L, -58896L, -59244L, -59583L, -59914L, -60235L, -60547L, -60851L, -61145L, -61429L, -61705L, -61971L, -62228L, -62476L, -62714L, -62943L, -63162L, -63372L, -63572L, -63763L, -63944L, -64115L, -64277L, -64429L, -64571L, -64704L, -64827L, -64940L, -65043L, -65137L, -65220L, -65294L, -65358L, -65413L, -65457L, -65492L, -65516L, -65531L, -65536L, -65531L, -65516L, -65492L, -65457L, -65413L, -65358L, -65294L, -65220L, -65137L, -65043L, -64940L, -64827L, -64704L, -64571L, -64429L, -64277L, -64115L, -63944L, -63763L, -63572L, -63372L, -63162L, -62943L, -62714L, -62476L, -62228L, -61971L, -61705L, -61429L, -61145L, -60851L, -60547L, -60235L, -59914L, -59583L, -59244L, -58896L, -58538L, -58172L, -57798L, -57414L, -57022L, -56621L, -56212L, -55794L, -55368L, -54934L, -54491L, -54040L, -53581L, -53114L, -52639L, -52156L, -51665L, -51166L, -50660L, -50146L, -49624L, -49095L, -48559L, -48015L, -47464L, -46906L, -46341L, -45769L, -45190L, -44604L, -44011L, -43412L, -42806L, -42194L, -41576L, -40951L, -40320L, -39683L, -39040L, -38391L, -37736L, -37076L, -36410L, -35738L, -35062L, -34380L, -33692L, -33000L, -32303L, -31600L, -30893L, -30182L, -29466L, -28745L, -28020L, -27291L, -26558L, -25821L, -25080L, -24335L, -23586L, -22834L, -22078L, -21320L, -20557L, -19792L, -19024L, -18253L, -17479L, -16703L, -15924L, -15143L, -14359L, -13573L, -12785L, -11996L, -11204L, -10411L, -9616L, -8820L, -8022L, -7224L, -6424L, -5623L, -4821L, -4019L, -3216L, -2412L, -1608L, -804L, 0L, 804L, 1608L, 2412L, 3216L, 4019L, 4821L, 5623L, 6424L, 7224L, 8022L, 8820L, 9616L, 10411L, 11204L, 11996L, 12785L, 13573L, 14359L, 15143L, 15924L, 16703L, 17479L, 18253L, 19024L, 19792L, 20557L, 21320L, 22078L, 22834L, 23586L, 24335L, 25080L, 25821L, 26558L, 27291L, 28020L, 28745L, 29466L, 30182L, 30893L, 31600L, 32303L, 33000L, 33692L, 34380L, 35062L, 35738L, 36410L, 37076L, 37736L, 38391L, 39040L, 39683L, 40320L, 40951L, 41576L, 42194L, 42806L, 43412L, 44011L, 44604L, 45190L, 45769L, 46341L, 46906L, 47464L, 48015L, 48559L, 49095L, 49624L, 50146L, 50660L, 51166L, 51665L, 52156L, 52639L, 53114L, 53581L, 54040L, 54491L, 54934L, 55368L, 55794L, 56212L, 56621L, 57022L, 57414L, 57798L, 58172L, 58538L, 58896L, 59244L, 59583L, 59914L, 60235L, 60547L, 60851L, 61145L, 61429L, 61705L, 61971L, 62228L, 62476L, 62714L, 62943L, 63162L, 63372L, 63572L, 63763L, 63944L, 64115L, 64277L, 64429L, 64571L, 64704L, 64827L, 64940L, 65043L, 65137L, 65220L, 65294L, 65358L, 65413L, 65457L, 65492L, 65516L, 65531L }; al_fixed _al_fix_tan_tbl[256] = { /* precalculated fixed point (16.16) tangents for a half circle (0-127) */ 0L, 804L, 1609L, 2414L, 3220L, 4026L, 4834L, 5644L, 6455L, 7268L, 8083L, 8901L, 9721L, 10545L, 11372L, 12202L, 13036L, 13874L, 14717L, 15564L, 16416L, 17273L, 18136L, 19005L, 19880L, 20762L, 21650L, 22546L, 23449L, 24360L, 25280L, 26208L, 27146L, 28093L, 29050L, 30018L, 30996L, 31986L, 32988L, 34002L, 35030L, 36071L, 37126L, 38196L, 39281L, 40382L, 41500L, 42636L, 43790L, 44963L, 46156L, 47369L, 48605L, 49863L, 51145L, 52451L, 53784L, 55144L, 56532L, 57950L, 59398L, 60880L, 62395L, 63947L, 65536L, 67165L, 68835L, 70548L, 72308L, 74116L, 75974L, 77887L, 79856L, 81885L, 83977L, 86135L, 88365L, 90670L, 93054L, 95523L, 98082L, 100736L, 103493L, 106358L, 109340L, 112447L, 115687L, 119071L, 122609L, 126314L, 130198L, 134276L, 138564L, 143081L, 147847L, 152884L, 158218L, 163878L, 169896L, 176309L, 183161L, 190499L, 198380L, 206870L, 216043L, 225990L, 236817L, 248648L, 261634L, 275959L, 291845L, 309568L, 329472L, 351993L, 377693L, 407305L, 441808L, 482534L, 531352L, 590958L, 665398L, 761030L, 888450L, 1066730L,1334016L,1779314L,2669641L,5340086L, -2147483647L,-5340086L,-2669641L,-1779314L,-1334016L,-1066730L,-888450L,-761030L, -665398L,-590958L,-531352L,-482534L,-441808L,-407305L,-377693L,-351993L, -329472L,-309568L,-291845L,-275959L,-261634L,-248648L,-236817L,-225990L, -216043L,-206870L,-198380L,-190499L,-183161L,-176309L,-169896L,-163878L, -158218L,-152884L,-147847L,-143081L,-138564L,-134276L,-130198L,-126314L, -122609L,-119071L,-115687L,-112447L,-109340L,-106358L,-103493L,-100736L, -98082L, -95523L, -93054L, -90670L, -88365L, -86135L, -83977L, -81885L, -79856L, -77887L, -75974L, -74116L, -72308L, -70548L, -68835L, -67165L, -65536L, -63947L, -62395L, -60880L, -59398L, -57950L, -56532L, -55144L, -53784L, -52451L, -51145L, -49863L, -48605L, -47369L, -46156L, -44963L, -43790L, -42636L, -41500L, -40382L, -39281L, -38196L, -37126L, -36071L, -35030L, -34002L, -32988L, -31986L, -30996L, -30018L, -29050L, -28093L, -27146L, -26208L, -25280L, -24360L, -23449L, -22546L, -21650L, -20762L, -19880L, -19005L, -18136L, -17273L, -16416L, -15564L, -14717L, -13874L, -13036L, -12202L, -11372L, -10545L, -9721L, -8901L, -8083L, -7268L, -6455L, -5644L, -4834L, -4026L, -3220L, -2414L, -1609L, -804L }; al_fixed _al_fix_acos_tbl[513] = { /* precalculated fixed point (16.16) inverse cosines (-1 to 1) */ 0x800000L, 0x7C65C7L, 0x7AE75AL, 0x79C19EL, 0x78C9BEL, 0x77EF25L, 0x772953L, 0x76733AL, 0x75C991L, 0x752A10L, 0x74930CL, 0x740345L, 0x7379C1L, 0x72F5BAL, 0x72768FL, 0x71FBBCL, 0x7184D3L, 0x711174L, 0x70A152L, 0x703426L, 0x6FC9B5L, 0x6F61C9L, 0x6EFC36L, 0x6E98D1L, 0x6E3777L, 0x6DD805L, 0x6D7A5EL, 0x6D1E68L, 0x6CC40BL, 0x6C6B2FL, 0x6C13C1L, 0x6BBDAFL, 0x6B68E6L, 0x6B1558L, 0x6AC2F5L, 0x6A71B1L, 0x6A217EL, 0x69D251L, 0x698420L, 0x6936DFL, 0x68EA85L, 0x689F0AL, 0x685465L, 0x680A8DL, 0x67C17DL, 0x67792CL, 0x673194L, 0x66EAAFL, 0x66A476L, 0x665EE5L, 0x6619F5L, 0x65D5A2L, 0x6591E7L, 0x654EBFL, 0x650C26L, 0x64CA18L, 0x648890L, 0x64478CL, 0x640706L, 0x63C6FCL, 0x63876BL, 0x63484FL, 0x6309A5L, 0x62CB6AL, 0x628D9CL, 0x625037L, 0x621339L, 0x61D69FL, 0x619A68L, 0x615E90L, 0x612316L, 0x60E7F7L, 0x60AD31L, 0x6072C3L, 0x6038A9L, 0x5FFEE3L, 0x5FC56EL, 0x5F8C49L, 0x5F5372L, 0x5F1AE7L, 0x5EE2A7L, 0x5EAAB0L, 0x5E7301L, 0x5E3B98L, 0x5E0473L, 0x5DCD92L, 0x5D96F3L, 0x5D6095L, 0x5D2A76L, 0x5CF496L, 0x5CBEF2L, 0x5C898BL, 0x5C545EL, 0x5C1F6BL, 0x5BEAB0L, 0x5BB62DL, 0x5B81E1L, 0x5B4DCAL, 0x5B19E7L, 0x5AE638L, 0x5AB2BCL, 0x5A7F72L, 0x5A4C59L, 0x5A1970L, 0x59E6B6L, 0x59B42AL, 0x5981CCL, 0x594F9BL, 0x591D96L, 0x58EBBDL, 0x58BA0EL, 0x588889L, 0x58572DL, 0x5825FAL, 0x57F4EEL, 0x57C40AL, 0x57934DL, 0x5762B5L, 0x573243L, 0x5701F5L, 0x56D1CCL, 0x56A1C6L, 0x5671E4L, 0x564224L, 0x561285L, 0x55E309L, 0x55B3ADL, 0x558471L, 0x555555L, 0x552659L, 0x54F77BL, 0x54C8BCL, 0x549A1BL, 0x546B98L, 0x543D31L, 0x540EE7L, 0x53E0B9L, 0x53B2A7L, 0x5384B0L, 0x5356D4L, 0x532912L, 0x52FB6BL, 0x52CDDDL, 0x52A068L, 0x52730CL, 0x5245C9L, 0x52189EL, 0x51EB8BL, 0x51BE8FL, 0x5191AAL, 0x5164DCL, 0x513825L, 0x510B83L, 0x50DEF7L, 0x50B280L, 0x50861FL, 0x5059D2L, 0x502D99L, 0x500175L, 0x4FD564L, 0x4FA967L, 0x4F7D7DL, 0x4F51A6L, 0x4F25E2L, 0x4EFA30L, 0x4ECE90L, 0x4EA301L, 0x4E7784L, 0x4E4C19L, 0x4E20BEL, 0x4DF574L, 0x4DCA3AL, 0x4D9F10L, 0x4D73F6L, 0x4D48ECL, 0x4D1DF1L, 0x4CF305L, 0x4CC829L, 0x4C9D5AL, 0x4C729AL, 0x4C47E9L, 0x4C1D45L, 0x4BF2AEL, 0x4BC826L, 0x4B9DAAL, 0x4B733BL, 0x4B48D9L, 0x4B1E84L, 0x4AF43BL, 0x4AC9FEL, 0x4A9FCDL, 0x4A75A7L, 0x4A4B8DL, 0x4A217EL, 0x49F77AL, 0x49CD81L, 0x49A393L, 0x4979AFL, 0x494FD5L, 0x492605L, 0x48FC3FL, 0x48D282L, 0x48A8CFL, 0x487F25L, 0x485584L, 0x482BECL, 0x48025DL, 0x47D8D6L, 0x47AF57L, 0x4785E0L, 0x475C72L, 0x47330AL, 0x4709ABL, 0x46E052L, 0x46B701L, 0x468DB7L, 0x466474L, 0x463B37L, 0x461201L, 0x45E8D0L, 0x45BFA6L, 0x459682L, 0x456D64L, 0x45444BL, 0x451B37L, 0x44F229L, 0x44C920L, 0x44A01CL, 0x44771CL, 0x444E21L, 0x44252AL, 0x43FC38L, 0x43D349L, 0x43AA5FL, 0x438178L, 0x435894L, 0x432FB4L, 0x4306D8L, 0x42DDFEL, 0x42B527L, 0x428C53L, 0x426381L, 0x423AB2L, 0x4211E5L, 0x41E91AL, 0x41C051L, 0x41978AL, 0x416EC5L, 0x414601L, 0x411D3EL, 0x40F47CL, 0x40CBBBL, 0x40A2FBL, 0x407A3CL, 0x40517DL, 0x4028BEL, 0x400000L, 0x3FD742L, 0x3FAE83L, 0x3F85C4L, 0x3F5D05L, 0x3F3445L, 0x3F0B84L, 0x3EE2C2L, 0x3EB9FFL, 0x3E913BL, 0x3E6876L, 0x3E3FAFL, 0x3E16E6L, 0x3DEE1BL, 0x3DC54EL, 0x3D9C7FL, 0x3D73ADL, 0x3D4AD9L, 0x3D2202L, 0x3CF928L, 0x3CD04CL, 0x3CA76CL, 0x3C7E88L, 0x3C55A1L, 0x3C2CB7L, 0x3C03C8L, 0x3BDAD6L, 0x3BB1DFL, 0x3B88E4L, 0x3B5FE4L, 0x3B36E0L, 0x3B0DD7L, 0x3AE4C9L, 0x3ABBB5L, 0x3A929CL, 0x3A697EL, 0x3A405AL, 0x3A1730L, 0x39EDFFL, 0x39C4C9L, 0x399B8CL, 0x397249L, 0x3948FFL, 0x391FAEL, 0x38F655L, 0x38CCF6L, 0x38A38EL, 0x387A20L, 0x3850A9L, 0x38272AL, 0x37FDA3L, 0x37D414L, 0x37AA7CL, 0x3780DBL, 0x375731L, 0x372D7EL, 0x3703C1L, 0x36D9FBL, 0x36B02BL, 0x368651L, 0x365C6DL, 0x36327FL, 0x360886L, 0x35DE82L, 0x35B473L, 0x358A59L, 0x356033L, 0x353602L, 0x350BC5L, 0x34E17CL, 0x34B727L, 0x348CC5L, 0x346256L, 0x3437DAL, 0x340D52L, 0x33E2BBL, 0x33B817L, 0x338D66L, 0x3362A6L, 0x3337D7L, 0x330CFBL, 0x32E20FL, 0x32B714L, 0x328C0AL, 0x3260F0L, 0x3235C6L, 0x320A8CL, 0x31DF42L, 0x31B3E7L, 0x31887CL, 0x315CFFL, 0x313170L, 0x3105D0L, 0x30DA1EL, 0x30AE5AL, 0x308283L, 0x305699L, 0x302A9CL, 0x2FFE8BL, 0x2FD267L, 0x2FA62EL, 0x2F79E1L, 0x2F4D80L, 0x2F2109L, 0x2EF47DL, 0x2EC7DBL, 0x2E9B24L, 0x2E6E56L, 0x2E4171L, 0x2E1475L, 0x2DE762L, 0x2DBA37L, 0x2D8CF4L, 0x2D5F98L, 0x2D3223L, 0x2D0495L, 0x2CD6EEL, 0x2CA92CL, 0x2C7B50L, 0x2C4D59L, 0x2C1F47L, 0x2BF119L, 0x2BC2CFL, 0x2B9468L, 0x2B65E5L, 0x2B3744L, 0x2B0885L, 0x2AD9A7L, 0x2AAAABL, 0x2A7B8FL, 0x2A4C53L, 0x2A1CF7L, 0x29ED7BL, 0x29BDDCL, 0x298E1CL, 0x295E3AL, 0x292E34L, 0x28FE0BL, 0x28CDBDL, 0x289D4BL, 0x286CB3L, 0x283BF6L, 0x280B12L, 0x27DA06L, 0x27A8D3L, 0x277777L, 0x2745F2L, 0x271443L, 0x26E26AL, 0x26B065L, 0x267E34L, 0x264BD6L, 0x26194AL, 0x25E690L, 0x25B3A7L, 0x25808EL, 0x254D44L, 0x2519C8L, 0x24E619L, 0x24B236L, 0x247E1FL, 0x2449D3L, 0x241550L, 0x23E095L, 0x23ABA2L, 0x237675L, 0x23410EL, 0x230B6AL, 0x22D58AL, 0x229F6BL, 0x22690DL, 0x22326EL, 0x21FB8DL, 0x21C468L, 0x218CFFL, 0x215550L, 0x211D59L, 0x20E519L, 0x20AC8EL, 0x2073B7L, 0x203A92L, 0x20011DL, 0x1FC757L, 0x1F8D3DL, 0x1F52CFL, 0x1F1809L, 0x1EDCEAL, 0x1EA170L, 0x1E6598L, 0x1E2961L, 0x1DECC7L, 0x1DAFC9L, 0x1D7264L, 0x1D3496L, 0x1CF65BL, 0x1CB7B1L, 0x1C7895L, 0x1C3904L, 0x1BF8FAL, 0x1BB874L, 0x1B7770L, 0x1B35E8L, 0x1AF3DAL, 0x1AB141L, 0x1A6E19L, 0x1A2A5EL, 0x19E60BL, 0x19A11BL, 0x195B8AL, 0x191551L, 0x18CE6CL, 0x1886D4L, 0x183E83L, 0x17F573L, 0x17AB9BL, 0x1760F6L, 0x17157BL, 0x16C921L, 0x167BE0L, 0x162DAFL, 0x15DE82L, 0x158E4FL, 0x153D0BL, 0x14EAA8L, 0x14971AL, 0x144251L, 0x13EC3FL, 0x1394D1L, 0x133BF5L, 0x12E198L, 0x1285A2L, 0x1227FBL, 0x11C889L, 0x11672FL, 0x1103CAL, 0x109E37L, 0x10364BL, 0xFCBDAL, 0xF5EAEL, 0xEEE8CL, 0xE7B2DL, 0xE0444L, 0xD8971L, 0xD0A46L, 0xC863FL, 0xBFCBBL, 0xB6CF4L, 0xAD5F0L, 0xA366FL, 0x98CC6L, 0x8D6ADL, 0x810DBL, 0x73642L, 0x63E62L, 0x518A6L, 0x39A39L, 0x0L }; /* Function: al_fixatan * Fixed point inverse tangent. Does a binary search on the tan table. */ al_fixed al_fixatan(al_fixed x) { int a, b, c; /* for binary search */ al_fixed d; /* difference value for search */ if (x >= 0) { /* search the first part of tan table */ a = 0; b = 127; } else { /* search the second half instead */ a = 128; b = 255; } do { c = (a + b) >> 1; d = x - _al_fix_tan_tbl[c]; if (d > 0) a = c + 1; else if (d < 0) b = c - 1; } while ((a <= b) && (d)); if (x >= 0) return ((long)c) << 15; return (-0x00800000L + (((long)c) << 15)); } /* Function: al_fixatan2 * Like the libc atan2, but for fixed point numbers. */ al_fixed al_fixatan2(al_fixed y, al_fixed x) { al_fixed r; if (x==0) { if (y==0) { al_set_errno(EDOM); return 0L; } else return ((y < 0) ? -0x00400000L : 0x00400000L); } al_set_errno(0); r = al_fixdiv(y, x); if (al_get_errno()) { al_set_errno(0); return ((y < 0) ? -0x00400000L : 0x00400000L); } r = al_fixatan(r); if (x >= 0) return r; if (y >= 0) return 0x00800000L + r; return r - 0x00800000L; } /* Enum: al_fixtorad_r * Ratios for converting between radians and fixed point angles. * 2pi/256 */ const al_fixed al_fixtorad_r = (al_fixed)1608; /* Enum: al_radtofix_r * Ratios for converting between radians and fixed point angles. * 256/2pi */ const al_fixed al_radtofix_r = (al_fixed)2670177; /* Function: al_fixsqrt * Fixed point square root routine for non-i386. */ al_fixed al_fixsqrt(al_fixed x) { if (x > 0) return al_ftofix(sqrt(al_fixtof(x))); if (x < 0) al_set_errno(EDOM); return 0; } /* Function: al_fixhypot * Fixed point sqrt (x*x+y*y) for non-i386. */ al_fixed al_fixhypot(al_fixed x, al_fixed y) { return al_ftofix(hypotf(al_fixtof(x), al_fixtof(y))); } /* These prototypes exist for documentation only. */ /* Function: al_itofix */ al_fixed al_itofix(int x); /* Function: al_fixtoi */ int al_fixtoi(al_fixed x); /* Function: al_fixfloor */ int al_fixfloor(al_fixed x); /* Function: al_fixceil */ int al_fixceil(al_fixed x); /* Function: al_ftofix */ al_fixed al_ftofix(double x); /* Function: al_fixtof */ double al_fixtof(al_fixed x); /* Function: al_fixadd */ al_fixed al_fixadd(al_fixed x, al_fixed y); /* Function: al_fixsub */ al_fixed al_fixsub(al_fixed x, al_fixed y); /* Function: al_fixmul */ al_fixed al_fixmul(al_fixed x, al_fixed y); /* Function: al_fixdiv */ al_fixed al_fixdiv(al_fixed x, al_fixed y); /* Function: al_fixcos */ al_fixed al_fixcos(al_fixed x); /* Function: al_fixsin */ al_fixed al_fixsin(al_fixed x); /* Function: al_fixtan */ al_fixed al_fixtan(al_fixed x); /* Function: al_fixacos */ al_fixed al_fixacos(al_fixed x); /* Function: al_fixasin */ al_fixed al_fixasin(al_fixed x); allegro-5.0.10/src/timernu.c0000644000175000001440000002071012125160224015017 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New timer API. * * By Peter Wang. * * See readme.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_timer.h" #ifndef ALLEGRO_MSVC #ifndef ALLEGRO_BCC32 #include #endif #endif /* forward declarations */ static double timer_thread_handle_tick(double interval); static void timer_handle_tick(ALLEGRO_TIMER *timer); struct ALLEGRO_TIMER { ALLEGRO_EVENT_SOURCE es; bool started; double speed_secs; int64_t count; double counter; /* counts down to zero=blastoff */ }; /* * The timer thread that runs in the background to drive the timers. */ static _AL_MUTEX timers_mutex = _AL_MUTEX_UNINITED; static _AL_VECTOR active_timers = _AL_VECTOR_INITIALIZER(ALLEGRO_TIMER *); static _AL_THREAD * volatile timer_thread = NULL; /* timer_thread_proc: [timer thread] * The timer thread procedure itself. */ static void timer_thread_proc(_AL_THREAD *self, void *unused) { #if 0 /* Block all signals. */ /* This was needed for some reason in v4, but I can't remember why, * and it might not be relevant now. It has a tendency to create * zombie processes if the program is aborted abnormally, so I'm * taking it out for now. */ { sigset_t mask; sigfillset(&mask); pthread_sigmask(SIG_BLOCK, &mask, NULL); } #endif #ifdef ALLEGRO_QNX /* thread priority adjustment for QNX: * The timer thread is set to the highest relative priority. * (see the comment in src/qnx/qsystem.c about the scheduling policy) */ { struct sched_param sparam; int spolicy; if (pthread_getschedparam(pthread_self(), &spolicy, &sparam) == EOK) { sparam.sched_priority += 4; pthread_setschedparam(pthread_self(), spolicy, &sparam); } } #endif double old_time = al_get_time(); double new_time; double interval = 0.032768; while (!_al_get_thread_should_stop(self)) { al_rest(interval); _al_mutex_lock(&timers_mutex); { /* Calculate actual time elapsed. */ new_time = al_get_time(); interval = new_time - old_time; old_time = new_time; /* Handle a tick. */ interval = timer_thread_handle_tick(interval); } _al_mutex_unlock(&timers_mutex); } (void)unused; } /* timer_thread_handle_tick: [timer thread] * Call handle_tick() method of every timer in active_timers, and * returns the duration that the timer thread should try to sleep * next time. */ static double timer_thread_handle_tick(double interval) { double new_delay = 0.032768; unsigned int i; for (i = 0; i < _al_vector_size(&active_timers); i++) { ALLEGRO_TIMER **slot = _al_vector_ref(&active_timers, i); ALLEGRO_TIMER *timer = *slot; timer->counter -= interval; while (timer->counter <= 0) { timer_handle_tick(timer); timer->counter += timer->speed_secs; } if ((timer->counter > 0) && (timer->counter < new_delay)) new_delay = timer->counter; } return new_delay; } static void shutdown_timers(void) { ASSERT(_al_vector_size(&active_timers) == 0); ASSERT(timer_thread == NULL); _al_mutex_destroy(&timers_mutex); } void _al_init_timers(void) { _al_mutex_init(&timers_mutex); _al_add_exit_func(shutdown_timers, "shutdown_timers"); } /* * Timer objects */ /* Function: al_create_timer */ ALLEGRO_TIMER *al_create_timer(double speed_secs) { ASSERT(speed_secs > 0); { ALLEGRO_TIMER *timer = al_malloc(sizeof *timer); ASSERT(timer); if (timer) { _al_event_source_init(&timer->es); timer->started = false; timer->count = 0; timer->speed_secs = speed_secs; timer->counter = 0; _al_register_destructor(_al_dtor_list, timer, (void (*)(void *)) al_destroy_timer); } return timer; } } /* Function: al_destroy_timer */ void al_destroy_timer(ALLEGRO_TIMER *timer) { if (timer) { al_stop_timer(timer); _al_unregister_destructor(_al_dtor_list, timer); _al_event_source_free(&timer->es); al_free(timer); } } /* Function: al_start_timer */ void al_start_timer(ALLEGRO_TIMER *timer) { ASSERT(timer); { size_t new_size; if (timer->started) return; _al_mutex_lock(&timers_mutex); { ALLEGRO_TIMER **slot; timer->started = true; timer->counter = timer->speed_secs; slot = _al_vector_alloc_back(&active_timers); *slot = timer; new_size = _al_vector_size(&active_timers); } _al_mutex_unlock(&timers_mutex); if (new_size == 1) { timer_thread = al_malloc(sizeof(_AL_THREAD)); _al_thread_create(timer_thread, timer_thread_proc, NULL); } } } /* Function: al_stop_timer */ void al_stop_timer(ALLEGRO_TIMER *timer) { ASSERT(timer); { _AL_THREAD *thread_to_join = NULL; if (!timer->started) return; _al_mutex_lock(&timers_mutex); { _al_vector_find_and_delete(&active_timers, &timer); timer->started = false; if (_al_vector_size(&active_timers) == 0) { _al_vector_free(&active_timers); thread_to_join = timer_thread; timer_thread = NULL; } } _al_mutex_unlock(&timers_mutex); if (thread_to_join) { _al_thread_join(thread_to_join); al_free(thread_to_join); } } } /* Function: al_get_timer_started */ bool al_get_timer_started(const ALLEGRO_TIMER *timer) { ASSERT(timer); return timer->started; } /* Function: al_get_timer_speed */ double al_get_timer_speed(const ALLEGRO_TIMER *timer) { ASSERT(timer); return timer->speed_secs; } /* Function: al_set_timer_speed */ void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs) { ASSERT(timer); ASSERT(new_speed_secs > 0); _al_mutex_lock(&timers_mutex); { if (timer->started) { timer->counter -= timer->speed_secs; timer->counter += new_speed_secs; } timer->speed_secs = new_speed_secs; } _al_mutex_unlock(&timers_mutex); } /* Function: al_get_timer_count */ int64_t al_get_timer_count(const ALLEGRO_TIMER *timer) { ASSERT(timer); return timer->count; } /* Function: al_set_timer_count */ void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count) { ASSERT(timer); _al_mutex_lock(&timers_mutex); { timer->count = new_count; } _al_mutex_unlock(&timers_mutex); } /* Function: al_add_timer_count */ void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff) { ASSERT(timer); _al_mutex_lock(&timers_mutex); { timer->count += diff; } _al_mutex_unlock(&timers_mutex); } /* timer_handle_tick: [timer thread] * Handle a single tick. */ static void timer_handle_tick(ALLEGRO_TIMER *timer) { /* Lock out event source helper functions (e.g. the release hook * could be invoked simultaneously with this function). */ _al_event_source_lock(&timer->es); { /* Update the count. */ timer->count++; /* Generate an event, maybe. */ if (_al_event_source_needs_to_generate_event(&timer->es)) { ALLEGRO_EVENT event; event.timer.type = ALLEGRO_EVENT_TIMER; event.timer.timestamp = al_get_time(); event.timer.count = timer->count; event.timer.error = -timer->counter; _al_event_source_emit_event(&timer->es, &event); } } _al_event_source_unlock(&timer->es); } /* Function: al_get_timer_event_source */ ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer) { return &timer->es; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/tls_native.inc0000644000175000001440000000207112066715441016046 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread local storage. * * See LICENSE.txt for copyright information. */ #if defined(ALLEGRO_MSVC) || defined(ALLEGRO_BCC32) #define THREAD_LOCAL_QUALIFIER __declspec(thread) #else #define THREAD_LOCAL_QUALIFIER __thread #endif static THREAD_LOCAL_QUALIFIER thread_local_state _tls; void _al_tls_init_once(void) { /* nothing */ } static thread_local_state *tls_get(void) { static THREAD_LOCAL_QUALIFIER thread_local_state *ptr = NULL; if (!ptr) { ptr = &_tls; initialize_tls_values(ptr); } return ptr; } /* vim: set ft=c sts=3 sw=3 et: */ allegro-5.0.10/src/linux/0000755000175000001440000000000012157230740014335 5ustar tjadenusersallegro-5.0.10/src/linux/lmemory.c0000644000175000001440000000460611426530105016167 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory mapping helpers for Linux Allegro. * * By George Foot, heavily based upon Marek Habersack's code. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #if !defined(_POSIX_MAPPED_FILES) || !defined(ALLEGRO_HAVE_MMAP) #error "Sorry, mapped files are required for Linux console Allegro to work!" #endif #include #include static int mem_fd = -1; /* fd of /dev/mem */ /* __al_linux_init_memory: * Prepares to be able to map memory; returns 0 on success. */ int __al_linux_init_memory (void) { mem_fd = open ("/dev/mem", O_RDWR); if (mem_fd < 0) return 1; mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ); return 0; } /* __al_linux_shutdown_memory: * Turns off memory mapping, returning 0 on success. */ int __al_linux_shutdown_memory (void) { if (mem_fd < 0) return 1; mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ | PROT_WRITE); close (mem_fd); mem_fd = -1; return 0; } /* __al_linux_map_memory: * Given a MAPPED_MEMORY struct with physical address, size and * permissions filled in, this function maps the memory and fills * in the pointer in the struct. Returns 0 on success; errno will * be set on error. */ int __al_linux_map_memory (struct MAPPED_MEMORY *info) { ASSERT(info); info->data = mmap (0, info->size, info->perms, MAP_SHARED, mem_fd, info->base); if (info->data == MAP_FAILED) { info->data = NULL; return 1; } return 0; } /* __al_linux_unmap_memory: * Given a MAPPED_MEMORY struct, this function unmaps * the block. Returns 0 on success, errno set on error. */ int __al_linux_unmap_memory (struct MAPPED_MEMORY *info) { ASSERT(info); if (info->data == NULL) return 0; if (!munmap (info->data, info->size)) { info->data = NULL; return 0; } return 1; } allegro-5.0.10/src/linux/lasyncio.c0000644000175000001440000000630712132132150016315 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Asynchronous I/O helpers for Linux Allegro. * * By Marek Habersack, mangled by George Foot. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #include #include #include static SIGIO_HOOK user_sigio_hook = NULL; #define DEFAULT_ASYNC_IO_MODE ASYNC_BSD unsigned __al_linux_async_io_mode = 0; /* al_linux_install_sigio_hook: * Install a hook to be called from inside the SIGIO signal handler. * It will be invoked AFTER the standard drivers are called. Note * that it's not a very good way to handle SIGIO in your application. * If you really need to use SIGIO, consider updating input events * by hand, i.e. synchronously. Or, preferably, use the select(2) * facility for asynchronous input. * * The previous hook is returned, NULL if none. */ SIGIO_HOOK al_linux_install_sigio_hook (SIGIO_HOOK hook) { SIGIO_HOOK ret = user_sigio_hook; user_sigio_hook = hook; return ret; } /* async_io_event: * A handler for the SIGIO signal. It used to be inelegant, more * optimised for speed, but I changed that because it was causing * problems (mouse motion stopped the keyboard responding). */ static void async_io_event(int signo) { if (__al_linux_std_drivers[STD_MOUSE]) __al_linux_std_drivers[STD_MOUSE]->update(); if (__al_linux_std_drivers[STD_KBD]) __al_linux_std_drivers[STD_KBD]->update(); if (user_sigio_hook) user_sigio_hook(SIGIO); return; } /* al_linux_set_async_mode: * Sets the asynchronous I/O mode for the registered standard device * drivers. The async I/O is based on the BSD-compatible SIGIO signal. */ int al_linux_set_async_mode (unsigned type) { static struct sigaction org_sigio; struct sigaction sa; if (type == ASYNC_DEFAULT) type = DEFAULT_ASYNC_IO_MODE; /* Turn off drivers */ __al_linux_async_set_drivers (__al_linux_async_io_mode, 0); /* Shut down the previous mode */ switch (__al_linux_async_io_mode) { case ASYNC_BSD: sigaction (SIGIO, &org_sigio, NULL); break; } __al_linux_async_io_mode = type; /* Initialise the new mode */ switch (__al_linux_async_io_mode) { case ASYNC_BSD: sa.sa_flags = SA_RESTART; sa.sa_handler = async_io_event; sigfillset (&sa.sa_mask); sigaction (SIGIO, &sa, &org_sigio); break; } /* Turn drivers back on again */ __al_linux_async_set_drivers (__al_linux_async_io_mode, 1); return 0; } int al_linux_is_async_mode (void) { return (__al_linux_async_io_mode != ASYNC_OFF); } allegro-5.0.10/src/linux/lmsedrv.c0000644000175000001440000000301612125426002016146 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console mouse driver list. * * By George Foot. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/platform/aintunix.h" /* list the available drivers */ _AL_DRIVER_INFO _al_linux_mouse_driver_list[] = { /* These drivers have not been updated for the new mouse API. * They may be updated as required, although the evdev driver * should be fine on modern kernels --pw */ /* { MOUSEDRV_LINUX_GPMDATA, &mousedrv_linux_gpmdata, true },*/ /* { MOUSEDRV_LINUX_MS, &mousedrv_linux_ms, true },*/ /* { MOUSEDRV_LINUX_IMS, &mousedrv_linux_ims, true },*/ /* { MOUSEDRV_LINUX_PS2, &mousedrv_linux_ps2, true },*/ /* { MOUSEDRV_LINUX_IPS2, &mousedrv_linux_ips2, true },*/ #ifdef ALLEGRO_HAVE_LINUX_INPUT_H { AL_MOUSEDRV_LINUX_EVDEV, &_al_mousedrv_linux_evdev, true }, #endif { 0, NULL, 0 } }; allegro-5.0.10/src/linux/lsystem.c0000644000175000001440000001330212132133074016173 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console system driver. * * By George Foot. * * See readme.txt for copyright information. */ #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/platform/aintunix.h" #include "allegro5/platform/aintlnx.h" #include "allegro5/linalleg.h" #ifndef ALLEGRO_LINUX #error Something is wrong with the makefile #endif static int sys_linux_init(void); static void sys_linux_exit(void); static void sys_linux_message (const char *msg); static void sys_linux_save_console_state(void); static void sys_linux_restore_console_state(void); /* driver list getters */ #define make_getter(x,y) static _AL_DRIVER_INFO *get_##y##_driver_list (void) { return x##_##y##_driver_list; } make_getter (_unix, gfx) make_getter (_unix, digi) make_getter (_unix, midi) make_getter (_al_linux, keyboard) make_getter (_al_linux, mouse) make_getter (_al_linux, joystick) #undef make_getter /* the main system driver for running on the Linux console */ SYSTEM_DRIVER system_linux = { SYSTEM_LINUX, "", "", "Linux console", sys_linux_init, sys_linux_exit, _unix_get_executable_name, _unix_get_path, _unix_find_resource, NULL, /* set_window_title */ NULL, /* set_close_button_callback */ sys_linux_message, NULL, /* assert */ sys_linux_save_console_state, sys_linux_restore_console_state, NULL, /* create_bitmap */ NULL, /* created_bitmap */ NULL, /* create_sub_bitmap */ NULL, /* created_sub_bitmap */ NULL, /* destroy_bitmap */ NULL, /* read_hardware_palette */ NULL, /* set_palette_range */ NULL, /* get_vtable */ __al_linux_set_display_switch_mode, __al_linux_display_switch_lock, NULL, /* desktop_color_depth */ NULL, /* get_desktop_resolution */ NULL, /* get_gfx_safe_mode */ _unix_yield_timeslice, get_gfx_driver_list, get_digi_driver_list, get_midi_driver_list, get_keyboard_driver_list, get_mouse_driver_list, get_joystick_driver_list }; int __al_linux_have_ioperms = 0; typedef void (*temp_sighandler_t)(int); static temp_sighandler_t old_sig_abrt, old_sig_fpe, old_sig_ill, old_sig_segv, old_sig_term, old_sig_int, old_sig_quit; /* signal_handler: * Used to trap various signals, to make sure things get shut down cleanly. */ static void signal_handler (int num) { al_uninstall_system(); fprintf (stderr, "Shutting down Allegro due to signal #%d\n", num); raise (num); } /* __al_linux_bgman_init: * Starts asynchronous processing. */ static int __al_linux_bgman_init (void) { _unix_bg_man = &_bg_man_pthreads; if (_unix_bg_man->init()) return -1; /* if (_unix_bg_man->register_func (__al_linux_update_standard_drivers)) return -1; */ return 0; } /* __al_linux_bgman_exit: * Stops asynchronous processing. */ static void __al_linux_bgman_exit (void) { _unix_bg_man->exit(); } /* sys_linux_init: * Top level system driver wakeup call. */ static int sys_linux_init (void) { /* Get OS type */ _unix_read_os_type(); if (os_type != OSTYPE_LINUX) return -1; /* FWIW */ /* This is the only bit that needs root privileges. First * we attempt to set our euid to 0, in case this is the * second time we've been called. */ __al_linux_have_ioperms = !seteuid (0); __al_linux_have_ioperms &= !__al_linux_init_memory(); /* At this stage we can drop the root privileges. */ seteuid (getuid()); /* Install emergency-exit signal handlers */ old_sig_abrt = signal(SIGABRT, signal_handler); old_sig_fpe = signal(SIGFPE, signal_handler); old_sig_ill = signal(SIGILL, signal_handler); old_sig_segv = signal(SIGSEGV, signal_handler); old_sig_term = signal(SIGTERM, signal_handler); old_sig_int = signal(SIGINT, signal_handler); #ifdef SIGQUIT old_sig_quit = signal(SIGQUIT, signal_handler); #endif /* Initialise async event processing */ if (__al_linux_bgman_init()) { /* shutdown everything. */ sys_linux_exit(); return -1; } /* Mark the beginning of time */ _al_unix_init_time(); return 0; } /* sys_linux_exit: * The end of the world... */ static void sys_linux_exit (void) { /* shut down asynchronous event processing */ __al_linux_bgman_exit(); /* remove emergency exit signal handlers */ signal(SIGABRT, old_sig_abrt); signal(SIGFPE, old_sig_fpe); signal(SIGILL, old_sig_ill); signal(SIGSEGV, old_sig_segv); signal(SIGTERM, old_sig_term); signal(SIGINT, old_sig_int); #ifdef SIGQUIT signal(SIGQUIT, old_sig_quit); #endif __al_linux_shutdown_memory(); } static void sys_linux_save_console_state(void) { __al_linux_use_console(); } static void sys_linux_restore_console_state(void) { __al_linux_leave_console(); } /* sys_linux_message: * Display a message on our original console. */ static void sys_linux_message (const char *msg) { char *tmp; int ret; ASSERT(msg); tmp = al_malloc(ALLEGRO_MESSAGE_SIZE); msg = uconvert(msg, U_UTF8, tmp, U_ASCII, ALLEGRO_MESSAGE_SIZE); do { ret = write(STDERR_FILENO, msg, strlen(msg)); if ((ret < 0) && (errno != EINTR)) break; } while (ret < (int)strlen(msg)); __al_linux_got_text_message = true; al_free(tmp); } allegro-5.0.10/src/linux/lconsole.c0000644000175000001440000002324711426530105016323 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Console control functions for Linux Allegro. * * Originally by Marek Habersack, mangled by George Foot. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #include #include #include #include #include #include #include #include #include /* Console number and open file descriptor */ int __al_linux_vt = -1; int __al_linux_console_fd = -1; int __al_linux_prev_vt = -1; int __al_linux_got_text_message = false; /* Startup termios and working copy */ struct termios __al_linux_startup_termio; struct termios __al_linux_work_termio; /* get_tty: * Compares the inodes of /dev/ttyn (1 <= n <= 24) with the inode of the * passed file, returning whichever it matches, 0 if none, -1 on error. */ static int get_tty (int fd) { char name[16]; int tty; ino_t inode; struct stat st; if (fstat (fd, &st)) return -1; inode = st.st_ino; for (tty = 1; tty <= 24; tty++) { snprintf (name, sizeof(name), "/dev/tty%d", tty); name[sizeof(name)-1] = 0; if (!stat (name, &st) && (inode == st.st_ino)) break; } return (tty <= 24) ? tty : 0; } /* init_console: * Initialises this subsystem. */ static int init_console(void) { char tmp[256]; /* Find our tty's VT number */ __al_linux_vt = get_tty(STDIN_FILENO); if (__al_linux_vt < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error finding our VT: %s"), ustrerror(errno)); return 1; } if (__al_linux_vt != 0) { /* Open our current console */ if ((__al_linux_console_fd = open("/dev/tty", O_RDWR)) < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"), uconvert_ascii("/dev/tty", tmp), ustrerror(errno)); return 1; } } else { int tty, console_fd, fd, child; unsigned short mask; char tty_name[16]; struct vt_stat vts; /* Now we need to find a VT we can use. It must be readable and * writable by us, if we're not setuid root. VT_OPENQRY itself * isn't too useful because it'll only ever come up with one * suggestion, with no guarrantee that we actually have access * to it. * * At some stage I think this is a candidate for config * file overriding, but for now we'll stat the first N consoles * to see which ones we can write to (hopefully at least one!), * so that we can use that one to do ioctls. We used to use * /dev/console for that purpose but it looks like it's not * always writable by enough people. * * Having found and opened a writable device, we query the state * of the first sixteen (fifteen really) consoles, and try * opening each unused one in turn. */ if ((console_fd = open ("/dev/console", O_WRONLY)) < 0) { int n; uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("%s /dev/console: %s", tmp), get_config_text("Unable to open"), ustrerror (errno)); /* Try some ttys instead... */ for (n = 1; n <= 24; n++) { snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", n); tty_name[sizeof(tty_name)-1] = 0; if ((console_fd = open (tty_name, O_WRONLY)) >= 0) break; } if (n > 24) return 1; /* leave the error message about /dev/console */ } /* Get the state of the console -- in particular, the free VT field */ if (ioctl (console_fd, VT_GETSTATE, &vts)) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("VT_GETSTATE: %s", tmp), ustrerror (errno)); close (console_fd); return 1; } __al_linux_prev_vt = vts.v_active; /* We attempt to set our euid to 0; if we were run with euid 0 to * start with, we'll be able to do this now. Otherwise, we'll just * ignore the error returned since it might not be a problem if the * ttys we look at are owned by the user running the program. */ seteuid(0); /* tty0 is not really a console, so start counting at 2. */ fd = -1; for (tty = 1, mask = 2; mask; tty++, mask <<= 1) { if (!(vts.v_state & mask)) { snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", tty); tty_name[sizeof(tty_name)-1] = 0; if ((fd = open (tty_name, O_RDWR)) != -1) { close (fd); break; } } } seteuid (getuid()); if (!mask) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to find a usable VT")); close (console_fd); return 1; } /* OK, now fork into the background, detach from the current console, * and attach to the new one. */ child = fork(); if (child < 0) { /* fork failed */ uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii ("fork: %s", tmp), ustrerror (errno)); close (console_fd); return 1; } if (child) { /* We're the parent -- write a note to the user saying where the * app went, then quit */ fprintf (stderr, "Allegro application is running on VT %d\n", tty); exit (0); } /* We're the child. Detach from our controlling terminal, and start * a new session. */ close (console_fd); ioctl (0, TIOCNOTTY, 0); setsid(); /* Open the new one again. It becomes our ctty, because we started a * new session above. */ seteuid(0); fd = open (tty_name, O_RDWR); seteuid(getuid()); if (fd == -1) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to reopen new console")); return 1; } /* Try to switch to it -- should succeed, since it's our ctty */ ioctl (fd, VT_ACTIVATE, tty); __al_linux_vt = tty; __al_linux_console_fd = fd; /* Check we can reliably wait until we have the display */ if (__al_linux_wait_for_display()) { close (fd); ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("VT_WAITACTIVE failure")); return 1; } /* dup2 it to stdin, stdout and stderr if necessary */ if (isatty(0)) dup2 (fd, 0); if (isatty(1)) dup2 (fd, 1); if (isatty(2)) dup2 (fd, 2); } /* Get termio settings and make a working copy */ tcgetattr(__al_linux_console_fd, &__al_linux_startup_termio); __al_linux_work_termio = __al_linux_startup_termio; return 0; } /* done_console * Undo `init_console'. */ static int done_console (void) { char msg[256]; int ret; if (__al_linux_prev_vt >= 0) { if (__al_linux_got_text_message) { snprintf(msg, sizeof(msg), "\nProgram finished: press %s+F%d to switch back to the previous console\n", (__al_linux_prev_vt > 12) ? "AltGR" : "Alt", __al_linux_prev_vt%12); msg[sizeof(msg)-1] = 0; do { ret = write(STDERR_FILENO, msg, strlen(msg)); if ((ret < 0) && (errno != EINTR)) break; } while (ret < (int)strlen(msg)); __al_linux_got_text_message = false; } else ioctl (__al_linux_console_fd, VT_ACTIVATE, __al_linux_prev_vt); __al_linux_prev_vt = -1; } tcsetattr (__al_linux_console_fd, TCSANOW, &__al_linux_startup_termio); close (__al_linux_console_fd); __al_linux_console_fd = -1; return 0; } static int console_users = 0; /* __al_linux_use_console: * Init Linux console if not initialized yet. */ int __al_linux_use_console(void) { console_users++; if (console_users > 1) return 0; if (init_console()) { console_users--; return 1; } /* Initialise the console switching system */ set_display_switch_mode (SWITCH_PAUSE); return __al_linux_init_vtswitch(); } /* __al_linux_leave_console: * Close Linux console if no driver uses it any more. */ int __al_linux_leave_console(void) { ASSERT (console_users > 0); console_users--; if (console_users > 0) return 0; /* shut down the console switching system */ if (__al_linux_done_vtswitch()) return 1; if (done_console()) return 1; return 0; } static int graphics_mode = 0; /* __al_linux_console_graphics: * Puts the Linux console into graphics mode. */ int __al_linux_console_graphics (void) { if (__al_linux_use_console()) return 1; if (graphics_mode) return 0; /* shouldn't happen */ ioctl(__al_linux_console_fd, KDSETMODE, KD_GRAPHICS); __al_linux_wait_for_display(); graphics_mode = 1; return 0; } /* __al_linux_console_text: * Returns the console to text mode. */ int __al_linux_console_text (void) { int ret; if (!graphics_mode) return 0; /* shouldn't happen */ ioctl(__al_linux_console_fd, KDSETMODE, KD_TEXT); do { ret = write(__al_linux_console_fd, "\e[H\e[J\e[0m", 10); if ((ret < 0) && (errno != EINTR)) break; } while (ret < 10); graphics_mode = 0; __al_linux_leave_console(); return 0; } /* __al_linux_wait_for_display: * Waits until we have the display. */ int __al_linux_wait_for_display (void) { int x; do { x = ioctl (__al_linux_console_fd, VT_WAITACTIVE, __al_linux_vt); } while (x && errno != EINTR); return x; } allegro-5.0.10/src/linux/lmsems.c0000644000175000001440000001350211426530105015776 0ustar tjadenusers#error This driver has not been updated to the new mouse API. /* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console internal mouse driver for Microsoft mouse. * * By George Foot. * * See readme.txt for copyright information. */ #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" static int intellimouse; static int packet_size; /* processor: * Processes the first packet in the buffer, if any, returning the number * of bytes eaten. * * Microsoft protocol has only seven data bits. The top bit is set in * the first byte of the packet, clear in the other two. The next two * bits in the header are the button state. The next two are the top * bits of the Y offset (second data byte), and the last two are the * top bits of the X offset (first data byte). */ static int processor (unsigned char *buf, int buf_size) { int r, l, m, x, y, z; if (buf_size < packet_size) return 0; /* not enough data, spit it out for now */ /* if packet is invalid, just eat it */ if (!(buf[0] & 0x40)) return 1; /* invalid byte */ if (buf[1] & 0x40) return 1; /* first data byte is actually a header */ if (buf[2] & 0x40) return 2; /* second data byte is actually a header */ /* packet is valid, decode the data */ l = !!(buf[0] & 0x20); r = !!(buf[0] & 0x10); if (intellimouse) { m = !!(buf[3] & 0x10); z = (buf[3] & 0x0f); if (z) z = (z-7) >> 3; } else { m = 0; z = 0; } x = (signed char) (((buf[0] & 0x03) << 6) | (buf[1] & 0x3F)); y = -(signed char) (((buf[0] & 0x0C) << 4) | (buf[2] & 0x3F)); __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); return packet_size; /* yum */ } /* analyse_data: * Analyses the given data, returning 0 if it is unparsable, nonzero * if there's a reasonable chance that this driver can work with that * data. */ static int analyse_data (const char *buffer, int size) { int pos = 0; int packets = 0, errors = 0; int step = 0; for (pos = 0; pos < size; pos++) switch (step) { case 3: packets++; step = 0; case 0: if (!(buffer[pos] & 0x40)) { errors++; } else { step++; } break; case 1: case 2: if (buffer[pos] & 0x40) { errors++; step = 0; pos--; } else { step++; } break; } return (errors <= 5) || (errors < size / 20); /* 5% error allowance */ } static INTERNAL_MOUSE_DRIVER intdrv = { -1, processor, 2 }; /* sync_mouse: * To find the start of a packet, we just read all the data that's * waiting. This isn't a particularly good way, obviously. :) */ static void sync_mouse (int fd) { fd_set set; int result; struct timeval tv; char bitbucket; do { FD_ZERO (&set); FD_SET (fd, &set); tv.tv_sec = tv.tv_usec = 0; result = select (FD_SETSIZE, &set, NULL, NULL, &tv); if (result > 0) read (fd, &bitbucket, 1); } while (result > 0); } /* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static int mouse_init (void) { char tmp1[128], tmp2[128], tmp3[128]; const char *udevice; struct termios t; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), uconvert_ascii ("/dev/mouse", tmp3)); /* Open mouse device. Devices are cool. */ intdrv.device = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); if (intdrv.device < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice, ustrerror (errno)); return -1; } /* Set parameters */ tcgetattr (intdrv.device, &t); t.c_iflag = IGNBRK | IGNPAR; t.c_oflag = t.c_lflag = t.c_line = 0; t.c_cflag = CS7 | CREAD | CLOCAL | HUPCL | B1200; tcsetattr (intdrv.device, TCSAFLUSH, &t); /* Discard any garbage, so the next thing we read is a packet header */ sync_mouse (intdrv.device); return __al_linux_mouse_init (&intdrv); } /* ms_mouse_init: * Initialisation for vanilla MS mouse. */ static int ms_mouse_init (void) { intellimouse = false; packet_size = 3; intdrv.num_buttons = 2; return mouse_init (); } /* msi_mouse_init: * Initialisation for MS mouse with Intellimouse extension. */ static int ims_mouse_init (void) { intellimouse = true; packet_size = 4; intdrv.num_buttons = 3; return mouse_init (); } /* mouse_exit: * Chain to the framework, then uninitialise things. */ static void mouse_exit (void) { __al_linux_mouse_exit(); close (intdrv.device); } MOUSE_DRIVER mousedrv_linux_ms = { MOUSEDRV_LINUX_MS, "", "", "Linux MS mouse", ms_mouse_init, mouse_exit, NULL, /* poll() */ NULL, /* timer_poll() */ __al_linux_mouse_position, __al_linux_mouse_set_range, __al_linux_mouse_set_speed, __al_linux_mouse_get_mickeys, analyse_data, NULL, /* enable_hardware_cursor */ NULL }; MOUSE_DRIVER mousedrv_linux_ims = { MOUSEDRV_LINUX_IMS, "", "", "Linux MS Intellimouse", ims_mouse_init, mouse_exit, NULL, /* poll() */ NULL, /* timer_poll() */ __al_linux_mouse_position, __al_linux_mouse_set_range, __al_linux_mouse_set_speed, __al_linux_mouse_get_mickeys, analyse_data, NULL, /* enable_hardware_cursor */ NULL }; allegro-5.0.10/src/linux/ljoynu.c0000644000175000001440000005124411771527532016040 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux joystick driver. * * By George Foot and Peter Wang. * * Updated for new joystick API by Peter Wang. * * See readme.txt for copyright information. */ #include #include #include #include #include #include #include #define ALLEGRO_NO_KEY_DEFINES #define ALLEGRO_NO_COMPATIBILITY #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_joystick.h" #include ALLEGRO_INTERNAL_HEADER #ifdef ALLEGRO_HAVE_LINUX_JOYSTICK_H /* To be safe, include sys/types.h before linux/joystick.h to avoid conflicting * definitions of fd_set. */ #include #include #if defined(ALLEGRO_HAVE_SYS_INOTIFY_H) && defined(ALLEGRO_HAVE_SYS_TIMERFD_H) #define SUPPORT_HOTPLUG #include #include #endif ALLEGRO_DEBUG_CHANNEL("ljoy"); #define TOTAL_JOYSTICK_AXES (_AL_MAX_JOYSTICK_STICKS * _AL_MAX_JOYSTICK_AXES) /* State transitions: * unused -> born * born -> alive * born -> dying * active -> dying * dying -> unused */ typedef enum { LJOY_STATE_UNUSED, LJOY_STATE_BORN, LJOY_STATE_ALIVE, LJOY_STATE_DYING } CONFIG_STATE; #define ACTIVE_STATE(st) \ ((st) == LJOY_STATE_ALIVE || (st) == LJOY_STATE_DYING) /* map a Linux joystick axis number to an Allegro (stick,axis) pair */ typedef struct { int stick; int axis; } AXIS_MAPPING; typedef struct ALLEGRO_JOYSTICK_LINUX { ALLEGRO_JOYSTICK parent; int config_state; bool marked; int fd; ALLEGRO_USTR *device_name; AXIS_MAPPING axis_mapping[TOTAL_JOYSTICK_AXES]; ALLEGRO_JOYSTICK_STATE joystate; char name[100]; } ALLEGRO_JOYSTICK_LINUX; /* forward declarations */ static bool ljoy_init_joystick(void); static void ljoy_exit_joystick(void); static bool ljoy_reconfigure_joysticks(void); static int ljoy_num_joysticks(void); static ALLEGRO_JOYSTICK *ljoy_get_joystick(int num); static void ljoy_release_joystick(ALLEGRO_JOYSTICK *joy_); static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state); static const char *ljoy_get_name(ALLEGRO_JOYSTICK *joy_); static bool ljoy_get_active(ALLEGRO_JOYSTICK *joy_); static void ljoy_process_new_data(void *data); static void ljoy_generate_axis_event(ALLEGRO_JOYSTICK_LINUX *joy, int stick, int axis, float pos); static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type); /* the driver vtable */ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_linux = { _ALLEGRO_JOYDRV_LINUX, "", "", "Linux joystick(s)", ljoy_init_joystick, ljoy_exit_joystick, ljoy_reconfigure_joysticks, ljoy_num_joysticks, ljoy_get_joystick, ljoy_release_joystick, ljoy_get_joystick_state, ljoy_get_name, ljoy_get_active }; static unsigned num_joysticks; /* number of joysticks known to the user */ static _AL_VECTOR joysticks; /* of ALLEGRO_JOYSTICK_LINUX pointers */ static volatile bool config_needs_merging; static ALLEGRO_MUTEX *config_mutex; #ifdef SUPPORT_HOTPLUG static int inotify_fd = -1; static int timer_fd = -1; #endif /* check_js_api_version: [primary thread] * * Return true if the joystick API used by the device is supported by * this driver. */ static bool check_js_api_version(int fd) { unsigned int raw_version; if (ioctl(fd, JSIOCGVERSION, &raw_version) < 0) { /* NOTE: IOCTL fails if the joystick API is version 0.x */ ALLEGRO_WARN("Your Linux joystick API is version 0.x which is unsupported.\n"); return false; } /* struct { unsigned char build, minor, major; } version; version.major = (raw_version & 0xFF0000) >> 16; version.minor = (raw_version & 0xFF00) >> 8; version.build = (raw_version & 0xFF); */ return true; } static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name) { ALLEGRO_CONFIG *cfg; char key[80]; const char *value; struct stat stbuf; al_ustr_truncate(device_name, 0); cfg = al_get_system_config(); if (cfg) { snprintf(key, sizeof(key), "device%d", num); value = al_get_config_value(cfg, "joystick", key); if (value) al_ustr_assign_cstr(device_name, value); } if (al_ustr_size(device_name) == 0) al_ustr_appendf(device_name, "/dev/input/js%d", num); return (stat(al_cstr(device_name), &stbuf) == 0); } static ALLEGRO_JOYSTICK_LINUX *ljoy_by_device_name( const ALLEGRO_USTR *device_name) { unsigned i; for (i = 0; i < _al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); ALLEGRO_JOYSTICK_LINUX *joy = *slot; if (joy && al_ustr_equal(device_name, joy->device_name)) return joy; } return NULL; } static void ljoy_generate_configure_event(void) { ALLEGRO_EVENT event; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; event.joystick.timestamp = al_get_time(); _al_generate_joystick_event(&event); } static ALLEGRO_JOYSTICK_LINUX *ljoy_allocate_structure(void) { ALLEGRO_JOYSTICK_LINUX **slot; ALLEGRO_JOYSTICK_LINUX *joy; unsigned i; for (i = 0; i < _al_vector_size(&joysticks); i++) { slot = _al_vector_ref(&joysticks, i); joy = *slot; if (joy->config_state == LJOY_STATE_UNUSED) return joy; } joy = al_calloc(1, sizeof *joy); slot = _al_vector_alloc_back(&joysticks); *slot = joy; return joy; } static void inactivate_joy(ALLEGRO_JOYSTICK_LINUX *joy) { int i; if (joy->config_state == LJOY_STATE_UNUSED) return; joy->config_state = LJOY_STATE_UNUSED; _al_unix_stop_watching_fd(joy->fd); close(joy->fd); joy->fd = -1; for (i = 0; i < joy->parent.info.num_sticks; i++) al_free((void *)joy->parent.info.stick[i].name); for (i = 0; i < joy->parent.info.num_buttons; i++) al_free((void *)joy->parent.info.button[i].name); memset(&joy->parent.info, 0, sizeof(joy->parent.info)); memset(&joy->joystate, 0, sizeof(joy->joystate)); al_ustr_free(joy->device_name); joy->device_name = NULL; } static void ljoy_scan(bool configure) { int fd; ALLEGRO_JOYSTICK_LINUX *joy, **joypp; int num; ALLEGRO_USTR *device_name; unsigned i; /* Clear mark bits. */ for (i = 0; i < _al_vector_size(&joysticks); i++) { joypp = _al_vector_ref(&joysticks, i); joy = *joypp; joy->marked = false; } device_name = al_ustr_new(""); /* This is a big number, but there can be gaps. */ for (num = 0; num < 16; num++) { if (!ljoy_detect_device_name(num, device_name)) continue; joy = ljoy_by_device_name(device_name); if (joy) { ALLEGRO_DEBUG("Device %s still exists\n", al_cstr(device_name)); joy->marked = true; continue; } /* Try to open the device. */ fd = open(al_cstr(device_name), O_RDONLY|O_NONBLOCK); if (fd == -1) { ALLEGRO_WARN("Failed to open device %s\n", al_cstr(device_name)); continue; } if (!check_js_api_version(fd)) { close(fd); continue; } ALLEGRO_DEBUG("Device %s is new\n", al_cstr(device_name)); joy = ljoy_allocate_structure(); joy->fd = fd; joy->device_name = al_ustr_dup(device_name); joy->config_state = LJOY_STATE_BORN; joy->marked = true; config_needs_merging = true; if (ioctl(fd, JSIOCGNAME(sizeof(joy->name)), joy->name) < 0) strcpy(joy->name, "Unknown"); /* Fill in the joystick information fields. */ { char num_axes; char num_buttons; int throttle; int s, a, b; ioctl(fd, JSIOCGAXES, &num_axes); ioctl(fd, JSIOCGBUTTONS, &num_buttons); if (num_axes > TOTAL_JOYSTICK_AXES) num_axes = TOTAL_JOYSTICK_AXES; if (num_buttons > _AL_MAX_JOYSTICK_BUTTONS) num_buttons = _AL_MAX_JOYSTICK_BUTTONS; /* XXX use configuration system when we get one */ throttle = -1; #if 0 /* User is allowed to override our simple assumption of which * axis number (kernel) the throttle is located at. */ snprintf(tmp, sizeof(tmp), "throttle_axis_%d", num); throttle = get_config_int("joystick", tmp, -1); if (throttle == -1) { throttle = get_config_int("joystick", "throttle_axis", -1); } #endif /* Each pair of axes is assumed to make up a stick unless it * is the sole remaining axis, or has been user specified, in * which case it is a throttle. */ for (s = 0, a = 0; s < _AL_MAX_JOYSTICK_STICKS && a < num_axes; s++) { if ((a == throttle) || (a == num_axes-1)) { /* One axis throttle. */ joy->parent.info.stick[s].flags = ALLEGRO_JOYFLAG_ANALOGUE; joy->parent.info.stick[s].num_axes = 1; joy->parent.info.stick[s].axis[0].name = "Throttle"; char *name = joy->parent.info.stick[s].axis[0].name; joy->parent.info.stick[s].name = al_malloc(strlen(name) + 1); strcpy(joy->parent.info.stick[s].name, name); joy->axis_mapping[a].stick = s; joy->axis_mapping[a].axis = 0; a++; } else { /* Two axis stick. */ joy->parent.info.stick[s].flags = ALLEGRO_JOYFLAG_ANALOGUE; joy->parent.info.stick[s].num_axes = 2; joy->parent.info.stick[s].axis[0].name = "X"; joy->parent.info.stick[s].axis[1].name = "Y"; joy->parent.info.stick[s].name = al_malloc (32); snprintf((char *)joy->parent.info.stick[s].name, 32, "Stick %d", s+1); joy->axis_mapping[a].stick = s; joy->axis_mapping[a].axis = 0; a++; joy->axis_mapping[a].stick = s; joy->axis_mapping[a].axis = 1; a++; } } joy->parent.info.num_sticks = s; /* Do the buttons. */ for (b = 0; b < num_buttons; b++) { joy->parent.info.button[b].name = al_malloc(32); snprintf((char *)joy->parent.info.button[b].name, 32, "B%d", b+1); } joy->parent.info.num_buttons = num_buttons; } /* Register the joystick with the fdwatch subsystem. */ _al_unix_start_watching_fd(joy->fd, ljoy_process_new_data, joy); } al_ustr_free(device_name); /* Schedule unmarked structures to be inactivated. */ for (i = 0; i < _al_vector_size(&joysticks); i++) { joypp = _al_vector_ref(&joysticks, i); joy = *joypp; if (joy->config_state == LJOY_STATE_ALIVE && !joy->marked) { ALLEGRO_DEBUG("Device %s to be inactivated\n", al_cstr(joy->device_name)); joy->config_state = LJOY_STATE_DYING; config_needs_merging = true; } } /* Generate a configure event if necessary. * Even if we generated one before that the user hasn't responded to, * we don't know if the user received it so always generate it. */ if (config_needs_merging && configure) { ljoy_generate_configure_event(); } } static void ljoy_merge(void) { unsigned i; config_needs_merging = false; num_joysticks = 0; for (i = 0; i < _al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); ALLEGRO_JOYSTICK_LINUX *joy = *slot; switch (joy->config_state) { case LJOY_STATE_UNUSED: break; case LJOY_STATE_BORN: case LJOY_STATE_ALIVE: joy->config_state = LJOY_STATE_ALIVE; num_joysticks++; break; case LJOY_STATE_DYING: inactivate_joy(joy); break; } } ALLEGRO_DEBUG("Merge done, num_joysticks=%d\n", num_joysticks); } #ifdef SUPPORT_HOTPLUG /* ljoy_config_dev_changed: [fdwatch thread] * Called when the /dev hierarchy changes. */ static void ljoy_config_dev_changed(void *data) { char buf[128]; struct itimerspec spec; (void)data; /* Empty the event buffer. We only care that some inotify event was sent but it * doesn't matter what it is since we are going to do a full scan anyway once * the timer_fd fires. */ while (read(inotify_fd, buf, sizeof(buf)) > 0) { } /* Set the timer to fire once in one second. * We cannot scan immediately because the devices may not be ready yet :-P */ spec.it_value.tv_sec = 1; spec.it_value.tv_nsec = 0; spec.it_interval.tv_sec = 0; spec.it_interval.tv_nsec = 0; timerfd_settime(timer_fd, 0, &spec, NULL); } /* ljoy_config_rescan: [fdwatch thread] * Rescans for joystick devices a little while after devices change. */ static void ljoy_config_rescan(void *data) { uint64_t exp; (void)data; /* Empty the event buffer. */ while (read(timer_fd, &exp, sizeof(uint64_t)) > 0) { } al_lock_mutex(config_mutex); ljoy_scan(true); al_unlock_mutex(config_mutex); } #endif /* ljoy_init_joystick: [primary thread] * Initialise the joystick driver. */ static bool ljoy_init_joystick(void) { _al_vector_init(&joysticks, sizeof(ALLEGRO_JOYSTICK_LINUX *)); num_joysticks = 0; // Scan for joysticks ljoy_scan(false); ljoy_merge(); config_mutex = al_create_mutex(); #ifdef SUPPORT_HOTPLUG inotify_fd = inotify_init1(IN_NONBLOCK); timer_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); if (inotify_fd != -1 && timer_fd != -1) { /* Modern Linux probably only needs to monitor /dev/input. */ inotify_add_watch(inotify_fd, "/dev/input", IN_CREATE|IN_DELETE); _al_unix_start_watching_fd(inotify_fd, ljoy_config_dev_changed, NULL); _al_unix_start_watching_fd(timer_fd, ljoy_config_rescan, NULL); ALLEGRO_INFO("Hotplugging enabled\n"); } else { ALLEGRO_WARN("Hotplugging not enabled\n"); if (inotify_fd != -1) { close(inotify_fd); inotify_fd = -1; } if (timer_fd != -1) { close(timer_fd); timer_fd = -1; } } #endif return true; } /* ljoy_exit_joystick: [primary thread] * Shut down the joystick driver. */ static void ljoy_exit_joystick(void) { int i; #ifdef SUPPORT_HOTPLUG if (inotify_fd != -1) { _al_unix_stop_watching_fd(inotify_fd); close(inotify_fd); inotify_fd = -1; } if (timer_fd != -1) { _al_unix_stop_watching_fd(timer_fd); close(timer_fd); timer_fd = -1; } #endif al_destroy_mutex(config_mutex); config_mutex = NULL; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); inactivate_joy(*slot); al_free(*slot); } _al_vector_free(&joysticks); num_joysticks = 0; } /* ljoy_reconfigure_joysticks: [primary thread] */ static bool ljoy_reconfigure_joysticks(void) { bool ret = false; al_lock_mutex(config_mutex); if (config_needs_merging) { ljoy_merge(); ret = true; } al_unlock_mutex(config_mutex); return ret; } /* ljoy_num_joysticks: [primary thread] * * Return the number of joysticks available on the system. */ static int ljoy_num_joysticks(void) { return num_joysticks; } /* ljoy_get_joystick: [primary thread] * * Returns the address of a ALLEGRO_JOYSTICK structure for the device * number NUM. */ static ALLEGRO_JOYSTICK *ljoy_get_joystick(int num) { ALLEGRO_JOYSTICK *ret = NULL; unsigned i; ASSERT(num >= 0); al_lock_mutex(config_mutex); for (i = 0; i < _al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); ALLEGRO_JOYSTICK_LINUX *joy = *slot; if (ACTIVE_STATE(joy->config_state)) { if (num == 0) { ret = (ALLEGRO_JOYSTICK *)joy; break; } num--; } } al_unlock_mutex(config_mutex); return ret; } /* ljoy_release_joystick: [primary thread] * * Close the device for a joystick then free the joystick structure. */ static void ljoy_release_joystick(ALLEGRO_JOYSTICK *joy_) { (void)joy_; } /* ljoy_get_joystick_state: [primary thread] * * Copy the internal joystick state to a user-provided structure. */ static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *) joy_; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); { *ret_state = joy->joystate; } _al_event_source_unlock(es); } static const char *ljoy_get_name(ALLEGRO_JOYSTICK *joy_) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *)joy_; return joy->name; } static bool ljoy_get_active(ALLEGRO_JOYSTICK *joy_) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *)joy_; return ACTIVE_STATE(joy->config_state); } /* ljoy_process_new_data: [fdwatch thread] * * Process new data arriving in the joystick's fd. */ static void ljoy_process_new_data(void *data) { ALLEGRO_JOYSTICK_LINUX *joy = data; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!es) { // Joystick driver not fully initialized return; } _al_event_source_lock(es); { struct js_event js_events[32]; int bytes, nr, i; while ((bytes = read(joy->fd, &js_events, sizeof js_events)) > 0) { nr = bytes / sizeof(struct js_event); for (i = 0; i < nr; i++) { int type = js_events[i].type; int number = js_events[i].number; int value = js_events[i].value; if (type & JS_EVENT_BUTTON) { if (number < _AL_MAX_JOYSTICK_BUTTONS) { if (value) joy->joystate.button[number] = 32767; else joy->joystate.button[number] = 0; ljoy_generate_button_event(joy, number, (value ? ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN : ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)); } } else if (type & JS_EVENT_AXIS) { if (number < TOTAL_JOYSTICK_AXES) { int stick = joy->axis_mapping[number].stick; int axis = joy->axis_mapping[number].axis; float pos = value / 32767.0; joy->joystate.stick[stick].axis[axis] = pos; ljoy_generate_axis_event(joy, stick, axis, pos); } } } } } _al_event_source_unlock(es); } /* ljoy_generate_axis_event: [fdwatch thread] * * Helper to generate an event after an axis is moved. * The joystick must be locked BEFORE entering this function. */ static void ljoy_generate_axis_event(ALLEGRO_JOYSTICK_LINUX *joy, int stick, int axis, float pos) { ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; event.joystick.timestamp = al_get_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = stick; event.joystick.axis = axis; event.joystick.pos = pos; event.joystick.button = 0; _al_event_source_emit_event(es, &event); } /* ljoy_generate_button_event: [fdwatch thread] * * Helper to generate an event after a button is pressed or released. * The joystick must be locked BEFORE entering this function. */ static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type) { ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = event_type; event.joystick.timestamp = al_get_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = 0; event.joystick.axis = 0; event.joystick.pos = 0.0; event.joystick.button = button; _al_event_source_emit_event(es, &event); } #endif /* ALLEGRO_HAVE_LINUX_JOYSTICK_H */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/linux/lstddrv.c0000644000175000001440000000507411426530105016165 0ustar tjadenusers#error This file is no longer used. /* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Standard driver helpers for Linux Allegro. * * By Marek Habersack, mangled by George Foot. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #include /* List of standard drivers */ STD_DRIVER *__al_linux_std_drivers[N_STD_DRIVERS]; static int std_drivers_suspended = false; /* __al_linux_add_standard_driver: * Adds a standard driver; returns 0 on success, non-zero if the sanity * checks fail. */ int __al_linux_add_standard_driver (STD_DRIVER *spec) { if (!spec) return 1; if (spec->type >= N_STD_DRIVERS) return 2; if (!spec->update) return 3; if (spec->fd < 0) return 4; __al_linux_std_drivers[spec->type] = spec; spec->resume(); return 0; } /* __al_linux_remove_standard_driver: * Removes a standard driver, returning 0 on success or non-zero on * failure. */ int __al_linux_remove_standard_driver (STD_DRIVER *spec) { if (!spec) return 1; if (spec->type >= N_STD_DRIVERS) return 3; if (!__al_linux_std_drivers[spec->type]) return 4; if (__al_linux_std_drivers[spec->type] != spec) return 5; spec->suspend(); __al_linux_std_drivers[spec->type] = NULL; return 0; } /* __al_linux_update_standard_drivers: * Updates all drivers. */ void __al_linux_update_standard_drivers (int threaded) { int i; if (!std_drivers_suspended) { for (i = 0; i < N_STD_DRIVERS; i++) if (__al_linux_std_drivers[i]) __al_linux_std_drivers[i]->update(); } } /* __al_linux_suspend_standard_drivers: * Temporary disable standard drivers during a VT switch. */ void __al_linux_suspend_standard_drivers (void) { ASSERT(!std_drivers_suspended); std_drivers_suspended = true; } /* __al_linux_resume_standard_drivers: * Re-enable standard drivers after a VT switch. */ void __al_linux_resume_standard_drivers (void) { ASSERT(std_drivers_suspended); std_drivers_suspended = false; } allegro-5.0.10/src/linux/lmseps2.c0000644000175000001440000001530711426530105016070 0ustar tjadenusers#error This driver has not been updated to the new mouse API. /* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console internal mouse driver for PS/2. * * By George Foot. * * See readme.txt for copyright information. */ #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" static int intellimouse; static int packet_size; /* processor: * Processes the first packet in the buffer, if any, returning the number * of bytes eaten. * * PS/2 mouse protocol is pretty simple; packets consist of three bytes, * one header byte and two data bytes. In the header, the bottom three * bits show the current button state. The next bit should always be * set, but apparently some mice don't do this. The next two bits are * the X and Y sign bits, and the last two are the X and Y overflow * flags. The two data bytes are the X and Y deltas; prepend the * corresponding sign bit to get a nine-bit two's complement number. * * Finding the header byte can be tricky in you lose sync; bit 3 isn't * that useful, not only because some mice don't set it, but also * because a data byte could have it set. The overflow bits are very * rarely set, so we just test for these being zero. Of course the * data bytes can have zeros here too, but as soon as you move the * mouse down or left the data bytes become negative and have ones * here instead. */ static int processor (unsigned char *buf, int buf_size) { int r, l, m, x, y, z; if (buf_size < packet_size) return 0; /* not enough data, spit it out for now */ /* if data is invalid, return no motion and all buttons released */ if (intellimouse) { if ((buf[0] & 0xc8) != 0x08) return 1; /* invalid byte, eat it */ } else { if ((buf[0] & 0xc0) != 0x00) return 1; /* invalid byte, eat it */ } /* data is valid, process it */ l = !!(buf[0] & 1); r = !!(buf[0] & 2); m = !!(buf[0] & 4); x = buf[1]; y = buf[2]; if (buf[0] & 0x10) x -= 256; if (buf[0] & 0x20) y -= 256; if (intellimouse) { z = buf[3] & 0xf; if (z) z = (z-7) >> 3; } else z = 0; __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); return packet_size; /* yum */ } /* analyse_data: * Analyses the given data, returning 0 if it is unparsable, nonzero * if there's a reasonable chance that this driver can work with that * data. */ static int analyse_data (const char *buffer, int size) { int pos = 0; int packets = 0, errors = 0; int step = 0; for (pos = 0; pos < size; pos++) switch (step) { case 3: packets++; step = 0; case 0: if (buffer[pos] & 0xC0) { errors++; } else { step++; } break; case 1: case 2: step++; break; } return (errors <= 5) || (errors < size / 20); /* 5% error allowance */ } static INTERNAL_MOUSE_DRIVER intdrv = { -1, processor, 3 }; /* sync_mouse: * To find the start of a packet, we just read all the data that's * waiting. This isn't a particularly good way, obviously. :) */ static void sync_mouse (int fd) { fd_set set; int result; struct timeval tv; char bitbucket; do { FD_ZERO (&set); FD_SET (fd, &set); tv.tv_sec = tv.tv_usec = 0; result = select (FD_SETSIZE, &set, NULL, NULL, &tv); if (result > 0) read (fd, &bitbucket, 1); } while (result > 0); } /* wakeup_im: * Intellimouse needs some special initialisation. */ static void wakeup_im (int fd) { unsigned char init[] = { 243, 200, 243, 100, 243, 80 }; int ret; do { ret = write (fd, init, sizeof (init)); if ((ret < 0) && (errno != EINTR)) break; } while (ret < (int)sizeof (init)); } /* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static int mouse_init (void) { char tmp1[128], tmp2[128]; const char *udevice; int flags; static const char * const default_devices[] = { "/dev/mouse", "/dev/input/mice", }; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), NULL); /* Open mouse device. Devices are cool. */ flags = O_NONBLOCK | (intellimouse ? O_RDWR : O_RDONLY); if (udevice) { intdrv.device = open (uconvert_toascii (udevice, tmp1), flags); } else { size_t n; for (n = 0; n < sizeof(default_devices) / sizeof(default_devices[0]); n++) { intdrv.device = open (default_devices[n], flags); if (intdrv.device >= 0) break; } } if (intdrv.device < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice ? udevice : get_config_text("one of the default mice devices"), ustrerror (errno)); return -1; } /* Put Intellimouse into wheel mode */ if (intellimouse) wakeup_im (intdrv.device); /* Discard any garbage, so the next thing we read is a packet header */ sync_mouse (intdrv.device); return __al_linux_mouse_init (&intdrv); } /* ps2_mouse_init: * Plain PS/2 mouse init. */ static int ps2_mouse_init (void) { intellimouse = false; packet_size = 3; return mouse_init (); } /* ps2i_mouse_init: * PS/2 Intellimouse init. */ static int ips2_mouse_init (void) { intellimouse = true; packet_size = 4; return mouse_init (); } /* mouse_exit: * Chain to the framework, then uninitialise things. */ static void mouse_exit (void) { __al_linux_mouse_exit(); close (intdrv.device); } MOUSE_DRIVER mousedrv_linux_ps2 = { MOUSEDRV_LINUX_PS2, "", "", "Linux PS/2 mouse", ps2_mouse_init, mouse_exit, NULL, /* poll() */ NULL, /* timer_poll() */ __al_linux_mouse_position, __al_linux_mouse_set_range, __al_linux_mouse_set_speed, __al_linux_mouse_get_mickeys, analyse_data, NULL, /* enable_hardware_cursor */ NULL }; MOUSE_DRIVER mousedrv_linux_ips2 = { MOUSEDRV_LINUX_IPS2, "", "", "Linux PS/2 Intellimouse", ips2_mouse_init, mouse_exit, NULL, /* poll() */ NULL, /* timer_poll() */ __al_linux_mouse_position, __al_linux_mouse_set_range, __al_linux_mouse_set_speed, __al_linux_mouse_get_mickeys, analyse_data, NULL, /* enable_hardware_cursor */ NULL }; allegro-5.0.10/src/linux/lkeybdnu.c0000644000175000001440000004605212132126261016320 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console keyboard driver. * * By Marek Habersack, modified by George Foot. * * Modified for the new keyboard API by Peter Wang. * * See readme.txt for copyright information. * *--- * Recommended reading: * * - "Kernel Korner: The Linux keyboard driver" by Andries E. Brouwer * http://www.linuxjournal.com/article.php?sid=1080 * * - Console Programming HOWTO * * TODO: diacriticals */ #define ALLEGRO_NO_COMPATIBILITY #include #include #include #include #include #include #include #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintlnx.h" #include "allegro5/platform/aintunix.h" #define PREFIX_I "al-ckey INFO: " #define PREFIX_W "al-ckey WARNING: " #define PREFIX_E "al-ckey ERROR: " typedef struct ALLEGRO_KEYBOARD_LINUX { ALLEGRO_KEYBOARD parent; int fd; struct termios startup_termio; struct termios work_termio; int startup_kbmode; ALLEGRO_KEYBOARD_STATE state; unsigned int modifiers; } ALLEGRO_KEYBOARD_LINUX; /* the one and only keyboard object */ static ALLEGRO_KEYBOARD_LINUX the_keyboard; /* the pid to kill when three finger saluting */ static pid_t main_pid; /* forward declarations */ static bool lkeybd_init_keyboard(void); static void lkeybd_exit_keyboard(void); static ALLEGRO_KEYBOARD *lkeybd_get_keyboard(void); static bool lkeybd_set_keyboard_leds(int leds); static void lkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); static void process_new_data(void *unused); static void process_character(unsigned char ch); static void handle_key_press(int mycode, unsigned int ascii); static void handle_key_release(int mycode); /* the driver vtable */ #define KEYDRV_LINUX AL_ID('L','N','X','C') static ALLEGRO_KEYBOARD_DRIVER keydrv_linux = { KEYDRV_LINUX, "", "", "Linux console keyboard", lkeybd_init_keyboard, lkeybd_exit_keyboard, lkeybd_get_keyboard, lkeybd_set_keyboard_leds, NULL, /* const char *keycode_to_name(int keycode) */ lkeybd_get_keyboard_state }; /* list the available drivers */ _AL_DRIVER_INFO _al_linux_keyboard_driver_list[] = { { KEYDRV_LINUX, &keydrv_linux, true }, { 0, NULL, 0 } }; /* * Various ugly things. */ #define KB_MODIFIERS (ALLEGRO_KEYMOD_SHIFT | ALLEGRO_KEYMOD_CTRL | ALLEGRO_KEYMOD_ALT | \ ALLEGRO_KEYMOD_ALTGR | ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN | \ ALLEGRO_KEYMOD_MENU) #define KB_LED_FLAGS (ALLEGRO_KEYMOD_SCROLLLOCK | ALLEGRO_KEYMOD_NUMLOCK | \ ALLEGRO_KEYMOD_CAPSLOCK) /* lookup table for converting kernel keycodes into Allegro format */ static unsigned char kernel_to_mycode[128] = { /* 0x00 */ 0, ALLEGRO_KEY_ESCAPE, ALLEGRO_KEY_1, ALLEGRO_KEY_2, /* 0x04 */ ALLEGRO_KEY_3, ALLEGRO_KEY_4, ALLEGRO_KEY_5, ALLEGRO_KEY_6, /* 0x08 */ ALLEGRO_KEY_7, ALLEGRO_KEY_8, ALLEGRO_KEY_9, ALLEGRO_KEY_0, /* 0x0C */ ALLEGRO_KEY_MINUS, ALLEGRO_KEY_EQUALS, ALLEGRO_KEY_BACKSPACE, ALLEGRO_KEY_TAB, /* 0x10 */ ALLEGRO_KEY_Q, ALLEGRO_KEY_W, ALLEGRO_KEY_E, ALLEGRO_KEY_R, /* 0x14 */ ALLEGRO_KEY_T, ALLEGRO_KEY_Y, ALLEGRO_KEY_U, ALLEGRO_KEY_I, /* 0x18 */ ALLEGRO_KEY_O, ALLEGRO_KEY_P, ALLEGRO_KEY_OPENBRACE, ALLEGRO_KEY_CLOSEBRACE, /* 0x1C */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_A, ALLEGRO_KEY_S, /* 0x20 */ ALLEGRO_KEY_D, ALLEGRO_KEY_F, ALLEGRO_KEY_G, ALLEGRO_KEY_H, /* 0x24 */ ALLEGRO_KEY_J, ALLEGRO_KEY_K, ALLEGRO_KEY_L, ALLEGRO_KEY_SEMICOLON, /* 0x28 */ ALLEGRO_KEY_QUOTE, ALLEGRO_KEY_TILDE, ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_BACKSLASH, /* 0x2C */ ALLEGRO_KEY_Z, ALLEGRO_KEY_X, ALLEGRO_KEY_C, ALLEGRO_KEY_V, /* 0x30 */ ALLEGRO_KEY_B, ALLEGRO_KEY_N, ALLEGRO_KEY_M, ALLEGRO_KEY_COMMA, /* 0x34 */ ALLEGRO_KEY_FULLSTOP, ALLEGRO_KEY_SLASH, ALLEGRO_KEY_RSHIFT, ALLEGRO_KEY_PAD_ASTERISK, /* 0x38 */ ALLEGRO_KEY_ALT, ALLEGRO_KEY_SPACE, ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_F1, /* 0x3C */ ALLEGRO_KEY_F2, ALLEGRO_KEY_F3, ALLEGRO_KEY_F4, ALLEGRO_KEY_F5, /* 0x40 */ ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F8, ALLEGRO_KEY_F9, /* 0x44 */ ALLEGRO_KEY_F10, ALLEGRO_KEY_NUMLOCK, ALLEGRO_KEY_SCROLLLOCK, ALLEGRO_KEY_PAD_7, /* 0x48 */ ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_MINUS, ALLEGRO_KEY_PAD_4, /* 0x4C */ ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_PLUS, ALLEGRO_KEY_PAD_1, /* 0x50 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_DELETE, /* 0x54 */ ALLEGRO_KEY_PRINTSCREEN, 0, ALLEGRO_KEY_BACKSLASH2, ALLEGRO_KEY_F11, /* 0x58 */ ALLEGRO_KEY_F12, 0, 0, 0, /* 0x5C */ 0, 0, 0, 0, /* 0x60 */ ALLEGRO_KEY_PAD_ENTER, ALLEGRO_KEY_RCTRL, ALLEGRO_KEY_PAD_SLASH, ALLEGRO_KEY_PRINTSCREEN, /* 0x64 */ ALLEGRO_KEY_ALTGR, ALLEGRO_KEY_PAUSE, ALLEGRO_KEY_HOME, ALLEGRO_KEY_UP, /* 0x68 */ ALLEGRO_KEY_PGUP, ALLEGRO_KEY_LEFT, ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_END, /* 0x6C */ ALLEGRO_KEY_DOWN, ALLEGRO_KEY_PGDN, ALLEGRO_KEY_INSERT, ALLEGRO_KEY_DELETE, /* 0x70 */ 0, 0, 0, 0, /* 0x74 */ 0, 0, 0, ALLEGRO_KEY_PAUSE, /* 0x78 */ 0, 0, 0, 0, /* 0x7C */ 0, ALLEGRO_KEY_LWIN, ALLEGRO_KEY_RWIN, ALLEGRO_KEY_MENU /* "Two keys are unusual in the sense that their keycode is not constant, * but depends on modifiers. The PrintScrn key will yield keycode 84 when * combined with either Alt key, but keycode 99 otherwise. The Pause key * will yield keycode 101 when combined with either Ctrl key, but keycode * 119 otherwise. (This has historic reasons, but might change, to free * keycodes 99 and 119 for other purposes.)" */ }; /* convert kernel keycodes for numpad keys into ASCII characters */ #define NUM_PAD_KEYS 17 static const char pad_asciis[NUM_PAD_KEYS] = { '0','1','2','3','4','5','6','7','8','9', '+','-','*','/','\r',',','.' }; static const char pad_asciis_no_numlock[NUM_PAD_KEYS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '+', '-', '*', '/', '\r', 0, 0 }; /* convert Allegro format keycodes into ALLEGRO_KEYMOD_* */ static const unsigned int modifier_table[ALLEGRO_KEY_MAX - ALLEGRO_KEY_MODIFIERS] = { ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEYMOD_CTRL, ALLEGRO_KEYMOD_CTRL, ALLEGRO_KEYMOD_ALT, ALLEGRO_KEYMOD_ALTGR, ALLEGRO_KEYMOD_LWIN, ALLEGRO_KEYMOD_RWIN, ALLEGRO_KEYMOD_MENU, ALLEGRO_KEYMOD_SCROLLLOCK, ALLEGRO_KEYMOD_NUMLOCK, ALLEGRO_KEYMOD_CAPSLOCK }; /* keycode_to_char: [fdwatch thread] * Helper function. * KEYCODE is a Linux kernel keycode, not an Allegro keycode. * * In the process of doing the translation, we may find that the user * has pressed a key that for VT switching. In that case a negative * number is returned, the absolute value of which is the VT to * switch to. Yes, ugly. */ static int keycode_to_char(int keycode) { const unsigned int modifiers = the_keyboard.modifiers; struct kbentry kbe; int keymap; int ascii; /* build kernel keymap number */ keymap = 0; if (modifiers & ALLEGRO_KEYMOD_SHIFT) keymap |= 1; if (modifiers & ALLEGRO_KEYMOD_ALTGR) keymap |= 2; if (modifiers & ALLEGRO_KEYMOD_CTRL) keymap |= 4; if (modifiers & ALLEGRO_KEYMOD_ALT) keymap |= 8; /* map keycode to type and value */ kbe.kb_table = keymap; kbe.kb_index = keycode; ioctl(the_keyboard.fd, KDGKBENT, &kbe); if (keycode == KEY_BACKSPACE) ascii = 8; else { if (kbe.kb_value == K_NOSUCHMAP) { /* invalid keymaps */ /* FIXME: Maybe we should just redo the */ /* ioctl with keymap 0? */ ascii = 0; } else { /* most keys come here */ ascii = KVAL(kbe.kb_value); } } /* finally do some things based on key type */ switch (KTYP(kbe.kb_value)) { case KT_CONS: /* VT switch key -- return a negative number */ return -( KVAL(kbe.kb_value)+1 ); case KT_LETTER: /* apply capslock translation. */ if (modifiers & ALLEGRO_KEYMOD_CAPSLOCK) return ascii ^ 0x20; else return ascii; case KT_LATIN: case KT_ASCII: return ascii; case KT_PAD: { int val = KVAL(kbe.kb_value); if (modifiers & ALLEGRO_KEYMOD_NUMLOCK) { if ((val >= 0) && (val < NUM_PAD_KEYS)) ascii = pad_asciis[val]; } else { if ((val >= 0) && (val < NUM_PAD_KEYS)) ascii = pad_asciis_no_numlock[val]; } return ascii; } case KT_SPEC: if (keycode == KEY_ENTER) return '\r'; else return 0; default: /* dunno */ return 0; } } /* lkeybd_init_keyboard: [primary thread] * Initialise the keyboard driver. */ static bool lkeybd_init_keyboard(void) { bool can_restore_termio_and_kbmode = false; memset(&the_keyboard, 0, sizeof the_keyboard); if (__al_linux_use_console()) return false; the_keyboard.fd = dup(__al_linux_console_fd); /* Save the current terminal attributes, which we will restore when * we close up shop. */ if (tcgetattr(the_keyboard.fd, &the_keyboard.startup_termio) != 0) goto Error; /* Save previous keyboard mode (probably XLATE). */ if (ioctl(the_keyboard.fd, KDGKBMODE, &the_keyboard.startup_kbmode) != 0) goto Error; can_restore_termio_and_kbmode = true; /* Set terminal attributes we need. * * Input modes (c_iflag): We want to disable: * - stripping bytes to 7 bits * - ignoring of carriage returns * - translating of carriage returns to newlines, and vice versa * - start/stop control on input and output * * Control modes (c_cflag): We want 8 bits per byte. * * Local modes (c_lflag: We want to disable: * - canonical (line by line) input * - echoing input back to the display * - interpretation of signal characters * * The c_iflag, c_lflag settings come from svgalib. Allegro 4 * simply set them to 0, which is a bit crude. */ the_keyboard.work_termio = the_keyboard.startup_termio; the_keyboard.work_termio.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); the_keyboard.work_termio.c_cflag &= ~CSIZE; the_keyboard.work_termio.c_cflag |= CS8; the_keyboard.work_termio.c_lflag &= ~(ICANON | ECHO | ISIG); if (tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.work_termio) != 0) goto Error; /* Set the keyboard mode to mediumraw. */ if (ioctl(the_keyboard.fd, KDSKBMODE, K_MEDIUMRAW) != 0) goto Error; /* Initialise the keyboard object for use as an event source. */ _al_event_source_init(&the_keyboard.parent.es); /* Start watching for data on the fd. */ _al_unix_start_watching_fd(the_keyboard.fd, process_new_data, NULL); /* Get the pid, which we use for the three finger salute */ main_pid = getpid(); return true; Error: if (can_restore_termio_and_kbmode) { tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.startup_termio); ioctl(the_keyboard.fd, KDSKBMODE, the_keyboard.startup_kbmode); } close(the_keyboard.fd); __al_linux_leave_console(); return false; } /* lkeybd_exit_keyboard: [primary thread] * Shut down the keyboard driver. */ static void lkeybd_exit_keyboard(void) { _al_unix_stop_watching_fd(the_keyboard.fd); _al_event_source_free(&the_keyboard.parent.es); /* Restore terminal attrs, keyboard mode, and reset the LED mode. */ tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.startup_termio); ioctl(the_keyboard.fd, KDSKBMODE, the_keyboard.startup_kbmode); ioctl(the_keyboard.fd, KDSETLED, 8); close(the_keyboard.fd); __al_linux_leave_console(); /* This may help catch bugs in the user program, since the pointer * we return to the user is always the same. */ memset(&the_keyboard, 0, sizeof the_keyboard); } /* lkeybd_get_keyboard: * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. */ static ALLEGRO_KEYBOARD *lkeybd_get_keyboard(void) { return (ALLEGRO_KEYBOARD *)&the_keyboard; } /* lkeybd_set_keyboard_leds: * Updates the LED state. */ static bool lkeybd_set_keyboard_leds(int leds) { int val = 0; if (leds & ALLEGRO_KEYMOD_SCROLLLOCK) val |= LED_SCR; if (leds & ALLEGRO_KEYMOD_NUMLOCK) val |= LED_NUM; if (leds & ALLEGRO_KEYMOD_CAPSLOCK) val |= LED_CAP; return (ioctl(the_keyboard.fd, KDSETLED, val) == 0) ? true : false; } /* lkeybd_get_keyboard_state: [primary thread] * Copy the current keyboard state into RET_STATE, with any necessary locking. */ static void lkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { _al_event_source_lock(&the_keyboard.parent.es); { *ret_state = the_keyboard.state; } _al_event_source_unlock(&the_keyboard.parent.es); } /* process_new_data: [fdwatch thread] * Process new data arriving in the keyboard's fd. */ static void process_new_data(void *unused) { _al_event_source_lock(&the_keyboard.parent.es); { unsigned char buf[128]; size_t bytes_read; unsigned int ch; bytes_read = read(the_keyboard.fd, &buf, sizeof(buf)); for (ch = 0; ch < bytes_read; ch++) process_character(buf[ch]); } _al_event_source_unlock(&the_keyboard.parent.es); (void)unused; } /* process_character: [fdwatch thread] * This is where most of the work gets done. CH is a byte read in * from the keyboard's fd. This function finds the Allegro equivalent * of that key code, figures out which ASCII character that key * generates (if any), and then calls the handle_key_press() and * handle_key_release() functions with that information. It also does * some things with modifier keys. */ static void process_character(unsigned char ch) { /* read kernel's keycode and convert to Allegro's keycode */ int keycode = ch & 0x7f; bool press = !(ch & 0x80); int mycode = kernel_to_mycode[keycode]; /* if the key was something weird we don't understand, skip it */ if (mycode == 0) return; /* process modifiers */ if (mycode >= ALLEGRO_KEY_MODIFIERS) { int flag = modifier_table[mycode - ALLEGRO_KEY_MODIFIERS]; if (press) { if (flag & KB_MODIFIERS) the_keyboard.modifiers |= flag; else if ((flag & KB_LED_FLAGS) && _al_key_led_flag) the_keyboard.modifiers ^= flag; } else { /* XXX: if the user presses LCTRL, then RCTRL, then releases * LCTRL, the ALLEGRO_KEYMOD_CTRL modifier should still be on. */ if (flag & KB_MODIFIERS) the_keyboard.modifiers &= ~flag; } } /* call the handlers */ if (press) { int ascii = keycode_to_char(keycode); /* switch VT if the user requested so */ if (ascii < 0) { int console = -ascii; int last_console; ioctl(the_keyboard.fd, VT_OPENQRY, &last_console); if (console < last_console) if (ioctl(the_keyboard.fd, VT_ACTIVATE, console) == 0) return; } handle_key_press(mycode, ascii); } else { handle_key_release(mycode); } /* three-finger salute for killing the program */ if ((_al_three_finger_flag) && ((mycode == ALLEGRO_KEY_DELETE) || (mycode == ALLEGRO_KEY_END)) && (the_keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) && (the_keyboard.modifiers & ALLEGRO_KEYMOD_ALT)) { TRACE(PREFIX_W "Three finger combo detected. SIGTERMing " "pid %d\n", main_pid); kill(main_pid, SIGTERM); } } /* handle_key_press: [fdwatch thread] * Helper: stuff to do when a key is pressed. */ static void handle_key_press(int mycode, unsigned int ascii) { ALLEGRO_EVENT_TYPE event_type; ALLEGRO_EVENT event; event_type = (_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode) ? ALLEGRO_EVENT_KEY_REPEAT : ALLEGRO_EVENT_KEY_DOWN); /* Maintain the key_down array. */ _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode); /* Generate key press/repeat events if necessary. */ if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) return; event.keyboard.type = event_type; event.keyboard.timestamp = al_get_time(); event.keyboard.display = NULL; event.keyboard.keycode = mycode; event.keyboard.unichar = ascii; event.keyboard.modifiers = the_keyboard.modifiers; _al_event_source_emit_event(&the_keyboard.parent.es, &event); /* The first press should generate a KEY_CHAR also */ if (event_type == ALLEGRO_EVENT_KEY_DOWN) { event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; event.keyboard.timestamp = al_get_time(); _al_event_source_emit_event(&the_keyboard.parent.es, &event); } } /* handle_key_release: [fdwatch thread] * Helper: stuff to do when a key is released. */ static void handle_key_release(int mycode) { ALLEGRO_EVENT event; /* This can happen, e.g. when we are switching back into a VT with * ALT+Fn, we only get the release event of the function key. */ if (!_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode)) return; /* Maintain the key_down array. */ _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode); /* Generate key release events if necessary. */ if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) return; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = NULL; event.keyboard.keycode = mycode; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_emit_event(&the_keyboard.parent.es, &event); } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/src/linux/lmouse.c0000644000175000001440000001365011426530105016006 0ustar tjadenusers#error This file is no longer used. /* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console mouse module. * * By George Foot. * * This file contains a generic framework for different mouse * types to hook into. See lmseps2.c for an example. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" static int mouse_mx = 0; /* internal position, in mickeys */ static int mouse_my = 0; static int mouse_sx = 128; /* mickey -> pixel scaling factor */ static int mouse_sy = 128; static int mouse_minx = 0; /* mouse range */ static int mouse_miny = 0; static int mouse_maxx = 319; static int mouse_maxy = 199; static int mymickey_x = 0; /* for get_mouse_mickeys() */ static int mymickey_y = 0; #define MICKEY_TO_COORD_X(n) ((n) * mouse_sx / 256) #define MICKEY_TO_COORD_Y(n) ((n) * mouse_sy / 256) #define COORD_TO_MICKEY_X(n) ((n) * 256 / mouse_sx) #define COORD_TO_MICKEY_Y(n) ((n) * 256 / mouse_sy) /* __al_linux_mouse_position: * Sets the position of the mickey-mode mouse. */ void __al_linux_mouse_position(int x, int y) { DISABLE(); _mouse_x = x; _mouse_y = y; mouse_mx = COORD_TO_MICKEY_X(x); mouse_my = COORD_TO_MICKEY_Y(y); mymickey_x = mymickey_y = 0; ENABLE(); } /* __al_linux_mouse_set_range: * Sets the range of the mickey-mode mouse. */ void __al_linux_mouse_set_range(int x1, int y1, int x2, int y2) { mouse_minx = x1; mouse_miny = y1; mouse_maxx = x2; mouse_maxy = y2; DISABLE(); _mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx); _mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy); mouse_mx = COORD_TO_MICKEY_X(_mouse_x); mouse_my = COORD_TO_MICKEY_Y(_mouse_y); ENABLE(); } /* __al_linux_mouse_set_speed: * Sets the speed of the mickey-mode mouse. */ void __al_linux_mouse_set_speed(int xspeed, int yspeed) { int scale; if (gfx_driver) scale = 256*gfx_driver->w/320; else scale = 256; DISABLE(); mouse_sx = scale / MAX(1, xspeed); mouse_sy = scale / MAX(1, yspeed); mouse_mx = COORD_TO_MICKEY_X(_mouse_x); mouse_my = COORD_TO_MICKEY_Y(_mouse_y); ENABLE(); } /* __al_linux_mouse_get_mickeys: * Reads the mickey-mode count. */ void __al_linux_mouse_get_mickeys(int *mickeyx, int *mickeyy) { int temp_x = mymickey_x; int temp_y = mymickey_y; mymickey_x -= temp_x; mymickey_y -= temp_y; *mickeyx = temp_x; *mickeyy = temp_y; } /* __al_linux_mouse_handler: * Movement callback for mickey-mode driver. */ void __al_linux_mouse_handler (int x, int y, int z, int b) { _mouse_b = b; mymickey_x += x; mymickey_y -= y; mouse_mx += x; mouse_my -= y; _mouse_x = MICKEY_TO_COORD_X(mouse_mx); _mouse_y = MICKEY_TO_COORD_Y(mouse_my); _mouse_z += z; if ((_mouse_x < mouse_minx) || (_mouse_x > mouse_maxx) || (_mouse_y < mouse_miny) || (_mouse_y > mouse_maxy)) { _mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx); _mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy); mouse_mx = COORD_TO_MICKEY_X(_mouse_x); mouse_my = COORD_TO_MICKEY_Y(_mouse_y); } _handle_mouse_input(); } static int update_mouse (void); static void resume_mouse (void); static void suspend_mouse (void); static STD_DRIVER std_mouse = { STD_MOUSE, update_mouse, resume_mouse, suspend_mouse, -1 /* fd -- filled in later */ }; #include #include #include #include #include #include static int resume_count; static INTERNAL_MOUSE_DRIVER *internal_driver; /* update_mouse: * Reads data from the mouse, attempting to process it. */ static int update_mouse (void) { static unsigned char buf[1024]; static int bytes_in_buffer = 0; int bytes_read; fd_set set; struct timeval tv = { 0, 0 }; if (resume_count <= 0) return 0; FD_ZERO(&set); FD_SET(std_mouse.fd, &set); if (select (FD_SETSIZE, &set, NULL, NULL, &tv) <= 0) return 0; bytes_read = read(std_mouse.fd, &buf[bytes_in_buffer], sizeof(buf) - bytes_in_buffer); if (bytes_read <= 0) return 0; bytes_in_buffer += bytes_read; while (bytes_in_buffer && (bytes_read = internal_driver->process (buf, bytes_in_buffer))) { int i; bytes_in_buffer -= bytes_read; for (i = 0; i < bytes_in_buffer; i++) buf[i] = buf[i+bytes_read]; } return 1; } /* activate_mouse: * Put mouse device into the mode we want. */ static void activate_mouse (void) { } /* deactivate_mouse: * Restore the original settings. */ static void deactivate_mouse (void) { } /* suspend_mouse: * Suspend our mouse handling. */ static void suspend_mouse (void) { resume_count--; if (resume_count == 0) deactivate_mouse(); } /* resume_mouse: * Start/resume Allegro mouse handling. */ static void resume_mouse (void) { if (resume_count == 0) activate_mouse(); resume_count++; } /* __al_linux_mouse_init: * Sets up the mouse driver. */ int __al_linux_mouse_init (INTERNAL_MOUSE_DRIVER *drv) { internal_driver = drv; std_mouse.fd = drv->device; /* Mouse is disabled now. */ resume_count = 0; /* Register our driver (enables it too). */ __al_linux_add_standard_driver (&std_mouse); return internal_driver->num_buttons; } /* __al_linux_mouse_exit: * Removes our driver. */ void __al_linux_mouse_exit (void) { __al_linux_remove_standard_driver (&std_mouse); } allegro-5.0.10/src/linux/lmseev.c0000644000175000001440000005207512125675500016007 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console mouse driver for event interface (EVDEV). * * By Annie Testes. * * Handles all inputs that fill evdev with informations * about movement and click. * * Hacked for new mouse API by Peter Wang. * * See readme.txt for copyright information. */ #define ALLEGRO_NO_COMPATIBILITY #include "allegro5/allegro.h" #ifdef ALLEGRO_HAVE_LINUX_INPUT_H #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #include #include #include #include #define PREFIX_I "al-evdev INFO: " #define PREFIX_W "al-evdev WARNING: " #define PREFIX_E "al-evdev ERROR: " typedef struct AL_MOUSE_EVDEV { ALLEGRO_MOUSE parent; int fd; ALLEGRO_MOUSE_STATE state; } AL_MOUSE_EVDEV; /* the one and only mouse object */ static AL_MOUSE_EVDEV the_mouse; /* forward declarations */ static void process_new_data(void *unused); static void process_event(struct input_event *event); static void handle_button_event(unsigned int button, bool is_down); static void handle_axis_event(int dx, int dy, int dz); static void generate_mouse_event(unsigned int type, int x, int y, int z, int dx, int dy, int dz, unsigned int button); /* * Tools data */ /* Tool mode * This mode is the behavior the user sees, it is not the way the device * reports the position. * Tools that send relative informations can only be in relative mode, * tools that send absolute informations can be either in absolute mode or in * relative mode */ typedef enum { MODE_RELATIVE, MODE_ABSOLUTE } MODE; typedef struct TOOL { int tool_id; /* One of the BTN_TOOL_... from linux/input.h */ MODE mode; /* Relative or absolute */ } TOOL; static TOOL tools[] = { { BTN_TOOL_MOUSE, MODE_RELATIVE }, { BTN_TOOL_PEN, MODE_ABSOLUTE }, { BTN_TOOL_RUBBER, MODE_ABSOLUTE }, { BTN_TOOL_BRUSH, MODE_ABSOLUTE }, { BTN_TOOL_PENCIL, MODE_ABSOLUTE }, { BTN_TOOL_AIRBRUSH, MODE_ABSOLUTE }, { BTN_TOOL_FINGER, MODE_ABSOLUTE }, { BTN_TOOL_LENS, MODE_ABSOLUTE }, { -1, MODE_ABSOLUTE } /* No tool */ }; /* Default tool, in case the device does not send a tool id */ static TOOL *default_tool = tools + 0; static TOOL *no_tool = tools + (sizeof(tools)/sizeof(tools[0]) - 1); static TOOL *current_tool; /* find_tool: * Returns the tool with id 'tool_id' which is one of the BTN_TOOL_... defined * in linux/input.h. Returns 'default_tool' if not found. */ static TOOL *find_tool(int tool_id) { TOOL *t; for (t=tools; t!=no_tool; t++) { if (t->tool_id == tool_id) return t; } return default_tool; } /* * Pointer axis */ typedef struct AXIS { int in_min; /* For absolute mode */ int in_max; /* For absolute mode */ int out_min; /* For absolute mode */ int out_max; /* For absolute mode */ float speed; /* For set_mouse_speed */ int mickeys; /* For get_mouse_mickeys */ float scale; /* Scale factor, because tablet mice generate more movement than common mice */ int in_abs; /* Current absolute position, used for absolute input, whether the output is absolute or relative */ int out_abs; /* Position on the screen */ } AXIS; #define IN_RANGE(axis) ( (axis).in_max-(axis).in_min+1 ) #define OUT_RANGE(axis) ( (axis).out_max-(axis).out_min+1 ) /* in_to_screen: * maps an input absolute position to a screen position */ static int in_to_screen(const AXIS *axis, int v) { return (((v-axis->in_min) * OUT_RANGE(*axis)) / IN_RANGE(*axis)) + axis->out_min; } /* rel_event: * returns the new screen position, given the input relative one. * The tool mode is always relative */ static int rel_event(AXIS *axis, int v) { /* When input only send relative events, the mode is always relative */ int ret = axis->out_abs + v*axis->speed; axis->mickeys += v; axis->in_abs += v; return ret; } /* abs_event: * returns the new screen position, given the input absolute one, * and depending on the tool mode */ static int abs_event(AXIS *axis, MODE mode, int v) { if (mode == MODE_ABSOLUTE) { axis->mickeys = 0; /* No mickeys in absolute mode */ axis->in_abs = v; return in_to_screen(axis, v); } else { /* Input is absolute, but tool is relative */ int value = (v-axis->in_abs)*axis->scale; axis->mickeys += value; axis->in_abs = v; return axis->out_abs + value*axis->speed; } } /* get_axis_value: * returns the input absolute position */ static void get_axis_value(int fd, AXIS *axis, int type) { int abs[5]; int ret = ioctl(fd, EVIOCGABS(type), abs); if (ret>=0) { axis->in_abs = abs[0]; } } /* has_event: * returns true if the device generates the event */ static int has_event(int fd, unsigned short type, unsigned short code) { const unsigned int len = sizeof(unsigned long)*8; const unsigned int max = MAX(EV_MAX, MAX(KEY_MAX, MAX(REL_MAX, MAX(ABS_MAX, MAX(LED_MAX, MAX(SND_MAX, FF_MAX)))))); unsigned long bits[(max+len-1)/len]; if (ioctl(fd, EVIOCGBIT(type, max), bits)) { return (bits[code/len] >> (code%len)) & 1; } return 0; } /* get_num_buttons: * return the number of buttons */ static int get_num_buttons(int fd) { if (has_event(fd, EV_KEY, BTN_MIDDLE)) return 3; if (has_event(fd, EV_KEY, BTN_RIGHT)) return 2; if (has_event(fd, EV_KEY, BTN_MOUSE)) return 1; return 0; /* Not a mouse */ } /* The three axis: horizontal, vertical and wheel */ static AXIS x_axis; static AXIS y_axis; static AXIS z_axis; /* * Initialization functions */ /* init_axis: * initialize an AXIS structure, from the device and the config file */ static void init_axis(int fd, AXIS *axis, const char *name, const char *section, int type) { char tmp1[256]; /* config string */ char tmp2[256]; /* format string */ char tmp3[256]; /* Converted 'name' */ int abs[5]; /* values given by the input */ int config_speed; uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_min_%s", tmp2), uconvert_ascii(name, tmp3)); axis->in_min = get_config_int(section, tmp1, 0); uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_max_%s", tmp2), uconvert_ascii(name, tmp3)); axis->in_max = get_config_int(section, tmp1, 0); uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_abs_to_rel_%s", tmp2), uconvert_ascii(name, tmp3)); config_speed = get_config_int(section, tmp1, 1); if (config_speed<=0) config_speed = 1; axis->scale = 1; /* Ask the input */ if (ioctl(fd, EVIOCGABS(type), abs)>=0) { if (axis->in_min==0) axis->in_min=abs[1]; if (axis->in_max==0) axis->in_max=abs[2]; axis->in_abs = abs[0]; axis->scale = 320.0*config_speed/IN_RANGE(*axis); } if (axis->in_min>axis->in_max) { axis->in_min = axis->in_max = 0; axis->scale = 1; } axis->out_min = INT_MIN; axis->out_max = INT_MAX; axis->speed = 1; axis->mickeys = 0; } /* init_tablet: * initialize the tools and axis */ static void init_tablet(int fd) { char tmp[256]; char *mouse_str = uconvert_ascii("mouse", tmp); char tmp2[256]; int default_abs = default_tool->mode==MODE_ABSOLUTE; default_abs = get_config_int(mouse_str, uconvert_ascii("ev_absolute", tmp2), default_abs); if (default_abs) { default_tool->mode = MODE_ABSOLUTE; } else { default_tool->mode = MODE_RELATIVE; } init_axis(fd, &x_axis, "x", mouse_str, ABS_X); init_axis(fd, &y_axis, "y", mouse_str, ABS_Y); init_axis(fd, &z_axis, "z", mouse_str, ABS_Z); } /* * Process input functions */ /* process_key: [fdwatch thread] * process events of type key (button clicks and vicinity events are currently * supported) */ static void process_key(const struct input_event *event) { switch (event->code) { /* Buttons click * if event->value is 1 the button has just been pressed * if event->value is 0 the button has just been released */ case BTN_LEFT: /* Mouse */ case BTN_TOUCH: /* Stylus */ handle_button_event(1, event->value); break; case BTN_RIGHT: /* Mouse */ case BTN_STYLUS: /* Stylus */ handle_button_event(2, event->value); break; case BTN_MIDDLE: /* Mouse */ case BTN_STYLUS2: /* Stylus */ handle_button_event(3, event->value); break; /* Vicinity events * if event->value is 1, the tool enters the tablet vicinity * if event->value is 0, the tool leaves the tablet vicinity */ case BTN_TOOL_MOUSE: case BTN_TOOL_PEN: case BTN_TOOL_RUBBER: case BTN_TOOL_BRUSH: case BTN_TOOL_PENCIL: case BTN_TOOL_AIRBRUSH: case BTN_TOOL_FINGER: case BTN_TOOL_LENS: if (event->value) { current_tool = find_tool(event->code); get_axis_value(the_mouse.fd, &x_axis, ABS_X); get_axis_value(the_mouse.fd, &y_axis, ABS_Y); get_axis_value(the_mouse.fd, &z_axis, ABS_Z); #ifdef ABS_WHEEL /* absent in 2.2.x */ get_axis_value(the_mouse.fd, &z_axis, ABS_WHEEL); #endif } else { current_tool = no_tool; } break; } } /* [fdwatch thread] */ static void handle_button_event(unsigned int button, bool is_down) { unsigned int event_type; if (is_down) { the_mouse.state.buttons |= (1 << (button-1)); event_type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; } else { the_mouse.state.buttons &=~ (1 << (button-1)); event_type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; } generate_mouse_event( event_type, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, 0, 0, 0, button); } /* process_rel: [fdwatch thread] * process relative events (x, y and z movement are currently supported) */ static void process_rel(const struct input_event *event) { /* The device can send a report when there's no tool */ if (current_tool!=no_tool) { switch (event->code) { case REL_X: x_axis.out_abs = rel_event(&x_axis, event->value); handle_axis_event(x_axis.mickeys, 0, 0); x_axis.mickeys = 0; break; case REL_Y: y_axis.out_abs = rel_event(&y_axis, event->value); handle_axis_event(0, y_axis.mickeys, 0); y_axis.mickeys = 0; break; #ifdef REL_WHEEL /* absent in 2.2.x */ case REL_WHEEL: #endif case REL_Z: z_axis.out_abs = rel_event(&z_axis, event->value); handle_axis_event(0, 0, z_axis.mickeys); z_axis.mickeys = 0; break; } } } /* process_abs: [fdwatch thread] * process absolute events (x, y and z movement are currently supported) * TODO: missing handle_axis_event calls */ static void process_abs(const struct input_event *event) { /* The device can send a report when there's no tool */ if (current_tool!=no_tool) { switch (event->code) { case ABS_X: x_axis.out_abs = abs_event(&x_axis, current_tool->mode, event->value); break; case ABS_Y: y_axis.out_abs = abs_event(&y_axis, current_tool->mode, event->value); break; #ifdef ABS_WHEEL /* absent in 2.2.x */ case ABS_WHEEL: #endif case ABS_Z: z_axis.out_abs = abs_event(&z_axis, current_tool->mode, event->value); break; } } } /* [fdwatch thread] */ static void handle_axis_event(int dx, int dy, int dz) { if (current_tool != no_tool) { x_axis.out_abs = CLAMP(x_axis.out_min, x_axis.out_abs, x_axis.out_max); y_axis.out_abs = CLAMP(y_axis.out_min, y_axis.out_abs, y_axis.out_max); /* There's no range for z */ the_mouse.state.x = x_axis.out_abs; the_mouse.state.y = y_axis.out_abs; the_mouse.state.z = z_axis.out_abs; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, dx, dy, dz, 0); } } /* open_mouse_device: * Open the specified device file and check that it is a mouse device. * Returns the file descriptor if successful or a negative number on error. */ static int open_mouse_device (const char *device_file) { int fd; fd = open (device_file, O_RDONLY | O_NONBLOCK); if (fd >= 0) { TRACE(PREFIX_I "Opened device %s\n", device_file); /* The device is a mouse if it has a BTN_MOUSE */ if (has_event(fd, EV_KEY, BTN_MOUSE)) { TRACE(PREFIX_I "Device %s was a mouse.\n", device_file); } else { TRACE(PREFIX_I "Device %s was not mouse, closing.\n", device_file); close(fd); fd = -1; } } return fd; } /* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static bool mouse_init (void) { char tmp1[128], tmp2[128]; const char *udevice; /* Set the current tool */ current_tool = default_tool; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), NULL); /* Open mouse device. Devices are cool. */ if (udevice) { TRACE(PREFIX_I "Trying %s device\n", udevice); the_mouse.fd = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); if (the_mouse.fd < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice, ustrerror (errno)); return false; } } else { /* If not specified in the config file, try several /dev/input/event * devices. */ const char *device_name[] = { "/dev/input/event0", "/dev/input/event1", "/dev/input/event2", "/dev/input/event3", NULL }; int i; TRACE(PREFIX_I "Trying /dev/input/event[0-3] devices\n"); for (i=0; device_name[i]; i++) { the_mouse.fd = open_mouse_device (device_name[i]); if (the_mouse.fd >= 0) break; } if (!device_name[i]) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open a mouse device: %s"), ustrerror (errno)); return false; } } /* Init the tablet data */ init_tablet(the_mouse.fd); /* Initialise the mouse object for use as an event source. */ _al_event_source_init(&the_mouse.parent.es); /* Start watching for data on the fd. */ _al_unix_start_watching_fd(the_mouse.fd, process_new_data, &the_mouse); return true; } /* mouse_exit: * Chain to the framework, then uninitialise things. */ static void mouse_exit (void) { _al_unix_stop_watching_fd(the_mouse.fd); _al_event_source_free(&the_mouse.parent.es); close(the_mouse.fd); /* This may help catch bugs in the user program, since the pointer * we return to the user is always the same. */ memset(&the_mouse, 0, sizeof the_mouse); the_mouse.fd = -1; } /* mouse_get_mouse: * Returns the address of a ALLEGRO_MOUSE structure representing the mouse. */ static ALLEGRO_MOUSE *mouse_get_mouse(void) { return (ALLEGRO_MOUSE *)&the_mouse; } /* mouse_get_mouse_num_buttons: * Return the number of buttons on the mouse. */ static unsigned int mouse_get_mouse_num_buttons(void) { ASSERT(the_mouse.fd >= 0); return get_num_buttons(the_mouse.fd); } /* mouse_get_mouse_num_axes: * Return the number of axes on the mouse. */ static unsigned int mouse_get_mouse_num_axes(void) { ASSERT(the_mouse.fd >= 0); /* XXX get the right number later */ return 3; } /* mouse_set_mouse_xy: * */ static bool mouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) { (void)display; _al_event_source_lock(&the_mouse.parent.es); { int dx, dy; x_axis.out_abs = _ALLEGRO_CLAMP(x_axis.out_min, x, x_axis.out_max); y_axis.out_abs = _ALLEGRO_CLAMP(y_axis.out_min, y, y_axis.out_max); x_axis.mickeys = 0; y_axis.mickeys = 0; dx = x_axis.out_abs - the_mouse.state.x; dy = y_axis.out_abs - the_mouse.state.y; if ((dx != 0) && (dy != 0)) { the_mouse.state.x = x_axis.out_abs; the_mouse.state.y = y_axis.out_abs; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, dx, dy, 0, 0); } } _al_event_source_unlock(&the_mouse.parent.es); return true; } /* mouse_set_mouse_axis: * * Number of mickeys to cross the screen horizontally: speed * 320. */ static bool mouse_set_mouse_axis(int which, int z) { if (which != 2) { return false; } _al_event_source_lock(&the_mouse.parent.es); { int dz; z_axis.out_abs = z; dz = z_axis.out_abs - the_mouse.state.z; if (dz != 0) { the_mouse.state.z = z_axis.out_abs; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, 0, 0, dz, 0); } } _al_event_source_unlock(&the_mouse.parent.es); return true; } /* mouse_set_mouse_range: * */ static bool mouse_set_mouse_range(int x1, int y1, int x2, int y2) { _al_event_source_lock(&the_mouse.parent.es); { int dx, dy; x_axis.out_min = x1; y_axis.out_min = y1; x_axis.out_max = x2; y_axis.out_max = y2; x_axis.out_abs = CLAMP(x_axis.out_min, x_axis.out_abs, x_axis.out_max); y_axis.out_abs = CLAMP(y_axis.out_min, y_axis.out_abs, y_axis.out_max); dx = x_axis.out_abs - the_mouse.state.x; dy = y_axis.out_abs - the_mouse.state.y; if ((dx != 0) && (dy != 0)) { the_mouse.state.x = x_axis.out_abs; the_mouse.state.y = y_axis.out_abs; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, dx, dy, 0, 0); } } _al_event_source_unlock(&the_mouse.parent.es); return true; } /* mouse_get_state: * Copy the current mouse state into RET_STATE, with any necessary locking. */ static void mouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) { _al_event_source_lock(&the_mouse.parent.es); { *ret_state = the_mouse.state; } _al_event_source_unlock(&the_mouse.parent.es); } /* process_new_data: [fdwatch thread] * Process new data arriving in the keyboard's fd. */ static void process_new_data(void *data) { ASSERT((AL_MOUSE_EVDEV *)data == &the_mouse); _al_event_source_lock(&the_mouse.parent.es); { struct input_event events[32]; int bytes, nr, i; while ((bytes = read(the_mouse.fd, &events, sizeof events)) > 0) { nr = bytes / sizeof(events[0]); for (i = 0; i < nr; i++) { process_event(&events[i]); } } } _al_event_source_unlock(&the_mouse.parent.es); } /* [fdwatch thread] */ static void process_event(struct input_event *event) { switch (event->type) { case EV_KEY: process_key(event); break; case EV_REL: process_rel(event); break; case EV_ABS: process_abs(event); break; } } /* [fdwatch thread] */ static void generate_mouse_event(unsigned int type, int x, int y, int z, int dx, int dy, int dz, unsigned int button) { ALLEGRO_EVENT event; if (!_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) return; event.mouse.type = type; event.mouse.timestamp = al_get_time(); event.mouse.display = NULL; event.mouse.x = x; event.mouse.y = y; event.mouse.z = z; event.mouse.dx = dx; event.mouse.dy = dy; event.mouse.dz = dz; event.mouse.button = button; event.mouse.pressure = 0.0; /* TODO */ _al_event_source_emit_event(&the_mouse.parent.es, &event); } /* the driver vtable */ ALLEGRO_MOUSE_DRIVER _al_mousedrv_linux_evdev = { AL_MOUSEDRV_LINUX_EVDEV, "", "", "Linux EVDEV mouse (and tablet)", mouse_init, mouse_exit, mouse_get_mouse, mouse_get_mouse_num_buttons, mouse_get_mouse_num_axes, mouse_set_mouse_xy, mouse_set_mouse_axis, mouse_set_mouse_range, mouse_get_state }; #endif /* ALLEGRO_HAVE_LINUX_INPUT_H */ /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/src/linux/vtswitch.c0000644000175000001440000001440212132132150016342 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Virtual console handling routines for Linux console Allegro. * * By George Foot, based on Marek Habersack's code. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #ifdef ALLEGRO_HAVE_MMAP #include #endif #if !defined(_POSIX_MAPPED_FILES) || !defined(ALLEGRO_HAVE_MMAP) #error "Sorry, mapped files are required for Allegro/Linux to work!" #endif static int switch_mode = SWITCH_PAUSE; static int vtswitch_initialised = 0; static struct vt_mode startup_vtmode; volatile int __al_linux_switching_blocked = 0; static volatile int console_active = 1; /* are we active? */ static volatile int console_should_be_active = 1; /* should we be? */ int __al_linux_set_display_switch_mode (int mode) { /* Clean up after the previous mode, if necessary */ if (switch_mode == SWITCH_NONE) __al_linux_switching_blocked--; switch_mode = mode; /* Initialise the new mode */ if (switch_mode == SWITCH_NONE) __al_linux_switching_blocked++; return 0; } /* go_away: * Performs a switch away. */ static void go_away(void) { _switch_out(); _unix_bg_man->disable_interrupts(); if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA)) _al_suspend_old_timer_emulation(); /* Disable input devices while we're away */ /* __al_linux_suspend_standard_drivers(); */ _save_switch_state(switch_mode); if (gfx_driver && gfx_driver->save_video_state) gfx_driver->save_video_state(); ioctl (__al_linux_console_fd, VT_RELDISP, 1); console_active = 0; __al_linux_switching_blocked--; if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA)) { __al_linux_wait_for_display(); _al_resume_old_timer_emulation(); } _unix_bg_man->enable_interrupts(); } /* come_back: * Performs a switch back. */ static void come_back(void) { _unix_bg_man->disable_interrupts(); if (gfx_driver && gfx_driver->restore_video_state) gfx_driver->restore_video_state(); _restore_switch_state(); ioctl(__al_linux_console_fd, VT_RELDISP, VT_ACKACQ); console_active = 1; /* __al_linux_resume_standard_drivers(); */ _unix_bg_man->enable_interrupts(); _switch_in(); __al_linux_switching_blocked--; } /* poll_console_switch: * Checks whether a switch is needed and not blocked; if so, * makes the switch. */ static void poll_console_switch (void) { if (console_active == console_should_be_active) return; if (__al_linux_switching_blocked) return; __al_linux_switching_blocked++; if (console_should_be_active) come_back(); else go_away(); } /* vt_switch_requested: * This is our signal handler; it gets called whenever a switch is * requested, because either SIGRELVT or SIGACQVT is raised. */ static void vt_switch_requested(int signo) { switch (signo) { case SIGRELVT: console_should_be_active = 0; break; case SIGACQVT: console_should_be_active = 1; break; default: return; } poll_console_switch(); } /* __al_linux_acquire_bitmap: * Increases the switching_blocked counter to block switches during * critical code (e.g. code accessing unsaved graphics controller * registers; or in background mode, code that does anything at all * connected with the screen bitmap). */ void __al_linux_acquire_bitmap(BITMAP *bmp) { ASSERT(bmp); __al_linux_switching_blocked++; } /* __al_linux_release_bitmap: * Decreases the blocking count and polls for switching. */ void __al_linux_release_bitmap(BITMAP *bmp) { ASSERT(bmp); __al_linux_switching_blocked--; poll_console_switch(); } /* __al_linux_display_switch_lock: * System driver routine for locking the display around crucial bits of * code, for example when changing video modes. */ void __al_linux_display_switch_lock(int lock, int foreground) { if (__al_linux_console_fd == -1) { return; } if (foreground) { __al_linux_wait_for_display(); } if (lock) { __al_linux_switching_blocked++; } else { __al_linux_switching_blocked--; poll_console_switch(); } } /* __al_linux_init_vtswitch: * Takes control over our console. It means we'll be notified when user * switches to and from the graphics console. */ int __al_linux_init_vtswitch(void) { struct sigaction sa; struct vt_mode vtm; if (vtswitch_initialised) return 0; /* shouldn't happen */ __al_linux_switching_blocked = (switch_mode == SWITCH_NONE) ? 1 : 0; console_active = console_should_be_active = 1; /* Hook the signals */ sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); /* block async IO during the VT switch */ sa.sa_flags = 0; sa.sa_handler = vt_switch_requested; if ((sigaction(SIGRELVT, &sa, NULL) < 0) || (sigaction(SIGACQVT, &sa, NULL) < 0)) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to control VT switching")); return 1; } /* Save old mode, take control, and arrange for the signals * to be raised. */ ioctl(__al_linux_console_fd, VT_GETMODE, &startup_vtmode); vtm = startup_vtmode; vtm.mode = VT_PROCESS; vtm.relsig = SIGRELVT; vtm.acqsig = SIGACQVT; ioctl(__al_linux_console_fd, VT_SETMODE, &vtm); vtswitch_initialised = 1; return 0; } /* __al_linux_done_vtswitch: * Undoes the effect of `init_vtswitch'. */ int __al_linux_done_vtswitch(void) { struct sigaction sa; if (!vtswitch_initialised) return 0; /* shouldn't really happen either */ /* !trout gfoot. Must turn off the signals before unhooking them... */ ioctl(__al_linux_console_fd, VT_SETMODE, &startup_vtmode); sigemptyset (&sa.sa_mask); sa.sa_handler = SIG_DFL; sa.sa_flags = SA_RESTART; sigaction (SIGRELVT, &sa, NULL); sigaction (SIGACQVT, &sa, NULL); vtswitch_initialised = 0; return 0; } allegro-5.0.10/src/linux/lmsegpmd.c0000644000175000001440000000760211426530105016312 0ustar tjadenusers#error This driver has not been updated to the new mouse API. /* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Linux console internal mouse driver for `gpmdata' repeater. * * By George Foot. * * See readme.txt for copyright information. */ #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/linalleg.h" #define ASCII_NAME "GPM repeater" #define DEVICE_FILENAME "/dev/gpmdata" /* processor: * Processes the first packet in the buffer, if any, returning the number * of bytes eaten. * * The GPM repeater uses Mouse Systems protocol. Packets contain five * bytes. The low bits of the first byte represent the button state. * The following bytes represent motion left, up, right and down * respectively. I think. * * We recognise the start of a packet by looking for a byte with the top * bit set and the next four bits not set -- while this can occur in the * data bytes, it's pretty unlikely. */ static int processor (unsigned char *buf, int buf_size) { int r, m, l, x, y, z; if (buf_size < 5) return 0; /* not enough data, spit it out for now */ if ((buf[0] & 0xf8) != 0x80) return 1; /* invalid byte, eat it */ /* packet is valid, process the data */ r = !(buf[0] & 1); m = !(buf[0] & 2); l = !(buf[0] & 4); x = (signed char)buf[1] + (signed char)buf[3]; y = (signed char)buf[2] + (signed char)buf[4]; z = 0; __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); return 5; /* yum */ } static INTERNAL_MOUSE_DRIVER intdrv = { -1, processor, 3 }; /* sync_mouse: * To find the start of a packet, we just read all the data that's * waiting. This isn't a particularly good way, obviously. :) */ static void sync_mouse (int fd) { fd_set set; int result; struct timeval tv; char bitbucket; do { FD_ZERO (&set); FD_SET (fd, &set); tv.tv_sec = tv.tv_usec = 0; result = select (FD_SETSIZE, &set, NULL, NULL, &tv); if (result > 0) read (fd, &bitbucket, 1); } while (result > 0); } /* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static int mouse_init (void) { char tmp1[128], tmp2[128], tmp3[128]; const char *udevice; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), uconvert_ascii (DEVICE_FILENAME, tmp3)); /* Open mouse device. Devices are cool. */ intdrv.device = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); if (intdrv.device < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice, ustrerror (errno)); return -1; } /* Discard any garbage, so the next thing we read is a packet header */ sync_mouse (intdrv.device); return __al_linux_mouse_init (&intdrv); } /* mouse_exit: * Chain to the framework, then uninitialise things. */ static void mouse_exit (void) { __al_linux_mouse_exit(); close (intdrv.device); } MOUSE_DRIVER mousedrv_linux_gpmdata = { MOUSEDRV_LINUX_GPMDATA, "", "", ASCII_NAME, mouse_init, mouse_exit, NULL, /* poll() */ NULL, /* timer_poll() */ __al_linux_mouse_position, __al_linux_mouse_set_range, __al_linux_mouse_set_speed, __al_linux_mouse_get_mickeys, NULL, /* analyse_data */ NULL, NULL }; allegro-5.0.10/src/optimized.c0000644000175000001440000002777311433551043015364 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Optimized memory blitters * * By Trent Gamblin * */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include ALLEGRO_INTERNAL_HEADER #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_float.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_convert.h" #include static unsigned char four_bit_lookup[16][16]; static unsigned char five_bit_lookup[32][16]; static unsigned char six_bit_lookup[64][16]; static unsigned char _565_lookup[65536*3]; static unsigned char _4444_lookup[65536*3]; static void init_lookups(void) { int i, j; for (i = 0; i < 16; i++) { for (j = 1; j <= 16; j++) { four_bit_lookup[i][j-1] = (char)(i*(j/16.0)); } } for (i = 0; i < 32; i++) { for (j = 1; j <= 16; j++) { five_bit_lookup[i][j-1] = (char)(i*(j/16.0)); } } for (i = 0; i < 64; i++) { for (j = 1; j <= 16; j++) { six_bit_lookup[i][j-1] = (char)(i*(j/16.0)); } } for (i = 0; i < 65536; i++) { _565_lookup[i*3] = (i & 0xF800) >> 11; _565_lookup[i*3+1] = (i & 0x07E0) >> 5; _565_lookup[i*3+2] = (i & 0x001F); _4444_lookup[i*3] = (i & 0xF000) >> 12; _4444_lookup[i*3+1] = (i & 0x0F00) >> 8; _4444_lookup[i*3+2] = (i & 0x00F0) >> 4; } } static bool inited = false; /* if we get here, all we have to do is blit * with no alpha and only blend color */ void _al_draw_bitmap_region_optimized_rgb_565_to_rgb_565( ALLEGRO_COLOR tint, ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags) { int xinc, yinc; int xd, yd; int x, y; ALLEGRO_COLOR *bc; if (!inited) { init_lookups(); inited = true; } if (flags != 0) { if (flags & ALLEGRO_FLIP_VERTICAL) { yinc = -1; yd = dy + sh - 1; } else { yinc = 1; yd = dy; } if (flags & ALLEGRO_FLIP_HORIZONTAL) { xinc = -1; xd = dx + sw - 1; } else { xinc = 1; xd = dx; } } else { yinc = 1; yd = dy; xinc = 1; xd = dx; } uint16_t pixel; bc = ∭ char *dest_data = ((char *)dest->memory+yd*dest->pitch+xd*2); char *src_data = ((char *)src->memory+sy*src->pitch+sx*2); int dest_data_inc; int src_data_inc; int dest_inc = xinc * 2; dest_data_inc = (dest->pitch*yinc) - (sw*dest_inc); src_data_inc = src->pitch - (sw*2); int rindex = bc->r*15; int gindex = bc->g*15; int bindex = bc->b*15; int r, g, b; for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); unsigned char *ptr = &(_565_lookup[pixel*3]); r = five_bit_lookup[*ptr++][rindex]; g = six_bit_lookup[*ptr++][gindex]; b = five_bit_lookup[*ptr][bindex]; pixel = (r << 11) | (g << 5) | b; *((uint16_t *)dest_data) = pixel; src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } void _al_draw_bitmap_region_optimized_rgba_4444_to_rgb_565( ALLEGRO_COLOR tint, ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags) { int xinc, yinc; int xd, yd; int x, y; ALLEGRO_COLOR *bc; static ALLEGRO_COLOR white = { 1, 1, 1, 1 }; if (!inited) { init_lookups(); inited = true; } if (flags != 0) { if (flags & ALLEGRO_FLIP_VERTICAL) { yinc = -1; yd = dy + sh - 1; } else { yinc = 1; yd = dy; } if (flags & ALLEGRO_FLIP_HORIZONTAL) { xinc = -1; xd = dx + sw - 1; } else { xinc = 1; xd = dx; } } else { yinc = 1; yd = dy; xinc = 1; xd = dx; } bc = ∭ uint16_t pixel; char *dest_data = ((char *)dest->memory+yd*dest->pitch+xd*2); char *src_data = ((char *)src->memory+sy*src->pitch+sx*2); int dest_data_inc; int src_data_inc; int dest_inc = xinc * 2; dest_data_inc = (dest->pitch*yinc) - (sw*dest_inc); src_data_inc = src->pitch - (sw*2); if ((src->flags & ALLEGRO_ALPHA_TEST) && !memcmp(bc, &white, sizeof(ALLEGRO_COLOR))) { for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); if (pixel & 0xF) { *((uint16_t *)dest_data) = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(pixel); } src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } else { int rindex = bc->r*15; int gindex = bc->g*15; int bindex = bc->b*15; int r, g, b; for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); if (pixel & 0xF) { float alpha = ((pixel & 0xF) / 15.0f) * bc->a; float inv_alpha = 1 - alpha; int alpha_index = alpha*15; int inv_alpha_index = inv_alpha*15; pixel = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(pixel); // Below is fast but doesn't look good /* pixel = (pixel & 0xF000) | ((pixel & 0x0F00) >> 1) | ((pixel & 0x00F0) >> 3) | 0x861; */ unsigned char *ptr = &(_565_lookup[pixel*3]); r = five_bit_lookup[*ptr++][rindex]; g = six_bit_lookup[*ptr++][gindex]; b = five_bit_lookup[*ptr][bindex]; r = five_bit_lookup[r][alpha_index]; g = six_bit_lookup[g][alpha_index]; b = five_bit_lookup[b][alpha_index]; uint16_t dpix = *((uint16_t *)dest_data); ptr = &(_565_lookup[dpix*3]); int r2 = five_bit_lookup[*ptr++][inv_alpha_index]; int g2 = six_bit_lookup[*ptr++][inv_alpha_index]; int b2 = five_bit_lookup[*ptr][inv_alpha_index]; r = _ALLEGRO_MIN(0x1F, r+r2); g = _ALLEGRO_MIN(0x3F, g+g2); b = _ALLEGRO_MIN(0x1F, b+b2); pixel = (r << 11) | (g << 5) | b; *((uint16_t *)dest_data) = pixel; } src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } } void _al_draw_bitmap_region_optimized_rgba_4444_to_rgba_4444( ALLEGRO_COLOR tint, ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags) { int xinc, yinc; int xd, yd; int x, y; ALLEGRO_COLOR *bc; if (!inited) { init_lookups(); inited = true; } if (flags != 0) { if (flags & ALLEGRO_FLIP_VERTICAL) { yinc = -1; yd = dy + sh - 1; } else { yinc = 1; yd = dy; } if (flags & ALLEGRO_FLIP_HORIZONTAL) { xinc = -1; xd = dx + sw - 1; } else { xinc = 1; xd = dx; } } else { yinc = 1; yd = dy; xinc = 1; xd = dx; } bc = ∭ int rindex = bc->r*15; int gindex = bc->g*15; int bindex = bc->b*15; int r, g, b; uint16_t pixel; char *dest_data = ((char *)dest->memory+yd*dest->pitch+xd*2); char *src_data = ((char *)src->memory+sy*src->pitch+sx*2); int dest_data_inc; int src_data_inc; int dest_inc = xinc * 2; dest_data_inc = (dest->pitch*yinc) - (sw*dest_inc); src_data_inc = src->pitch - (sw*2); if (src->flags & ALLEGRO_ALPHA_TEST) { if (bc->r == 1 && bc->g == 1 && bc->b == 1 && bc->a == 1) { for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); if (pixel & 0xF) { *((uint16_t *)dest_data) = pixel; } src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } else { for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); if (pixel & 0xF) { unsigned char *ptr = &(_4444_lookup[pixel*3]); r = four_bit_lookup[*ptr++][rindex]; g = four_bit_lookup[*ptr++][gindex]; b = four_bit_lookup[*ptr][bindex]; pixel = (r << 12) | (g << 8) | (b << 4) | 0xF; *((uint16_t *)dest_data) = pixel; } src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } } else { for (y = 0; y < sh; y++) { for (x = 0; x < sw; x++) { pixel = *((uint16_t *)src_data); if (pixel & 0xF) { float alpha = ((pixel & 0xF) / 15.0f) * bc->a; float inv_alpha = 1 - alpha; int alpha_index = alpha*15; int inv_alpha_index = inv_alpha*15; unsigned char *ptr = &(_4444_lookup[pixel*3]); r = four_bit_lookup[*ptr++][alpha_index]; g = four_bit_lookup[*ptr++][alpha_index]; b = four_bit_lookup[*ptr][alpha_index]; uint16_t dpix = *((uint16_t *)dest_data); ptr = &(_4444_lookup[dpix*3]); int r2 = four_bit_lookup[*ptr++][inv_alpha_index]; int g2 = four_bit_lookup[*ptr++][inv_alpha_index]; int b2 = four_bit_lookup[*ptr][inv_alpha_index]; r = four_bit_lookup[(r + r2) & 0xF][rindex]; g = four_bit_lookup[(g + g2) & 0xF][gindex]; b = four_bit_lookup[(b + b2) & 0xF][bindex]; pixel = (r << 12) | (g << 8) | (b << 4) | 0xF; *((uint16_t *)dest_data) = pixel; } src_data += 2; dest_data += dest_inc; } src_data += src_data_inc; dest_data += dest_data_inc; } } } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/utf8.c0000644000175000001440000005461311771526542014252 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * UTF-8 string handling functions. * * By Peter Wang. * * See LICENSE.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/utf8.h" #include "allegro5/internal/bstrlib.h" #include "allegro5/internal/aintern.h" ALLEGRO_STATIC_ASSERT(utf8, sizeof(ALLEGRO_USTR_INFO) >= sizeof(struct _al_tagbstring)); #ifdef ALLEGRO_MSVC #pragma warning (disable: 4066) #endif #ifndef ALLEGRO_HAVE_VA_COPY /* If va_copy() is not defined we assume that a simple assignment suffices. * From a few web searches, this appears to be true for MSVC 7. */ #define va_copy(a, b) ((a) = (b)) #endif #define IS_SINGLE_BYTE(c) (((unsigned)(c) & 0x80) == 0) #define IS_LEAD_BYTE(c) (((unsigned)(c) - 0xC0) < 0x3E) #define IS_TRAIL_BYTE(c) (((unsigned)(c) & 0xC0) == 0x80) static bool all_ascii(const ALLEGRO_USTR *us) { const unsigned char *data = (const unsigned char *) _al_bdata(us); int size = _al_blength(us); while (size-- > 0) { if (*data > 127) return false; data++; } return true; } /* Function: al_ustr_new */ ALLEGRO_USTR *al_ustr_new(const char *s) { return _al_bfromcstr(s); } /* Function: al_ustr_new_from_buffer */ ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size) { return _al_blk2bstr(s, size); } /* Function: al_ustr_newf */ ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...) { ALLEGRO_USTR *us; va_list ap; us = al_ustr_new(""); va_start(ap, fmt); al_ustr_vappendf(us, fmt, ap); va_end(ap); return us; } /* Function: al_ustr_free */ void al_ustr_free(ALLEGRO_USTR *us) { _al_bdestroy(us); } /* Function: al_cstr */ const char *al_cstr(const ALLEGRO_USTR *us) { /* May or may not be NUL terminated. */ return _al_bdata(us); } /* Function: al_ustr_to_buffer */ void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size) { int need; if (size <= 0) return; /* add 1 for terminating 0 byte */ need = _al_blength(us) + 1; if (size > need) size = need; _al_sane_strncpy(buffer, _al_bdata(us), size); } /* Function: al_cstr_dup */ char *al_cstr_dup(const ALLEGRO_USTR *us) { return _al_bstr2cstr(us, '\0'); } /* Function: al_ustr_dup */ ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us) { return _al_bstrcpy(us); } /* Function: al_ustr_dup_substr */ ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos, int end_pos) { return _al_bmidstr(us, start_pos, end_pos - start_pos); } /* Function: al_ustr_empty_string */ const ALLEGRO_USTR *al_ustr_empty_string(void) { static struct _al_tagbstring empty = _al_bsStatic(""); return ∅ } /* Function: al_ref_cstr */ const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s) { struct _al_tagbstring *tb = (struct _al_tagbstring *) info; ASSERT(info); ASSERT(s); _al_btfromcstr(*tb, s); return tb; } /* Function: al_ref_buffer */ const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size) { struct _al_tagbstring *tb = (struct _al_tagbstring *) info; ASSERT(s); _al_blk2tbstr(*tb, s, size); return tb; } /* Function: al_ref_ustr */ const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us, int start_pos, int end_pos) { struct _al_tagbstring *tb = (struct _al_tagbstring *) info; _al_bmid2tbstr(*tb, us, start_pos, end_pos - start_pos); return tb; } /* Function: al_ustr_size */ size_t al_ustr_size(const ALLEGRO_USTR *us) { return _al_blength(us); } /* Function: al_ustr_length */ size_t al_ustr_length(const ALLEGRO_USTR *us) { int pos = 0; int c = 0; while (al_ustr_next(us, &pos)) c++; return c; } /* Function: al_ustr_offset */ int al_ustr_offset(const ALLEGRO_USTR *us, int index) { int pos = 0; if (index < 0) index += al_ustr_length(us); while (index-- > 0) { if (!al_ustr_next(us, &pos)) return pos; } return pos; } /* Function: al_ustr_next */ bool al_ustr_next(const ALLEGRO_USTR *us, int *pos) { const unsigned char *data = (const unsigned char *) _al_bdata(us); int size = _al_blength(us); int c; if (*pos >= size) { return false; } while (++(*pos) < size) { c = data[*pos]; if (IS_SINGLE_BYTE(c) || IS_LEAD_BYTE(c)) break; } return true; } /* Function: al_ustr_prev */ bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos) { const unsigned char *data = (const unsigned char *) _al_bdata(us); int c; if (*pos <= 0) return false; while (*pos > 0) { (*pos)--; c = data[*pos]; if (IS_SINGLE_BYTE(c) || IS_LEAD_BYTE(c)) break; } return true; } /* Function: al_ustr_get */ int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos) { int32_t c; int remain; int32_t minc; const unsigned char *data; c = _al_bchare(ub, pos, -1); if (c < 0) { /* Out of bounds. */ al_set_errno(ERANGE); return -1; } if (c <= 0x7F) { /* Plain ASCII. */ return c; } if (c <= 0xC1) { /* Trailing byte of multi-byte sequence or an overlong encoding for * code point <= 127. */ al_set_errno(EILSEQ); return -2; } if (c <= 0xDF) { /* 2-byte sequence. */ c &= 0x1F; remain = 1; minc = 0x80; } else if (c <= 0xEF) { /* 3-byte sequence. */ c &= 0x0F; remain = 2; minc = 0x800; } else if (c <= 0xF4) { /* 4-byte sequence. */ c &= 0x07; remain = 3; minc = 0x10000; } else { /* Otherwise invalid. */ al_set_errno(EILSEQ); return -2; } if (pos + remain > _al_blength(ub)) { al_set_errno(EILSEQ); return -2; } data = (const unsigned char *) _al_bdata(ub); while (remain--) { int d = data[++pos]; if (!IS_TRAIL_BYTE(d)) { al_set_errno(EILSEQ); return -2; } c = (c << 6) | (d & 0x3F); } /* Check for overlong forms, which could be used to bypass security * validations. We could also check code points aren't above U+10FFFF or in * the surrogate ranges, but we don't. */ if (c < minc) { al_set_errno(EILSEQ); return -2; } return c; } /* Function: al_ustr_get_next */ int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos) { int32_t c = al_ustr_get(us, *pos); if (c >= 0) { (*pos) += al_utf8_width(c); return c; } if (c == -1) { /* Past end. */ return c; } /* Some invalid byte sequence. */ al_ustr_next(us, pos); return c; } /* Function: al_ustr_prev_get */ int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos) { if (al_ustr_prev(us, pos)) { return al_ustr_get(us, *pos); } /* Past beginning. */ return -1; } /* Function: al_ustr_insert */ bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2) { return _al_binsert(us1, pos, us2, '\0') == _AL_BSTR_OK; } /* Function: al_ustr_insert_cstr */ bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s) { ALLEGRO_USTR_INFO info; return al_ustr_insert(us, pos, al_ref_cstr(&info, s)); } /* Function: al_ustr_insert_chr */ size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c) { uint32_t uc = c; size_t sz; if (uc < 128) { return (_al_binsertch(us, pos, 1, uc) == _AL_BSTR_OK) ? 1 : 0; } sz = al_utf8_width(c); if (_al_binsertch(us, pos, sz, '\0') == _AL_BSTR_OK) { return al_utf8_encode(_al_bdataofs(us, pos), c); } return 0; } /* Function: al_ustr_append */ bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { return _al_bconcat(us1, us2) == _AL_BSTR_OK; } /* Function: al_ustr_append_cstr */ bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s) { return _al_bcatcstr(us, s) == _AL_BSTR_OK; } /* Function: al_ustr_append_chr */ size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c) { uint32_t uc = c; if (uc < 128) { return (_al_bconchar(us, uc) == _AL_BSTR_OK) ? 1 : 0; } return al_ustr_insert_chr(us, al_ustr_size(us), c); } /* Function: al_ustr_appendf */ bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...) { va_list ap; bool rc; va_start(ap, fmt); rc = al_ustr_vappendf(us, fmt, ap); va_end(ap); return rc; } /* Function: al_ustr_vappendf */ bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap) { va_list arglist; int sz; int rc; #ifdef DEBUGMODE /* Exercise resizing logic more often. */ sz = 1; #else sz = 128; #endif for (;;) { /* Make a copy of the argument list as vsnprintf() may clobber it. */ va_copy(arglist, ap); rc = _al_bvcformata(us, sz, fmt, arglist); va_end(arglist); if (rc >= 0) { return true; } if (rc == _AL_BSTR_ERR) { /* A real error? */ return false; } /* Increase size */ sz = -rc; } } /* Function: al_ustr_remove_chr */ bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos) { int32_t c; size_t w; c = al_ustr_get(us, pos); if (c < 0) return false; w = al_utf8_width(c); return _al_bdelete(us, pos, w) == _AL_BSTR_OK; } /* Function: al_ustr_remove_range */ bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos) { return _al_bdelete(us, start_pos, end_pos - start_pos) == _AL_BSTR_OK; } /* Function: al_ustr_truncate */ bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos) { return _al_btrunc(us, start_pos) == _AL_BSTR_OK; } /* Function: al_ustr_ltrim_ws */ bool al_ustr_ltrim_ws(ALLEGRO_USTR *us) { return _al_bltrimws(us) == _AL_BSTR_OK; } /* Function: al_ustr_rtrim_ws */ bool al_ustr_rtrim_ws(ALLEGRO_USTR *us) { return _al_brtrimws(us) == _AL_BSTR_OK; } /* Function: al_ustr_trim_ws */ bool al_ustr_trim_ws(ALLEGRO_USTR *us) { return _al_btrimws(us) == _AL_BSTR_OK; } /* Function: al_ustr_assign */ bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { return _al_bassign(us1, us2) == _AL_BSTR_OK; } /* Function: al_ustr_assign_substr */ bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int start_pos, int end_pos) { int rc = _al_bassignmidstr(us1, us2, start_pos, end_pos - start_pos); return rc == _AL_BSTR_OK; } /* Function: al_ustr_assign_cstr */ bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s) { return _al_bassigncstr(us1, s) == _AL_BSTR_OK; } /* Function: al_ustr_set_chr */ size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c) { int32_t oldc; size_t oldw; size_t neww; int rc; oldc = al_ustr_get(us, start_pos); if (oldc == -2) return 0; oldw = al_utf8_width(oldc); neww = al_utf8_width(c); if (neww == 0) return 0; if (oldw > neww) rc = _al_bdelete(us, start_pos, oldw - neww); else if (neww > oldw) rc = _al_binsertch(us, start_pos, neww - oldw, '\0'); else rc = _AL_BSTR_OK; if (rc == _AL_BSTR_OK) return al_utf8_encode(_al_bdataofs(us, start_pos), c); else return 0; } /* Function: al_ustr_replace_range */ bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1, const ALLEGRO_USTR *us2) { return _al_breplace(us1, start_pos1, end_pos1 - start_pos1, us2, '\0') == _AL_BSTR_OK; } /* Function: al_ustr_find_chr */ int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c) { char encc[4]; size_t sizec; struct _al_tagbstring enctb; int rc; /* Fast path for ASCII characters. */ if (c < 128) { rc = _al_bstrchrp(us, c, start_pos); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Non-ASCII. We can simply encode the character into a string and search * for that. */ sizec = al_utf8_encode(encc, c); if (!sizec) { al_set_errno(EINVAL); return -1; /* error */ } _al_blk2tbstr(enctb, encc, sizec); rc = _al_binstr(us, start_pos, &enctb); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Function: al_ustr_rfind_chr */ int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c) { char encc[4]; size_t sizec; struct _al_tagbstring enctb; int rc; /* Fast path for ASCII characters. */ if (c < 128) { rc = _al_bstrrchrp(us, c, end_pos - 1); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Non-ASCII. We can simply encode the character into a string and search * for that. */ sizec = al_utf8_encode(encc, c); if (!sizec) { al_set_errno(EINVAL); return -1; /* error */ } _al_blk2tbstr(enctb, encc, sizec); rc = _al_binstrr(us, end_pos - sizec, &enctb); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Function: al_ustr_find_set */ int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *accept) { int rc; int32_t c, d; int pos; int set_pos; /* Fast path for ASCII characters. */ if (all_ascii(accept)) { rc = _al_binchr(us, start_pos, accept); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Non-ASCII. */ pos = 0; while ((c = al_ustr_get(us, pos)) != -1) { if (c == -2) { /* Invalid byte sequence. */ pos++; continue; } set_pos = 0; while ((d = al_ustr_get_next(accept, &set_pos)) != -1) { if (c == d) return pos; } pos += al_utf8_width(c); } return -1; } /* Function: al_ustr_find_set_cstr */ int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos, const char *accept) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *accept_us = al_ref_cstr(&info, accept); return al_ustr_find_set(us, start_pos, accept_us); } /* Function: al_ustr_find_cset */ int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *reject) { int rc; int32_t c, d; int pos; int set_pos; /* Fast path for ASCII characters. */ if (all_ascii(reject)) { rc = _al_bninchr(us, start_pos, reject); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Non-ASCII. */ pos = 0; while ((c = al_ustr_get(us, pos)) != -1) { if (c == -2) { /* Invalid byte sequence. */ pos++; continue; } set_pos = 0; while ((d = al_ustr_get_next(reject, &set_pos)) != -1) { if (c == d) break; } if (d == -1) { return pos; } pos += al_utf8_width(c); } return -1; } /* Function: al_ustr_find_cset_cstr */ int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos, const char *reject) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *reject_us = al_ref_cstr(&info, reject); return al_ustr_find_cset(us, start_pos, reject_us); } /* Function: al_ustr_find_str */ int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos, const ALLEGRO_USTR *needle) { int rc = _al_binstr(haystack, start_pos, needle); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Function: al_ustr_find_cstr */ int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos, const char *needle) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *needle_us = al_ref_cstr(&info, needle); return al_ustr_find_str(haystack, start_pos, needle_us); } /* Function: al_ustr_rfind_str */ int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos, const ALLEGRO_USTR *needle) { int rc = _al_binstrr(haystack, end_pos - _al_blength(needle), needle); return (rc == _AL_BSTR_ERR) ? -1 : rc; } /* Function: al_ustr_rfind_cstr */ int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos, const char *needle) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *needle_us = al_ref_cstr(&info, needle); return al_ustr_rfind_str(haystack, end_pos, needle_us); } /* Function: al_ustr_find_replace */ bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace) { return _al_bfindreplace(us, find, replace, start_pos) == _AL_BSTR_OK; } /* Function: al_ustr_find_replace_cstr */ bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos, const char *find, const char *replace) { ALLEGRO_USTR_INFO find_info; ALLEGRO_USTR_INFO repl_info; const ALLEGRO_USTR *find_us = al_ref_cstr(&find_info, find); const ALLEGRO_USTR *repl_us = al_ref_cstr(&repl_info, replace); return al_ustr_find_replace(us, start_pos, find_us, repl_us); } /* Function: al_ustr_equal */ bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { return _al_biseq(us1, us2) == 1; } /* Function: al_ustr_compare */ int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { int pos1 = 0; int pos2 = 0; for (;;) { int32_t c1 = al_ustr_get_next(us1, &pos1); int32_t c2 = al_ustr_get_next(us2, &pos2); if (c1 != c2) { /* This happens to work even when one of c1 or c2 is -1. */ return c1 - c2; } if (c1 == -1) /* == c2 */ return 0; } } /* Function: al_ustr_ncompare */ int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n) { int pos1 = 0; int pos2 = 0; if (n <= 0) return 0; for (;;) { int32_t c1 = al_ustr_get_next(us1, &pos1); int32_t c2 = al_ustr_get_next(us2, &pos2); if (c1 != c2) { /* This happens to work even when one of c1 or c2 is -1. */ return c1 - c2; } if ((c1 == -1) || (--n <= 0)) return 0; } } /* Function: al_ustr_has_prefix */ bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { return 0 == _al_bstrncmp(us1, us2, _al_blength(us2)); } /* Function: al_ustr_has_prefix_cstr */ bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us2 = al_ref_cstr(&info, s2); return al_ustr_has_prefix(us1, us2); } /* Function: al_ustr_has_suffix */ bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) { struct _al_tagbstring tb1; int pos; pos = _al_blength(us1) - _al_blength(us2); _al_bmid2tbstr(tb1, us1, pos, INT_MAX); return _al_biseq(&tb1, us2); } /* Function: al_ustr_has_suffix_cstr */ bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us2 = al_ref_cstr(&info, s2); return al_ustr_has_suffix(us1, us2); } /* Function: al_utf8_width */ size_t al_utf8_width(int c) { /* So we don't need to check for negative values nor use unsigned ints * in the interface, which are a pain. */ uint32_t uc = c; if (uc <= 0x7f) return 1; if (uc <= 0x7ff) return 2; if (uc <= 0xffff) return 3; if (uc <= 0x10ffff) return 4; /* The rest are illegal. */ return 0; } /* Function: al_utf8_encode */ size_t al_utf8_encode(char s[], int32_t c) { uint32_t uc = c; if (uc <= 0x7f) { s[0] = uc; return 1; } if (uc <= 0x7ff) { s[0] = 0xC0 | ((uc >> 6) & 0x1F); s[1] = 0x80 | (uc & 0x3F); return 2; } if (uc <= 0xffff) { s[0] = 0xE0 | ((uc >> 12) & 0x0F); s[1] = 0x80 | ((uc >> 6) & 0x3F); s[2] = 0x80 | (uc & 0x3F); return 3; } if (uc <= 0x10ffff) { s[0] = 0xF0 | ((uc >> 18) & 0x07); s[1] = 0x80 | ((uc >> 12) & 0x3F); s[2] = 0x80 | ((uc >> 6) & 0x3F); s[3] = 0x80 | (uc & 0x3F); return 4; } /* Otherwise is illegal. */ return 0; } /* Function: al_utf16_width */ size_t al_utf16_width(int c) { /* So we don't need to check for negative values nor use unsigned ints * in the interface, which are a pain. */ uint32_t uc = c; /* We do not check for invalid code points. */ if (uc <= 0xffff) return 2; if (uc <= 0x10ffff) return 4; /* The rest are illegal. */ return 0; } /* Function: al_utf16_encode */ size_t al_utf16_encode(uint16_t s[], int32_t c) { uint32_t uc = c; if (uc <= 0xffff) { /* Note: We always assume the native endianness here. */ s[0] = uc; return 2; } if (uc <= 0x10ffff) { uint32_t u_ = uc - 0x10000; /* Note: We always assume the native endianness here. */ s[0] = 0xd800 | (u_ >> 10); s[1] = 0xdc00 | (u_ & 0x3ff); return 4; } /* Otherwise is illegal. */ return 0; } static size_t _al_utf16_get(uint16_t const *s, int n, int *c) { if (s[0] < 0xd800 || s[0] > 0xdfff) { *c = s[0]; return 1; } if (n < 2) return 0; *c = 0x10000 | ((s[0] & 0x3ff) << 10) | (s[1] & 0x3ff); return 2; } /* Function: al_ustr_new_from_utf16 */ ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s) { unsigned int i = 0; ALLEGRO_USTR *ustr = al_ustr_new(""); while (1) { int c; /* We expect the passed string to be 0 terminated, so there are * always 2 words available. */ size_t n = _al_utf16_get(s + i, 2, &c); /* Note: The string already is 0 terminated. */ if (c == 0) break; al_ustr_append_chr(ustr, c); i += n; } return ustr; } /* Function: al_ustr_size_utf16 */ size_t al_ustr_size_utf16(const ALLEGRO_USTR *us) { int pos = 0; size_t sz = 0; while (1) { int32_t c = al_ustr_get_next(us, &pos); if (c < 0) break; sz += al_utf16_width(c); } /* Size of terminating 0 character - al_ustr_get_next will not * return it. */ sz += 2; return sz; } /* Function: al_ustr_encode_utf16 */ size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s, size_t n) { int pos = 0; size_t i = 0; while (1) { /* Used to hold one encoded UTF-16 character. */ uint16_t encoded[2] = {0, 0}; size_t sz; int32_t c = al_ustr_get_next(us, &pos); if (c < 0) break; sz = al_utf16_encode(encoded, c); /* Need two bytes for terminating 0. */ if (i * 2 + sz > n - 2) break; s[i++] = encoded[0]; if (sz == 4) s[i++] = encoded[1]; } /* Append terminating 0 - al_ustr_get_next withheld it. */ if (i * 2 + 1 < n) s[i++] = 0; return i * 2; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/unix/0000755000175000001440000000000012157230740014161 5ustar tjadenusersallegro-5.0.10/src/unix/ugfxdrv.c0000644000175000001440000000000011053052251015771 0ustar tjadenusersallegro-5.0.10/src/unix/upath.c0000644000175000001440000003443512101051734015450 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * List of system pathes for the Unix library. * * By Michael Bukin. * * See readme.txt for copyright information. */ #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintunix.h" #include "allegro5/fshook.h" #include "allegro5/path.h" #ifdef ALLEGRO_HAVE_SYS_UTSNAME_H #include #endif #ifdef ALLEGRO_HAVE_SV_PROCFS_H #include #include #include #endif ALLEGRO_DEBUG_CHANNEL("upath") #ifndef ALLEGRO_MACOSX /* _find_executable_file: * Helper function: searches path and current directory for executable. * Returns 1 on succes, 0 on failure. */ static ALLEGRO_PATH *_find_executable_file(const char *filename) { char *env; /* If filename has an explicit path, search current directory */ if (strchr(filename, '/')) { if (filename[0] == '/') { /* Full path; done */ return al_create_path(filename); } else { struct stat finfo; char *cwd; /* Prepend current directory */ cwd = al_get_current_directory(); if (cwd) { ALLEGRO_PATH *path = al_create_path_for_directory(cwd); al_free(cwd); al_set_path_filename(path, filename); if (stat(al_path_cstr(path, '/'), &finfo) == 0 && !S_ISDIR(finfo.st_mode)) { return path; } al_destroy_path(path); } } } /* If filename has no explicit path, but we do have $PATH, search * there */ else if ((env = getenv("PATH"))) { struct stat finfo; ALLEGRO_USTR *us = al_ustr_new(env); int start_pos = 0; while (start_pos >= 0) { int next_start_pos = al_ustr_find_chr(us, start_pos + 1, ':'); int end_pos = next_start_pos; if (next_start_pos < 0) end_pos = al_ustr_size(us); ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *sub = al_ref_ustr(&info, us, start_pos, end_pos); ALLEGRO_PATH *path = al_create_path_for_directory(al_cstr(sub)); al_set_path_filename(path, filename); if (stat(al_path_cstr(path, '/'), &finfo) == 0 && !S_ISDIR (finfo.st_mode)) { al_ustr_free(us); return path; } al_destroy_path(path); start_pos = next_start_pos; } al_ustr_free(us); } return NULL; } /* Return full path to the current executable, use proc fs if * available. */ static ALLEGRO_PATH *get_executable_name(void) { ALLEGRO_PATH *path; #ifdef ALLEGRO_HAVE_GETEXECNAME { const char *s = getexecname(); if (s) { if (s[0] == '/') { /* Absolute path */ return al_create_path(s); } else { /* Not an absolute path */ path = _find_executable_file(s); if (path) return path; } } } #endif /* We need the PID in order to query procfs */ pid_t pid = getpid(); /* Try a Linux-like procfs */ /* get symolic link to executable from proc fs */ char linkname[1024]; char filename[1024]; struct stat finfo; sprintf(linkname, "/proc/%d/exe", (int)pid); if (stat(linkname, &finfo) == 0) { int len = readlink(linkname, filename, sizeof(filename) - 1); if (len > -1) { filename[len] = '\0'; return al_create_path(filename); } } /* Use System V procfs calls if available */ #ifdef ALLEGRO_HAVE_SV_PROCFS_H struct prpsinfo psinfo; int fd; sprintf(linkname, "/proc/%d/exe", (int)pid); fd = open(linkname, O_RDONLY); if (fd != -1) { ioctl(fd, PIOCPSINFO, &psinfo); close(fd); /* Use argv[0] directly if we can */ #ifdef ALLEGRO_HAVE_PROCFS_ARGCV if (psinfo.pr_argv && psinfo.pr_argc) { path = _find_executable_file(psinfo.pr_argv[0]); if (path) return path; } else #endif { /* Emulate it */ /* We use the pr_psargs field to find argv[0] * This is better than using the pr_fname field because we need * the additional path information that may be present in argv[0] */ /* Skip other args */ char *s = strchr(psinfo.pr_psargs, ' '); if (s) s[0] = '\0'; path = _find_executable_file(psinfo.pr_psargs); if (path) return path; } /* Try the pr_fname just for completeness' sake if argv[0] fails */ path = _find_executable_file(psinfo.pr_fname); if (path) return path; } #endif /* Last resort: try using the output of the ps command to at least find */ /* the name of the file if not the full path */ char command[1024]; sprintf(command, "ps -p %d", (int)pid); FILE *pipe = popen(command, "r"); if (pipe) { char* ret; /* The first line of output is a header */ ret = fgets(linkname, sizeof(linkname), pipe); if (!ret) ALLEGRO_ERROR("Failed to read the name of the executable file.\n"); /* The information we want is in the last column; find it */ int len = strlen(linkname); while (linkname[len] != ' ' && linkname[len] != '\t') len--; /* The second line contains the info we want */ ret = fgets(linkname, sizeof(linkname), pipe); if (!ret) ALLEGRO_ERROR("Failed to read the name of the executable file.\n"); pclose(pipe); /* Treat special cases: filename between [] and - for login shell */ if (linkname[len] == '-') len++; if (linkname[len] == '[' && linkname[strlen(linkname)] == ']') { len++; linkname[strlen(linkname)] = '\0'; } /* Now, the filename should be in the last column */ _al_sane_strncpy(filename, linkname+len+1, strlen(linkname)-len+1); path = _find_executable_file(filename); if (path) return path; /* Just return the output from ps... */ return al_create_path(filename); } /* Give up; return empty string */ return al_create_path(""); } static ALLEGRO_PATH *follow_symlinks(ALLEGRO_PATH *path) { for (;;) { const char *path_str = al_path_cstr(path, '/'); char buf[PATH_MAX]; int len; len = readlink(path_str, buf, sizeof(buf) - 1); if (len <= 0) break; buf[len] = '\0'; al_destroy_path(path); path = al_create_path(buf); } /* Make absolute path. */ { const char *cwd = al_get_current_directory(); ALLEGRO_PATH *cwd_path = al_create_path_for_directory(cwd); if (al_rebase_path(cwd_path, path)) al_make_path_canonical(path); al_destroy_path(cwd_path); al_free((void *) cwd); } return path; } #endif #define XDG_MAX_PATH_LEN 1000 /* get_xdg_path - locate an XDG user dir */ static ALLEGRO_PATH *_get_xdg_path(const char *location) { ALLEGRO_PATH *location_path = NULL; ALLEGRO_PATH *xdg_config_path = NULL; ALLEGRO_FILE *xdg_config_file = NULL; const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); int fd; if (xdg_config_home) { /* use $XDG_CONFIG_HOME since it exists */ xdg_config_path = al_create_path_for_directory(xdg_config_home); } else { /* the default XDG location is ~/.config */ xdg_config_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH); if (!xdg_config_path) return NULL; al_append_path_component(xdg_config_path, ".config"); } al_set_path_filename(xdg_config_path, "user-dirs.dirs"); fd = open(al_path_cstr(xdg_config_path, '/'), O_RDONLY); if (fd != -1) { xdg_config_file = al_fopen_fd(fd, "r"); } al_destroy_path(xdg_config_path); if (!xdg_config_file) return NULL; while (!al_feof(xdg_config_file)) { char line[XDG_MAX_PATH_LEN]; /* one line of the config file */ const char *p = line; /* where we're at in the line */ char component[XDG_MAX_PATH_LEN]; /* the path component being parsed */ int i = 0; /* how long the current component is */ al_fgets(xdg_config_file, line, XDG_MAX_PATH_LEN); /* skip leading white space */ while (*p == ' ' || *p == '\t') p++; /* skip the line if it does not begin with XDG_location_DIR */ if (strncmp(p, "XDG_", 4)) continue; p += 4; if (strncmp(p, location, strlen(location))) continue; p += strlen(location); if (strncmp(p, "_DIR", 4)) continue; p += 4; /* skip past the =", allowing for white space */ while (*p == ' ' || *p == '\t') p++; if (*p++ != '=') continue; while (*p == ' ' || *p == '\t') p++; if (*p++ != '"') continue; /* We've found the right line. Now parse it, basically assuming that it is in a sane format. */ if (!strncmp(p, "$HOME", 5)) { /* $HOME is the only environment variable that the path is allowed to use, and it must be first, by specification. */ location_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH); p += 5; } else { location_path = al_create_path("/"); } while (*p) { if (*p == '"' || *p == '/') { /* add the component (if non-empty) to the path */ if (i > 0) { component[i] = 0; al_append_path_component(location_path, component); i = 0; } if (*p == '"') break; } else { if (*p == '\\') { /* treat any escaped character as a literal */ p++; if (!*p) break; } component[i++] = *p; } p++; } /* Finished parsing the path. */ break; } al_fclose(xdg_config_file); return location_path; } static ALLEGRO_PATH *_unix_find_home(void) { char *home_env = getenv("HOME"); if (!home_env || home_env[0] == '\0') { /* since HOME isn't set, we have to ask libc for the info */ /* get user id */ uid_t uid = getuid(); /* grab user information */ struct passwd *pass = getpwuid(uid); if (!pass) { al_set_errno(errno); return NULL; } if (pass->pw_dir) { /* hey, we got our home directory */ return al_create_path_for_directory(pass->pw_dir); } al_set_errno(ENOENT); return NULL; } else { return al_create_path_for_directory(home_env); } } ALLEGRO_PATH *_al_unix_get_path(int id) { switch (id) { case ALLEGRO_TEMP_PATH: { /* Check: TMP, TMPDIR, TEMP or TEMPDIR */ char *envs[] = { "TMP", "TMPDIR", "TEMP", "TEMPDIR", NULL}; uint32_t i = 0; for (; envs[i] != NULL; ++i) { char *tmp = getenv(envs[i]); if (tmp) { return al_create_path_for_directory(tmp); } } /* next try: /tmp /var/tmp /usr/tmp */ char *paths[] = { "/tmp/", "/var/tmp/", "/usr/tmp/", NULL }; for (i=0; paths[i] != NULL; ++i) { ALLEGRO_FS_ENTRY *fse = al_create_fs_entry(paths[i]); bool found = (al_get_fs_entry_mode(fse) & ALLEGRO_FILEMODE_ISDIR) != 0; al_destroy_fs_entry(fse); if (found) { return al_create_path_for_directory(paths[i]); } } /* Give up? */ return NULL; } break; case ALLEGRO_RESOURCES_PATH: { ALLEGRO_PATH *exe = get_executable_name(); exe = follow_symlinks(exe); al_set_path_filename(exe, NULL); return exe; } break; case ALLEGRO_USER_DATA_PATH: case ALLEGRO_USER_SETTINGS_PATH: { ALLEGRO_PATH *local_path = NULL; const char *org_name = al_get_org_name(); const char *app_name = al_get_app_name(); /* to avoid writing directly into the user's directory, require at least an app name */ if (!app_name) return NULL; /* find the appropriate path from the xdg environment variables, if possible */ if (id == ALLEGRO_USER_DATA_PATH) { const char *xdg_data_home = getenv("XDG_DATA_HOME"); local_path = al_create_path_for_directory(xdg_data_home ? xdg_data_home : ".local/share"); } else { const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); local_path = al_create_path_for_directory(xdg_config_home ? xdg_config_home : ".config"); } if (!local_path) return NULL; /* if the path is relative, prepend the user's home directory */ if (al_path_cstr(local_path, '/')[0] != '/') { ALLEGRO_PATH *home_path = _unix_find_home(); if (!home_path) return NULL; al_rebase_path(home_path, local_path); al_destroy_path(home_path); } /* only add org name if not blank */ if (org_name && org_name[0]) { al_append_path_component(local_path, al_get_org_name()); } al_append_path_component(local_path, al_get_app_name()); return local_path; } break; case ALLEGRO_USER_HOME_PATH: return _unix_find_home(); case ALLEGRO_USER_DOCUMENTS_PATH: { ALLEGRO_PATH *local_path = _get_xdg_path("DOCUMENTS"); return local_path ? local_path : _unix_find_home(); } break; case ALLEGRO_EXENAME_PATH: return get_executable_name(); break; default: return NULL; } return NULL; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/unix/ukeybd.c0000644000175000001440000000146212125426002015604 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Unix keyboard module. * * By Michael Bukin. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_driver.h" /* list the available drivers */ _AL_DRIVER_INFO _al_keyboard_driver_list[] = { { 0, NULL, 0 } }; allegro-5.0.10/src/unix/udrvlist.c0000644000175000001440000000232212132133074016173 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Dynamic driver lists shared by Unixy system drivers. * * By Peter Wang. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_system.h" #if defined ALLEGRO_WITH_XWINDOWS #include "allegro5/platform/aintxglx.h" #endif /* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { #ifdef ALLEGRO_WITH_XWINDOWS ALLEGRO_SYSTEM_INTERFACE **add; /* This is the only system driver right now */ add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_xglx_driver(); #endif } allegro-5.0.10/src/unix/ujoydrv.c0000644000175000001440000000202211771525577016043 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * List of Unix joystick drivers. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/platform/aintunix.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_joystick.h" _AL_BEGIN_JOYSTICK_DRIVER_LIST #ifdef ALLEGRO_GP2XWIZ _AL_JOYSTICK_DRIVER_GP2XWIZ #endif #if defined ALLEGRO_HAVE_LINUX_JOYSTICK_H && defined ALLEGRO_WITH_XWINDOWS { _ALLEGRO_JOYDRV_LINUX, &_al_joydrv_linux, true }, #endif _AL_END_JOYSTICK_DRIVER_LIST allegro-5.0.10/src/unix/uxthread.c0000644000175000001440000000632511426530105016153 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Internal cross-platform threading API for Unix. * * By Peter Wang. * * See readme.txt for copyright information. */ #define _XOPEN_SOURCE 500 /* for Unix98 recursive mutexes */ /* XXX: added configure test */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/platform/aintunix.h" /* threads */ static void *thread_proc_trampoline(void *data) { _AL_THREAD *thread = data; (*thread->proc)(thread, thread->arg); return NULL; } void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), void *arg) { ASSERT(thread); ASSERT(proc); { int status; pthread_mutex_init(&thread->mutex, NULL); thread->should_stop = false; thread->proc = proc; thread->arg = arg; status = pthread_create(&thread->thread, NULL, thread_proc_trampoline, thread); ASSERT(status == 0); if (status != 0) abort(); } } void _al_thread_set_should_stop(_AL_THREAD *thread) { ASSERT(thread); pthread_mutex_lock(&thread->mutex); { thread->should_stop = true; } pthread_mutex_unlock(&thread->mutex); } void _al_thread_join(_AL_THREAD *thread) { ASSERT(thread); _al_thread_set_should_stop(thread); pthread_join(thread->thread, NULL); pthread_mutex_destroy(&thread->mutex); } void _al_thread_detach(_AL_THREAD *thread) { ASSERT(thread); pthread_mutex_destroy(&thread->mutex); pthread_detach(thread->thread); } /* mutexes */ void _al_mutex_init(_AL_MUTEX *mutex) { ASSERT(mutex); pthread_mutex_init(&mutex->mutex, NULL); mutex->inited = true; } void _al_mutex_init_recursive(_AL_MUTEX *mutex) { pthread_mutexattr_t attr; ASSERT(mutex); pthread_mutexattr_init(&attr); if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EINVAL) { pthread_mutexattr_destroy(&attr); abort(); /* XXX */ } pthread_mutex_init(&mutex->mutex, &attr); mutex->inited = true; pthread_mutexattr_destroy(&attr); } void _al_mutex_destroy(_AL_MUTEX *mutex) { ASSERT(mutex); if (mutex->inited) { pthread_mutex_destroy(&mutex->mutex); mutex->inited = false; } } /* condition variables */ /* most of the condition variable implementation is actually inline */ int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mutex, const ALLEGRO_TIMEOUT *timeout) { ALLEGRO_TIMEOUT_UNIX *unix_timeout = (ALLEGRO_TIMEOUT_UNIX *) timeout; int retcode; retcode = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &unix_timeout->abstime); return (retcode == ETIMEDOUT) ? -1 : 0; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/src/unix/utime.c0000644000175000001440000000450611771523242015460 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Unix time module. * * By Peter Wang. * * See readme.txt for copyright information. */ #include #include #include "allegro5/altime.h" #include "allegro5/debug.h" #include "allegro5/platform/aintunix.h" #include "allegro5/platform/aintuthr.h" ALLEGRO_STATIC_ASSERT(utime, sizeof(ALLEGRO_TIMEOUT_UNIX) <= sizeof(ALLEGRO_TIMEOUT)); /* Marks the time Allegro was initialised, for al_get_time(). */ struct timeval _al_unix_initial_time; /* _al_unix_init_time: * Called by the system driver to mark the beginning of time. */ void _al_unix_init_time(void) { gettimeofday(&_al_unix_initial_time, NULL); } /* Function: al_get_time */ double al_get_time(void) { struct timeval now; double time; gettimeofday(&now, NULL); time = (double) (now.tv_sec - _al_unix_initial_time.tv_sec) + (double) (now.tv_usec - _al_unix_initial_time.tv_usec) * 1.0e-6; return time; } /* Function: al_rest */ void al_rest(double seconds) { struct timespec timeout; double fsecs = floor(seconds); timeout.tv_sec = (time_t) fsecs; timeout.tv_nsec = (suseconds_t) ((seconds - fsecs) * 1e9); nanosleep(&timeout, 0); } /* Function: al_init_timeout */ void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) { ALLEGRO_TIMEOUT_UNIX *ut = (ALLEGRO_TIMEOUT_UNIX *) timeout; struct timeval now; double integral; double frac; ASSERT(ut); gettimeofday(&now, NULL); if (seconds <= 0.0) { ut->abstime.tv_sec = now.tv_sec; ut->abstime.tv_nsec = now.tv_usec * 1000; } else { frac = modf(seconds, &integral); ut->abstime.tv_sec = now.tv_sec + integral; ut->abstime.tv_nsec = (now.tv_usec * 1000) + (frac * 1000000000L); ut->abstime.tv_sec += ut->abstime.tv_nsec / 1000000000L; ut->abstime.tv_nsec = ut->abstime.tv_nsec % 1000000000L; } } /* vim: set sts=3 sw=3 et */ allegro-5.0.10/src/unix/ufdwatch.c0000644000175000001440000001230711434162734016141 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Unix fd watcher thread. * * By Peter Wang. * * See readme.txt for copyright information. * * This module implements a background thread that waits for data * to arrive in file descriptors, at which point it dispatches to * functions which will process that data. */ #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/platform/aintunix.h" typedef struct WATCH_ITEM { int fd; void (*callback)(void *); void *cb_data; } WATCH_ITEM; static _AL_THREAD fd_watch_thread; static _AL_MUTEX fd_watch_mutex = _AL_MUTEX_UNINITED; static _AL_VECTOR fd_watch_list = _AL_VECTOR_INITIALIZER(WATCH_ITEM); /* fd_watch_thread_func: [fdwatch thread] * The thread loop function. */ static void fd_watch_thread_func(_AL_THREAD *self, void *unused) { (void)unused; while (!_al_get_thread_should_stop(self)) { fd_set rfds; int max_fd; /* set up max_fd and rfds */ _al_mutex_lock(&fd_watch_mutex); { WATCH_ITEM *wi; unsigned int i; FD_ZERO(&rfds); max_fd = -1; for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { wi = _al_vector_ref(&fd_watch_list, i); FD_SET(wi->fd, &rfds); if (wi->fd > max_fd) max_fd = wi->fd; } } _al_mutex_unlock(&fd_watch_mutex); /* wait for something to happen on one of the fds */ { struct timeval tv; int retval; tv.tv_sec = 0; tv.tv_usec = 250000; retval = select(max_fd+1, &rfds, NULL, NULL, &tv); if (retval < 1) continue; } /* one or more of the fds has activity */ _al_mutex_lock(&fd_watch_mutex); { WATCH_ITEM *wi; unsigned int i; for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { wi = _al_vector_ref(&fd_watch_list, i); if (FD_ISSET(wi->fd, &rfds)) { /* The callback is allowed to modify the watch list so the mutex * must be recursive. */ wi->callback(wi->cb_data); } } } _al_mutex_unlock(&fd_watch_mutex); } } /* _al_unix_start_watching_fd: [primary thread] * * Start watching for data on file descriptor `fd'. This is done in * a background thread, which is started if necessary. When there is * data waiting to be read on fd, `callback' is applied to `cb_data'. * The callback function should read as much data off fd as possible. * * Note: the callback is run from the background thread. You can * assume there is only one callback being called from the fdwatch * module at a time. */ void _al_unix_start_watching_fd(int fd, void (*callback)(void *), void *cb_data) { ASSERT(fd >= 0); ASSERT(callback); /* start the background thread if necessary */ if (_al_vector_size(&fd_watch_list) == 0) { /* We need a recursive mutex to allow callbacks to modify the fd watch * list. */ _al_mutex_init_recursive(&fd_watch_mutex); _al_thread_create(&fd_watch_thread, fd_watch_thread_func, NULL); } /* now add the watch item to the list */ _al_mutex_lock(&fd_watch_mutex); { WATCH_ITEM *wi = _al_vector_alloc_back(&fd_watch_list); wi->fd = fd; wi->callback = callback; wi->cb_data = cb_data; } _al_mutex_unlock(&fd_watch_mutex); } /* _al_unix_stop_watching_fd: [primary thread] * * Stop watching for data on `fd'. Once there are no more file * descriptors to watch, the background thread will be stopped. This * function is synchronised with the background thread, so you don't * have to do any locking before calling it. */ void _al_unix_stop_watching_fd(int fd) { bool list_empty = false; /* find the fd in the watch list and remove it */ _al_mutex_lock(&fd_watch_mutex); { WATCH_ITEM *wi; unsigned int i; for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { wi = _al_vector_ref(&fd_watch_list, i); if (wi->fd == fd) { _al_vector_delete_at(&fd_watch_list, i); list_empty = _al_vector_is_empty(&fd_watch_list); break; } } } _al_mutex_unlock(&fd_watch_mutex); /* if no more fd's are being watched, stop the background thread */ if (list_empty) { _al_thread_join(&fd_watch_thread); _al_mutex_destroy(&fd_watch_mutex); _al_vector_free(&fd_watch_list); } } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/src/unix/umouse.c0000644000175000001440000000141712125426002015636 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Unix mouse module. * * By Michael Bukin. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_driver.h" /* list the available drivers */ _AL_DRIVER_INFO _al_mouse_driver_list[] = { { 0, NULL, 0 } }; allegro-5.0.10/src/drawing.c0000644000175000001440000000315312142407204014772 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Simple drawing primitives. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_memdraw.h" /* Function: al_clear_to_color */ void al_clear_to_color(ALLEGRO_COLOR color) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); ASSERT(target); if (target->flags & ALLEGRO_MEMORY_BITMAP) { _al_clear_bitmap_by_locking(target, &color); } else { ALLEGRO_DISPLAY *display = target->display; ASSERT(display); ASSERT(display->vt); display->vt->clear(display, &color); } } /* Function: al_draw_pixel */ void al_draw_pixel(float x, float y, ALLEGRO_COLOR color) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); ASSERT(target); if (target->flags & ALLEGRO_MEMORY_BITMAP) { _al_draw_pixel_memory(target, x, y, &color); } else { ALLEGRO_DISPLAY *display = target->display; ASSERT(display); ASSERT(display->vt); display->vt->draw_pixel(display, x, y, &color); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/tls_pthread.inc0000644000175000001440000000264412066715441016215 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread local storage. * * See LICENSE.txt for copyright information. */ static pthread_key_t tls_key = 0; static thread_local_state _tls; static void tls_dtor(void *ptr) { al_free(ptr); } void _al_tls_init_once(void) { pthread_key_create(&tls_key, tls_dtor); } static thread_local_state *pthreads_thread_init(void) { /* Allocate and copy the 'template' object */ thread_local_state *ptr = (thread_local_state *)al_malloc(sizeof(thread_local_state)); memcpy(ptr, &_tls, sizeof(thread_local_state)); pthread_setspecific(tls_key, ptr); return ptr; } /* This function is short so it can hopefully be inlined. */ static thread_local_state *tls_get(void) { thread_local_state *ptr = (thread_local_state*)pthread_getspecific(tls_key); if (ptr == NULL) { /* Must create object. */ ptr = pthreads_thread_init(); initialize_tls_values(ptr); } return ptr; } /* vim: set ft=c sts=3 sw=3: */ allegro-5.0.10/src/libc.c0000644000175000001440000000442011431772337014262 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Emulation for libc routines that may be missing on some platforms. * * By Michael Bukin. * * Henrik Stokseth added _al_sane_realloc() and _al_sane_strncpy() functions. * * _al_srand() and _al_rand() functions based on code by Paul Pridham. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include #include static int _al_rand_seed = 0; /* _al_stricmp: * Case-insensitive comparison of 7-bit ASCII strings. */ int _al_stricmp(const char *s1, const char *s2) { int c1, c2; ASSERT(s1); ASSERT(s2); do { c1 = tolower(*(s1++)); c2 = tolower(*(s2++)); } while ((c1) && (c1 == c2)); return c1 - c2; } /* _al_sane_realloc: * al_realloc() substitution with guaranteed behaviour. */ void *_al_sane_realloc(void *ptr, size_t size) { void *tmp_ptr; tmp_ptr = NULL; if (ptr && size) { tmp_ptr = al_realloc(ptr, size); if (!tmp_ptr && ptr) al_free(ptr); } else if (!size) { tmp_ptr = NULL; if (ptr) al_free(ptr); } else if (!ptr) { tmp_ptr = al_malloc(size); } return tmp_ptr; } /* _al_sane_strncpy: * strncpy() substitution which properly null terminates a string. */ char *_al_sane_strncpy(char *dest, const char *src, size_t n) { if (n <= 0) return dest; dest[0] = '\0'; strncat(dest, src, n - 1); return dest; } /* _al_srand: * Seed initialization routine for rand() replacement. */ void _al_srand(int seed) { _al_rand_seed = seed; } /* _al_rand: * Simple rand() replacement with guaranteed randomness in the lower 16 bits. */ int _al_rand(void) { _al_rand_seed = (_al_rand_seed + 1) * 1103515245 + 12345; return ((_al_rand_seed >> 16) & _AL_RAND_MAX); } allegro-5.0.10/src/memory.c0000644000175000001440000000345511426530105014655 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory management routines. * * By Peter Wang. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" /* globals */ static ALLEGRO_MEMORY_INTERFACE *mem = NULL; /* Function: al_set_memory_interface */ void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface) { mem = memory_interface; } /* Function: al_malloc_with_context */ void *al_malloc_with_context(size_t n, int line, const char *file, const char *func) { if (mem) return mem->mi_malloc(n, line, file, func); else return malloc(n); } /* Function: al_free_with_context */ void al_free_with_context(void *ptr, int line, const char *file, const char *func) { if (mem) mem->mi_free(ptr, line, file, func); else free(ptr); } /* Function: al_realloc_with_context */ void *al_realloc_with_context(void *ptr, size_t n, int line, const char *file, const char *func) { if (mem) return mem->mi_realloc(ptr, n, line, file, func); else return realloc(ptr, n); } /* Function: al_calloc_with_context */ void *al_calloc_with_context(size_t count, size_t n, int line, const char *file, const char *func) { if (mem) return mem->mi_calloc(count, n, line, file, func); else return calloc(count, n); } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/display.c0000644000175000001440000002335312132126261015010 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New display driver. * * By Elias Pschernig. * * Modified by Trent Gamblin. * * See readme.txt for copyright information. */ /* Title: Display routines */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_bitmap.h" ALLEGRO_DEBUG_CHANNEL("display") /* Function: al_create_display */ ALLEGRO_DISPLAY *al_create_display(int w, int h) { ALLEGRO_SYSTEM *system; ALLEGRO_DISPLAY_INTERFACE *driver; ALLEGRO_DISPLAY *display; ALLEGRO_TRANSFORM identity; system = al_get_system_driver(); driver = system->vt->get_display_driver(); if (!driver) { ALLEGRO_ERROR("Failed to create display (no display driver)\n"); return NULL; } display = driver->create_display(w, h); if (!display) { ALLEGRO_ERROR("Failed to create display (NULL)\n"); return NULL; } ASSERT(display->vt); display->vertex_cache = 0; display->num_cache_vertices = 0; display->cache_enabled = false; display->vertex_cache_size = 0; display->cache_texture = 0; display->display_invalidated = 0; _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*)); if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) al_set_target_bitmap(al_get_backbuffer(display)); else { ALLEGRO_DEBUG("ALLEGRO_COMPATIBLE_DISPLAY not set\n"); _al_set_current_display_only(display); } al_identity_transform(&identity); al_use_transform(&identity); /* Clear the screen */ if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) { al_clear_to_color(al_map_rgb(0, 0, 0)); /* TODO: * on iphone, don't kill the initial splashscreen - in fact, it's also * annoying in linux to have an extra black frame as first frame and I * suppose we never really want it */ #if 0 al_flip_display(); #endif } al_set_window_title(display, al_get_app_name()); return display; } /* Function: al_destroy_display */ void al_destroy_display(ALLEGRO_DISPLAY *display) { if (display) { ALLEGRO_BITMAP *bmp; bmp = al_get_target_bitmap(); if (bmp && bmp->display == display) al_set_target_bitmap(NULL); /* This can happen if we have a current display, but the target bitmap * was a memory bitmap. */ if (display == al_get_current_display()) _al_set_current_display_only(NULL); ASSERT(display->vt); display->vt->destroy_display(display); } } /* Function: al_get_backbuffer */ ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display) { if (display) { ASSERT(display->vt); return display->vt->get_backbuffer(display); } return NULL; } /* Function: al_flip_display */ void al_flip_display(void) { ALLEGRO_DISPLAY *display = al_get_current_display(); if (display) { ASSERT(display->vt); display->vt->flip_display(display); } } /* Function: al_update_display_region */ void al_update_display_region(int x, int y, int width, int height) { ALLEGRO_DISPLAY *display = al_get_current_display(); if (display) { ASSERT(display->vt); display->vt->update_display_region(display, x, y, width, height); } } /* Function: al_acknowledge_resize */ bool al_acknowledge_resize(ALLEGRO_DISPLAY *display) { ASSERT(display); ASSERT(display->vt); if (!(display->flags & ALLEGRO_FULLSCREEN)) { if (display->vt->acknowledge_resize) { return display->vt->acknowledge_resize(display); } } return false; } /* Function: al_resize_display */ bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height) { ASSERT(display); ASSERT(display->vt); ALLEGRO_INFO("Requested display resize %dx%d\n", width, height); if (display->vt->resize_display) { return display->vt->resize_display(display, width, height); } return false; } /* Function: al_is_compatible_bitmap */ bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_DISPLAY *display = al_get_current_display(); ASSERT(bitmap); if (display) { ASSERT(display->vt); return display->vt->is_compatible_bitmap(display, bitmap); } return false; } /* Function: al_get_display_width */ int al_get_display_width(ALLEGRO_DISPLAY *display) { ASSERT(display); return display->w; } /* Function: al_get_display_height */ int al_get_display_height(ALLEGRO_DISPLAY *display) { ASSERT(display); return display->h; } /* Function: al_get_display_format */ int al_get_display_format(ALLEGRO_DISPLAY *display) { ASSERT(display); return display->backbuffer_format; } /* Function: al_get_display_refresh_rate */ int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display) { ASSERT(display); return display->refresh_rate; } /* Function: al_get_display_flags */ int al_get_display_flags(ALLEGRO_DISPLAY *display) { ASSERT(display); return display->flags; } /* Function: al_wait_for_vsync */ bool al_wait_for_vsync(void) { ALLEGRO_DISPLAY *display = al_get_current_display(); ASSERT(display); if (display->vt->wait_for_vsync) return display->vt->wait_for_vsync(display); else return false; } /* Function: al_set_display_icon */ void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon) { ALLEGRO_BITMAP *icons[1] = { icon }; al_set_display_icons(display, 1, icons); } /* Function: al_set_display_icons */ void al_set_display_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *icons[]) { int i; ASSERT(display); ASSERT(num_icons >= 1); ASSERT(icons); for (i = 0; i < num_icons; i++) { ASSERT(icons[i]); } if (display->vt->set_icons) { display->vt->set_icons(display, num_icons, icons); } } /* Destroys all bitmaps created for this display. */ void _al_destroy_display_bitmaps(ALLEGRO_DISPLAY *d) { while (_al_vector_size(&d->bitmaps) > 0) { ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); ALLEGRO_BITMAP *b = *bptr; al_destroy_bitmap(b); } } /* Function: al_set_window_position */ void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { ASSERT(display); if (display && display->flags & ALLEGRO_FULLSCREEN) { return; } if (display && display->vt && display->vt->set_window_position) { display->vt->set_window_position(display, x, y); } } /* Function: al_get_window_position */ void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) { ASSERT(x); ASSERT(y); if (display && display->vt && display->vt->get_window_position) { display->vt->get_window_position(display, x, y); } else { *x = *y = -1; } } /* Function: al_set_display_flag */ bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) { ASSERT(display); if (display && display->vt && display->vt->set_display_flag) { return display->vt->set_display_flag(display, flag, onoff); } return false; } /* Function: al_toggle_display_flag * This is deprecated. * On the 5.0 branch this needs to be a function for backwards compatibility. */ bool al_toggle_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) { return al_set_display_flag(display, flag, onoff); } /* Function: al_set_window_title */ void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title) { if (display && display->vt && display->vt->set_window_title) display->vt->set_window_title(display, title); } /* Function: al_get_display_event_source */ ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display) { return &display->es; } /* Function: al_hold_bitmap_drawing */ void al_hold_bitmap_drawing(bool hold) { ALLEGRO_DISPLAY *current_display = al_get_current_display(); if (current_display) { if (hold && !current_display->cache_enabled) { /* * Set the hardware transformation to identity, but keep the bitmap * transform the same as it was. Relies on the fact that when bitmap * holding is turned on, al_use_transform does not update the hardware * transformation. */ ALLEGRO_TRANSFORM old, ident; al_copy_transform(&old, al_get_current_transform()); al_identity_transform(&ident); al_use_transform(&ident); current_display->cache_enabled = hold; al_use_transform(&old); } else { current_display->cache_enabled = hold; } if (!hold) { current_display->vt->flush_vertex_cache(current_display); /* * Reset the hardware transform to match the stored transform. */ al_use_transform(al_get_current_transform()); } } } /* Function: al_is_bitmap_drawing_held */ bool al_is_bitmap_drawing_held(void) { ALLEGRO_DISPLAY *current_display = al_get_current_display(); if (current_display) return current_display->cache_enabled; else return false; } void _al_set_display_invalidated_callback(ALLEGRO_DISPLAY* display, void (*display_invalidated)(ALLEGRO_DISPLAY*)) { display->display_invalidated = display_invalidated; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/fshook_stdio.c0000644000175000001440000004235312067154200016040 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File System Hook, POSIX "driver" (not stdio). * * By Thomas Fjellstrom. * * Modified by Peter Wang. * * See readme.txt for copyright information. */ /* Eventually we will make Allegro use the Unicode (UTF-16) Windows API * globally but not yet. */ #define UNICODE #define _UNICODE #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_wunicode.h" ALLEGRO_DEBUG_CHANNEL("fshook") /* Enable large file support in gcc/glibc. */ #if defined ALLEGRO_HAVE_FTELLO && defined ALLEGRO_HAVE_FSEEKO #define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE64 #define _FILE_OFFSET_BITS 64 #endif #include #include #ifdef _MSC_VER #define _POSIX_ #include #undef _POSIX_ #include #endif #include "allegro5/internal/aintern_file.h" #include "allegro5/internal/aintern_fshook.h" #ifdef ALLEGRO_HAVE_SYS_STAT_H #include #endif #ifdef ALLEGRO_HAVE_DIRENT_H #include #include #define NAMLEN(dirent) (strlen((dirent)->d_name)) #else #define dirent direct #define NAMLEN(dirent) ((dirent)->d_namlen) #ifdef ALLEGRO_HAVE_SYS_NDIR_H #include #endif #ifdef ALLEGRO_HAVE_SYS_DIR_H #include #endif #ifdef ALLEGRO_HAVE_NDIR_H #include #endif #endif #ifndef S_IRGRP #define S_IRGRP (0) #endif #ifndef S_IWGRP #define S_IWGRP (0) #endif #ifndef S_IXGRP #define S_IXGRP (0) #endif #ifdef ALLEGRO_HAVE_SYS_TIME #include #endif #ifdef ALLEGRO_HAVE_TIME_H #include #endif #ifdef ALLEGRO_WINDOWS #include #include "fshook_win.inc" typedef wchar_t WRAP_CHAR; typedef struct _stat WRAP_STAT_TYPE; typedef _WDIR WRAP_DIR_TYPE; typedef struct _wdirent WRAP_DIRENT_TYPE; #define WRAP_LIT(s) _TEXT(s) #define WRAP_STRLEN(s) (wcslen(s)) #define WRAP_STRCMP(s1, s2) (wcscmp((s1), (s2))) #define WRAP_STAT(p, b) (_wstat((p), (b))) #define WRAP_MKDIR(p) (_wmkdir(p)) #define WRAP_RMDIR(p) (_wrmdir(p)) #define WRAP_UNLINK(p) (_wunlink(p)) #define WRAP_OPENDIR(p) (_wopendir(p)) #define WRAP_CLOSEDIR(d) (_wclosedir(d)) #define WRAP_READDIR(d) (_wreaddir(d)) #else typedef char WRAP_CHAR; typedef struct stat WRAP_STAT_TYPE; typedef DIR WRAP_DIR_TYPE; typedef struct dirent WRAP_DIRENT_TYPE; #define WRAP_LIT(s) (s) #define WRAP_STRLEN(s) (strlen(s)) #define WRAP_STRCMP(s1, s2) (strcmp((s1), (s2))) #define WRAP_STAT(p, b) (stat((p), (b))) #define WRAP_STAT_UNSLASH(p, b) (stat((p), (b))) #define WRAP_MKDIR(p) (mkdir(p, 0755)) #define WRAP_RMDIR(p) (rmdir(p)) #define WRAP_UNLINK(p) (unlink(p)) #define WRAP_OPENDIR(p) (opendir(p)) #define WRAP_CLOSEDIR(d) (closedir(d)) #define WRAP_READDIR(d) (readdir(d)) #endif typedef struct ALLEGRO_FS_ENTRY_STDIO ALLEGRO_FS_ENTRY_STDIO; struct ALLEGRO_FS_ENTRY_STDIO { ALLEGRO_FS_ENTRY fs_entry; /* must be first */ WRAP_CHAR *abs_path; #ifdef ALLEGRO_WINDOWS char *abs_path_utf8; #define ABS_PATH_UTF8 abs_path_utf8 #else #define ABS_PATH_UTF8 abs_path #endif uint32_t stat_mode; WRAP_STAT_TYPE st; WRAP_DIR_TYPE *dir; }; static void fs_update_stat_mode(ALLEGRO_FS_ENTRY_STDIO *fp_stdio); static bool fs_stdio_update_entry(ALLEGRO_FS_ENTRY *fp); /* Make an absolute path given a potentially relative path. * The result must be freed with free(), NOT al_free(). */ static WRAP_CHAR *make_absolute_path_inner(const WRAP_CHAR *tail) { #ifdef ALLEGRO_WINDOWS /* We use _wfullpath to get the proper drive letter semantics on Windows. */ wchar_t *abs_path = _wfullpath(NULL, tail, 0); /* Remove trailing backslash (_wstat fails otherwise), but NOT directly * following the drive letter. */ if (abs_path) { const size_t abs_len = WRAP_STRLEN(abs_path); if (abs_len == 3 && abs_path[1] == ':' && abs_path[2] == '\\') { /* Do not strip "C:\" */ } else if (abs_len > 1 && abs_path[abs_len - 1] == '\\') { abs_path[abs_len - 1] = '\0'; } } return abs_path; #else char cwd[PATH_MAX]; ALLEGRO_PATH *cwdpath = NULL; ALLEGRO_PATH *tailpath = NULL; char *ret = NULL; if (!getcwd(cwd, sizeof(cwd))) { ALLEGRO_WARN("Unable to get current working directory.\n"); al_set_errno(errno); goto Error; } cwdpath = al_create_path_for_directory(cwd); if (!cwdpath) { goto Error; } tailpath = al_create_path(tail); if (!tailpath) { goto Error; } if (al_rebase_path(cwdpath, tailpath)) { al_make_path_canonical(tailpath); } ret = strdup(al_path_cstr(tailpath, ALLEGRO_NATIVE_PATH_SEP)); Error: al_destroy_path(cwdpath); al_destroy_path(tailpath); return ret; #endif } static WRAP_CHAR *make_absolute_path(const char *tail) { WRAP_CHAR *abs_path = NULL; #ifdef ALLEGRO_WINDOWS wchar_t *wtail = _al_win_utf16(tail); if (wtail) { abs_path = make_absolute_path_inner(wtail); al_free(wtail); } #else abs_path = make_absolute_path_inner(tail); #endif return abs_path; } static ALLEGRO_FS_ENTRY *create_abs_path_entry(const WRAP_CHAR *abs_path) { ALLEGRO_FS_ENTRY_STDIO *fh; size_t len; fh = al_calloc(1, sizeof(*fh)); if (!fh) { al_set_errno(errno); return NULL; } fh->fs_entry.vtable = &_al_fs_interface_stdio; len = WRAP_STRLEN(abs_path) + 1; /* including terminator */ fh->abs_path = al_malloc(len * sizeof(WRAP_CHAR)); if (!fh->abs_path) { al_free(fh); return NULL; } memcpy(fh->abs_path, abs_path, len * sizeof(WRAP_CHAR)); #ifdef ALLEGRO_WINDOWS fh->abs_path_utf8 = _al_win_utf8(fh->abs_path); if (!fh->abs_path_utf8) { al_free(fh->abs_path); al_free(fh); return NULL; } #endif ALLEGRO_DEBUG("Creating entry for %s\n", fh->ABS_PATH_UTF8); fs_stdio_update_entry((ALLEGRO_FS_ENTRY *) fh); return (ALLEGRO_FS_ENTRY *) fh; } static ALLEGRO_FS_ENTRY *fs_stdio_create_entry(const char *orig_path) { ALLEGRO_FS_ENTRY *ret = NULL; WRAP_CHAR *abs_path; abs_path = make_absolute_path(orig_path); if (abs_path) { ret = create_abs_path_entry(abs_path); free(abs_path); } return ret; } #if defined(ALLEGRO_UNIX) || defined(ALLEGRO_MACOSX) static bool unix_hidden_file(const char *path) { /* Filenames beginning with dot are considered hidden. */ const char *p = strrchr(path, ALLEGRO_NATIVE_PATH_SEP); if (p) p++; else p = path; return (p[0] == '.'); } #endif static void fs_update_stat_mode(ALLEGRO_FS_ENTRY_STDIO *fp_stdio) { fp_stdio->stat_mode = 0; if (S_ISDIR(fp_stdio->st.st_mode)) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_ISDIR; else /* marks special unix files as files... might want to add enum items for symlink, CHAR, BLOCK and SOCKET files. */ fp_stdio->stat_mode |= ALLEGRO_FILEMODE_ISFILE; /* if (S_ISREG(fh->st.st_mode)) fh->stat_mode |= ALLEGRO_FILEMODE_ISFILE; */ if (fp_stdio->st.st_mode & (S_IRUSR | S_IRGRP)) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_READ; if (fp_stdio->st.st_mode & (S_IWUSR | S_IWGRP)) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_WRITE; if (fp_stdio->st.st_mode & (S_IXUSR | S_IXGRP)) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_EXECUTE; #if defined(ALLEGRO_WINDOWS) { DWORD attrib = GetFileAttributes(fp_stdio->abs_path); if (attrib & FILE_ATTRIBUTE_HIDDEN) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; } #endif #if defined(ALLEGRO_MACOSX) && defined(UF_HIDDEN) { /* OSX hidden files can both start with the dot as well as having this flag set... * Note that this flag does not exist on all versions of OS X (Tiger * doesn't seem to have it) so we need to test for it. */ if (fp_stdio->st.st_flags & UF_HIDDEN) fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; } #endif #if defined(ALLEGRO_UNIX) || defined(ALLEGRO_MACOSX) if (0 == (fp_stdio->stat_mode & ALLEGRO_FILEMODE_HIDDEN)) { if (unix_hidden_file(fp_stdio->abs_path)) { fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; } } #endif } static bool fs_stdio_update_entry(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; int ret; ret = WRAP_STAT(fp_stdio->abs_path, &(fp_stdio->st)); if (ret == -1) { al_set_errno(errno); return false; } fs_update_stat_mode(fp_stdio); return true; } static bool fs_stdio_open_directory(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; if (!(fp_stdio->stat_mode & ALLEGRO_FILEMODE_ISDIR)) return false; fp_stdio->dir = WRAP_OPENDIR(fp_stdio->abs_path); if (!fp_stdio->dir) { al_set_errno(errno); return false; } return true; } static bool fs_stdio_close_directory(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; int rc; if (!fp_stdio->dir) { al_set_errno(ENOTDIR); return false; } rc = WRAP_CLOSEDIR(fp_stdio->dir); fp_stdio->dir = NULL; if (rc == -1) { al_set_errno(errno); return false; } return true; } static ALLEGRO_FS_ENTRY *fs_stdio_read_directory(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; // FIXME: Must use readdir_r as Allegro allows file functions being // called from different threads. WRAP_DIRENT_TYPE *ent; ALLEGRO_FS_ENTRY *ret; ASSERT(fp_stdio->dir); do { ent = WRAP_READDIR(fp_stdio->dir); if (!ent) { al_set_errno(errno); return NULL; } /* Don't bother the user with these entries. */ } while (0 == WRAP_STRCMP(ent->d_name, WRAP_LIT(".")) || 0 == WRAP_STRCMP(ent->d_name, WRAP_LIT(".."))); #ifdef ALLEGRO_WINDOWS { wchar_t buf[MAX_PATH]; int buflen; buflen = _snwprintf(buf, MAX_PATH, L"%s\\%s", fp_stdio->abs_path, ent->d_name); if (buflen >= MAX_PATH) { al_set_errno(ERANGE); return NULL; } ret = create_abs_path_entry(buf); } #else { int abs_path_len = strlen(fp_stdio->abs_path); int ent_name_len = strlen(ent->d_name); char *buf = al_malloc(abs_path_len + 1 + ent_name_len + 1); if (!buf) { al_set_errno(ENOMEM); return NULL; } memcpy(buf, fp_stdio->abs_path, abs_path_len); buf[abs_path_len] = ALLEGRO_NATIVE_PATH_SEP; memcpy(buf + abs_path_len + 1, ent->d_name, ent_name_len); buf[abs_path_len + 1 + ent_name_len] = '\0'; ret = create_abs_path_entry(buf); al_free(buf); } #endif return ret; } static void fs_stdio_destroy_entry(ALLEGRO_FS_ENTRY *fh_) { ALLEGRO_FS_ENTRY_STDIO *fh = (ALLEGRO_FS_ENTRY_STDIO *) fh_; al_free(fh->abs_path); #ifdef ALLEGRO_WINDOWS al_free(fh->abs_path_utf8); #endif if (fh->dir) fs_stdio_close_directory(fh_); al_free(fh); } static off_t fs_stdio_entry_size(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; ASSERT(ent); return ent->st.st_size; } static uint32_t fs_stdio_entry_mode(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; ASSERT(ent); return ent->stat_mode; } static time_t fs_stdio_entry_atime(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; ASSERT(ent); return ent->st.st_atime; } static time_t fs_stdio_entry_mtime(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; ASSERT(ent); return ent->st.st_mtime; } static time_t fs_stdio_entry_ctime(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; ASSERT(ent); return ent->st.st_ctime; } static char *fs_stdio_get_current_directory(void) { #ifdef ALLEGRO_WINDOWS wchar_t *wcwd; char *cwd; wcwd = _wgetcwd(NULL, 1); if (!wcwd) { al_set_errno(errno); return NULL; } cwd = _al_win_utf8(wcwd); free(wcwd); return cwd; #else char tmpdir[PATH_MAX]; char *cwd; if (!getcwd(tmpdir, PATH_MAX)) { al_set_errno(errno); return NULL; } cwd = al_malloc(strlen(tmpdir) + 1); if (!cwd) { al_set_errno(ENOMEM); return NULL; } return strcpy(cwd, tmpdir); #endif } static bool fs_stdio_change_directory(const char *path) { int ret = -1; #ifdef ALLEGRO_WINDOWS wchar_t *wpath = _al_win_utf16(path); if (wpath) { ret = _wchdir(wpath); al_free(wpath); } #else ret = chdir(path); #endif if (ret == -1) { al_set_errno(errno); return false; } return true; } static bool mkdir_exists(const WRAP_CHAR *path) { WRAP_STAT_TYPE st; if (WRAP_STAT(path, &st) == 0) { return S_ISDIR(st.st_mode); } return WRAP_MKDIR(path) == 0; } static bool do_make_directory(WRAP_CHAR *abs_path) { const WRAP_CHAR * const end = abs_path + WRAP_STRLEN(abs_path); WRAP_CHAR *p; bool ret; p = abs_path + 1; #ifdef ALLEGRO_WINDOWS /* Skip drive letter. */ if (end - abs_path >= 3 && abs_path[1] == ':' && (abs_path[2] == '\\' || abs_path[2] == '/')) { p = abs_path + 3; } #endif for ( ; p < end; p++) { const WRAP_CHAR c = *p; if (c == ALLEGRO_NATIVE_PATH_SEP || c == '/') { *p = '\0'; ret = mkdir_exists(abs_path); *p = c; if (!ret) return false; } } return mkdir_exists(abs_path); } static bool fs_stdio_make_directory(const char *tail) { bool ret = false; WRAP_CHAR *abs_path = make_absolute_path(tail); if (abs_path) { ret = do_make_directory(abs_path); free(abs_path); } return ret; } static bool fs_stdio_entry_exists(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; WRAP_STAT_TYPE st; if (WRAP_STAT(fp_stdio->abs_path, &st) != 0) { if (errno != ENOENT) { al_set_errno(errno); } return false; } return true; } static bool fs_stdio_filename_exists(const char *path) { WRAP_STAT_TYPE st; bool ret = false; ASSERT(path); #ifdef ALLEGRO_WINDOWS { /* Pass an path created by _wfullpath() to avoid issues * with stat() failing when there is a trailing slash. */ wchar_t *abs_path = make_absolute_path(path); if (abs_path) { ret = (0 == WRAP_STAT(abs_path, &st)); if (!ret && errno != ENOENT) { al_set_errno(errno); } free(abs_path); } } #else ret = (0 == WRAP_STAT(path, &st)); if (!ret && errno != ENOENT) { al_set_errno(errno); } #endif return ret; } static bool fs_stdio_remove_entry(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; int err; ASSERT(fp); if (fs_stdio_entry_mode(fp) & ALLEGRO_FILEMODE_ISDIR) { err = WRAP_RMDIR(fp_stdio->abs_path); } else if (fs_stdio_entry_mode(fp) & ALLEGRO_FILEMODE_ISFILE) { err = WRAP_UNLINK(fp_stdio->abs_path); } else { al_set_errno(ENOENT); return false; } if (err != 0) { al_set_errno(errno); return false; } return true; } static bool fs_stdio_remove_filename(const char *path) { ALLEGRO_FS_ENTRY *fp; bool rc; fp = fs_stdio_create_entry(path); if (!fp) return false; rc = fs_stdio_remove_entry(fp); fs_stdio_destroy_entry(fp); return rc; } static const char *fs_stdio_name(ALLEGRO_FS_ENTRY *fp) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; return fp_stdio->ABS_PATH_UTF8; } static ALLEGRO_FILE *fs_stdio_open_file(ALLEGRO_FS_ENTRY *fp, const char *mode) { ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; /* XXX on Windows it would be nicer to use the UTF-16 abs_path field * directly */ return al_fopen_interface(&_al_file_interface_stdio, fp_stdio->ABS_PATH_UTF8, mode); } struct ALLEGRO_FS_INTERFACE _al_fs_interface_stdio = { fs_stdio_create_entry, fs_stdio_destroy_entry, fs_stdio_name, fs_stdio_update_entry, fs_stdio_entry_mode, fs_stdio_entry_atime, fs_stdio_entry_mtime, fs_stdio_entry_ctime, fs_stdio_entry_size, fs_stdio_entry_exists, fs_stdio_remove_entry, fs_stdio_open_directory, fs_stdio_read_directory, fs_stdio_close_directory, fs_stdio_filename_exists, fs_stdio_remove_filename, fs_stdio_get_current_directory, fs_stdio_change_directory, fs_stdio_make_directory, fs_stdio_open_file }; /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/inline.c0000644000175000001440000000252311426530105014616 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Copies of the inline functions in allegro.h, in case anyone needs * to take the address of them, or is compiling without optimisation. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include "allegro5/platform/alplatf.h" // apple's cross-compiler already adds the symbols for the "extern __inline__" // declared variants, so the ones here are duplicates and the linker dies #ifndef ALLEGRO_IPHONE #define AL_INLINE(type, name, args, code) \ extern type name args; \ type name args code #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #ifdef ALLEGRO_INTERNAL_HEADER #include ALLEGRO_INTERNAL_HEADER #endif /* not used now */ /* #include "allegro5/internal/aintern_atomicops.h" */ #include "allegro5/internal/aintern_float.h" #include "allegro5/internal/aintern_vector.h" #endif allegro-5.0.10/src/bitmap_io.c0000644000175000001440000001307712125160224015307 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Bitmap I/O framework. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_vector.h" #include ALLEGRO_DEBUG_CHANNEL("bitmap") #define MAX_EXTENSION (32) typedef struct Handler { char extension[MAX_EXTENSION]; ALLEGRO_IIO_LOADER_FUNCTION loader; ALLEGRO_IIO_SAVER_FUNCTION saver; ALLEGRO_IIO_FS_LOADER_FUNCTION fs_loader; ALLEGRO_IIO_FS_SAVER_FUNCTION fs_saver; } Handler; /* globals */ static _AL_VECTOR iio_table = _AL_VECTOR_INITIALIZER(Handler); static Handler *find_handler(const char *extension) { unsigned i; for (i = 0; i < _al_vector_size(&iio_table); i++) { Handler *l = _al_vector_ref(&iio_table, i); if (0 == _al_stricmp(extension, l->extension)) { return l; } } return NULL; } static Handler *add_iio_table_f(const char *ext) { Handler *ent; ent = _al_vector_alloc_back(&iio_table); strcpy(ent->extension, ext); ent->loader = NULL; ent->saver = NULL; ent->fs_loader = NULL; ent->fs_saver = NULL; return ent; } static void free_iio_table(void) { _al_vector_free(&iio_table); } void _al_init_iio_table(void) { _al_add_exit_func(free_iio_table, "free_iio_table"); } /* Function: al_register_bitmap_loader */ bool al_register_bitmap_loader(const char *extension, ALLEGRO_BITMAP *(*loader)(const char *filename)) { Handler *ent; ASSERT(extension); if (strlen(extension) + 1 >= MAX_EXTENSION) { return false; } ent = find_handler(extension); if (!loader) { if (!ent || !ent->loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_iio_table_f(extension); } ent->loader = loader; return true; } /* Function: al_register_bitmap_saver */ bool al_register_bitmap_saver(const char *extension, bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp)) { Handler *ent; ASSERT(extension); ASSERT(saver); if (strlen(extension) + 1 >= MAX_EXTENSION) { return false; } ent = find_handler(extension); if (!saver) { if (!ent || !ent->saver) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_iio_table_f(extension); } ent->saver = saver; return true; } /* Function: al_register_bitmap_loader_f */ bool al_register_bitmap_loader_f(const char *extension, ALLEGRO_BITMAP *(*loader_f)(ALLEGRO_FILE *fp)) { Handler *ent; ASSERT(extension); if (strlen(extension) + 1 >= MAX_EXTENSION) { return false; } ent = find_handler(extension); if (!loader_f) { if (!ent || !ent->fs_loader) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_iio_table_f(extension); } ent->fs_loader = loader_f; return true; } /* Function: al_register_bitmap_saver_f */ bool al_register_bitmap_saver_f(const char *extension, bool (*saver_f)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp)) { Handler *ent; ASSERT(extension); ASSERT(saver_f); if (strlen(extension) + 1 >= MAX_EXTENSION) { return false; } ent = find_handler(extension); if (!saver_f) { if (!ent || !ent->fs_saver) { return false; /* Nothing to remove. */ } } else if (!ent) { ent = add_iio_table_f(extension); } ent->fs_saver = saver_f; return true; } /* Function: al_load_bitmap */ ALLEGRO_BITMAP *al_load_bitmap(const char *filename) { const char *ext; Handler *h; ALLEGRO_BITMAP *ret; ext = strrchr(filename, '.'); if (!ext) { ALLEGRO_WARN("Bitmap %s has no extension - " "not even trying to load it.\n", filename); return NULL; } h = find_handler(ext); if (h) { ret = h->loader(filename); if (!ret) ALLEGRO_WARN("Failed loading %s with %s handler.\n", filename, ext); } else { ALLEGRO_WARN("No handler for bitmap extensions %s - " "therefore not trying to load %s.\n", ext, filename); ret = NULL; } return ret; } /* Function: al_save_bitmap */ bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap) { const char *ext; Handler *h; ext = strrchr(filename, '.'); if (!ext) return false; h = find_handler(ext); if (h) return h->saver(filename, bitmap); else { ALLEGRO_WARN("No handler for image %s found\n", filename); return false; } } /* Function: al_load_bitmap_f */ ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident) { Handler *h = find_handler(ident); if (h) return h->fs_loader(fp); else return NULL; } /* Function: al_save_bitmap_f */ bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_BITMAP *bitmap) { Handler *h = find_handler(ident); if (h) return h->fs_saver(fp, bitmap); else { ALLEGRO_WARN("No handler for image %s found\n", ident); return false; } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/scanline_drawers.inc0000644000175000001440000023043312146021714017216 0ustar tjadenusers// Warning: This file was created by make_scanline_drawers.py - do not edit. #if __GNUC__ #define _AL_EXPECT_FAIL(expr) __builtin_expect((expr), 0) #else #define _AL_EXPECT_FAIL(expr) (expr) #endif static void shader_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) { state_solid_any_2d *s = (state_solid_any_2d *) state; ALLEGRO_COLOR cur_color = s->cur_color; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); { { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } } } } } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } } } } else { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } } } } } } } } static void shader_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) { state_solid_any_2d *s = (state_solid_any_2d *) state; ALLEGRO_COLOR cur_color = s->cur_color; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { { { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); } } } else { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); } } } } } } } static void shader_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) { state_grad_any_2d *gs = (state_grad_any_2d *) state; state_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { cur_color.r += gs->color_dx.r * -x1; cur_color.g += gs->color_dx.g * -x1; cur_color.b += gs->color_dx.b * -x1; cur_color.a += gs->color_dx.a * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); { { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } } } } static void shader_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) { state_grad_any_2d *gs = (state_grad_any_2d *) state; state_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { cur_color.r += gs->color_dx.r * -x1; cur_color.g += gs->color_dx.g * -x1; cur_color.b += gs->color_dx.b * -x1; cur_color.a += gs->color_dx.a * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { { { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { { for (; x1 <= x2; x1++) { ALLEGRO_COLOR src_color = cur_color; _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } } } } static void shader_texture_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) { state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } } } } static void shader_texture_solid_any_draw_shade_white(uintptr_t state, int x1, int y, int x2) { state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } } } } static void shader_texture_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) { state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, s->cur_color); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } } } } static void shader_texture_solid_any_draw_opaque_white(uintptr_t state, int x1, int y, int x2) { state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (dst_format == src_format && src_size == 4) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; switch (4) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; switch (4) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else if (dst_format == src_format && src_size == 3) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; switch (3) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; switch (3) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else if (dst_format == src_format && src_size == 2) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; switch (2) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; switch (2) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; } } } } } } } static void shader_texture_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) { state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; state_texture_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; cur_color.r += gs->color_dx.r * -x1; cur_color.g += gs->color_dx.g * -x1; cur_color.b += gs->color_dx.b * -x1; cur_color.a += gs->color_dx.a * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); } uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } } } } static void shader_texture_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) { state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; state_texture_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; float u = s->u; float v = s->v; ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { u += s->du_dx * -x1; v += s->dv_dx * -x1; cur_color.r += gs->color_dx.r * -x1; cur_color.g += gs->color_dx.g * -x1; cur_color.b += gs->color_dx.b * -x1; cur_color.a += gs->color_dx.a * -x1; x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } { { const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); { const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *) target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); uu += du_dx; vv += dv_dx; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { { al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + 0; const int src_y = (vv >> 16) + 0; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } else { al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); for (; x1 <= x2; x1++) { const int src_x = (uu >> 16) + uu_ofs; const int src_y = (vv >> 16) + vv_ofs; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); SHADE_COLORS(src_color, cur_color); _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); uu += du_dx; vv += dv_dx; if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; } } } } } } } allegro-5.0.10/src/fshook.c0000644000175000001440000001063511462746522014650 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File System Hooks. * * By Thomas Fjellstrom. * * See readme.txt for copyright information. */ /* Title: Filesystem routines */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_fshook.h" /* Function: al_create_fs_entry */ ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(vt->fs_create_entry); return vt->fs_create_entry(path); } /* Function: al_destroy_fs_entry */ void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh) { if (fh) { fh->vtable->fs_destroy_entry(fh); } } /* Function: al_get_fs_entry_name */ const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_name(e); } /* Function: al_update_fs_entry */ bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_update_entry(e); } /* Function: al_get_fs_entry_mode */ uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_mode(e); } /* Function: al_get_fs_entry_atime */ time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_atime(e); } /* Function: al_get_fs_entry_mtime */ time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_mtime(e); } /* Function: al_get_fs_entry_ctime */ time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_ctime(e); } /* Function: al_get_fs_entry_size */ off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_size(e); } /* Function: al_remove_fs_entry */ bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_remove_entry(e); } /* Function: al_fs_entry_exists */ bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_entry_exists(e); } /* Function: al_open_directory */ bool al_open_directory(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_open_directory(e); } /* Function: al_close_directory */ bool al_close_directory(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_close_directory(e); } /* Function: al_read_directory */ ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e) { ASSERT(e != NULL); return e->vtable->fs_read_directory(e); } /* Function: al_get_current_directory */ char *al_get_current_directory(void) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(vt->fs_get_current_directory); return vt->fs_get_current_directory(); } /* Function: al_change_directory */ bool al_change_directory(const char *path) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(vt->fs_change_directory); ASSERT(path); return vt->fs_change_directory(path); } /* Function: al_make_directory */ bool al_make_directory(const char *path) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(path); ASSERT(vt->fs_make_directory); return vt->fs_make_directory(path); } /* Function: al_filename_exists */ bool al_filename_exists(const char *path) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(path != NULL); ASSERT(vt->fs_filename_exists); return vt->fs_filename_exists(path); } /* Function: al_remove_filename */ bool al_remove_filename(const char *path) { const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); ASSERT(vt->fs_remove_filename); ASSERT(path != NULL); return vt->fs_remove_filename(path); } /* Function: al_open_fs_entry */ ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode) { ASSERT(e != NULL); if (e->vtable->fs_open_file) return e->vtable->fs_open_file(e, mode); al_set_errno(EINVAL); return NULL; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/file_stdio.c0000644000175000001440000001601312125201710015452 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File I/O. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" /* enable large file support in gcc/glibc */ #if defined ALLEGRO_HAVE_FTELLO && defined ALLEGRO_HAVE_FSEEKO #ifndef _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE #endif #ifndef _LARGEFILE_SOURCE64 #define _LARGEFILE_SOURCE64 #endif #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif #endif #include #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_file.h" #include "allegro5/internal/aintern_wunicode.h" #ifdef ALLEGRO_HAVE_SYS_STAT_H #include #endif /* forward declaration */ const struct ALLEGRO_FILE_INTERFACE _al_file_interface_stdio; static FILE *get_fp(ALLEGRO_FILE *f) { if (f) return (FILE *)al_get_file_userdata(f); else return NULL; } /* Function: al_fopen_fd */ ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode) { ALLEGRO_FILE *f; FILE *fp; /* The fd should remain open if this function fails in either way. */ fp = fdopen(fd, mode); if (!fp) { al_set_errno(errno); return NULL; } f = al_create_file_handle(&_al_file_interface_stdio, fp); if (!f) { al_set_errno(errno); return NULL; } return f; } static void *file_stdio_fopen(const char *path, const char *mode) { FILE *fp; #ifdef ALLEGRO_WINDOWS { wchar_t *wpath = _al_win_utf16(path); wchar_t *wmode = _al_win_utf16(mode); fp = _wfopen(wpath, wmode); al_free(wpath); al_free(wmode); } #else fp = fopen(path, mode); #endif if (!fp) { al_set_errno(errno); return NULL; } return fp; } static void file_stdio_fclose(ALLEGRO_FILE *f) { fclose(get_fp(f)); } static size_t file_stdio_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { if (size == 1) { /* Optimise common case. */ int c = fgetc(get_fp(f)); if (c == EOF) { al_set_errno(errno); return 0; } *((char *)ptr) = (char)c; return 1; } else { size_t ret = fread(ptr, 1, size, get_fp(f)); if (ret < size) { al_set_errno(errno); } return ret; } } static size_t file_stdio_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) { size_t ret; ret = fwrite(ptr, 1, size, get_fp(f)); if (ret < size) { al_set_errno(errno); } return ret; } static bool file_stdio_fflush(ALLEGRO_FILE *f) { FILE *fp = get_fp(f); if (fflush(fp) == EOF) { al_set_errno(errno); return false; } return true; } static int64_t file_stdio_ftell(ALLEGRO_FILE *f) { FILE *fp = get_fp(f); int64_t ret; #ifdef ALLEGRO_HAVE_FTELLO ret = ftello(fp); #else ret = ftell(fp); #endif if (ret == -1) { al_set_errno(errno); } return ret; } static bool file_stdio_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) { FILE *fp = get_fp(f); int rc; switch (whence) { case ALLEGRO_SEEK_SET: whence = SEEK_SET; break; case ALLEGRO_SEEK_CUR: whence = SEEK_CUR; break; case ALLEGRO_SEEK_END: whence = SEEK_END; break; } #ifdef ALLEGRO_HAVE_FSEEKO rc = fseeko(fp, offset, whence); #else rc = fseek(fp, offset, whence); #endif if (rc == -1) { al_set_errno(errno); return false; } return true; } static bool file_stdio_feof(ALLEGRO_FILE *f) { return feof(get_fp(f)); } static bool file_stdio_ferror(ALLEGRO_FILE *f) { return ferror(get_fp(f)); } static void file_stdio_fclearerr(ALLEGRO_FILE *f) { clearerr(get_fp(f)); } static int file_stdio_fungetc(ALLEGRO_FILE *f, int c) { int rc = ungetc(c, get_fp(f)); if (rc == EOF) { al_set_errno(errno); } return rc; } static off_t file_stdio_fsize(ALLEGRO_FILE *f) { int64_t old_pos; int64_t new_pos; old_pos = file_stdio_ftell(f); if (old_pos == -1) goto Error; if (!file_stdio_fseek(f, 0, ALLEGRO_SEEK_END)) goto Error; new_pos = file_stdio_ftell(f); if (new_pos == -1) goto Error; if (!file_stdio_fseek(f, old_pos, ALLEGRO_SEEK_SET)) goto Error; return new_pos; Error: al_set_errno(errno); return -1; } const struct ALLEGRO_FILE_INTERFACE _al_file_interface_stdio = { file_stdio_fopen, file_stdio_fclose, file_stdio_fread, file_stdio_fwrite, file_stdio_fflush, file_stdio_ftell, file_stdio_fseek, file_stdio_feof, file_stdio_ferror, file_stdio_fclearerr, file_stdio_fungetc, file_stdio_fsize }; /* Function: al_set_standard_file_interface */ void al_set_standard_file_interface(void) { al_set_new_file_interface(&_al_file_interface_stdio); } #define MAX_MKTEMP_TRIES 1000 static void mktemp_replace_XX(const char *template, char *dst) { static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; size_t len = strlen(template); unsigned i; for (i=0; ivt && system->vt->get_num_video_adapters) { return system->vt->get_num_video_adapters(); } return 0; } /* Function: al_get_monitor_info */ bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { ALLEGRO_SYSTEM *system = al_get_system_driver(); if (adapter < al_get_num_video_adapters()) { if (system && system->vt && system->vt->get_monitor_info) { return system->vt->get_monitor_info(adapter, info); } } info->x1 = info->y1 = info->x2 = info->y2 = INT_MAX; return false; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/opengl/0000755000175000001440000000000012157230740014462 5ustar tjadenusersallegro-5.0.10/src/opengl/ogl_draw.c0000644000175000001440000001521712146021714016427 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * OpenGL drawing routines * * By Elias Pschernig. */ #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_memdraw.h" #include "allegro5/internal/aintern_opengl.h" ALLEGRO_DEBUG_CHANNEL("opengl") bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp) { int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; const int blend_modes[8] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_DST_COLOR }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); /* glBlendFuncSeparate was only included with OpenGL 1.4 */ /* (And not in OpenGL ES) */ #if defined ALLEGRO_IPHONE || defined ALLEGRO_GP2XWIZ if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { #else if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { #endif glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else { glBlendEquation(blend_equations[op]); } } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); } else { ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n", op, src_color, dst_color, op_alpha, src_alpha, dst_alpha); return false; } } return true; } static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY *ogl_disp = (void *)d; ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_OGL *ogl_target; float r, g, b, a; if (target->parent) target = target->parent; ogl_target = (void *)target; if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || target->locked) { _al_clear_bitmap_by_locking(target, color); return; } al_unmap_rgba_f(*color, &r, &g, &b, &a); glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT); } static void ogl_draw_pixel(ALLEGRO_DISPLAY *d, float x, float y, ALLEGRO_COLOR *color) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_OGL *ogl_target; GLfloat vert[2]; /* For sub-bitmaps */ if (target->parent) { target = target->parent; } ogl_target = (void *)target; if ((!ogl_target->is_backbuffer && d->ogl_extras->opengl_target != ogl_target) || target->locked || !_al_opengl_set_blender(d)) { _al_draw_pixel_memory(target, x, y, color); return; } vert[0] = x; vert[1] = y; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(2, GL_FLOAT, 0, vert); glColorPointer(4, GL_FLOAT, 0, color); glDrawArrays(GL_POINTS, 0, 1); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); } static void* ogl_prepare_vertex_cache(ALLEGRO_DISPLAY* disp, int num_new_vertices) { disp->num_cache_vertices += num_new_vertices; if (!disp->vertex_cache) { disp->vertex_cache = al_malloc(num_new_vertices * sizeof(ALLEGRO_OGL_BITMAP_VERTEX)); disp->vertex_cache_size = num_new_vertices; } else if (disp->num_cache_vertices > disp->vertex_cache_size) { disp->vertex_cache = al_realloc(disp->vertex_cache, 2 * disp->num_cache_vertices * sizeof(ALLEGRO_OGL_BITMAP_VERTEX)); disp->vertex_cache_size = 2 * disp->num_cache_vertices; } return (ALLEGRO_OGL_BITMAP_VERTEX*)disp->vertex_cache + (disp->num_cache_vertices - num_new_vertices); } static void ogl_flush_vertex_cache(ALLEGRO_DISPLAY* disp) { GLboolean on; GLuint current_texture; if (!disp->vertex_cache) return; if (disp->num_cache_vertices == 0) return; glGetBooleanv(GL_TEXTURE_2D, &on); if (!on) { glEnable(GL_TEXTURE_2D); } glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)¤t_texture); if (current_texture != disp->cache_texture) { glBindTexture(GL_TEXTURE_2D, disp->cache_texture); } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(2, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), disp->vertex_cache); glTexCoordPointer(2, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), (char*)(disp->vertex_cache) + offsetof(ALLEGRO_OGL_BITMAP_VERTEX, tx)); glColorPointer(4, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), (char*)(disp->vertex_cache) + offsetof(ALLEGRO_OGL_BITMAP_VERTEX, r)); glDrawArrays(GL_TRIANGLES, 0, disp->num_cache_vertices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); disp->num_cache_vertices = 0; if (!on) { glDisable(GL_TEXTURE_2D); } } static void ogl_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target) { (void)disp; glMatrixMode(GL_MODELVIEW); if (target->parent) { /* Sub-bitmaps have an additional offset. */ glLoadIdentity(); glTranslatef(target->xofs, target->yofs, 0); glMultMatrixf((float*)(target->transform.m)); } else { glLoadMatrixf((float *)target->transform.m); } } /* Add drawing commands to the vtable. */ void _al_ogl_add_drawing_functions(ALLEGRO_DISPLAY_INTERFACE *vt) { vt->clear = ogl_clear; vt->draw_pixel = ogl_draw_pixel; vt->flush_vertex_cache = ogl_flush_vertex_cache; vt->prepare_vertex_cache = ogl_prepare_vertex_cache; vt->update_transformation = ogl_update_transformation; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/opengl/ogl_display.c0000644000175000001440000003600712114262314017135 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * OpenGL routines common to all OpenGL drivers. * * By Elias Pschernig and Milan Mimica. * */ #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_pixels.h" #ifdef ALLEGRO_GP2XWIZ #include "allegro5/internal/aintern_gp2xwiz.h" #endif #ifdef ALLEGRO_IPHONE #include "allegro5/internal/aintern_iphone.h" #endif #include ALLEGRO_DEBUG_CHANNEL("opengl") #ifdef ALLEGRO_IPHONE #define glGenFramebuffersEXT glGenFramebuffersOES #define glBindFramebufferEXT glBindFramebufferOES #define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_OES #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES #define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES #define glFramebufferTexture2DEXT glFramebufferTexture2DOES #define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE_OES #define glDeleteFramebuffersEXT glDeleteFramebuffersOES #define glOrtho glOrthof #endif void _al_ogl_reset_fbo_info(ALLEGRO_FBO_INFO *info) { info->fbo_state = FBO_INFO_UNUSED; info->fbo = 0; info->owner = NULL; info->last_use_time = 0.0; } bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap; ALLEGRO_FBO_INFO *info; GLint old_fbo; if (bitmap->parent) bitmap = bitmap->parent; ogl_bitmap = (void *)bitmap; /* Don't continue if the bitmap does not belong to the current display. */ if (bitmap->display->ogl_extras->is_shared == false && bitmap->display != al_get_current_display()) { return false; } if (ogl_bitmap->is_backbuffer) { return false; } ASSERT(!ogl_bitmap->fbo_info); info = al_malloc(sizeof(ALLEGRO_FBO_INFO)); glGenFramebuffersEXT(1, &info->fbo); if (info->fbo == 0) { al_free(info); return false; } glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &old_fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, info->fbo); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ogl_bitmap->texture, 0); if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { ALLEGRO_ERROR("FBO incomplete.\n"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo); glDeleteFramebuffersEXT(1, &info->fbo); al_free(info); return false; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo); info->fbo_state = FBO_INFO_PERSISTENT; info->owner = ogl_bitmap; info->last_use_time = al_get_time(); ogl_bitmap->fbo_info = info; ALLEGRO_DEBUG("Persistent FBO: %u\n", info->fbo); return true; } ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_FBO_INFO *transient_fbo_info) { ALLEGRO_OGL_EXTRAS *extras = display->ogl_extras; int i; ASSERT(transient_fbo_info->fbo_state == FBO_INFO_TRANSIENT); for (i = 0; i < ALLEGRO_MAX_OPENGL_FBOS; i++) { if (transient_fbo_info == &extras->fbos[i]) { ALLEGRO_FBO_INFO *new_info = al_malloc(sizeof(ALLEGRO_FBO_INFO)); *new_info = *transient_fbo_info; new_info->fbo_state = FBO_INFO_PERSISTENT; _al_ogl_reset_fbo_info(transient_fbo_info); ALLEGRO_DEBUG("Persistent FBO: %u\n", new_info->fbo); return new_info; } } ALLEGRO_ERROR("Could not find FBO %u in pool\n", transient_fbo_info->fbo); return transient_fbo_info; } static ALLEGRO_FBO_INFO *ogl_find_unused_fbo(ALLEGRO_DISPLAY *display) { ALLEGRO_OGL_EXTRAS *extras = display->ogl_extras; double min_time = DBL_MAX; int min_time_index = -1; int i; for (i = 0; i < ALLEGRO_MAX_OPENGL_FBOS; i++) { if (extras->fbos[i].fbo_state == FBO_INFO_UNUSED) return &extras->fbos[i]; if (extras->fbos[i].last_use_time < min_time) { min_time = extras->fbos[i].last_use_time; min_time_index = i; } } return &extras->fbos[min_time_index]; } static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap; if (bitmap->parent) bitmap = bitmap->parent; ogl_bitmap = (void *)bitmap; /* We can't return here. Target's FBO can be taken away by locking * a lot of bitmaps consecutively. * Also affects ex_multiwin; resizing one window affects the other. */ if (false && display->ogl_extras->opengl_target == ogl_bitmap) return; #if !defined ALLEGRO_GP2XWIZ if (!ogl_bitmap->is_backbuffer) { ALLEGRO_FBO_INFO *info = NULL; /* When a bitmap is set as target bitmap, we try to create an FBO for it. */ if (ogl_bitmap->fbo_info == NULL && !(bitmap->flags & ALLEGRO_FORCE_LOCKING)) { #ifdef ALLEGRO_IPHONE /* FIXME This is quite a hack but I don't know how the Allegro extension * manager works to fix this properly (getting extensions properly reported * on iphone. */ if (true) #else if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object || al_get_opengl_extension_list()->ALLEGRO_GL_OES_framebuffer_object) #endif { info = ogl_find_unused_fbo(display); ASSERT(info->fbo_state != FBO_INFO_PERSISTENT); if (info->fbo_state == FBO_INFO_TRANSIENT) { info->owner->fbo_info = NULL; ALLEGRO_DEBUG("Deleting FBO: %u\n", info->fbo); glDeleteFramebuffersEXT(1, &info->fbo); _al_ogl_reset_fbo_info(info); } glGenFramebuffersEXT(1, &info->fbo); ALLEGRO_DEBUG("Created FBO: %u\n", info->fbo); } } else { info = ogl_bitmap->fbo_info; } if (info && info->fbo) { /* Bind to the FBO. */ #ifndef ALLEGRO_IPHONE ASSERT(display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object || display->ogl_extras->extension_list->ALLEGRO_GL_OES_framebuffer_object); #endif if (info->fbo_state == FBO_INFO_UNUSED) info->fbo_state = FBO_INFO_TRANSIENT; info->owner = ogl_bitmap; info->last_use_time = al_get_time(); ogl_bitmap->fbo_info = info; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, info->fbo); /* Attach the texture. */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ogl_bitmap->texture, 0); if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { /* For some reason, we cannot use the FBO with this * texture. So no reason to keep re-trying, output a log * message and switch to (extremely slow) software mode. */ ALLEGRO_ERROR("Could not use FBO for bitmap with format %s.\n", _al_pixel_format_name(bitmap->format)); ALLEGRO_ERROR("*** SWITCHING TO SOFTWARE MODE ***\n"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &info->fbo); _al_ogl_reset_fbo_info(info); ogl_bitmap->fbo_info = NULL; } else { display->ogl_extras->opengl_target = ogl_bitmap; glViewport(0, 0, bitmap->w, bitmap->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, bitmap->w, bitmap->h, 0, -1, 1); } } } else { display->ogl_extras->opengl_target = ogl_bitmap; // TODO: Might as well have a vtable entry here #ifdef ALLEGRO_IPHONE _al_iphone_setup_opengl_view(display); #else if (display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object || display->ogl_extras->extension_list->ALLEGRO_GL_OES_framebuffer_object) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } glViewport(0, 0, display->w, display->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* We use upside down coordinates compared to OpenGL, so the bottommost * coordinate is display->h not 0. */ glOrtho(0, display->w, display->h, 0, -1, 1); #endif } #else ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (ALLEGRO_DISPLAY_GP2XWIZ_OGL *)display; display->ogl_extras->opengl_target = ogl_bitmap; if (!ogl_bitmap->is_backbuffer) { /* FIXME: implement */ } else { eglMakeCurrent(wiz_disp->egl_display, wiz_disp->egl_surface, wiz_disp->egl_surface, wiz_disp->egl_context); glViewport(0, 0, display->w, display->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* We use upside down coordinates compared to OpenGL, so the bottommost * coordinate is display->h not 0. */ glOrtho(0, display->w, display->h, 0, -1, 1); } #endif } /* Helper to set up GL state as we want it. */ void _al_ogl_setup_gl(ALLEGRO_DISPLAY *d) { ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; glViewport(0, 0, d->w, d->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, d->w, d->h, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (ogl->backbuffer) _al_ogl_resize_backbuffer(ogl->backbuffer, d->w, d->h); else ogl->backbuffer = _al_ogl_create_backbuffer(d); } void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (bitmap->parent) ogl_bitmap = (void *)bitmap->parent; /* if either this bitmap or its parent (in the case of subbitmaps) * is locked then don't do anything */ if (!(bitmap->locked || (bitmap->parent && bitmap->parent->locked))){ setup_fbo(display, bitmap); if (display->ogl_extras->opengl_target == ogl_bitmap) { _al_ogl_setup_bitmap_clipping(bitmap); } } } /* Function: al_set_current_opengl_context */ void al_set_current_opengl_context(ALLEGRO_DISPLAY *display) { ASSERT(display); if (!(display->flags & ALLEGRO_OPENGL)) return; if (display) { ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); if (bmp && bmp->display && bmp->display != display) { al_set_target_bitmap(NULL); } } _al_set_current_display_only(display); } void _al_ogl_setup_bitmap_clipping(const ALLEGRO_BITMAP *bitmap) { int x_1, y_1, x_2, y_2, h; bool use_scissor = true; x_1 = bitmap->cl; y_1 = bitmap->ct; x_2 = bitmap->cr_excl; y_2 = bitmap->cb_excl; h = bitmap->h; /* Drawing onto the sub bitmap is handled by clipping the parent. */ if (bitmap->parent) { x_1 += bitmap->xofs; y_1 += bitmap->yofs; x_2 += bitmap->xofs; y_2 += bitmap->yofs; h = bitmap->parent->h; } if (x_1 == 0 && y_1 == 0 && x_2 == bitmap->w && y_2 == bitmap->h) { if (bitmap->parent) { /* Can only disable scissor if the sub-bitmap covers the * complete parent. */ if (bitmap->xofs == 0 && bitmap->yofs == 0 && bitmap->w == bitmap->parent->w && bitmap->h == bitmap->parent->h) { use_scissor = false; } } else { use_scissor = false; } } if (!use_scissor) { glDisable(GL_SCISSOR_TEST); } else { glEnable(GL_SCISSOR_TEST); #ifdef ALLEGRO_IPHONE _al_iphone_clip(bitmap, x_1, y_1, x_2, y_2); #else /* OpenGL is upside down, so must adjust y_2 to the height. */ glScissor(x_1, h - y_2, x_2 - x_1, y_2 - y_1); #endif } } ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d) { return (ALLEGRO_BITMAP *)d->ogl_extras->backbuffer; } bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP_OGL *b, int w, int h) { int pitch; pitch = w * al_get_pixel_size(b->bitmap.format); b->bitmap.w = w; b->bitmap.h = h; b->bitmap.pitch = pitch; b->bitmap.cl = 0; b->bitmap.ct = 0; b->bitmap.cr_excl = w; b->bitmap.cb_excl = h; /* There is no texture associated with the backbuffer so no need to care * about texture size limitations. */ b->true_w = w; b->true_h = h; #if !defined(ALLEGRO_IPHONE) && !defined(ALLEGRO_GP2XWIZ) b->bitmap.memory = NULL; #else /* iPhone/Wiz ports still expect the buffer to be present. */ { /* FIXME: lazily manage memory */ size_t bytes = pitch * h; al_free(b->bitmap.memory); b->bitmap.memory = al_calloc(1, bytes); } #endif return true; } ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp) { ALLEGRO_BITMAP_OGL *ogl_backbuffer; ALLEGRO_BITMAP *backbuffer; ALLEGRO_STATE backup; int format; ALLEGRO_DEBUG("Creating backbuffer\n"); al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); // FIXME: _al_deduce_color_format would work fine if the display paramerers // are filled in, for WIZ and IPOD #ifdef ALLEGRO_GP2XWIZ format = ALLEGRO_PIXEL_FORMAT_RGB_565; /* Only support display format */ #elif defined ALLEGRO_IPHONE format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE; // TODO: This one is also supported //format = ALLEGRO_PIXEL_FORMAT_RGB_565; #else format = _al_deduce_color_format(&disp->extra_settings); /* Eww. No OpenGL hardware in the world does that - let's just * switch to some default. */ if (al_get_pixel_size(format) == 3) { /* Or should we use RGBA? Maybe only if not Nvidia cards? */ format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; } #endif ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)("Deduced format %s for backbuffer.\n", _al_pixel_format_name(format)); /* Now that the display backbuffer has a format, update extra_settings so * the user can query it back. */ _al_set_color_components(format, &disp->extra_settings, ALLEGRO_REQUIRE); disp->backbuffer_format = format; ALLEGRO_DEBUG("Creating backbuffer bitmap\n"); al_set_new_bitmap_format(format); /* Using ALLEGRO_NO_PRESERVE_TEXTURE prevents extra memory being allocated */ al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PRESERVE_TEXTURE); backbuffer = _al_ogl_create_bitmap(disp, disp->w, disp->h); al_restore_state(&backup); if (!backbuffer) { ALLEGRO_DEBUG("Backbuffer bitmap creation failed.\n"); return NULL; } ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)( "Created backbuffer bitmap (actual format: %s)\n", _al_pixel_format_name(backbuffer->format)); ogl_backbuffer = (ALLEGRO_BITMAP_OGL*)backbuffer; ogl_backbuffer->is_backbuffer = 1; backbuffer->display = disp; return ogl_backbuffer; } void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP_OGL *b) { al_destroy_bitmap((ALLEGRO_BITMAP *)b); } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/src/opengl/extensions.c0000644000175000001440000006166612104442100017027 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * OpenGL extensions management subsystem * * By Elias Pschernig and Milan Mimica. * * Based on AllegroGL extensions management. */ #include #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/opengl/gl_ext.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_system.h" /* We need some driver specific details not worth of a vtable entry. */ #if defined ALLEGRO_WINDOWS #include "../win/wgl.h" #elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xsystem.h" #endif #if defined ALLEGRO_MACOSX #include #elif !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE #include #endif ALLEGRO_DEBUG_CHANNEL("opengl") #ifdef ALLEGRO_HAVE_DYNAMIC_LINK #include /* Handle for dynamic library libGL.so */ static void *__libgl_handle = NULL; /* Pointer to glXGetProcAddressARB */ typedef void *(*GLXGETPROCADDRESSARBPROC) (const GLubyte *); static GLXGETPROCADDRESSARBPROC alXGetProcAddress; #else /* #ifdef ALLEGRO_HAVE_DYNAMIC_LINK */ /* Tries static linking */ /* FIXME: set ALLEGRO_GLXGETPROCADDRESSARB on configure time, if * glXGetProcAddressARB must be used! */ #if defined ALLEGRO_GLXGETPROCADDRESSARB #define alXGetProcAddress glXGetProcAddressARB #elif defined ALLEGRO_GP2XWIZ #define alXGetProcAddress eglGetProcAddress #else #define alXGetProcAddress glXGetProcAddress #endif #endif /* #ifdef ALLEGRO_HAVE_DYNAMIC_LINK */ #ifdef ALLEGRO_MACOSX #include static CFBundleRef opengl_bundle_ref; #endif /* Define the GL API pointers. * Example: * _ALLEGRO_glBlendEquation_t _al_glBlendEquation = NULL; */ #define AGL_API(type, name, args) _ALLEGRO_gl##name##_t _al_gl##name = NULL; # include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) _ALLEGRO_wgl##name##_t _al_wgl##name = NULL; # include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) _ALLEGRO_glX##name##_t _al_glX##name = NULL; # include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #endif #ifndef ALLEGRO_IPHONE static uint32_t parse_opengl_version(const char *s) { char *p = (char *) s; int v[4] = {0, 0, 0, 0}; int n; uint32_t ver; /* e.g. "4.0.0 Vendor blah blah" */ for (n = 0; n < 4; n++) { char *end; long l; errno = 0; l = strtol(p, &end, 10); if (errno) break; v[n] = _ALLEGRO_CLAMP(0, l, 255); if (*end != '.') break; p = end + 1; /* skip dot */ } ver = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3]; ALLEGRO_DEBUG("Parsed '%s' as 0x%08x\n", s, ver); return ver; } #endif /* Reads version info out of glGetString(GL_VERSION) */ static uint32_t _al_ogl_version(void) { #ifndef ALLEGRO_IPHONE ALLEGRO_CONFIG *cfg; const char *str; cfg = al_get_system_config(); if (cfg) { char const *value = al_get_config_value(cfg, "opengl", "force_opengl_version"); if (value) { uint32_t v = parse_opengl_version(value); ALLEGRO_INFO("OpenGL version forced to %d.%d.%d.%d.\n", (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, (v & 0xff)); return v; } } str = (const char *)glGetString(GL_VERSION); if (str) { return parse_opengl_version(str); } else { /* The OpenGL driver does not return a version * number. However it probably supports at least OpenGL 1.0 */ return _ALLEGRO_OPENGL_VERSION_1_0; } #else /* XXX this is asking for trouble, and should be documented */ const char *s = (char *)glGetString(GL_VERSION); if (strstr(s, "2.0")) return _ALLEGRO_OPENGL_VERSION_2_0; else if (strstr(s, "1.1")) return _ALLEGRO_OPENGL_VERSION_1_1; else return _ALLEGRO_OPENGL_VERSION_0; #endif } static bool _al_ogl_version_3_only(int flags) { const int mask = ALLEGRO_OPENGL_3_0 | ALLEGRO_OPENGL_FORWARD_COMPATIBLE; return (flags & mask) == mask; } /* print_extensions: * Given a string containing extensions (i.e. a NULL terminated string where * each extension are separated by a space and which names do not contain any * space) */ static void print_extensions(char const *extension) { char buf[80]; char *start; ASSERT(extension); while (*extension != '\0') { start = buf; _al_sane_strncpy(buf, extension, 80); while ((*start != ' ') && (*start != '\0')) { extension++; start++; } *start = '\0'; if (*extension != '\0') extension++; ALLEGRO_DEBUG("%s\n", buf); } } /* Print all extensions the OpenGL 3.0 way. */ static void print_extensions_3_0(void) { int i; GLint n; GLubyte const *name; glGetIntegerv(GL_NUM_EXTENSIONS, &n); for (i = 0; i < n; i++) { name = glGetStringi(GL_EXTENSIONS, i); ALLEGRO_DEBUG("%s\n", name); } } /* Function: al_get_opengl_version */ uint32_t al_get_opengl_version(void) { ALLEGRO_DISPLAY *ogl_disp; ogl_disp = al_get_current_display(); if (!ogl_disp || !ogl_disp->ogl_extras) return 0x0; return ogl_disp->ogl_extras->ogl_info.version; } /* NOTE: al_get_opengl_variant is pretty simple right now but may * eventually need driver support. */ /* Function: al_get_opengl_variant */ int al_get_opengl_variant(void) { #if defined ALLEGRO_IPHONE || defined ALLEGRO_GP2XWIZ return ALLEGRO_OPENGL_ES; #else return ALLEGRO_DESKTOP_OPENGL; #endif } /* Create the extension list */ static ALLEGRO_OGL_EXT_LIST *create_extension_list(void) { ALLEGRO_OGL_EXT_LIST *ret = al_calloc(1, sizeof(ALLEGRO_OGL_EXT_LIST)); if (!ret) { return NULL; } return ret; } /* Create the extension API table */ static ALLEGRO_OGL_EXT_API *create_extension_api_table(void) { ALLEGRO_OGL_EXT_API *ret = al_calloc(1, sizeof(ALLEGRO_OGL_EXT_API)); if (!ret) { return NULL; } return ret; } /* Load the extension API addresses into the table. * Should only be done on context creation. */ static void load_extensions(ALLEGRO_OGL_EXT_API *ext) { if (!ext) { return; } #ifdef ALLEGRO_UNIX #ifdef ALLEGRO_HAVE_DYNAMIC_LINK if (!alXGetProcAddress) { return; } #endif #endif #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) \ ext->name = (_ALLEGRO_gl##name##_t)wglGetProcAddress("gl" #name); \ if (ext->name) { ALLEGRO_DEBUG("gl" #name " successfully loaded\n"); } #include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #define AGL_API(type, name, args) \ ext->name = (_ALLEGRO_wgl##name##_t)wglGetProcAddress("wgl" #name); \ if (ext->name) { ALLEGRO_DEBUG("wgl" #name " successfully loaded\n"); } #include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) \ ext->name = (_ALLEGRO_gl##name##_t)alXGetProcAddress((const GLubyte*)"gl" #name); \ if (ext->name) { ALLEGRO_DEBUG("gl" #name " successfully loaded (%p)\n", ext->name); } #include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #define AGL_API(type, name, args) \ ext->name = (_ALLEGRO_glX##name##_t)alXGetProcAddress((const GLubyte*)"glX" #name); \ if (ext->name) { ALLEGRO_DEBUG("glX" #name " successfully loaded\n"); } #include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #elif defined ALLEGRO_MACOSX #define AGL_API(type, name, args) \ ext->name = (_ALLEGRO_gl##name##_t)CFBundleGetFunctionPointerForName(opengl_bundle_ref, CFSTR("gl" # name)); \ if (ext->name) { ALLEGRO_DEBUG("gl" #name " successfully loaded\n"); } #include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #endif } /* Set the GL API pointers to the current table * Should only be called on context switches. */ void _al_ogl_set_extensions(ALLEGRO_OGL_EXT_API *ext) { if (!ext) { return; } #define AGL_API(type, name, args) _al_gl##name = ext->name; # include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) _al_wgl##name = ext->name; # include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) _al_glX##name = ext->name; # include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #endif } /* Destroys the extension API table */ static void destroy_extension_api_table(ALLEGRO_OGL_EXT_API *ext) { if (ext) { al_free(ext); } } /* Destroys the extension list */ static void destroy_extension_list(ALLEGRO_OGL_EXT_LIST *list) { if (list) { al_free(list); } } /* _al_ogl_look_for_an_extension: * This function has been written by Mark J. Kilgard in one of his * tutorials about OpenGL extensions */ int _al_ogl_look_for_an_extension(const char *name, const GLubyte *extensions) { const GLubyte *start; GLubyte *where, *terminator; ASSERT(extensions); /* Extension names should not have spaces. */ where = (GLubyte *) strchr(name, ' '); if (where || *name == '\0') return false; /* It takes a bit of care to be fool-proof about parsing the * OpenGL extensions string. Don't be fooled by sub-strings, etc. */ start = extensions; for (;;) { where = (GLubyte *) strstr((const char *)start, name); if (!where) break; terminator = where + strlen(name); if (where == start || *(where - 1) == ' ') if (*terminator == ' ' || *terminator == '\0') return true; start = terminator; } return false; } static bool _ogl_is_extension_supported(const char *extension, ALLEGRO_DISPLAY *disp) { int ret = 0; GLubyte const *ext_str; int v = al_get_opengl_version(); (void)disp; #if defined ALLEGRO_GP2XWIZ return false; #endif #ifndef ALLEGRO_IPHONE if (disp->flags & ALLEGRO_OPENGL_3_0 || v >= _ALLEGRO_OPENGL_VERSION_3_0) { int i; GLint ext_cnt; glGetIntegerv(GL_NUM_EXTENSIONS, &ext_cnt); for (i = 0; i < ext_cnt; i++) { ext_str = glGetStringi(GL_EXTENSIONS, i); if (ext_str && !strcmp(extension, (char*)ext_str)) { ret = 1; break; } } } else #endif { ext_str = glGetString(GL_EXTENSIONS); if (!ext_str) return false; ret = _al_ogl_look_for_an_extension(extension, ext_str); } #ifdef ALLEGRO_WINDOWS if (!ret && strncmp(extension, "WGL", 3) == 0) { ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB; if (!wgl_disp->dc) return false; _wglGetExtensionsStringARB = (void *) wglGetProcAddress("wglGetExtensionsStringARB"); if (_wglGetExtensionsStringARB) { ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *) _wglGetExtensionsStringARB(wgl_disp->dc)); } } #elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX if (!ret && strncmp(extension, "GLX", 3) == 0) { ALLEGRO_SYSTEM_XGLX *sys = (void*)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx_disp = (void*)disp; char const *ext; if (!sys->gfxdisplay) return false; ext = glXQueryExtensionsString(sys->gfxdisplay, glx_disp->xscreen); if (!ext) { /* work around driver bugs? */ ext = ""; } ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *)ext); } #endif return ret; } static bool _ogl_is_extension_with_version_supported( const char *extension, ALLEGRO_DISPLAY *disp, uint32_t ver) { ALLEGRO_CONFIG *cfg; char const *value; /* For testing purposes, any OpenGL extension can be disable in * the config by using something like: * * [opengl_disabled_extensions] * GL_ARB_texture_non_power_of_two=0 * GL_EXT_framebuffer_object=0 * */ cfg = al_get_system_config(); if (cfg) { value = al_get_config_value(cfg, "opengl_disabled_extensions", extension); if (value) { ALLEGRO_WARN("%s found in [opengl_disabled_extensions].\n", extension); return false; } } /* If the extension is included in the OpenGL version, there is no * need to check the extensions list. */ if (ver > 0 && disp->ogl_extras->ogl_info.version >= ver) { return true; } return _ogl_is_extension_supported(extension, disp); } /* Function: al_have_opengl_extension */ bool al_have_opengl_extension(const char *extension) { ALLEGRO_DISPLAY *disp; disp = al_get_current_display(); if (!disp) return false; if (!(disp->flags & ALLEGRO_OPENGL)) return false; return _ogl_is_extension_supported(extension, disp); } /* Function: al_get_opengl_proc_address */ void *al_get_opengl_proc_address(const char *name) { void *symbol = NULL; #ifdef ALLEGRO_MACOSX CFStringRef function; #endif ALLEGRO_DISPLAY *disp; disp = al_get_current_display(); if (!disp) return NULL; if (!(disp->flags & ALLEGRO_OPENGL)) return NULL; #if defined ALLEGRO_WINDOWS /* For once Windows is the easiest platform to use :) * It provides a standardized way to get a function address * But of course there is a drawback : the symbol is only valid * under the current context :P */ { ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; if (!wgl_disp->dc) return NULL; symbol = wglGetProcAddress(name); } #elif defined ALLEGRO_UNIX #if defined ALLEGRO_HAVE_DYNAMIC_LINK if (alXGetProcAddress) #endif { /* This is definitely the *good* way on Unix to get a GL proc * address. Unfortunately glXGetProcAddress is an extension * and may not be available on all platforms */ #ifdef ALLEGRO_GP2XWIZ symbol = alXGetProcAddress(name); #else symbol = alXGetProcAddress((const GLubyte *)name); #endif } #elif defined ALLEGRO_HAVE_DYNAMIC_LINK else { /* Hack if glXGetProcAddress is not available : * we try to find the symbol into libGL.so */ if (__al_handle) { symbol = dlsym(__al_handle, name); } } #elif defined ALLEGRO_MACOSX function = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII); if (function) { symbol = CFBundleGetFunctionPointerForName(opengl_bundle_ref, function); CFRelease(function); } #endif if (!symbol) { #if defined ALLEGRO_HAVE_DYNAMIC_LINK if (!alXGetProcAddress) { ALLEGRO_WARN("get_proc_address: libdl::dlsym: %s\n", dlerror()); } #endif ALLEGRO_WARN("get_proc_address : Unable to load symbol %s\n", name); } else { ALLEGRO_DEBUG("get_proc_address : Symbol %s successfully loaded\n", name); } return symbol; } /* fill_in_info_struct: * Fills in the OPENGL_INFO info struct for blacklisting video cards. */ static void fill_in_info_struct(const GLubyte *rendereru, OPENGL_INFO *info) { const char *renderer = (const char *)rendereru; ASSERT(renderer); /* Some cards are "special"... */ if (strstr(renderer, "3Dfx/Voodoo")) { info->is_voodoo = 1; } else if (strstr(renderer, "Matrox G200")) { info->is_matrox_g200 = 1; } else if (strstr(renderer, "RagePRO")) { info->is_ati_rage_pro = 1; } else if (strstr(renderer, "RADEON 7000")) { info->is_ati_radeon_7000 = 1; } else if (strstr(renderer, "Mesa DRI R200")) { info->is_ati_r200_chip = 1; } if ((strncmp(renderer, "3Dfx/Voodoo3 ", 13) == 0) || (strncmp(renderer, "3Dfx/Voodoo2 ", 13) == 0) || (strncmp(renderer, "3Dfx/Voodoo ", 12) == 0)) { info->is_voodoo3_and_under = 1; } /* Read OpenGL properties */ info->version = _al_ogl_version(); ALLEGRO_INFO("Assumed OpenGL version: %d.%d.%d.%d\n", (info->version >> 24) & 0xff, (info->version >> 16) & 0xff, (info->version >> 8) & 0xff, (info->version ) & 0xff); return; } /* _al_ogl_manage_extensions: * This functions fills the extensions API table and extension list * structures and displays on the log file which extensions are available. */ void _al_ogl_manage_extensions(ALLEGRO_DISPLAY *gl_disp) { //const GLubyte *buf; #if defined ALLEGRO_MACOSX CFURLRef bundle_url; #endif ALLEGRO_OGL_EXT_API *ext_api; ALLEGRO_OGL_EXT_LIST *ext_list; /* Print out OpenGL extensions * We should use glGetStringi(GL_EXTENSIONS, i) for OpenGL 3.0+ * but it doesn't seem to work until later. */ if (!_al_ogl_version_3_only(gl_disp->flags)) { ALLEGRO_DEBUG("OpenGL Extensions:\n"); print_extensions((char const *)glGetString(GL_EXTENSIONS)); } /* Print out GLU version */ //buf = gluGetString(GLU_VERSION); //ALLEGRO_INFO("GLU Version : %s\n", buf); #ifdef ALLEGRO_HAVE_DYNAMIC_LINK /* Get glXGetProcAddress entry */ __libgl_handle = dlopen("libGL.so", RTLD_LAZY); if (__libgl_handle) { alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, "glXGetProcAddressARB"); if (!alXGetProcAddress) { alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, "glXGetProcAddress"); if (!alXGetProcAddress) { alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, "eglGetProcAddress"); } } } else { ALLEGRO_WARN("Failed to dlopen libGL.so : %s\n", dlerror()); } ALLEGRO_INFO("glXGetProcAddress Extension: %s\n", alXGetProcAddress ? "Supported" : "Unsupported"); #elif defined ALLEGRO_UNIX #ifdef ALLEGROGL_GLXGETPROCADDRESSARB ALLEGRO_INFO("glXGetProcAddressARB Extension: supported\n"); #else ALLEGRO_INFO("glXGetProcAddress Extension: supported\n"); #endif #endif #ifdef ALLEGRO_MACOSX bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR ("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true); opengl_bundle_ref = CFBundleCreate(kCFAllocatorDefault, bundle_url); CFRelease(bundle_url); #endif #if defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX ALLEGRO_DEBUG("GLX Extensions:\n"); ALLEGRO_SYSTEM_XGLX *glx_sys = (void*)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx_disp = (void *)gl_disp; char const *ext = glXQueryExtensionsString( glx_sys->gfxdisplay, glx_disp->xscreen); if (!ext) { /* work around driver bugs? */ ext = ""; } print_extensions(ext); #endif fill_in_info_struct(glGetString(GL_RENDERER), &(gl_disp->ogl_extras->ogl_info)); /* Create & load extension API table */ ext_api = create_extension_api_table(); load_extensions(ext_api); gl_disp->ogl_extras->extension_api = ext_api; /* Need that symbol already so can't wait until it is assigned later. */ glGetStringi = ext_api->GetStringi; if (_al_ogl_version_3_only(gl_disp->flags)) { ALLEGRO_DEBUG("OpenGL Extensions:\n"); print_extensions_3_0(); } /* Create the list of supported extensions. */ ext_list = create_extension_list(); gl_disp->ogl_extras->extension_list = ext_list; /* Fill the list. */ #define AGL_EXT(name, ver) { \ ext_list->ALLEGRO_GL_##name = \ _ogl_is_extension_with_version_supported("GL_" #name, gl_disp, \ _ALLEGRO_OPENGL_VERSION_##ver); \ } #include "allegro5/opengl/GLext/gl_ext_list.h" #undef AGL_EXT #ifdef ALLEGRO_UNIX #define AGL_EXT(name, ver) { \ ext_list->ALLEGRO_GLX_##name = \ _ogl_is_extension_with_version_supported("GLX_" #name, gl_disp, \ _ALLEGRO_OPENGL_VERSION_##ver); \ } #include "allegro5/opengl/GLext/glx_ext_list.h" #undef AGL_EXT #elif defined ALLEGRO_WINDOWS #define AGL_EXT(name, ver) { \ ext_list->ALLEGRO_WGL_##name = \ _ogl_is_extension_with_version_supported("WGL_" #name, gl_disp, \ _ALLEGRO_OPENGL_VERSION_##ver); \ } #include "allegro5/opengl/GLext/wgl_ext_list.h" #undef AGL_EXT #endif /* TODO: use these somewhere */ #if 0 for (i = 0; i < 5; i++) { __allegro_gl_texture_read_format[i] = -1; __allegro_gl_texture_components[i] = GL_RGB; } __allegro_gl_texture_read_format[3] = GL_UNSIGNED_BYTE; __allegro_gl_texture_read_format[4] = GL_UNSIGNED_BYTE; __allegro_gl_texture_components[4] = GL_RGBA; #endif /* #if 0 */ /* Get max texture size */ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *) & gl_disp->ogl_extras->ogl_info.max_texture_size); /* Note: Voodoo (even V5) don't seem to correctly support * packed pixel formats. Disabling them for those cards. */ ext_list->ALLEGRO_GL_EXT_packed_pixels &= !gl_disp->ogl_extras->ogl_info.is_voodoo; if (ext_list->ALLEGRO_GL_EXT_packed_pixels) { ALLEGRO_INFO("Packed Pixels formats available\n"); /* XXX On NV cards, we want to use BGRA instead of RGBA for speed */ /* Fills the __allegro_gl_texture_format array */ /* TODO: use these somewhere */ #if 0 __allegro_gl_texture_read_format[0] = GL_UNSIGNED_BYTE_3_3_2; __allegro_gl_texture_read_format[1] = GL_UNSIGNED_SHORT_5_5_5_1; __allegro_gl_texture_read_format[2] = GL_UNSIGNED_SHORT_5_6_5; #endif /* #if 0 */ } /* NVidia and ATI cards expose OpenGL 2.0 but often don't accelerate * non-power-of-2 textures. This check is how you verify that NP2 * textures are hardware accelerated or not. * We should clobber the NPOT support if it's not accelerated. */ { const char *vendor = (const char *)glGetString(GL_VENDOR); if (strstr(vendor, "NVIDIA Corporation")) { if (!ext_list->ALLEGRO_GL_NV_fragment_program2 || !ext_list->ALLEGRO_GL_NV_vertex_program3) { ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0; } } else if (strstr(vendor, "ATI Technologies")) { if (_al_ogl_version_3_only(gl_disp->flags)) { /* Assume okay. */ } else if (!strstr((const char *)glGetString(GL_EXTENSIONS), "GL_ARB_texture_non_power_of_two") && gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0; } } } { int *s = gl_disp->extra_settings.settings; glGetIntegerv(GL_MAX_TEXTURE_SIZE, s + ALLEGRO_MAX_BITMAP_SIZE); if (gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) s[ALLEGRO_SUPPORT_SEPARATE_ALPHA] = 1; s[ALLEGRO_SUPPORT_NPOT_BITMAP] = ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two; ALLEGRO_INFO("Use of non-power-of-two textures %s.\n", s[ALLEGRO_SUPPORT_NPOT_BITMAP] ? "enabled" : "disabled"); #ifdef ALLEGRO_IPHONE s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = ext_list->ALLEGRO_GL_OES_framebuffer_object; ALLEGRO_INFO("Use of FBO to draw to textures %s.\n", s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" : "disabled"); #else s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = ext_list->ALLEGRO_GL_EXT_framebuffer_object; ALLEGRO_INFO("Use of FBO to draw to textures %s.\n", s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" : "disabled"); #endif } } /* Function: al_get_opengl_extension_list */ ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void) { ALLEGRO_DISPLAY *disp; disp = al_get_current_display(); ASSERT(disp); if (!(disp->flags & ALLEGRO_OPENGL)) return NULL; ASSERT(disp->ogl_extras); return disp->ogl_extras->extension_list; } void _al_ogl_unmanage_extensions(ALLEGRO_DISPLAY *gl_disp) { destroy_extension_api_table(gl_disp->ogl_extras->extension_api); destroy_extension_list(gl_disp->ogl_extras->extension_list); gl_disp->ogl_extras->extension_api = NULL; gl_disp->ogl_extras->extension_list = NULL; #ifdef ALLEGRO_MACOSX CFRelease(opengl_bundle_ref); #endif #ifdef ALLEGRO_HAVE_DYNAMIC_LINK if (__libgl_handle) { dlclose(__libgl_handle); __libgl_handle = NULL; } #endif } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/opengl/ogl_bitmap.c0000644000175000001440000011544012146021714016745 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * OpenGL bitmap vtable * * By Elias Pschernig. * OpenGL ES 1.1 support by Trent Gamblin. * */ /* FIXME: Add the other format for gp2xwiz 1555 or 5551 */ #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_memblit.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_transform.h" #include #if defined ALLEGRO_GP2XWIZ #include "allegro5/internal/aintern_gp2xwiz.h" #endif #ifdef ALLEGRO_IPHONE #define glGenerateMipmapEXT glGenerateMipmapOES #endif ALLEGRO_DEBUG_CHANNEL("opengl") /* OpenGL does not support "locking", i.e. direct access to a memory * buffer with pixel data. Instead, the data can be copied from/to * client memory. Because OpenGL stores pixel data starting with the * pixel in the lower left corner, that's also how we return locked * data. Otherwise (and as was done in earlier versions of this code) * we would have to flip all locked memory after receiving and before * sending it to OpenGL. * * Also, we do support old OpenGL drivers where textures must have * power-of-two dimensions. If a non-power-of-two bitmap is created in * such a case, we use a texture with the next larger POT dimensions, * and just keep some unused padding space to the right/bottom of the * pixel data. * * Putting it all together, if we have an Allegro bitmap like this, * with Allegro's y-coordinates: * 0 ########### * 1 #111 # * 2 #222 # * 3 #333 # * 4 ########### * * Then the corresponding texture looks like this with OpenGL * y-coordinates (assuming we use an old driver which needs padding to * POT): * 7 ................ * 6 ................ * 5 ................ * 4 ###########..... * 3 #333 #..... * 2 #222 #..... * 1 #111 #..... * 0 ###########..... */ /* Conversion table from Allegro's pixel formats to corresponding OpenGL * formats. The three entries are: * - GL internal format: the number of color components in the texture * - GL pixel type: Specifies the data type of the pixel data. * - GL format: Specifies the format of the pixel data. * * GL does not support RGB_555 and BGR_555 directly so we use * GL_UNSIGNED_SHORT_1_5_5_5_REV when transferring pixel data, and ensure that * the alpha bit (the "1" component) is present by setting GL_ALPHA_BIAS. */ #if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE) static const int glformats[ALLEGRO_NUM_PIXEL_FORMATS][3] = { /* Skip pseudo formats */ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, /* Actual formats */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA}, /* ARGB_8888 */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBA_8888 */ {GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA}, /* ARGB_4444 */ {GL_RGB8, GL_UNSIGNED_BYTE, GL_BGR}, /* RGB_888 */ {GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB}, /* RGB_565 */ {GL_RGB5, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA}, /* RGB_555 - see above */ {GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA}, /* RGBA_5551 */ {GL_RGB5_A1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA}, /* ARGB_1555 */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_RGBA}, /* ABGR_8888 */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_RGBA}, /* XBGR_8888 */ {GL_RGB8, GL_UNSIGNED_BYTE, GL_RGB}, /* BGR_888 */ {GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, GL_RGB}, /* BGR_565 */ {GL_RGB5, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_RGBA}, /* BGR_555 - see above */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBX_8888 */ {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA}, /* XRGB_8888 */ {GL_RGBA32F_ARB, GL_FLOAT, GL_RGBA}, /* ABGR_F32 */ {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA}, /* ABGR_8888_LE */ {GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA} /* RGBA_4444 */ }; #else static const int glformats[ALLEGRO_NUM_PIXEL_FORMATS][3] = { /* Skip pseudo formats */ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, /* Actual formats */ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB}, /* RGB_565 */ {0, 0, 0}, {GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA}, /* RGBA_5551 */ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA}, /* ABGR_8888_LE */ {GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA} /* RGBA_4444 */ }; #endif static ALLEGRO_BITMAP_INTERFACE glbmp_vt; #define SWAP(type, x, y) {type temp = x; x = y; y = temp;} #define ERR(e) case e: return #e; static char const *error_string(GLenum e) { switch (e) { ERR(GL_NO_ERROR) ERR(GL_INVALID_ENUM) ERR(GL_INVALID_VALUE) ERR(GL_INVALID_OPERATION) ERR(GL_STACK_OVERFLOW) ERR(GL_STACK_UNDERFLOW) ERR(GL_OUT_OF_MEMORY) ERR(GL_INVALID_FRAMEBUFFER_OPERATION) } return "UNKNOWN"; } #undef ERR static INLINE void transform_vertex(float* x, float* y) { al_transform_coordinates(al_get_current_transform(), x, y); } static void draw_quad(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, int flags) { float tex_l, tex_t, tex_r, tex_b, w, h, true_w, true_h; float dw = sw, dh = sh; ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; ALLEGRO_OGL_BITMAP_VERTEX *verts; ALLEGRO_DISPLAY *disp = al_get_current_display(); (void)flags; if (disp->num_cache_vertices != 0 && ogl_bitmap->texture != disp->cache_texture) { disp->vt->flush_vertex_cache(disp); } disp->cache_texture = ogl_bitmap->texture; verts = disp->vt->prepare_vertex_cache(disp, 6); tex_l = ogl_bitmap->left; tex_r = ogl_bitmap->right; tex_t = ogl_bitmap->top; tex_b = ogl_bitmap->bottom; w = bitmap->w; h = bitmap->h; true_w = ogl_bitmap->true_w; true_h = ogl_bitmap->true_h; tex_l += sx / true_w; tex_t -= sy / true_h; tex_r -= (w - sx - sw) / true_w; tex_b += (h - sy - sh) / true_h; verts[0].x = 0; verts[0].y = dh; verts[0].tx = tex_l; verts[0].ty = tex_b; verts[0].r = tint.r; verts[0].g = tint.g; verts[0].b = tint.b; verts[0].a = tint.a; verts[1].x = 0; verts[1].y = 0; verts[1].tx = tex_l; verts[1].ty = tex_t; verts[1].r = tint.r; verts[1].g = tint.g; verts[1].b = tint.b; verts[1].a = tint.a; verts[2].x = dw; verts[2].y = dh; verts[2].tx = tex_r; verts[2].ty = tex_b; verts[2].r = tint.r; verts[2].g = tint.g; verts[2].b = tint.b; verts[2].a = tint.a; verts[4].x = dw; verts[4].y = 0; verts[4].tx = tex_r; verts[4].ty = tex_t; verts[4].r = tint.r; verts[4].g = tint.g; verts[4].b = tint.b; verts[4].a = tint.a; if (disp->cache_enabled) { /* If drawing is batched, we apply transformations manually. */ transform_vertex(&verts[0].x, &verts[0].y); transform_vertex(&verts[1].x, &verts[1].y); transform_vertex(&verts[2].x, &verts[2].y); transform_vertex(&verts[4].x, &verts[4].y); } verts[3] = verts[1]; verts[5] = verts[2]; if (!disp->cache_enabled) disp->vt->flush_vertex_cache(disp); } #undef SWAP static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, int flags) { // FIXME: hack // FIXME: need format conversion if they don't match ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_OGL *ogl_target; ALLEGRO_DISPLAY *disp = target->display; /* For sub-bitmaps */ if (target->parent) { target = target->parent; } ogl_target = (ALLEGRO_BITMAP_OGL *)target; if (!(bitmap->flags & ALLEGRO_MEMORY_BITMAP) && !bitmap->locked && !target->locked) { #if !defined ALLEGRO_GP2XWIZ ALLEGRO_BITMAP_OGL *ogl_source = (void *)bitmap; if (ogl_source->is_backbuffer) { /* Our source bitmap is the OpenGL backbuffer, the target * is an OpenGL texture. */ float xtrans, ytrans; /* Source and target cannot both be the back-buffer. */ ASSERT(!ogl_target->is_backbuffer); /* If we only translate, we can do this fast. */ if (_al_transform_is_translation(al_get_current_transform(), &xtrans, &ytrans)) { /* In general, we can't modify the texture while it's * FBO bound - so we temporarily disable the FBO. */ if (ogl_target->fbo_info) _al_ogl_set_target_bitmap(disp, bitmap); /* We need to do clipping because glCopyTexSubImage2D * fails otherwise. */ if (xtrans < target->cl) { sx -= xtrans - target->cl; sw += xtrans - target->cl; xtrans = target->cl; } if (ytrans < target->ct) { sy -= ytrans - target->ct; sh += ytrans - target->ct; ytrans = target->ct; } if (xtrans + sw > target->cr_excl) { sw = target->cr_excl - xtrans; } if (ytrans + sh > target->cb_excl) { sh = target->cb_excl - ytrans; } /* Note: Allegro 5.0.0 does not support blending or * tinting if the source bitmap is the screen. So it is * correct to ignore them here. */ glBindTexture(GL_TEXTURE_2D, ogl_target->texture); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xtrans, target->h - ytrans - sh, sx, bitmap->h - sy - sh, sw, sh); /* Fix up FBO again after the copy. */ if (ogl_target->fbo_info) _al_ogl_set_target_bitmap(disp, target); return; } /* Drawing a deformed backbuffer is not supported. */ ASSERT(0); } #elif defined ALLEGRO_GP2XWIZ /* FIXME: make this work somehow on Wiz */ return; #endif } if (disp->ogl_extras->opengl_target == ogl_target) { if (_al_opengl_set_blender(disp)) { draw_quad(bitmap, tint, sx, sy, sw, sh, flags); return; } } /* If all else fails, fall back to software implementation. */ _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); } /* Helper to get smallest fitting power of two. */ static int pot(int x) { int y = 1; while (y < x) y *= 2; return y; } // FIXME: need to do all the logic AllegroGL does, checking extensions, // proxy textures, formats, limits ... static bool ogl_upload_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; int w = bitmap->w; int h = bitmap->h; bool post_generate_mipmap = false; GLenum e; int filter; int gl_filters[] = { GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR }; if (ogl_bitmap->texture == 0) { glGenTextures(1, &ogl_bitmap->texture); } glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); e = glGetError(); if (e) { ALLEGRO_ERROR("glBindTexture for texture %d failed (%s).\n", ogl_bitmap->texture, error_string(e)); } /* Wrap, Min/Mag should always come before glTexImage2D so the texture is "complete" */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); filter = (bitmap->flags & ALLEGRO_MIPMAP) ? 2 : 0; if (bitmap->flags & ALLEGRO_MIN_LINEAR) { filter++; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filters[filter]); filter = 0; if (bitmap->flags & ALLEGRO_MAG_LINEAR) { filter++; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filters[filter]); if (post_generate_mipmap) { glGenerateMipmapEXT(GL_TEXTURE_2D); e = glGetError(); if (e) { ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", ogl_bitmap->texture, error_string(e)); } } // TODO: To support anisotropy, we would need an API for it. Something // like: // al_set_new_bitmap_option(ALLEGRO_ANISOTROPY, 16.0); #if 0 if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_texture_filter_anisotropic) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); } #endif if (bitmap->flags & ALLEGRO_MIPMAP) { /* If using FBOs, use glGenerateMipmapEXT instead of the GL_GENERATE_MIPMAP * texture parameter. GL_GENERATE_MIPMAP is deprecated in GL 3.0 so we * may want to use the new method in other cases as well. */ if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) { post_generate_mipmap = true; } else { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); } } #ifndef ALLEGRO_IPHONE glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); #endif if (bitmap->memory == NULL) { /* If there's unused space around the bitmap, we need to clear it * else linear filtering will cause artifacts from the random * data there. We also clear for floating point formats because * NaN values in the texture cause some blending modes to fail on * those pixels */ if (ogl_bitmap->true_w != bitmap->w || ogl_bitmap->true_h != bitmap->h || bitmap->format == ALLEGRO_PIXEL_FORMAT_ABGR_F32) { unsigned char *buf; #ifdef ALLEGRO_IPHONE { int pix_size = al_get_pixel_size(bitmap->format); buf = al_calloc(pix_size, ogl_bitmap->true_h * ogl_bitmap->true_w); glPixelStorei(GL_UNPACK_ALIGNMENT, pix_size); glTexImage2D(GL_TEXTURE_2D, 0, glformats[bitmap->format][0], ogl_bitmap->true_w, ogl_bitmap->true_h, 0, glformats[bitmap->format][2], glformats[bitmap->format][1], buf); } #else buf = al_calloc(ogl_bitmap->true_h, ogl_bitmap->true_w); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, glformats[bitmap->format][0], ogl_bitmap->true_w, ogl_bitmap->true_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf); #endif e = glGetError(); al_free(buf); } else { glTexImage2D(GL_TEXTURE_2D, 0, glformats[bitmap->format][0], ogl_bitmap->true_w, ogl_bitmap->true_h, 0, glformats[bitmap->format][2], glformats[bitmap->format][1], NULL); e = glGetError(); } } else { glPixelStorei(GL_UNPACK_ALIGNMENT, al_get_pixel_size(bitmap->format)); glTexImage2D(GL_TEXTURE_2D, 0, glformats[bitmap->format][0], ogl_bitmap->true_w, ogl_bitmap->true_h, 0, glformats[bitmap->format][2], glformats[bitmap->format][1], bitmap->memory); al_free(bitmap->memory); bitmap->memory = NULL; e = glGetError(); } #ifndef ALLEGRO_IPHONE glPopClientAttrib(); #endif if (e) { ALLEGRO_ERROR("glTexImage2D for format %s, size %dx%d failed (%s)\n", _al_pixel_format_name(bitmap->format), ogl_bitmap->true_w, ogl_bitmap->true_h, error_string(e)); glDeleteTextures(1, &ogl_bitmap->texture); ogl_bitmap->texture = 0; // FIXME: Should we convert it into a memory bitmap? Or if the size is // the problem try to use multiple textures? return false; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); filter = (bitmap->flags & ALLEGRO_MIPMAP) ? 2 : 0; if (bitmap->flags & ALLEGRO_MIN_LINEAR) { filter++; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filters[filter]); filter = 0; if (bitmap->flags & ALLEGRO_MAG_LINEAR) { filter++; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filters[filter]); // TODO: To support anisotropy, we would need an API for it. Something // like: // al_set_new_bitmap_option(ALLEGRO_ANISOTROPY, 16.0); #if 0 if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_texture_filter_anisotropic) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); } #endif if (post_generate_mipmap) { glGenerateMipmapEXT(GL_TEXTURE_2D); e = glGetError(); if (e) { ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", ogl_bitmap->texture, error_string(e)); } } ogl_bitmap->left = 0; ogl_bitmap->right = (float) w / ogl_bitmap->true_w; ogl_bitmap->top = (float) h / ogl_bitmap->true_h; ogl_bitmap->bottom = 0; return true; } static void ogl_update_clipping_rectangle(ALLEGRO_BITMAP *bitmap) { ALLEGRO_DISPLAY *ogl_disp = al_get_current_display(); ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (bitmap->parent) { ogl_bitmap = (ALLEGRO_BITMAP_OGL *)bitmap->parent; } if (ogl_disp->ogl_extras->opengl_target == ogl_bitmap) { _al_ogl_setup_bitmap_clipping(bitmap); } } static int ogl_pixel_alignment(int pixel_size) { /* Valid alignments are: 1, 2, 4, 8 bytes. */ switch (pixel_size) { case 1: case 2: case 4: case 8: return pixel_size; case 3: return 1; case 16: /* float32 */ return 4; default: ASSERT(false); return 4; } } static int ogl_pitch(int w, int pixel_size) { int pitch = w * pixel_size; return pitch; } static bool exactly_15bpp(int pixel_format) { return pixel_format == ALLEGRO_PIXEL_FORMAT_RGB_555 || pixel_format == ALLEGRO_PIXEL_FORMAT_BGR_555; } /* OpenGL cannot "lock" pixels, so instead we update our memory copy and * return a pointer into that. */ static ALLEGRO_LOCKED_REGION *ogl_lock_region(ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, int format, int flags) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; int pixel_size; int pixel_alignment; int pitch; ALLEGRO_DISPLAY *disp; ALLEGRO_DISPLAY *old_disp = NULL; GLint gl_y = bitmap->h - y - h; GLenum e; if (format == ALLEGRO_PIXEL_FORMAT_ANY) format = bitmap->format; disp = al_get_current_display(); format = _al_get_real_pixel_format(disp, format); pixel_size = al_get_pixel_size(format); pixel_alignment = ogl_pixel_alignment(pixel_size); if (bitmap->display->ogl_extras->is_shared == false && bitmap->display != disp) { old_disp = disp; _al_set_current_display_only(bitmap->display); } /* Set up the pixel store state. We will need to match it when unlocking. * There may be other pixel store state we should be setting. * See also pitfalls 7 & 8 from: * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ #ifndef ALLEGRO_IPHONE glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); #endif glPixelStorei(GL_PACK_ALIGNMENT, pixel_alignment); e = glGetError(); if (e) { ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n", pixel_alignment, error_string(e)); } if (ogl_bitmap->is_backbuffer) { ALLEGRO_DEBUG("Locking backbuffer\n"); pitch = ogl_pitch(w, pixel_size); ogl_bitmap->lock_buffer = al_malloc(pitch * h); if (!(flags & ALLEGRO_LOCK_WRITEONLY)) { glReadPixels(x, gl_y, w, h, glformats[format][2], glformats[format][1], ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", _al_pixel_format_name(format), error_string(e)); } } bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); } #if !defined ALLEGRO_GP2XWIZ else { if (flags & ALLEGRO_LOCK_WRITEONLY) { ALLEGRO_DEBUG("Locking non-backbuffer WRITEONLY\n"); pitch = ogl_pitch(w, pixel_size); ogl_bitmap->lock_buffer = al_malloc(pitch * h); bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); } else { ALLEGRO_DEBUG("Locking non-backbuffer READWRITE\n"); #ifdef ALLEGRO_IPHONE GLint current_fbo; unsigned char *tmpbuf; int tmp_pitch; /* Create an FBO if there isn't one. */ if (!ogl_bitmap->fbo_info) { ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); bitmap->locked = false; // hack :( al_set_target_bitmap(bitmap); // This creates the fbo bitmap->locked = true; al_restore_state(&state); } glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, ¤t_fbo); glBindFramebufferOES(GL_FRAMEBUFFER_OES, ogl_bitmap->fbo_info->fbo); e = glGetError(); if (e) { ALLEGRO_ERROR("glBindFramebufferOES failed.\n"); } pitch = ogl_pitch(w, pixel_size); ogl_bitmap->lock_buffer = al_malloc(pitch * h); tmp_pitch = ogl_pitch(w, 4); tmpbuf = al_malloc(tmp_pitch * h); /* NOTE: GLES 1.1 can only read 4 byte pixels, we have to convert */ glReadPixels(x, gl_y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpbuf); e = glGetError(); if (e) { ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", _al_pixel_format_name(format), error_string(e)); } _al_convert_bitmap_data( tmpbuf, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, tmp_pitch, ogl_bitmap->lock_buffer, format, pitch, 0, 0, 0, 0, w, h); al_free(tmpbuf); glBindFramebufferOES(GL_FRAMEBUFFER_OES, current_fbo); bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); #else // FIXME: Using glGetTexImage means we always read the complete // texture - even when only a single pixel is locked. Likely // using FBO and glReadPixels to just read the locked part // would be faster. pitch = ogl_pitch(ogl_bitmap->true_w, pixel_size); ogl_bitmap->lock_buffer = al_malloc(pitch * ogl_bitmap->true_h); glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); glGetTexImage(GL_TEXTURE_2D, 0, glformats[format][2], glformats[format][1], ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glGetTexImage for format %s failed (%s).\n", _al_pixel_format_name(format), error_string(e)); } bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (gl_y + h - 1) + pixel_size * x; #endif } } #else else { if (flags & ALLEGRO_LOCK_WRITEONLY) { pitch = ogl_pitch(w, pixel_size); ogl_bitmap->lock_buffer = al_malloc(pitch * h); bitmap->locked_region.data = ogl_bitmap->lock_buffer; pitch = -pitch; } else { /* FIXME: implement */ return NULL; } } #endif #ifndef ALLEGRO_IPHONE glPopClientAttrib(); #endif bitmap->locked_region.format = format; bitmap->locked_region.pitch = -pitch; bitmap->locked_region.pixel_size = pixel_size; if (old_disp) { _al_set_current_display_only(old_disp); } return &bitmap->locked_region; } /* Synchronizes the texture back to the (possibly modified) bitmap data. */ static void ogl_unlock_region(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; const int lock_format = bitmap->locked_region.format; ALLEGRO_DISPLAY *disp; ALLEGRO_DISPLAY *old_disp = NULL; GLenum e; GLint gl_y = bitmap->h - bitmap->lock_y - bitmap->lock_h; int orig_format; #ifdef ALLEGRO_IPHONE int orig_pixel_size; #endif int lock_pixel_size; int pixel_alignment; bool biased_alpha = false; (void)e; if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY) { goto Done; } disp = al_get_current_display(); orig_format = _al_get_real_pixel_format(disp, bitmap->format); /* Not used in all code paths. */ (void)orig_format; if (bitmap->display->ogl_extras->is_shared == false && bitmap->display != disp) { old_disp = disp; _al_set_current_display_only(bitmap->display); } /* Keep this in sync with ogl_lock_region. */ #ifndef ALLEGRO_IPHONE glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); #endif lock_pixel_size = al_get_pixel_size(lock_format); pixel_alignment = ogl_pixel_alignment(lock_pixel_size); glPixelStorei(GL_UNPACK_ALIGNMENT, pixel_alignment); e = glGetError(); if (e) { ALLEGRO_ERROR("glPixelStorei(GL_UNPACK_ALIGNMENT, %d) failed (%s).\n", pixel_alignment, error_string(e)); } if (exactly_15bpp(lock_format)) { /* OpenGL does not support 15-bpp internal format without an alpha, * so when storing such data we must ensure the alpha bit is set. */ #ifndef ALLEGRO_IPHONE glPixelTransferi(GL_ALPHA_BIAS, 1); biased_alpha = true; #endif } #if !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE if (ogl_bitmap->is_backbuffer) { bool popmatrix = false; ALLEGRO_DEBUG("Unlocking backbuffer\n"); /* glWindowPos2i may not be available. */ if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_1_4) { glWindowPos2i(bitmap->lock_x, gl_y); } else { /* glRasterPos is affected by the current modelview and projection * matrices (so maybe we actually need to reset both of them?). * The coordinate is also clipped; the small offset was required to * prevent it being culled on one of my machines. --pw * * Consider using glWindowPos2fMESAemulate from: * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ */ glPushMatrix(); glLoadIdentity(); glRasterPos2f(bitmap->lock_x, bitmap->lock_y + bitmap->lock_h - 1e-4f); popmatrix = true; } glDisable(GL_BLEND); glDrawPixels(bitmap->lock_w, bitmap->lock_h, glformats[lock_format][2], glformats[lock_format][1], ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glDrawPixels for format %s failed (%s).\n", _al_pixel_format_name(lock_format), error_string(e)); } if (popmatrix) { glPopMatrix(); } } else { unsigned char *start_ptr; // FIXME: would FBO and glDrawPixels be any faster? glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); if (bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY) { ALLEGRO_DEBUG("Unlocking non-backbuffer WRITEONLY\n"); start_ptr = ogl_bitmap->lock_buffer; } else { ALLEGRO_DEBUG("Unlocking non-backbuffer READWRITE\n"); glPixelStorei(GL_UNPACK_ROW_LENGTH, ogl_bitmap->true_w); start_ptr = (unsigned char *)bitmap->locked_region.data + (bitmap->lock_h - 1) * bitmap->locked_region.pitch; } glTexSubImage2D(GL_TEXTURE_2D, 0, bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h, glformats[lock_format][2], glformats[lock_format][1], start_ptr); e = glGetError(); if (e) { ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n", _al_pixel_format_name(lock_format), error_string(e)); } if (bitmap->flags & ALLEGRO_MIPMAP) { /* If using FBOs, we need to regenerate mipmaps explicitly now. */ if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) { glGenerateMipmapEXT(GL_TEXTURE_2D); e = glGetError(); if (e) { ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", ogl_bitmap->texture, error_string(e)); } } } } #else /* ALLEGRO_GP2XWIZ or ALLEGRO_IPHONE */ orig_pixel_size = al_get_pixel_size(orig_format); if (ogl_bitmap->is_backbuffer) { ALLEGRO_DEBUG("Unlocking backbuffer\n"); GLuint tmp_tex; glGenTextures(1, &tmp_tex); glBindTexture(GL_TEXTURE_2D, tmp_tex); glTexImage2D(GL_TEXTURE_2D, 0, glformats[lock_format][0], bitmap->lock_w, bitmap->lock_h, 0, glformats[lock_format][2], glformats[lock_format][1], ogl_bitmap->lock_buffer); e = glGetError(); if (e) { int printf(const char *, ...); printf("glTexImage2D failed: %d\n", e); } glDrawTexiOES(bitmap->lock_x, bitmap->lock_y, 0, bitmap->lock_w, bitmap->lock_h); e = glGetError(); if (e) { int printf(const char *, ...); printf("glDrawTexiOES failed: %d\n", e); } glDeleteTextures(1, &tmp_tex); } else { ALLEGRO_DEBUG("Unlocking non-backbuffer\n"); glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); if (bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY) { int dst_pitch = bitmap->lock_w * orig_pixel_size; unsigned char *tmpbuf = al_malloc(dst_pitch * bitmap->lock_h); _al_convert_bitmap_data( ogl_bitmap->lock_buffer, bitmap->locked_region.format, -bitmap->locked_region.pitch, tmpbuf, orig_format, dst_pitch, 0, 0, 0, 0, bitmap->lock_w, bitmap->lock_h); #ifdef ALLEGRO_IPHONE glPixelStorei(GL_UNPACK_ALIGNMENT, ogl_pixel_alignment(orig_pixel_size)); glTexSubImage2D(GL_TEXTURE_2D, 0, bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h, glformats[orig_format][2], glformats[orig_format][1], tmpbuf); al_free(tmpbuf); e = glGetError(); if (e) { ALLEGRO_ERROR("glTexSubImage2D for format %d failed (%s).\n", lock_format, error_string(e)); } #endif } else { glPixelStorei(GL_UNPACK_ALIGNMENT, ogl_pixel_alignment(orig_pixel_size)); glTexSubImage2D(GL_TEXTURE_2D, 0, bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h, glformats[lock_format][2], glformats[lock_format][1], ogl_bitmap->lock_buffer); e = glGetError(); if (e) { GLint tex_internalformat; ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n", _al_pixel_format_name(lock_format), error_string(e)); #ifndef ALLEGRO_IPHONE glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &tex_internalformat); ALLEGRO_DEBUG("x/y/w/h: %d/%d/%d/%d, internal format: %d\n", bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h, tex_internalformat); #else (void)tex_internalformat; ALLEGRO_DEBUG("x/y/w/h: %d/%d/%d/%d\n", bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h); #endif } } } #endif if (biased_alpha) { #ifndef ALLEGRO_IPHONE glPixelTransferi(GL_ALPHA_BIAS, 0); #endif } #ifndef ALLEGRO_IPHONE glPopClientAttrib(); #endif if (old_disp) { _al_set_current_display_only(old_disp); } Done: al_free(ogl_bitmap->lock_buffer); ogl_bitmap->lock_buffer = NULL; } static void ogl_destroy_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; ALLEGRO_DISPLAY *disp; ALLEGRO_DISPLAY *old_disp = NULL; disp = al_get_current_display(); if (bitmap->display->ogl_extras->is_shared == false && bitmap->display != disp) { old_disp = disp; _al_set_current_display_only(bitmap->display); } al_remove_opengl_fbo(bitmap); if (ogl_bitmap->texture) { glDeleteTextures(1, &ogl_bitmap->texture); ogl_bitmap->texture = 0; } if (old_disp) { _al_set_current_display_only(old_disp); } } /* Obtain a reference to this driver. */ static ALLEGRO_BITMAP_INTERFACE *ogl_bitmap_driver(void) { if (glbmp_vt.draw_bitmap_region) { return &glbmp_vt; } glbmp_vt.draw_bitmap_region = ogl_draw_bitmap_region; glbmp_vt.upload_bitmap = ogl_upload_bitmap; glbmp_vt.update_clipping_rectangle = ogl_update_clipping_rectangle; glbmp_vt.destroy_bitmap = ogl_destroy_bitmap; glbmp_vt.lock_region = ogl_lock_region; glbmp_vt.unlock_region = ogl_unlock_region; return &glbmp_vt; } ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h) { ALLEGRO_BITMAP_OGL *bitmap; int format = al_get_new_bitmap_format(); const int flags = al_get_new_bitmap_flags(); int true_w; int true_h; int pitch; (void)d; ALLEGRO_DEBUG("Creating OpenGL bitmap\n"); #if !defined ALLEGRO_GP2XWIZ if (d->ogl_extras->extension_list->ALLEGRO_GL_ARB_texture_non_power_of_two) { true_w = w; true_h = h; } else { true_w = pot(w); true_h = pot(h); } #else true_w = pot(w); true_h = pot(h); #endif /* FBOs are 16x16 minimum on iPhone, this is a workaround */ #ifdef ALLEGRO_IPHONE if (true_w < 16) true_w = 16; if (true_h < 16) true_h = 16; #endif ALLEGRO_DEBUG("Using dimensions: %d %d\n", true_w, true_h); #if !defined ALLEGRO_GP2XWIZ format = _al_get_real_pixel_format(d, format); #else if (format != ALLEGRO_PIXEL_FORMAT_RGB_565 && format != ALLEGRO_PIXEL_FORMAT_RGBA_4444) format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; #endif ALLEGRO_DEBUG("Chose format %s for OpenGL bitmap\n", _al_pixel_format_name(format)); ASSERT(_al_pixel_format_is_real(format)); pitch = true_w * al_get_pixel_size(format); bitmap = al_malloc(sizeof *bitmap); ASSERT(bitmap); memset(bitmap, 0, sizeof *bitmap); bitmap->bitmap.size = sizeof *bitmap; bitmap->bitmap.vt = ogl_bitmap_driver(); bitmap->bitmap.w = w; bitmap->bitmap.h = h; bitmap->bitmap.pitch = pitch; bitmap->bitmap.format = format; bitmap->bitmap.flags = flags | _ALLEGRO_INTERNAL_OPENGL; bitmap->bitmap.cl = 0; bitmap->bitmap.ct = 0; bitmap->bitmap.cr_excl = w; bitmap->bitmap.cb_excl = h; /* Back and front buffers should share a transform, which they do * because our OpenGL driver returns the same pointer for both. */ al_identity_transform(&bitmap->bitmap.transform); bitmap->true_w = true_w; bitmap->true_h = true_h; #if !defined(ALLEGRO_IPHONE) && !defined(ALLEGRO_GP2XWIZ) bitmap->bitmap.memory = NULL; #else /* iPhone/Wiz ports still expect the buffer to be present. */ { size_t bytes = pitch * true_h; /* We never allow un-initialized memory for OpenGL bitmaps, if it * is uploaded to a floating point texture it can lead to Inf and * NaN values which break all subsequent blending. */ bitmap->bitmap.memory = al_calloc(1, bytes); } #endif return &bitmap->bitmap; } ALLEGRO_BITMAP *_al_ogl_create_sub_bitmap(ALLEGRO_DISPLAY *d, ALLEGRO_BITMAP *parent, int x, int y, int w, int h) { ALLEGRO_BITMAP_OGL* ogl_bmp; ALLEGRO_BITMAP_OGL* ogl_parent = (void*)parent; (void)d; ogl_bmp = al_malloc(sizeof *ogl_bmp); memset(ogl_bmp, 0, sizeof *ogl_bmp); ogl_bmp->true_w = ogl_parent->true_w; ogl_bmp->true_h = ogl_parent->true_h; ogl_bmp->texture = ogl_parent->texture; #if !defined ALLEGRO_GP2XWIZ ogl_bmp->fbo_info = ogl_parent->fbo_info; #endif ogl_bmp->left = x / (float)ogl_parent->true_w; ogl_bmp->right = (x + w) / (float)ogl_parent->true_w; ogl_bmp->top = (parent->h - y) / (float)ogl_parent->true_h; ogl_bmp->bottom = (parent->h - y - h) / (float)ogl_parent->true_h; ogl_bmp->is_backbuffer = ogl_parent->is_backbuffer; ogl_bmp->bitmap.vt = parent->vt; ogl_bmp->bitmap.flags |= _ALLEGRO_INTERNAL_OPENGL; return (void*)ogl_bmp; } /* Function: al_get_opengl_texture */ GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL)) return 0; return ogl_bitmap->texture; } /* Function: al_remove_opengl_fbo */ void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL)) return; if (!ogl_bitmap->fbo_info) return; ASSERT(ogl_bitmap->fbo_info->fbo_state > FBO_INFO_UNUSED); ASSERT(ogl_bitmap->fbo_info->fbo != 0); ALLEGRO_DEBUG("Deleting FBO: %u\n", ogl_bitmap->fbo_info->fbo); #if !defined ALLEGRO_GP2XWIZ && !defined ALLEGRO_IPHONE glDeleteFramebuffersEXT(1, &ogl_bitmap->fbo_info->fbo); #elif defined ALLEGRO_IPHONE glDeleteFramebuffersOES(1, &ogl_bitmap->fbo_info->fbo); #endif ogl_bitmap->fbo_info->fbo = 0; if (ogl_bitmap->fbo_info->fbo_state == FBO_INFO_PERSISTENT) { al_free(ogl_bitmap->fbo_info); } else { _al_ogl_reset_fbo_info(ogl_bitmap->fbo_info); } ogl_bitmap->fbo_info = NULL; } /* Function: al_get_opengl_fbo */ GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap) { #if !defined ALLEGRO_GP2XWIZ ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL)) return 0; if (!ogl_bitmap->fbo_info) { if (!_al_ogl_create_persistent_fbo(bitmap)) { return 0; } } if (ogl_bitmap->fbo_info->fbo_state == FBO_INFO_TRANSIENT) { ogl_bitmap->fbo_info = _al_ogl_persist_fbo(bitmap->display, ogl_bitmap->fbo_info); } return ogl_bitmap->fbo_info->fbo; #else (void)bitmap; return 0; #endif } /* Function: al_get_opengl_texture_size */ void al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h) { /* The designers of OpenGL ES 1.0 forgot to add a function to query * texture sizes, so this will be the only way there to get the texture * size. On normal OpenGL also glGetTexLevelParameter could be used. */ ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap; if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL)) { *w = 0; *h = 0; return; } *w = ogl_bitmap->true_w; *h = ogl_bitmap->true_h; } /* Function: al_get_opengl_texture_position */ void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) { ASSERT(bitmap); ASSERT(u); ASSERT(v); *u = bitmap->xofs; *v = bitmap->yofs; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/tls.c0000644000175000001440000004211312146027721014146 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread local storage. * * By Trent Gamblin. * */ /* FIXME: * * There are several ways to get thread local storage: * * 1. pthreads. * 2. __thread keyword in gcc. * 3. __declspec(thread) in MSVC. * 4. TLS API under Windows. * * Since pthreads is available from the system everywhere except in * Windows, this is the only case which is problematic. It appears * that except for old mingw versions (before gcc 4.2) we can simply * use __thread, and for MSVC we can always use __declspec(thread): * * However there also is a WANT_TLS configuration variable which is on * by default and forces use of the TLS API instead. At the same time, * the implementation using the TLS API in this file does not work * with static linking. Someone should either completely remove * WANT_TLS, or fix the static linking case... */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_file.h" #include "allegro5/internal/aintern_fshook.h" #include "allegro5/internal/aintern_tls.h" #if defined(ALLEGRO_MINGW32) && !defined(ALLEGRO_CFG_DLL_TLS) /* * MinGW < 4.2.1 doesn't have builtin thread local storage, so we * must use the Windows API. */ #if __GNUC__ < 4 #define ALLEGRO_CFG_DLL_TLS #elif __GNUC__ == 4 && __GNUC_MINOR__ < 2 #define ALLEGRO_CFG_DLL_TLS #elif __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ < 1 #define ALLEGRO_CFG_DLL_TLS #endif #endif /* Thread local storage for various per-thread state. */ typedef struct thread_local_state { /* New display parameters */ int new_display_flags; int new_display_refresh_rate; int new_display_adapter; int new_window_x; int new_window_y; ALLEGRO_EXTRA_DISPLAY_SETTINGS new_display_settings; /* Current display */ ALLEGRO_DISPLAY *current_display; /* Target bitmap */ ALLEGRO_BITMAP *target_bitmap; /* Blender */ ALLEGRO_BLENDER current_blender; /* Bitmap parameters */ int new_bitmap_format; int new_bitmap_flags; /* Files */ const ALLEGRO_FILE_INTERFACE *new_file_interface; const ALLEGRO_FS_INTERFACE *fs_interface; /* Error code */ int allegro_errno; /* Destructor ownership count */ int dtor_owner_count; } thread_local_state; typedef struct INTERNAL_STATE { thread_local_state tls; ALLEGRO_BLENDER stored_blender; ALLEGRO_TRANSFORM stored_transform; int flags; } INTERNAL_STATE; ALLEGRO_STATIC_ASSERT(tls, sizeof(ALLEGRO_STATE) > sizeof(INTERNAL_STATE)); static void initialize_blender(ALLEGRO_BLENDER *b) { b->blend_op = ALLEGRO_ADD; b->blend_source = ALLEGRO_ONE, b->blend_dest = ALLEGRO_INVERSE_ALPHA; b->blend_alpha_op = ALLEGRO_ADD; b->blend_alpha_source = ALLEGRO_ONE; b->blend_alpha_dest = ALLEGRO_INVERSE_ALPHA; } static void initialize_tls_values(thread_local_state *tls) { memset(tls, 0, sizeof *tls); tls->new_display_adapter = ALLEGRO_DEFAULT_DISPLAY_ADAPTER; tls->new_window_x = INT_MAX; tls->new_window_y = INT_MAX; initialize_blender(&tls->current_blender); tls->new_bitmap_flags = ALLEGRO_VIDEO_BITMAP; tls->new_bitmap_format = ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA; tls->new_file_interface = &_al_file_interface_stdio; tls->fs_interface = &_al_fs_interface_stdio; _al_fill_display_settings(&tls->new_display_settings); } // FIXME: The TLS implementation below only works for dynamic linking // right now - instead of using DllMain we should simply initialize // on first request. #ifdef ALLEGRO_STATICLINK #undef ALLEGRO_CFG_DLL_TLS #endif #if defined(ALLEGRO_CFG_DLL_TLS) #include "tls_dll.inc" #elif defined(ALLEGRO_MACOSX) || defined(ALLEGRO_IPHONE) #include "tls_pthread.inc" #else #include "tls_native.inc" #endif void _al_set_new_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; memmove(&tls->new_display_settings, settings, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); } ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_get_new_display_settings(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return &tls->new_display_settings; } /* Function: al_set_new_display_flags */ void al_set_new_display_flags(int flags) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_display_flags = flags; } /* Function: al_get_new_display_flags */ int al_get_new_display_flags(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->new_display_flags; } /* Function: al_set_new_display_refresh_rate */ void al_set_new_display_refresh_rate(int refresh_rate) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_display_refresh_rate = refresh_rate; } /* Function: al_get_new_display_refresh_rate */ int al_get_new_display_refresh_rate(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->new_display_refresh_rate; } /* Function: al_set_new_display_adapter */ void al_set_new_display_adapter(int adapter) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; if (adapter < 0) { tls->new_display_adapter = ALLEGRO_DEFAULT_DISPLAY_ADAPTER; } tls->new_display_adapter = adapter; } /* Function: al_get_new_display_adapter */ int al_get_new_display_adapter(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return ALLEGRO_DEFAULT_DISPLAY_ADAPTER; return tls->new_display_adapter; } /* Function: al_set_new_window_position */ void al_set_new_window_position(int x, int y) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_window_x = x; tls->new_window_y = y; } /* Function: al_get_new_window_position */ void al_get_new_window_position(int *x, int *y) { thread_local_state *tls; int new_window_x = INT_MAX; int new_window_y = INT_MAX; if ((tls = tls_get()) != NULL) { new_window_x = tls->new_window_x; new_window_y = tls->new_window_y; } if (x) *x = new_window_x; if (y) *y = new_window_y; } /* Make the given display current, without changing the target bitmap. * This is used internally to change the current display transiently. */ bool _al_set_current_display_only(ALLEGRO_DISPLAY *display) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return false; if (tls->current_display && tls->current_display->vt && tls->current_display->vt->unset_current_display) { tls->current_display->vt->unset_current_display(tls->current_display); tls->current_display = NULL; } if (display && display->vt && display->vt->set_current_display) { if (!display->vt->set_current_display(display)) return false; } tls->current_display = display; return true; } /* Function: al_get_current_display */ ALLEGRO_DISPLAY *al_get_current_display(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return NULL; return tls->current_display; } /* Function: al_set_target_bitmap */ void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap) { thread_local_state *tls; ALLEGRO_DISPLAY *old_display; ALLEGRO_DISPLAY *new_display; ASSERT(!al_is_bitmap_drawing_held()); if ((tls = tls_get()) == NULL) return; old_display = tls->current_display; if (bitmap == NULL) { /* Explicitly releasing the current rendering context. */ new_display = NULL; } else if (bitmap->flags & ALLEGRO_MEMORY_BITMAP) { /* Setting a memory bitmap doesn't change the rendering context. */ new_display = old_display; } else { new_display = bitmap->display; } /* Change the rendering context if necessary. */ if (old_display != new_display) { if (old_display && old_display->vt && old_display->vt->unset_current_display) { old_display->vt->unset_current_display(old_display); } tls->current_display = new_display; if (new_display && new_display->vt && new_display->vt->set_current_display) { new_display->vt->set_current_display(new_display); } } /* Change the target bitmap itself. */ tls->target_bitmap = bitmap; if (bitmap && !(bitmap->flags & ALLEGRO_MEMORY_BITMAP) && new_display && new_display->vt && new_display->vt->set_target_bitmap) { new_display->vt->set_target_bitmap(new_display, bitmap); new_display->vt->update_transformation(new_display, bitmap); } } /* Function: al_set_target_backbuffer */ void al_set_target_backbuffer(ALLEGRO_DISPLAY *display) { al_set_target_bitmap(al_get_backbuffer(display)); } /* Function: al_get_target_bitmap */ ALLEGRO_BITMAP *al_get_target_bitmap(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->target_bitmap; } /* Function: al_set_blender */ void al_set_blender(int op, int src, int dst) { al_set_separate_blender(op, src, dst, op, src, dst); } /* Function: al_set_separate_blender */ void al_set_separate_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst) { thread_local_state *tls; ALLEGRO_BLENDER *b; ASSERT(op >= 0 && op < ALLEGRO_NUM_BLEND_OPERATIONS); ASSERT(src >= 0 && src < ALLEGRO_NUM_BLEND_MODES); ASSERT(dst >= 0 && src < ALLEGRO_NUM_BLEND_MODES); ASSERT(alpha_op >= 0 && alpha_op < ALLEGRO_NUM_BLEND_OPERATIONS); ASSERT(alpha_src >= 0 && alpha_src < ALLEGRO_NUM_BLEND_MODES); ASSERT(alpha_dst >= 0 && alpha_dst < ALLEGRO_NUM_BLEND_MODES); if ((tls = tls_get()) == NULL) return; b = &tls->current_blender; b->blend_op = op; b->blend_source = src; b->blend_dest = dst; b->blend_alpha_op = alpha_op; b->blend_alpha_source = alpha_src; b->blend_alpha_dest = alpha_dst; } /* Function: al_get_blender */ void al_get_blender(int *op, int *src, int *dst) { al_get_separate_blender(op, src, dst, NULL, NULL, NULL); } /* Function: al_get_separate_blender */ void al_get_separate_blender(int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst) { thread_local_state *tls; ALLEGRO_BLENDER *b; if ((tls = tls_get()) == NULL) return; b = &tls->current_blender; if (op) *op = b->blend_op; if (src) *src = b->blend_source; if (dst) *dst = b->blend_dest; if (alpha_op) *alpha_op = b->blend_alpha_op; if (alpha_src) *alpha_src = b->blend_alpha_source; if (alpha_dst) *alpha_dst = b->blend_alpha_dest; } /* Function: al_set_new_bitmap_format */ void al_set_new_bitmap_format(int format) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_bitmap_format = format; } /* Function: al_set_new_bitmap_flags */ void al_set_new_bitmap_flags(int flags) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; /* Assume ALLEGRO_VIDEO_BITMAP if ALLEGRO_MEMORY_BITMAP is not set. */ if (!(flags & ALLEGRO_MEMORY_BITMAP)) flags |= ALLEGRO_VIDEO_BITMAP; tls->new_bitmap_flags = flags; } /* Function: al_add_new_bitmap_flag */ void al_add_new_bitmap_flag(int flag) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_bitmap_flags |= flag; } /* Function: al_get_new_bitmap_format */ int al_get_new_bitmap_format(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->new_bitmap_format; } /* Function: al_get_new_bitmap_flags */ int al_get_new_bitmap_flags(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->new_bitmap_flags; } #define _STORE(x) stored->tls.x = tls->x; /* Function: al_store_state */ void al_store_state(ALLEGRO_STATE *state, int flags) { thread_local_state *tls; INTERNAL_STATE *stored; if ((tls = tls_get()) == NULL) return; stored = (void *)state; stored->flags = flags; if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) { _STORE(new_display_flags); _STORE(new_display_refresh_rate); _STORE(new_display_adapter); _STORE(new_window_x); _STORE(new_window_y); _STORE(new_display_settings); } if (flags & ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) { _STORE(new_bitmap_format); _STORE(new_bitmap_flags); } if (flags & ALLEGRO_STATE_DISPLAY) { _STORE(current_display); } if (flags & ALLEGRO_STATE_TARGET_BITMAP) { _STORE(target_bitmap); } if (flags & ALLEGRO_STATE_BLENDER) { stored->stored_blender = tls->current_blender; } if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) { _STORE(new_file_interface); _STORE(fs_interface); } if (flags & ALLEGRO_STATE_TRANSFORM) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); if (!target) al_identity_transform(&stored->stored_transform); else stored->stored_transform = target->transform; } } #undef _STORE #define _STORE(x) tls->x = stored->tls.x; /* Function: al_restore_state */ void al_restore_state(ALLEGRO_STATE const *state) { thread_local_state *tls; INTERNAL_STATE *stored; int flags; if ((tls = tls_get()) == NULL) return; stored = (void *)state; flags = stored->flags; if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) { _STORE(new_display_flags); _STORE(new_display_refresh_rate); _STORE(new_display_adapter); _STORE(new_window_x); _STORE(new_window_y); _STORE(new_display_settings); } if (flags & ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) { _STORE(new_bitmap_format); _STORE(new_bitmap_flags); } if (flags & ALLEGRO_STATE_DISPLAY) { _STORE(current_display); _al_set_current_display_only(tls->current_display); } if (flags & ALLEGRO_STATE_TARGET_BITMAP) { _STORE(target_bitmap); al_set_target_bitmap(tls->target_bitmap); } if (flags & ALLEGRO_STATE_BLENDER) { tls->current_blender = stored->stored_blender; } if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) { _STORE(new_file_interface); _STORE(fs_interface); } if (flags & ALLEGRO_STATE_TRANSFORM) { ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); if (bitmap) al_use_transform(&stored->stored_transform); } } #undef _STORE /* Function: al_get_new_file_interface * FIXME: added a work-around for the situation where TLS has not yet been * initialised when this function is called. This may happen if Allegro * tries to load a configuration file before the system has been * initialised. Should probably rethink the logic here... */ const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return &_al_file_interface_stdio; /* FIXME: this situation should never arise because tls_ has the stdio * interface set as a default, but it arises on OS X if * pthread_getspecific() is called before pthreads_thread_init()... */ if (tls->new_file_interface) return tls->new_file_interface; else return &_al_file_interface_stdio; } /* Function: al_set_new_file_interface */ void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->new_file_interface = file_interface; } /* Function: al_get_fs_interface */ const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return &_al_fs_interface_stdio; if (tls->fs_interface) return tls->fs_interface; else return &_al_fs_interface_stdio; } /* Function: al_set_fs_interface */ void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->fs_interface = fs_interface; } /* Function: al_set_standard_fs_interface */ void al_set_standard_fs_interface(void) { al_set_fs_interface(&_al_fs_interface_stdio); } /* Function: al_get_errno */ int al_get_errno(void) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return 0; return tls->allegro_errno; } /* Function: al_set_errno */ void al_set_errno(int errnum) { thread_local_state *tls; if ((tls = tls_get()) == NULL) return; tls->allegro_errno = errnum; } int *_al_tls_get_dtor_owner_count(void) { thread_local_state *tls; tls = tls_get(); return &tls->dtor_owner_count; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/fshook_win.inc0000644000175000001440000001501312063270027016035 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Helper routines for fshook implementation on Windows. * * See LICENSE.txt for copyright information. */ #if defined(ALLEGRO_MSVC) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* * MSVC is missing the whole dirent.h so we implement the bits we need here. * The following block is copied from dirent.c from MinGW Runtime sources * version 3.15.1 with minor modifications. The code was public domain. */ #ifdef _UNICODE #define _TDIR _WDIR #define _tdirent _wdirent #define _topendir _wopendir #define _tclosedir _wclosedir #define _treaddir _wreaddir #else #error _UNICODE not defined #endif #define SUFFIX _T("*") #define SLASH _T("\\") struct _wdirent { long d_ino; /* Always zero. */ unsigned short d_reclen; /* Always zero. */ unsigned short d_namlen; /* Length of name in d_name. */ wchar_t d_name[FILENAME_MAX]; /* File name. */ }; /* * This is an internal data structure. Good programmers will not use it * except as an argument to one of the functions below. * dd_stat field is now int (was short in older versions). */ typedef struct { /* disk transfer area for this dir */ struct _wfinddata_t dd_dta; /* dirent struct to return from dir (NOTE: this makes this thread * safe as long as only one thread uses a particular DIR struct at * a time) */ struct _wdirent dd_dir; /* _findnext handle */ intptr_t dd_handle; /* * Status of search: * 0 = not started yet (next entry to read is first entry) * -1 = off the end * positive = 0 based index of next entry */ int dd_stat; /* given path for dir with search pattern (struct is extended) */ wchar_t dd_name[1]; } _WDIR; /* * opendir * * Returns a pointer to a DIR structure appropriately filled in to begin * searching a directory. */ static _TDIR *_topendir(const _TCHAR *szPath) { _TDIR *nd; unsigned int rc; _TCHAR szFullPath[MAX_PATH]; errno = 0; if (!szPath) { errno = EFAULT; return (_TDIR *) 0; } if (szPath[0] == _T('\0')) { errno = ENOTDIR; return (_TDIR*) 0; } /* Attempt to determine if the given path really is a directory. */ rc = GetFileAttributes(szPath); if (rc == (unsigned int)-1) { /* call GetLastError for more error info */ errno = ENOENT; return (_TDIR*) 0; } if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) { /* Error, entry exists but not a directory. */ errno = ENOTDIR; return (_TDIR*) 0; } /* Make an absolute pathname. */ _tfullpath(szFullPath, szPath, MAX_PATH); /* Allocate enough space to store DIR structure and the complete * directory path given. */ nd = (_TDIR *) al_malloc(sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen(SLASH) + _tcslen(SUFFIX) + 1) * sizeof(_TCHAR)); if (!nd) { /* Error, out of memory. */ errno = ENOMEM; return (_TDIR*) 0; } /* Create the search expression. */ _tcscpy(nd->dd_name, szFullPath); /* Add on a slash if the path does not end with one. */ if (nd->dd_name[0] != _T('\0') && _tcsrchr(nd->dd_name, _T('/')) != nd->dd_name + _tcslen(nd->dd_name) - 1 && _tcsrchr(nd->dd_name, _T('\\')) != nd->dd_name + _tcslen(nd->dd_name) - 1) { _tcscat(nd->dd_name, SLASH); } /* Add on the search pattern */ _tcscat(nd->dd_name, SUFFIX); /* Initialize handle to -1 so that a premature closedir doesn't try * to call _findclose on it. */ nd->dd_handle = -1; /* Initialize the status. */ nd->dd_stat = 0; /* Initialize the dirent structure. ino and reclen are invalid under * Win32, and name simply points at the appropriate part of the * findfirst_t structure. */ nd->dd_dir.d_ino = 0; nd->dd_dir.d_reclen = 0; nd->dd_dir.d_namlen = 0; memset(nd->dd_dir.d_name, 0, FILENAME_MAX); return nd; } /* * readdir * * Return a pointer to a dirent structure filled with the information on the * next entry in the directory. */ static struct _tdirent* _treaddir(_TDIR* dirp) { errno = 0; /* Check for valid DIR struct. */ if (!dirp) { errno = EFAULT; return (struct _tdirent*) 0; } if (dirp->dd_stat < 0) { /* We have already returned all files in the directory * (or the structure has an invalid dd_stat). */ return (struct _tdirent*) 0; } else if (dirp->dd_stat == 0) { /* We haven't started the search yet. */ /* Start the search */ dirp->dd_handle = _tfindfirst(dirp->dd_name, &(dirp->dd_dta)); if (dirp->dd_handle == -1) { /* Whoops! Seems there are no files in that * directory. */ dirp->dd_stat = -1; } else { dirp->dd_stat = 1; } } else { /* Get the next search entry. */ if (_tfindnext(dirp->dd_handle, &(dirp->dd_dta))) { /* We are off the end or otherwise error. _findnext sets errno to ENOENT if no more file Undo this. */ DWORD winerr = GetLastError(); if (winerr == ERROR_NO_MORE_FILES) errno = 0; _findclose(dirp->dd_handle); dirp->dd_handle = -1; dirp->dd_stat = -1; } else { /* Update the status to indicate the correct * number. */ dirp->dd_stat++; } } if (dirp->dd_stat > 0) { /* Successfully got an entry. Everything about the file is * already appropriately filled in except the length of the * file name. */ dirp->dd_dir.d_namlen = _tcslen(dirp->dd_dta.name); _tcscpy(dirp->dd_dir.d_name, dirp->dd_dta.name); return &dirp->dd_dir; } return (struct _tdirent*) 0; } /* * closedir * * Frees up resources allocated by opendir. */ static int _tclosedir(_TDIR* dirp) { int rc; errno = 0; rc = 0; if (!dirp) { errno = EFAULT; return -1; } if (dirp->dd_handle != -1) { rc = _findclose(dirp->dd_handle); } /* Delete the dir structure. */ al_free(dirp); return rc; } #endif /* ALLEGRO_MSVC */ /* vim: set ft=c sts=3 sw=3 et: */ allegro-5.0.10/src/win/0000755000175000001440000000000012157230740013773 5ustar tjadenusersallegro-5.0.10/src/win/wkeyboard.c0000644000175000001440000004370112125426002016124 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows keyboard driver. * * By Milan Mimica. * * See readme.txt for copyright information. * */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintwin.h" /* Missing from MSVC 2005 headers. */ #ifndef MAPVK_VSC_TO_VK_EX #define MAPVK_VSC_TO_VK_EX 3 #endif static bool installed = false; static ALLEGRO_KEYBOARD the_keyboard; static ALLEGRO_KEYBOARD_STATE the_state; static int modifiers = 0; /* lookup table for converting virtualkey VK_* codes into Allegro ALLEGRO_KEY_* codes */ /* For handling of extended keys, extkey_to_keycode() takes priority over this. */ /* Last unknown key sequence: 39*/ static const unsigned char hw_to_mycode[256] = { /* 0x00 */ 0, ALLEGRO_KEY_UNKNOWN+0, ALLEGRO_KEY_UNKNOWN+1, ALLEGRO_KEY_UNKNOWN+2, /* 0x04 */ ALLEGRO_KEY_UNKNOWN+3, ALLEGRO_KEY_UNKNOWN+4, ALLEGRO_KEY_UNKNOWN+5, 0, /* 0x08 */ ALLEGRO_KEY_BACKSPACE, ALLEGRO_KEY_TAB, 0, 0, /* 0x0C */ ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_ENTER, 0, 0, /* 0x10 */ 0/*L or R shift*/, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_ALT, ALLEGRO_KEY_PAUSE, /* 0x14 */ ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_KANA, 0, ALLEGRO_KEY_UNKNOWN+6, /* 0x18 */ ALLEGRO_KEY_UNKNOWN+7, ALLEGRO_KEY_KANJI, 0, ALLEGRO_KEY_ESCAPE, /* 0x1C */ ALLEGRO_KEY_CONVERT, ALLEGRO_KEY_NOCONVERT, ALLEGRO_KEY_UNKNOWN+8, ALLEGRO_KEY_UNKNOWN+9, /* 0x20 */ ALLEGRO_KEY_SPACE, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_1, /* 0x24 */ ALLEGRO_KEY_PAD_7, ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_6, /* 0x28 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_UNKNOWN+10, ALLEGRO_KEY_UNKNOWN+11, ALLEGRO_KEY_UNKNOWN+12, /* 0x2C */ ALLEGRO_KEY_PRINTSCREEN, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_DELETE, ALLEGRO_KEY_UNKNOWN+13, /* 0x30 */ ALLEGRO_KEY_0, ALLEGRO_KEY_1, ALLEGRO_KEY_2, ALLEGRO_KEY_3, /* 0x34 */ ALLEGRO_KEY_4, ALLEGRO_KEY_5, ALLEGRO_KEY_6, ALLEGRO_KEY_7, /* 0x38 */ ALLEGRO_KEY_8, ALLEGRO_KEY_9, 0, 0, /* 0x3C */ 0, 0, 0, 0, /* 0x40 */ 0, ALLEGRO_KEY_A, ALLEGRO_KEY_B, ALLEGRO_KEY_C, /* 0x44 */ ALLEGRO_KEY_D, ALLEGRO_KEY_E, ALLEGRO_KEY_F, ALLEGRO_KEY_G, /* 0x48 */ ALLEGRO_KEY_H, ALLEGRO_KEY_I, ALLEGRO_KEY_J, ALLEGRO_KEY_K, /* 0x4C */ ALLEGRO_KEY_L, ALLEGRO_KEY_M, ALLEGRO_KEY_N, ALLEGRO_KEY_O, /* 0x50 */ ALLEGRO_KEY_P, ALLEGRO_KEY_Q, ALLEGRO_KEY_R, ALLEGRO_KEY_S, /* 0x54 */ ALLEGRO_KEY_T, ALLEGRO_KEY_U, ALLEGRO_KEY_V, ALLEGRO_KEY_W, /* 0x58 */ ALLEGRO_KEY_X, ALLEGRO_KEY_Y, ALLEGRO_KEY_Z, ALLEGRO_KEY_LWIN, /* 0x5C */ ALLEGRO_KEY_RWIN, ALLEGRO_KEY_MENU, 0, 0, /* 0x60 */ ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_1, ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, /* 0x64 */ ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_7, /* 0x68 */ ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_ASTERISK, ALLEGRO_KEY_PAD_PLUS, /* 0x6C */ ALLEGRO_KEY_UNKNOWN+15, ALLEGRO_KEY_PAD_MINUS, ALLEGRO_KEY_PAD_DELETE, ALLEGRO_KEY_PAD_SLASH, /* 0x70 */ ALLEGRO_KEY_F1, ALLEGRO_KEY_F2, ALLEGRO_KEY_F3, ALLEGRO_KEY_F4, /* 0x74 */ ALLEGRO_KEY_F5, ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F8, /* 0x78 */ ALLEGRO_KEY_F9, ALLEGRO_KEY_F10, ALLEGRO_KEY_F11, ALLEGRO_KEY_F12, /* 0x7C */ ALLEGRO_KEY_UNKNOWN+17, ALLEGRO_KEY_UNKNOWN+18, ALLEGRO_KEY_UNKNOWN+19, ALLEGRO_KEY_UNKNOWN+20, /* 0x80 */ ALLEGRO_KEY_UNKNOWN+21, ALLEGRO_KEY_UNKNOWN+22, ALLEGRO_KEY_UNKNOWN+23, ALLEGRO_KEY_UNKNOWN+24, /* 0x84 */ ALLEGRO_KEY_UNKNOWN+25, ALLEGRO_KEY_UNKNOWN+26, ALLEGRO_KEY_UNKNOWN+27, ALLEGRO_KEY_UNKNOWN+28, /* 0x88 */ 0, 0, 0, 0, /* 0x8C */ 0, 0, 0, 0, /* 0x90 */ ALLEGRO_KEY_NUMLOCK, ALLEGRO_KEY_SCROLLLOCK, 0, 0, /* 0x94 */ 0, 0, 0, 0, /* 0x98 */ 0, 0, 0, 0, /* 0x9C */ 0, 0, 0, 0, /* 0xA0 */ ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_RSHIFT, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_RCTRL, /* 0xA4 */ ALLEGRO_KEY_ALT, ALLEGRO_KEY_ALTGR, 0, 0, /* 0xA8 */ 0, 0, 0, 0, /* 0xAC */ 0, 0, 0, 0, /* 0xB0 */ 0, 0, 0, 0, /* 0xB4 */ 0, 0, 0, 0, /* 0xB8 */ 0, 0, ALLEGRO_KEY_SEMICOLON, ALLEGRO_KEY_EQUALS, /* 0xBC */ ALLEGRO_KEY_COMMA, ALLEGRO_KEY_MINUS, ALLEGRO_KEY_FULLSTOP, ALLEGRO_KEY_SLASH, /* 0xC0 */ ALLEGRO_KEY_TILDE, 0, 0, 0, /* 0xC4 */ 0, 0, 0, 0, /* 0xC8 */ 0, 0, 0, 0, /* 0xCC */ 0, 0, 0, 0, /* 0xD0 */ 0, 0, 0, 0, /* 0xD4 */ 0, 0, 0, 0, /* 0xD8 */ 0, 0, 0, ALLEGRO_KEY_OPENBRACE, /* 0xDC */ ALLEGRO_KEY_BACKSLASH, ALLEGRO_KEY_CLOSEBRACE, ALLEGRO_KEY_QUOTE, 0, /* 0xE0 */ 0, 0, ALLEGRO_KEY_BACKSLASH2, 0, /* 0xE4 */ 0, ALLEGRO_KEY_UNKNOWN+29, 0, 0, /* 0xE8 */ 0, 0, 0, 0, /* 0xEC */ 0, 0, 0, 0, /* 0xF0 */ 0, 0, 0, 0, /* 0xF4 */ 0, 0, ALLEGRO_KEY_UNKNOWN+30, ALLEGRO_KEY_UNKNOWN+31, /* 0xF8 */ ALLEGRO_KEY_UNKNOWN+32, ALLEGRO_KEY_UNKNOWN+33, ALLEGRO_KEY_UNKNOWN+34, ALLEGRO_KEY_UNKNOWN+35, /* 0xFC */ ALLEGRO_KEY_UNKNOWN+36, ALLEGRO_KEY_UNKNOWN+37, ALLEGRO_KEY_UNKNOWN+38, 0 }; /* forward declarations */ static bool init_keyboard(void); static void exit_keyboard(void); static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); static ALLEGRO_KEYBOARD *get_keyboard(void); /* the driver vtable */ #define KEYBOARD_WINAPI AL_ID('W','A','P','I') static ALLEGRO_KEYBOARD_DRIVER keyboard_winapi = { KEYBOARD_WINAPI, 0, 0, "WinAPI keyboard", init_keyboard, exit_keyboard, get_keyboard, NULL, /* bool set_leds(int leds) */ NULL, /* const char* keycode_to_name(int keycode)*/ get_keyboard_state }; /* list the available drivers */ _AL_DRIVER_INFO _al_keyboard_driver_list[] = { { KEYBOARD_WINAPI, &keyboard_winapi, true }, { 0, NULL, 0 } }; /* init_keyboard: * Initialise the keyboard driver. */ static bool init_keyboard(void) { memset(&the_keyboard, 0, sizeof the_keyboard); memset(&the_state, 0, sizeof the_state); modifiers = 0; /* Initialise the keyboard object for use as an event source. */ _al_event_source_init(&the_keyboard.es); installed = true; return true; } /* exit_keyboard: * Shut down the keyboard driver. */ static void exit_keyboard(void) { _al_event_source_free(&the_keyboard.es); /* This may help catch bugs in the user program, since the pointer * we return to the user is always the same. */ memset(&the_keyboard, 0, sizeof the_keyboard); installed = false; } /* _al_win_fix_modifiers: * Fix the modifiers. */ void _al_win_fix_modifiers(void) { modifiers = 0; } /* get_keyboard: * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. */ static ALLEGRO_KEYBOARD *get_keyboard(void) { return &the_keyboard; } /* get_keyboard_state: * Copy the current keyboard state into RET_STATE. */ static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { unsigned int i; ALLEGRO_DISPLAY *disp = NULL; ALLEGRO_SYSTEM *sys; sys = al_get_system_driver(); for (i = 0; i < sys->displays._size; i++) { ALLEGRO_DISPLAY_WIN **d = (void*)_al_vector_ref(&sys->displays, i); if ((*d)->window == GetForegroundWindow()) { disp = (void*)*d; break; } } the_state.display = disp; *ret_state = the_state; } /* extkey_to_keycode: * Given a VK code, returns the Allegro keycode for the corresponding extended * key. If no code is found, returns zero. */ static int extkey_to_keycode(int vcode) { switch (vcode) { /* These are ordered by VK value, lowest first. */ case VK_CANCEL: return ALLEGRO_KEY_PAUSE; case VK_RETURN: return ALLEGRO_KEY_PAD_ENTER; case VK_CONTROL: return ALLEGRO_KEY_RCTRL; case VK_MENU: return ALLEGRO_KEY_ALTGR; case VK_PRIOR: return ALLEGRO_KEY_PGUP; case VK_NEXT: return ALLEGRO_KEY_PGDN; case VK_END: return ALLEGRO_KEY_END; case VK_HOME: return ALLEGRO_KEY_HOME; case VK_LEFT: return ALLEGRO_KEY_LEFT; case VK_UP: return ALLEGRO_KEY_UP; case VK_RIGHT: return ALLEGRO_KEY_RIGHT; case VK_DOWN: return ALLEGRO_KEY_DOWN; case VK_SNAPSHOT: return ALLEGRO_KEY_PRINTSCREEN; case VK_INSERT: return ALLEGRO_KEY_INSERT; case VK_DELETE: return ALLEGRO_KEY_DELETE; case VK_LWIN: return ALLEGRO_KEY_LWIN; case VK_RWIN: return ALLEGRO_KEY_RWIN; case VK_APPS: return ALLEGRO_KEY_MENU; case VK_DIVIDE: return ALLEGRO_KEY_PAD_SLASH; case VK_NUMLOCK: return ALLEGRO_KEY_NUMLOCK; default: return 0; } } static void update_modifiers(int code, bool pressed) { #define ON_OFF2(code) \ { \ if (!pressed) \ modifiers &= ~code; \ else \ modifiers |= code; \ break; \ } switch (code) { case ALLEGRO_KEY_LSHIFT: ON_OFF2(ALLEGRO_KEYMOD_SHIFT); case ALLEGRO_KEY_RSHIFT: ON_OFF2(ALLEGRO_KEYMOD_SHIFT); case ALLEGRO_KEY_RCTRL: ON_OFF2(ALLEGRO_KEYMOD_CTRL); case ALLEGRO_KEY_LCTRL: ON_OFF2(ALLEGRO_KEYMOD_CTRL); case ALLEGRO_KEY_ALT: ON_OFF2(ALLEGRO_KEYMOD_ALT); case ALLEGRO_KEY_ALTGR: ON_OFF2(ALLEGRO_KEYMOD_ALTGR); case ALLEGRO_KEY_LWIN: ON_OFF2(ALLEGRO_KEYMOD_LWIN); case ALLEGRO_KEY_RWIN: ON_OFF2(ALLEGRO_KEYMOD_RWIN); case ALLEGRO_KEY_MENU: ON_OFF2(ALLEGRO_KEYMOD_MENU); } #undef ON_OFF2 } /* update_toggle_modifiers: * Update the state of Num Lock, Caps Lock, and Scroll Lock. */ static void update_toggle_modifiers(void) { #define ON_OFF(code, on) \ { \ if (on) \ modifiers |= code; \ else \ modifiers &= ~code; \ } /* GetKeyState appears to be the only reliable way of doing this. GetKeyboardState * is updated a bit too late in some cases. Maybe it would work if WM_CHARs were * used, since they arrive after the WM_KEYDOWNs that trigger them. */ ON_OFF(ALLEGRO_KEYMOD_NUMLOCK, GetKeyState(VK_NUMLOCK) & 1); ON_OFF(ALLEGRO_KEYMOD_CAPSLOCK, GetKeyState(VK_CAPITAL) & 1); ON_OFF(ALLEGRO_KEYMOD_SCROLLLOCK, GetKeyState(VK_SCROLL) & 1); #undef ON_OFF } /* _al_win_kbd_handle_key_press: * Does stuff when a key is pressed. */ void _al_win_kbd_handle_key_press(int scode, int vcode, bool extended, bool repeated, ALLEGRO_DISPLAY_WIN *win_disp) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_disp; ALLEGRO_EVENT event; int my_code; bool actual_repeat; int char_count; int event_count; int i; BYTE ks[256]; WCHAR buf[8] = { 0 }; if (!installed) return; /* Check for an extended key first. */ my_code = 0; if (extended) my_code = extkey_to_keycode(vcode); /* Map a non-extended key. This also works as a fallback in case the key was extended, but no extended mapping was found. */ if (my_code == 0) { if (vcode == VK_SHIFT) /* Left or right Shift key? */ vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX); my_code = hw_to_mycode[vcode]; } update_modifiers(my_code, true); actual_repeat = repeated && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, my_code); _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, my_code); if (!_al_event_source_needs_to_generate_event(&the_keyboard.es)) return; event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; event.keyboard.timestamp = al_get_time(); event.keyboard.display = display; event.keyboard.keycode = my_code; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; event.keyboard.repeat = false; _al_event_source_lock(&the_keyboard.es); if (my_code > 0 && !actual_repeat) { _al_event_source_emit_event(&the_keyboard.es, &event); } /* Send char events, but not for modifier keys or dead keys. */ if (my_code < ALLEGRO_KEY_MODIFIERS) { char_count = ToUnicode(vcode, scode, GetKeyboardState(ks) ? ks : NULL, buf, 8, 0); /* Send ASCII code 127 for both Del keys. */ if (char_count == 0 && vcode == VK_DELETE) { char_count = 1; buf[0] = 127; } if (char_count != -1) { /* -1 means it was a dead key. */ event_count = char_count ? char_count : 1; event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; update_toggle_modifiers(); event.keyboard.modifiers = modifiers; event.keyboard.repeat = actual_repeat; for (i = 0; i < event_count; i++) { event.keyboard.unichar = buf[i]; _al_event_source_emit_event(&the_keyboard.es, &event); } } } _al_event_source_unlock(&the_keyboard.es); /* Toggle mouse grab key. */ if (my_code && !repeated) { ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); if (my_code == system->toggle_mouse_grab_keycode && (modifiers & system->toggle_mouse_grab_modifiers) == system->toggle_mouse_grab_modifiers) { if (system->mouse_grab_display == display) { al_ungrab_mouse(); } else { al_grab_mouse(display); } } } } /* _al_win_kbd_handle_key_release: * Does stuff when a key is released. */ void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, ALLEGRO_DISPLAY_WIN *win_disp) { ALLEGRO_EVENT event; int my_code; if (!installed) return; my_code = 0; if (extended) my_code = extkey_to_keycode(vcode); if (my_code == 0) { if (vcode == VK_SHIFT) vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX); my_code = hw_to_mycode[vcode]; } update_modifiers(my_code, false); _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, my_code); /* Windows only sends a WM_KEYUP message for the Shift keys when both have been released. If one of the Shift keys is still reported as down, we need to release it as well. */ if (my_code == ALLEGRO_KEY_LSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT)) _al_win_kbd_handle_key_release(scode, VK_RSHIFT, extended, win_disp); else if (my_code == ALLEGRO_KEY_RSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT)) _al_win_kbd_handle_key_release(scode, VK_LSHIFT, extended, win_disp); if (!_al_event_source_needs_to_generate_event(&the_keyboard.es)) return; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = (void*)win_disp; event.keyboard.keycode = my_code; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_lock(&the_keyboard.es); _al_event_source_emit_event(&the_keyboard.es, &event); _al_event_source_unlock(&the_keyboard.es); } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wjoydxnu.c0000644000175000001440000014045711771523242016044 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows DirectInput joystick driver. * * By Eric Botcazou. * * Omar Cornut fixed it to handle a weird peculiarity of * the DirectInput joystick API. * * Modified extensively for the new joystick API by Peter Wang. * * See readme.txt for copyright information. */ /* * Driver operation: * * 1. When the driver is initialised all the joysticks on the system * are enumerated. For each joystick, an ALLEGRO_JOYSTICK_DIRECTX structure * is created. A win32 Event is also created for each joystick and DirectInput * is told to set that event whenever the joystick state changes. For some * devices this is not possible -- they must be polled. In that case, a * Waitable Timer object is used instead of a win32 Event. Once all the * joysticks are set up, a dedicated background thread is started. * * 2. When al_get_joystick() is called the address of one of the * ALLEGRO_JOYSTICK_DIRECTX structures is returned to the user. * * 3. The background thread waits upon the win32 Events/Waitable Timer * objects. When one of them is triggered, the thread wakes up and * reads in buffered joystick events. An internal ALLEGRO_JOYSTICK_STATE * structure (part of ALLEGRO_JOYSTICK_DIRECTX) is updated accordingly. * Also, any Allegro events are generated if necessary. * * 4. When the user calls al_get_joystick_state() the contents of the * internal ALLEGRO_JOYSTICK_STATE structure are copied to a user * ALLEGRO_JOYSTICK_STATE structure. * * 5. Every second or so, all the joysticks on the system are enumerated again. * We compare the GUIDs of the enumerated joysticks with the existing * ALLEGRO_JOYSTICK structures to tell if any new joysticks have been connected, * or old ones disconnected. */ #define ALLEGRO_NO_COMPATIBILITY #define DIRECTINPUT_VERSION 0x0800 /* For waitable timers */ #define _WIN32_WINNT 0x400 #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintwin.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_bitmap.h" #ifndef ALLEGRO_WINDOWS #error something is wrong with the makefile #endif #ifdef ALLEGRO_MINGW32 #undef MAKEFOURCC #endif #include #include #include #include ALLEGRO_DEBUG_CHANNEL("dinput") /* arbitrary limit to make life easier; this was the limit in Allegro 4.1.x */ #define MAX_JOYSTICKS 8 /* these limits are from DIJOYSTICK_STATE in dinput.h */ #define MAX_SLIDERS 2 #define MAX_POVS 4 #define MAX_BUTTONS 32 /* the number of joystick events that DirectInput is told to buffer */ #define DEVICE_BUFFER_SIZE 10 /* make sure all the constants add up */ /* the first two sticks are (x,y,z) and (rx,ry,rz) */ ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_STICKS >= (2 + MAX_SLIDERS + MAX_POVS)); ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_BUTTONS >= MAX_BUTTONS); #define GUID_EQUAL(a, b) (0 == memcmp(&(a), &(b), sizeof(GUID))) typedef enum { STATE_UNUSED, STATE_BORN, STATE_ALIVE, STATE_DYING } CONFIG_STATE; #define ACTIVE_STATE(st) \ ((st) == STATE_ALIVE || (st) == STATE_DYING) /* helper structure to record information through object_enum_callback */ #define NAME_LEN 128 typedef struct { bool have_x; char name_x[NAME_LEN]; bool have_y; char name_y[NAME_LEN]; bool have_z; char name_z[NAME_LEN]; bool have_rx; char name_rx[NAME_LEN]; bool have_ry; char name_ry[NAME_LEN]; bool have_rz; char name_rz[NAME_LEN]; int num_sliders; char name_slider[MAX_SLIDERS][NAME_LEN]; int num_povs; char name_pov[MAX_POVS][NAME_LEN]; int num_buttons; char name_button[MAX_BUTTONS][NAME_LEN]; } CAPS_AND_NAMES; /* map a DirectInput axis to an Allegro (stick,axis) pair */ typedef struct { int stick, axis; } AXIS_MAPPING; typedef struct ALLEGRO_JOYSTICK_DIRECTX { ALLEGRO_JOYSTICK parent; /* must be first */ CONFIG_STATE config_state; bool marked; LPDIRECTINPUTDEVICE2 device; GUID guid; HANDLE waker_event; ALLEGRO_JOYSTICK_STATE joystate; AXIS_MAPPING x_mapping; AXIS_MAPPING y_mapping; AXIS_MAPPING z_mapping; AXIS_MAPPING rx_mapping; AXIS_MAPPING ry_mapping; AXIS_MAPPING rz_mapping; AXIS_MAPPING slider_mapping[MAX_SLIDERS]; int pov_mapping_stick[MAX_POVS]; char name[80]; char all_names[512]; /* button/stick/axis names with NUL terminators */ } ALLEGRO_JOYSTICK_DIRECTX; /* forward declarations */ static bool joydx_init_joystick(void); static void joydx_exit_joystick(void); static bool joydx_reconfigure_joysticks(void); static int joydx_get_num_joysticks(void); static ALLEGRO_JOYSTICK *joydx_get_joystick(int num); static void joydx_release_joystick(ALLEGRO_JOYSTICK *joy); static void joydx_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state); static const char *joydx_get_name(ALLEGRO_JOYSTICK *joy); static bool joydx_get_active(ALLEGRO_JOYSTICK *joy); static void joydx_inactivate_joy(ALLEGRO_JOYSTICK_DIRECTX *joy); static unsigned __stdcall joydx_thread_proc(LPVOID unused); static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy); static void handle_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, const AXIS_MAPPING *axis_mapping, DWORD value); static void handle_pov_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, DWORD value); static void handle_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, bool down); static void generate_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, int axis, float pos); static void generate_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, ALLEGRO_EVENT_TYPE event_type); /* the driver vtable */ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_directx = { AL_JOY_TYPE_DIRECTX, "", "", "DirectInput joystick", joydx_init_joystick, joydx_exit_joystick, joydx_reconfigure_joysticks, joydx_get_num_joysticks, joydx_get_joystick, joydx_release_joystick, joydx_get_joystick_state, joydx_get_name, joydx_get_active }; /* GUID values are borrowed from Wine */ #define DEFINE_PRIVATE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ static const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } DEFINE_PRIVATE_GUID(__al_GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); DEFINE_PRIVATE_GUID(__al_IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); DEFINE_PRIVATE_GUID(__al_IID_IDirectInputDevice8A, 0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); /* definition of DirectInput Joystick was borrowed from Wine implementation */ #define DIDFT_AXIS 0x00000003 #define DIDFT_ANYINSTANCE 0x00FFFF00 #define DIDFT_OPTIONAL 0x80000000 static const DIOBJECTDATAFORMAT __al_dfDIJoystick[] = { { &__al_GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { &__al_GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, { NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, }; static const DIDATAFORMAT __al_c_dfDIJoystick = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), DIDF_ABSAXIS, sizeof(DIJOYSTATE), sizeof(__al_dfDIJoystick) / sizeof(*__al_dfDIJoystick), (LPDIOBJECTDATAFORMAT)__al_dfDIJoystick }; /* end of Wine code */ /* DirectInput creation prototype */ typedef HRESULT (WINAPI *DIRECTINPUT8CREATEPROC)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter); /* DirectInput module name */ static const char* _al_dinput_module_name = "dinput8.dll"; /* DirecInput module handle */ static HMODULE _al_dinput_module = NULL; /* DirectInput creation procedure */ static DIRECTINPUT8CREATEPROC _al_dinput_create = (DIRECTINPUT8CREATEPROC)NULL; /* a handle to the DirectInput interface */ static LPDIRECTINPUT joystick_dinput = NULL; /* last display which acquired the devices */ static ALLEGRO_DISPLAY_WIN *win_disp; /* number of joysticks visible to user */ static int joydx_num_joysticks; /* the joystick structures */ static ALLEGRO_JOYSTICK_DIRECTX joydx_joystick[MAX_JOYSTICKS]; /* for the background thread */ static HANDLE joydx_thread = NULL; static CRITICAL_SECTION joydx_thread_cs; /* whether the user should call al_reconfigure_joysticks */ static bool config_needs_merging = false; /* An array of objects that are to wake the background thread when * something interesting happens. The first handle is for thread * termination. The rest point to joydx_joystick[i].waker_event values, * for each active joystick. joydx_joystick[i].waker_event is NOT * necessarily at JOYSTICK_WAKER(i). */ static HANDLE joydx_thread_wakers[1+MAX_JOYSTICKS]; #define STOP_EVENT (joydx_thread_wakers[0]) #define JOYSTICK_WAKER(n) (joydx_thread_wakers[1+(n)]) /* names for things in case DirectInput doesn't provide them */ static char default_name_x[] = "X"; static char default_name_y[] = "Y"; static char default_name_z[] = "Z"; static char default_name_rx[] = "RX"; static char default_name_ry[] = "RY"; static char default_name_rz[] = "RZ"; static char default_name_stick[] = "stick"; static char default_name_slider[] = "slider"; static char default_name_hat[] = "hat"; static char *default_name_button[MAX_BUTTONS] = { "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "B20", "B21", "B22", "B23", "B24", "B25", "B26", "B27", "B28", "B29", "B30", "B31", "B32" }; #define JOY_POVFORWARD_WRAP 36000 /* Returns a pointer to a static buffer, for debugging. */ static char *joydx_guid_string(ALLEGRO_JOYSTICK_DIRECTX *joy) { static char buf[200]; sprintf(buf, "%lx-%x-%x-%x%x%x%x%x%x%x%x", joy->guid.Data1, joy->guid.Data2, joy->guid.Data3, joy->guid.Data4[0], joy->guid.Data4[1], joy->guid.Data4[2], joy->guid.Data4[3], joy->guid.Data4[4], joy->guid.Data4[5], joy->guid.Data4[6], joy->guid.Data4[7] ); return buf; } /* dinput_err_str: * Returns a DirectInput error string. */ #ifdef DEBUGMODE static char* dinput_err_str(long err) { static char err_str[64]; switch (err) { case DIERR_ACQUIRED: _al_sane_strncpy(err_str, "the device is acquired", sizeof(err_str)); break; case DIERR_NOTACQUIRED: _al_sane_strncpy(err_str, "the device is not acquired", sizeof(err_str)); break; case DIERR_INPUTLOST: _al_sane_strncpy(err_str, "access to the device was not granted", sizeof(err_str)); break; case DIERR_INVALIDPARAM: _al_sane_strncpy(err_str, "the device does not have a selected data format", sizeof(err_str)); break; case DIERR_OTHERAPPHASPRIO: _al_sane_strncpy(err_str, "can't acquire the device in background", sizeof(err_str)); break; default: _al_sane_strncpy(err_str, "unknown error", sizeof(err_str)); } return err_str; } #else #define dinput_err_str(hr) "\0" #endif /* _al_win_joystick_dinput_acquire: [window thread] * Acquires the joystick devices. */ static void joystick_dinput_acquire(void) { HRESULT hr; int i; if (!joystick_dinput) return; for (i=0; i < MAX_JOYSTICKS; i++) { if (joydx_joystick[i].device) { hr = IDirectInputDevice8_Acquire(joydx_joystick[i].device); if (FAILED(hr)) ALLEGRO_ERROR("acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); } } } /* _al_win_joystick_dinput_unacquire: [window thread] * Unacquires the joystick devices. */ void _al_win_joystick_dinput_unacquire(void *unused) { int i; (void)unused; if (joystick_dinput && win_disp) { for (i=0; i < MAX_JOYSTICKS; i++) { if (joydx_joystick[i].device) { ALLEGRO_DEBUG("Unacquiring joystick device at slot %d\n", i); IDirectInputDevice8_Unacquire(joydx_joystick[i].device); } } } } /* _al_win_joystick_dinput_grab: [window thread] * Grabs the joystick devices. */ void _al_win_joystick_dinput_grab(void *param) { int i; if (!joystick_dinput) return; /* Release the input from the previous window just in case, otherwise set cooperative level will fail. */ if (win_disp) { _al_win_wnd_call_proc(win_disp->window, _al_win_joystick_dinput_unacquire, NULL); } win_disp = param; /* set cooperative level */ for (i = 0; i < MAX_JOYSTICKS; i++) { HRESULT hr; if (!joydx_joystick[i].device) continue; hr = IDirectInputDevice8_SetCooperativeLevel(joydx_joystick[i].device, win_disp->window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); if (FAILED(hr)) { ALLEGRO_ERROR("IDirectInputDevice8_SetCooperativeLevel failed.\n"); return; } } joystick_dinput_acquire(); } static ALLEGRO_JOYSTICK_DIRECTX *joydx_by_guid(const GUID guid) { unsigned i; for (i = 0; i < MAX_JOYSTICKS; i++) { if (GUID_EQUAL(joydx_joystick[i].guid, guid)) return &joydx_joystick[i]; } return NULL; } static ALLEGRO_JOYSTICK_DIRECTX *joydx_allocate_structure(int *num) { int i; for (i = 0; i < MAX_JOYSTICKS; i++) { if (joydx_joystick[i].config_state == STATE_UNUSED) { *num = i; return &joydx_joystick[i]; } } *num = -1; return NULL; } /* object_enum_callback: [primary thread] * Helper function to find out what objects we have on the device. */ static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { #define GUIDTYPE_EQ(x) GUID_EQUAL(lpddoi->guidType, x) CAPS_AND_NAMES *can = pvRef; if (GUIDTYPE_EQ(__al_GUID_XAxis)) { can->have_x = true; _al_sane_strncpy(can->name_x, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_YAxis)) { can->have_y = true; _al_sane_strncpy(can->name_y, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_ZAxis)) { can->have_z = true; _al_sane_strncpy(can->name_z, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_RxAxis)) { can->have_rx = true; _al_sane_strncpy(can->name_rx, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_RyAxis)) { can->have_ry = true; _al_sane_strncpy(can->name_ry, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_RzAxis)) { can->have_rz = true; _al_sane_strncpy(can->name_rz, lpddoi->tszName, NAME_LEN); } else if (GUIDTYPE_EQ(__al_GUID_Slider)) { if (can->num_sliders < MAX_SLIDERS) { _al_sane_strncpy(can->name_slider[can->num_sliders], lpddoi->tszName, NAME_LEN); can->num_sliders++; } } else if (GUIDTYPE_EQ(__al_GUID_POV)) { if (can->num_povs < MAX_POVS) { _al_sane_strncpy(can->name_pov[can->num_povs], lpddoi->tszName, NAME_LEN); can->num_povs++; } } else if (GUIDTYPE_EQ(__al_GUID_Button)) { if (can->num_buttons < MAX_BUTTONS) { _al_sane_strncpy(can->name_button[can->num_buttons], lpddoi->tszName, NAME_LEN); can->num_buttons++; } } return DIENUM_CONTINUE; #undef GUIDTYPE_EQ } static char *add_string(char *buf, const char *src, int *pos, int bufsize) { char *dest = buf + *pos; if (*pos >= bufsize - 1) { /* Out of space. */ ASSERT(dest[0] == '\0'); return dest; } if (*pos > 0) { /* Skip over NUL separator. */ dest++; (*pos)++; } _al_sane_strncpy(dest, src, bufsize - *pos); (*pos) += strlen(dest); ASSERT(*pos < bufsize); return dest; } /* fill_joystick_info_using_caps_and_names: [primary thread] * Helper to fill in the contents of the joystick structure using the * information painstakingly stored into the caps_and_names substructure. */ static void fill_joystick_info_using_caps_and_names(ALLEGRO_JOYSTICK_DIRECTX *joy, const CAPS_AND_NAMES *can) { _AL_JOYSTICK_INFO *info = &joy->parent.info; int pos = 0; int i; #define N_STICK (info->num_sticks) #define N_AXIS (info->stick[N_STICK].num_axes) #define OR(A, B) ((A) ? ADD_STRING(A) : ADD_STRING(B)) #define ADD_STRING(s) add_string(joy->all_names, (s), &pos, \ sizeof(joy->all_names)) /* the X, Y, Z axes make up the first stick */ if (can->have_x || can->have_y || can->have_z) { if (can->have_x) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_x, default_name_x); joy->x_mapping.stick = N_STICK; joy->x_mapping.axis = N_AXIS; N_AXIS++; } if (can->have_y) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_y, default_name_y); joy->y_mapping.stick = N_STICK; joy->y_mapping.axis = N_AXIS; N_AXIS++; } if (can->have_z) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_z, default_name_z); joy->z_mapping.stick = N_STICK; joy->z_mapping.axis = N_AXIS; N_AXIS++; } info->stick[N_STICK].name = ADD_STRING(default_name_stick); N_STICK++; } /* the Rx, Ry, Rz axes make up the next stick */ if (can->have_rx || can->have_ry || can->have_rz) { if (can->have_rx) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_rx, default_name_rx); joy->rx_mapping.stick = N_STICK; joy->rx_mapping.axis = N_AXIS; N_AXIS++; } if (can->have_ry) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_ry, default_name_ry); joy->ry_mapping.stick = N_STICK; joy->ry_mapping.axis = N_AXIS; N_AXIS++; } if (can->have_rz) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].axis[N_AXIS].name = OR(can->name_rz, default_name_rz); joy->rz_mapping.stick = N_STICK; joy->rz_mapping.axis = N_AXIS; N_AXIS++; } info->stick[N_STICK].name = ADD_STRING(default_name_stick); N_STICK++; } /* sliders are assigned to one stick each */ for (i = 0; i < can->num_sliders; i++) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; info->stick[N_STICK].num_axes = 1; info->stick[N_STICK].axis[0].name = ADD_STRING("axis"); info->stick[N_STICK].name = OR(can->name_slider[i], default_name_slider); joy->slider_mapping[i].stick = N_STICK; joy->slider_mapping[i].axis = 0; N_STICK++; } /* POV devices are assigned to one stick each */ for (i = 0; i < can->num_povs; i++) { info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL; info->stick[N_STICK].num_axes = 2; info->stick[N_STICK].axis[0].name = ADD_STRING("left/right"); info->stick[N_STICK].axis[1].name = ADD_STRING("up/down"); info->stick[N_STICK].name = OR(can->name_pov[i], default_name_hat); joy->pov_mapping_stick[i] = N_STICK; N_STICK++; } /* buttons */ for (i = 0; i < can->num_buttons; i++) { info->button[i].name = OR(can->name_button[i], default_name_button[i]); } info->num_buttons = can->num_buttons; /* correct buggy MP-8866 Dual USB Joypad info received from DirectInput */ if (strstr(joy->name, "MP-8866")) { /* axes were mapped weird; remap as expected */ /* really R-stick X axis */ joy->z_mapping.stick = 1; joy->z_mapping.axis = 0; /* really R-stick Y axis */ joy->rz_mapping.stick = 1; joy->rz_mapping.axis = 1; info->stick[0].num_axes = 2; info->stick[1].num_axes = 2; /* reuse the axis names from the first stick */ info->stick[2].axis[0].name = info->stick[1].axis[0].name = info->stick[0].axis[0].name; info->stick[2].axis[1].name = info->stick[1].axis[1].name = info->stick[0].axis[1].name; /* first four button names contained junk; replace with valid strings */ info->button[ 0].name = ADD_STRING("Triangle"); info->button[ 1].name = ADD_STRING("Circle"); info->button[ 2].name = ADD_STRING("X"); info->button[ 3].name = ADD_STRING("Square"); /* while we're at it, give these controls more sensible names, too */ info->stick[0].name = ADD_STRING("[L-stick] or D-pad"); info->stick[1].name = ADD_STRING("[R-stick]"); info->stick[2].name = ADD_STRING("[D-pad]"); } #undef N_AXIS #undef N_STICK #undef OR #undef ADD_STRING } /* joystick_enum_callback: [primary thread] * Helper function to find out how many joysticks we have and set them up. * At the end joydx_num_joysticks and joydx_joystick[] will be initialised. */ static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { DIPROPRANGE property_range = { /* the header */ { sizeof(DIPROPRANGE), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ -32767, // lMin +32767 // lMax }; DIPROPDWORD property_deadzone = { /* the header */ { sizeof(DIPROPDWORD), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ 2000, // dwData }; DIPROPDWORD property_buffersize = { /* the header */ { sizeof(DIPROPDWORD), // diph.dwSize sizeof(DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, /* the data */ DEVICE_BUFFER_SIZE // number of data items }; LPDIRECTINPUTDEVICE _dinput_device1; LPDIRECTINPUTDEVICE2 dinput_device = NULL; HRESULT hr; LPVOID temp; CAPS_AND_NAMES caps_and_names; ALLEGRO_JOYSTICK_DIRECTX *joy; int num; (void)pvRef; /* check if the joystick already existed before */ joy = joydx_by_guid(lpddi->guidInstance); if (joy) { ALLEGRO_DEBUG("Device %s still exists\n", joydx_guid_string(joy)); joy->marked = true; return DIENUM_CONTINUE; } /* create the DirectInput joystick device */ hr = IDirectInput8_CreateDevice(joystick_dinput, &lpddi->guidInstance, &_dinput_device1, NULL); if (FAILED(hr)) goto Error; /* query the DirectInputDevice2 interface needed for the poll() method */ hr = IDirectInputDevice8_QueryInterface(_dinput_device1, &__al_IID_IDirectInputDevice8A, &temp); IDirectInputDevice8_Release(_dinput_device1); if (FAILED(hr)) goto Error; dinput_device = temp; /* enumerate objects available on the device */ memset(&caps_and_names, 0, sizeof(caps_and_names)); hr = IDirectInputDevice8_EnumObjects(dinput_device, object_enum_callback, &caps_and_names, DIDFT_PSHBUTTON | DIDFT_AXIS | DIDFT_POV); if (FAILED(hr)) goto Error; /* set data format */ hr = IDirectInputDevice8_SetDataFormat(dinput_device, &__al_c_dfDIJoystick); if (FAILED(hr)) goto Error; /* set the range of axes */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_RANGE, &property_range.diph); if (FAILED(hr)) goto Error; /* set the dead zone of axes */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_DEADZONE, &property_deadzone.diph); if (FAILED(hr)) goto Error; /* set the buffer size */ hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_BUFFERSIZE, &property_buffersize.diph); if (FAILED(hr)) goto Error; /* set up the joystick structure */ joy = joydx_allocate_structure(&num); if (!joy) { ALLEGRO_ERROR("Joystick array full\n"); goto Error; } joy->config_state = STATE_BORN; joy->marked = true; joy->device = dinput_device; memcpy(&joy->guid, &lpddi->guidInstance, sizeof(GUID)); _al_sane_strncpy(joy->name, lpddi->tszInstanceName, sizeof(joy->name)); /* fill in the joystick structure */ fill_joystick_info_using_caps_and_names(joy, &caps_and_names); /* create a thread event for this joystick, unless it was already created */ joy->waker_event = CreateEvent(NULL, false, false, NULL); /* tell the joystick background thread to wake up when this joystick * device's state changes */ hr = IDirectInputDevice8_SetEventNotification(joy->device, joy->waker_event); if (FAILED(hr)) { ALLEGRO_ERROR("SetEventNotification failed for joystick %d: %s\n", num, dinput_err_str(hr)); goto Error; } if (hr == DI_POLLEDDEVICE) { /* This joystick device must be polled -- replace the Event with * a Waitable Timer object. * * Theoretically all polled devices could share a single * waitable timer object. But, really, how many such devices * are there going to be on a system? */ CloseHandle(joy->waker_event); joy->waker_event = CreateWaitableTimer(NULL, false, NULL); if (joy->waker_event == NULL) { ALLEGRO_ERROR("CreateWaitableTimer failed for polled device.\n"); goto Error; } { LARGE_INTEGER due_time; due_time.HighPart = 0; due_time.LowPart = 150; /* 15 ms (arbitrary) */ SetWaitableTimer(joy->waker_event, &due_time, true, /* periodic */ NULL, NULL, false); } } ALLEGRO_INFO("Joystick %d initialized, GUID: %s\n", num, joydx_guid_string(joy)); config_needs_merging = true; return DIENUM_CONTINUE; Error: if (dinput_device) IDirectInputDevice8_Release(dinput_device); if (joy) { joy->device = NULL; joydx_inactivate_joy(joy); } return DIENUM_CONTINUE; } static void joydx_inactivate_joy(ALLEGRO_JOYSTICK_DIRECTX *joy) { if (joy->config_state == STATE_UNUSED) return; joy->config_state = STATE_UNUSED; joy->marked = false; if (joy->device) { IDirectInputDevice8_SetEventNotification(joy->device, NULL); IDirectInputDevice8_Release(joy->device); joy->device = NULL; } memset(&joy->guid, 0, sizeof(GUID)); if (joy->waker_event) { CloseHandle(joy->waker_event); joy->waker_event = NULL; } memset(&joy->parent.info, 0, sizeof(joy->parent.info)); /* XXX the joystick name really belongs in joy->parent.info too */ joy->name[0] = '\0'; memset(&joy->joystate, 0, sizeof(joy->joystate)); } static void joydx_generate_configure_event(void) { ALLEGRO_EVENT event; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; event.joystick.timestamp = al_get_time(); _al_generate_joystick_event(&event); } static bool joydx_scan(bool configure) { HRESULT hr; unsigned i; /* Clear mark bits. */ for (i = 0; i < MAX_JOYSTICKS; i++) joydx_joystick[i].marked = false; /* enumerate the joysticks attached to the system */ hr = IDirectInput8_EnumDevices(joystick_dinput, DI8DEVCLASS_GAMECTRL, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY); if (FAILED(hr)) { /* XXX will this ruin everything? */ IDirectInput8_Release(joystick_dinput); joystick_dinput = NULL; return false; } /* Schedule unmarked structures to be inactivated. */ for (i = 0; i < MAX_JOYSTICKS; i++) { ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; if (joy->config_state == STATE_ALIVE && !joy->marked) { ALLEGRO_DEBUG("Joystick %s to be inactivated\n", joydx_guid_string(joy)); joy->config_state = STATE_DYING; config_needs_merging = true; } } if (config_needs_merging && configure) joydx_generate_configure_event(); return config_needs_merging; } static void joydx_merge(void) { unsigned i; HRESULT hr; config_needs_merging = false; joydx_num_joysticks = 0; for (i = 0; i < MAX_JOYSTICKS; i++) { ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; switch (joy->config_state) { case STATE_UNUSED: break; case STATE_BORN: hr = IDirectInputDevice8_Acquire(joy->device); if (FAILED(hr)) { ALLEGRO_ERROR("acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); } joy->config_state = STATE_ALIVE; /* fall through */ case STATE_ALIVE: JOYSTICK_WAKER(joydx_num_joysticks) = joy->waker_event; joydx_num_joysticks++; break; case STATE_DYING: joydx_inactivate_joy(joy); break; } } ALLEGRO_INFO("Merged, num joysticks=%d\n", joydx_num_joysticks); joystick_dinput_acquire(); } /* joydx_init_joystick: [primary thread] * * Initialises the DirectInput joystick devices. * * To avoid enumerating the the joysticks over and over, this does * the enumeration once and does almost all the setting up required * of the devices. joydx_get_joystick() is left with very little work * to do. */ static bool joydx_init_joystick(void) { HRESULT hr; ALLEGRO_SYSTEM *system; size_t i; MAKE_UNION(&joystick_dinput, LPDIRECTINPUT *); ASSERT(!joystick_dinput); ASSERT(!joydx_num_joysticks); ASSERT(!joydx_thread); ASSERT(!STOP_EVENT); /* load DirectInput module */ _al_dinput_module = _al_win_safe_load_library(_al_dinput_module_name); if (_al_dinput_module == NULL) { ALLEGRO_ERROR("Failed to open '%s' library\n", _al_dinput_module_name); joystick_dinput = NULL; return false; } /* import DirectInput create proc */ _al_dinput_create = (DIRECTINPUT8CREATEPROC)GetProcAddress(_al_dinput_module, "DirectInput8Create"); if (_al_dinput_create == NULL) { ALLEGRO_ERROR("DirectInput8Create not in %s\n", _al_dinput_module_name); FreeLibrary(_al_dinput_module); joystick_dinput = NULL; return false; } /* get the DirectInput interface */ hr = _al_dinput_create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &__al_IID_IDirectInput8A, u.v, NULL); if (FAILED(hr)) { ALLEGRO_ERROR("Failed to create DirectInput interface\n"); FreeLibrary(_al_dinput_module); joystick_dinput = NULL; return false; } /* initialise the lock for the background thread */ InitializeCriticalSection(&joydx_thread_cs); // This initializes present joystick state joydx_scan(false); // This copies present state to user state joydx_merge(); /* create the dedicated thread stopping event */ STOP_EVENT = CreateEvent(NULL, false, false, NULL); /* If one of our windows is the foreground window make it grab the input. */ system = al_get_system_driver(); for (i = 0; i < _al_vector_size(&system->displays); i++) { ALLEGRO_DISPLAY_WIN **pwin_disp = _al_vector_ref(&system->displays, i); ALLEGRO_DISPLAY_WIN *win_disp = *pwin_disp; if (win_disp->window == GetForegroundWindow()) { _al_win_wnd_call_proc(win_disp->window, _al_win_joystick_dinput_grab, win_disp); } } /* start the background thread */ joydx_thread = (HANDLE) _beginthreadex(NULL, 0, joydx_thread_proc, NULL, 0, NULL); return true; } /* joydx_exit_joystick: [primary thread] * Shuts down the DirectInput joystick devices. */ static void joydx_exit_joystick(void) { int i; ALLEGRO_SYSTEM *system; size_t j; ALLEGRO_DEBUG("Entering joydx_exit_joystick\n"); ASSERT(joydx_thread); /* stop the thread */ SetEvent(STOP_EVENT); WaitForSingleObject(joydx_thread, INFINITE); CloseHandle(joydx_thread); joydx_thread = NULL; /* free thread resources */ CloseHandle(STOP_EVENT); STOP_EVENT = NULL; DeleteCriticalSection(&joydx_thread_cs); /* The toplevel display is assumed to have the input acquired. Release it. */ system = al_get_system_driver(); for (j = 0; j < _al_vector_size(&system->displays); j++) { ALLEGRO_DISPLAY_WIN **pwin_disp = _al_vector_ref(&system->displays, j); ALLEGRO_DISPLAY_WIN *win_disp = *pwin_disp; if (win_disp->window == GetForegroundWindow()) { ALLEGRO_DEBUG("Requesting window unacquire joystick devices\n"); _al_win_wnd_call_proc(win_disp->window, _al_win_joystick_dinput_unacquire, win_disp); } } /* destroy the devices */ for (i = 0; i < MAX_JOYSTICKS; i++) { joydx_inactivate_joy(&joydx_joystick[i]); } joydx_num_joysticks = 0; for (i = 0; i < MAX_JOYSTICKS; i++) { JOYSTICK_WAKER(i) = NULL; } /* destroy the DirectInput interface */ IDirectInput8_Release(joystick_dinput); joystick_dinput = NULL; /* release module handle */ FreeLibrary(_al_dinput_module); _al_dinput_module = NULL; ALLEGRO_DEBUG("Leaving joydx_exit_joystick\n"); } /* joydx_reconfigure_joysticks: [primary thread] */ static bool joydx_reconfigure_joysticks(void) { bool ret = false; EnterCriticalSection(&joydx_thread_cs); if (config_needs_merging) { joydx_merge(); ret = true; } LeaveCriticalSection(&joydx_thread_cs); return ret; } /* joydx_get_num_joysticks: [primary thread] * Return the number of joysticks available on the system. */ static int joydx_get_num_joysticks(void) { return joydx_num_joysticks; } /* joydx_get_joystick: [primary thread] * * Returns the address of a ALLEGRO_JOYSTICK structure for the device * number NUM. */ static ALLEGRO_JOYSTICK *joydx_get_joystick(int num) { ALLEGRO_JOYSTICK *ret = NULL; unsigned i; ASSERT(num >= 0); EnterCriticalSection(&joydx_thread_cs); for (i = 0; i < MAX_JOYSTICKS; i++) { ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; if (ACTIVE_STATE(joy->config_state)) { if (num == 0) { ret = (ALLEGRO_JOYSTICK *)joy; break; } num--; } } LeaveCriticalSection(&joydx_thread_cs); #if 0 /* is this needed? */ if (ret) { ALLEGRO_DISPLAY *display = al_get_current_display(); if (display) _al_win_joystick_dinput_grab(display); } #endif return ret; } /* joydx_release_joystick: [primary thread] * Releases a previously gotten joystick. */ static void joydx_release_joystick(ALLEGRO_JOYSTICK *joy) { (void)joy; } /* joydx_get_joystick_state: [primary thread] * Copy the internal joystick state to a user-provided structure. */ static void joydx_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_DIRECTX *joy = (ALLEGRO_JOYSTICK_DIRECTX *)joy_; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); { *ret_state = joy->joystate; } _al_event_source_unlock(es); } static const char *joydx_get_name(ALLEGRO_JOYSTICK *joy_) { ALLEGRO_JOYSTICK_DIRECTX *joy = (ALLEGRO_JOYSTICK_DIRECTX *)joy_; return joy->name; } static bool joydx_get_active(ALLEGRO_JOYSTICK *joy) { ALLEGRO_JOYSTICK_DIRECTX *joydx = (ALLEGRO_JOYSTICK_DIRECTX *)joy; return ACTIVE_STATE(joydx->config_state); } /* joydx_thread_proc: [joystick thread] * Thread loop function for the joystick thread. */ static unsigned __stdcall joydx_thread_proc(LPVOID unused) { double last_update = al_get_time(); /* XXX is this needed? */ _al_win_thread_init(); while (true) { DWORD result; result = WaitForMultipleObjects(joydx_num_joysticks + 1, /* +1 for STOP_EVENT */ joydx_thread_wakers, false, /* wait for any */ 1000); /* 1 second wait */ if (result == WAIT_OBJECT_0) break; /* STOP_EVENT */ EnterCriticalSection(&joydx_thread_cs); { if (al_get_time() > last_update+1 || result == WAIT_TIMEOUT) { joydx_scan(true); last_update = al_get_time(); } if (result != WAIT_TIMEOUT) { int waker_num = result - WAIT_OBJECT_0 - 1; /* -1 for STOP_EVENT */ HANDLE waker = JOYSTICK_WAKER(waker_num); unsigned i; for (i = 0; i < MAX_JOYSTICKS; i++) { if (waker == joydx_joystick[i].waker_event) { update_joystick(&joydx_joystick[i]); break; } } if (i == MAX_JOYSTICKS) { ALLEGRO_WARN("unable to match event to joystick\n"); } } } LeaveCriticalSection(&joydx_thread_cs); } _al_win_thread_exit(); (void)unused; return 0; } /* update_joystick: [joystick thread] * Reads in data for a single DirectInput joystick device, updates * the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro * events required. */ static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy) { DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE]; DWORD num_items = DEVICE_BUFFER_SIZE; HRESULT hr; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); /* some devices require polling */ IDirectInputDevice8_Poll(joy->device); /* get device data into buffer */ hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0); if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) { if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { ALLEGRO_WARN("joystick device not acquired or lost\n"); } else { ALLEGRO_ERROR("unexpected error while polling the joystick\n"); } return; } /* don't bother locking the event source if there's no work to do */ /* this happens a lot for polled devices */ if (num_items == 0) return; _al_event_source_lock(es); { unsigned int i; for (i = 0; i < num_items; i++) { const DIDEVICEOBJECTDATA *item = &buffer[i]; const int dwOfs = item->dwOfs; const DWORD dwData = item->dwData; switch (dwOfs) { case DIJOFS_X: handle_axis_event(joy, &joy->x_mapping, dwData); break; case DIJOFS_Y: handle_axis_event(joy, &joy->y_mapping, dwData); break; case DIJOFS_Z: handle_axis_event(joy, &joy->z_mapping, dwData); break; case DIJOFS_RX: handle_axis_event(joy, &joy->rx_mapping, dwData); break; case DIJOFS_RY: handle_axis_event(joy, &joy->ry_mapping, dwData); break; case DIJOFS_RZ: handle_axis_event(joy, &joy->rz_mapping, dwData); break; case DIJOFS_SLIDER(0): handle_axis_event(joy, &joy->slider_mapping[0], dwData); break; case DIJOFS_SLIDER(1): handle_axis_event(joy, &joy->slider_mapping[1], dwData); break; case DIJOFS_POV(0): handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); break; case DIJOFS_POV(1): handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); break; case DIJOFS_POV(2): handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); break; case DIJOFS_POV(3): handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); break; default: /* buttons */ if ((dwOfs >= DIJOFS_BUTTON0) && (dwOfs < DIJOFS_BUTTON(joy->parent.info.num_buttons))) { int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0); handle_button_event(joy, num, (dwData & 0x80)); } break; } } } _al_event_source_unlock(es); } /* handle_axis_event: [joystick thread] * Helper function to handle a state change in a non-POV axis. * The joystick must be locked BEFORE entering this function. */ static void handle_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, const AXIS_MAPPING *axis_mapping, DWORD value) { const int stick = axis_mapping->stick; const int axis = axis_mapping->axis; float pos; if (stick < 0 || stick >= joy->parent.info.num_sticks) return; if (axis < 0 || axis >= joy->parent.info.stick[stick].num_axes) return; pos = (int)value / 32767.0; joy->joystate.stick[stick].axis[axis] = pos; generate_axis_event(joy, stick, axis, pos); } /* handle_pov_event: [joystick thread] * Helper function to handle a state change in a POV device. * The joystick must be locked BEFORE entering this function. */ static void handle_pov_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, DWORD _value) { int value = _value; float old_p0, old_p1; float p0, p1; if (stick < 0 || stick >= joy->parent.info.num_sticks) return; old_p0 = joy->joystate.stick[stick].axis[0]; old_p1 = joy->joystate.stick[stick].axis[1]; /* left */ if ((value > JOY_POVBACKWARD) && (value < JOY_POVFORWARD_WRAP)) joy->joystate.stick[stick].axis[0] = p0 = -1.0; /* right */ else if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) joy->joystate.stick[stick].axis[0] = p0 = +1.0; else joy->joystate.stick[stick].axis[0] = p0 = 0.0; /* forward */ if (((value > JOY_POVLEFT) && (value <= JOY_POVFORWARD_WRAP)) || ((value >= JOY_POVFORWARD) && (value < JOY_POVRIGHT))) joy->joystate.stick[stick].axis[1] = p1 = -1.0; /* backward */ else if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) joy->joystate.stick[stick].axis[1] = p1 = +1.0; else joy->joystate.stick[stick].axis[1] = p1 = 0.0; if (old_p0 != p0) generate_axis_event(joy, stick, 0, p0); if (old_p1 != p1) generate_axis_event(joy, stick, 1, p1); } /* handle_button_event: [joystick thread] * Helper function to handle a state change in a button. * The joystick must be locked BEFORE entering this function. */ static void handle_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, bool down) { if (button < 0 && button >= joy->parent.info.num_buttons) return; if (down) { joy->joystate.button[button] = 32767; generate_button_event(joy, button, ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN); } else { joy->joystate.button[button] = 0; generate_button_event(joy, button, ALLEGRO_EVENT_JOYSTICK_BUTTON_UP); } } /* generate_axis_event: [joystick thread] * Helper to generate an event after an axis is moved. * The joystick must be locked BEFORE entering this function. */ static void generate_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, int axis, float pos) { ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; event.joystick.timestamp = al_get_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = stick; event.joystick.axis = axis; event.joystick.pos = pos; event.joystick.button = 0; _al_event_source_emit_event(es, &event); } /* generate_button_event: [joystick thread] * Helper to generate an event after a button is pressed or released. * The joystick must be locked BEFORE entering this function. */ static void generate_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, ALLEGRO_EVENT_TYPE event_type) { ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = event_type; event.joystick.timestamp = al_get_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = 0; event.joystick.axis = 0; event.joystick.pos = 0.0; event.joystick.button = button; _al_event_source_emit_event(es, &event); } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/d3d_display_formats.cpp0000644000175000001440000001445612124553574020452 0ustar tjadenusers#include "d3d.h" ALLEGRO_DEBUG_CHANNEL("d3d") struct DEPTH_STENCIL_DESC { int d; int s; D3DFORMAT format; }; static DEPTH_STENCIL_DESC depth_stencil_formats[] = { { 0, 0, (D3DFORMAT)0 }, { 32, 0, D3DFMT_D32 }, { 15, 1, D3DFMT_D15S1 }, { 24, 8, D3DFMT_D24S8 }, { 24, 0, D3DFMT_D24X8 }, { 24, 4, D3DFMT_D24X4S4 }, { 16, 0, D3DFMT_D16 }, }; static BOOL IsDepthFormatExisting(D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat) { HRESULT hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, DepthFormat); return SUCCEEDED(hr); } static const int D3D_DEPTH_FORMATS = sizeof(depth_stencil_formats) / sizeof(*depth_stencil_formats); static _AL_VECTOR eds_list; void _al_d3d_destroy_display_format_list(void) { /* Free the display format list */ for (int j = 0; j < (int)_al_vector_size(&eds_list); j++) { void **eds = (void **)_al_vector_ref(&eds_list, j); al_free(*eds); } _al_vector_free(&eds_list); } void _al_d3d_generate_display_format_list(void) { static bool fullscreen = !(al_get_new_display_flags() & ALLEGRO_FULLSCREEN); /* stop warning */ static int adapter = ~al_get_new_display_adapter(); /* stop warning */ int i; if (!_al_vector_is_empty(&eds_list) && (fullscreen == (bool)(al_get_new_display_flags() & ALLEGRO_FULLSCREEN)) && (adapter == al_get_new_display_adapter())) { return; } else if (!_al_vector_is_empty(&eds_list)) { _al_d3d_destroy_display_format_list(); } fullscreen = (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) != 0; adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; _al_vector_init(&eds_list, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS *)); /* Loop through each bit combination of: * bit 0: 16/32 bit * bit 1: single-buffer * bit 2: vsync */ for (i = 0; i < 8; i++) { int format_num = !!(i & 1); int single_buffer = !!(i & 2); int vsync = !!(i & 4); int allegro_format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; if (format_num == 1) allegro_format = ALLEGRO_PIXEL_FORMAT_RGB_565; D3DFORMAT d3d_format = (D3DFORMAT)_al_pixel_format_to_d3d(allegro_format); /* Count available multisample quality levels. */ DWORD quality_levels = 0; if (_al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, d3d_format, !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels) != D3D_OK) { _al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_REF, d3d_format, !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels); } /* Loop through available depth/stencil formats. */ for (int j = 0; j < D3D_DEPTH_FORMATS; j++) { if (j == 0 || IsDepthFormatExisting( depth_stencil_formats[j].format, d3d_format)) { DEPTH_STENCIL_DESC *ds = depth_stencil_formats + j; for (int k = 0; k < (int)quality_levels + 1; k++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds; peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_alloc_back(&eds_list); eds = *peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS *)al_malloc(sizeof *eds); memset(eds->settings, 0, sizeof(int) * ALLEGRO_DISPLAY_OPTIONS_COUNT); eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; if (format_num == 0) { eds->settings[ALLEGRO_RED_SIZE] = 8; eds->settings[ALLEGRO_GREEN_SIZE] = 8; eds->settings[ALLEGRO_BLUE_SIZE] = 8; eds->settings[ALLEGRO_RED_SHIFT] = 16; eds->settings[ALLEGRO_GREEN_SHIFT] = 8; eds->settings[ALLEGRO_BLUE_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 32; } else if (format_num == 1) { eds->settings[ALLEGRO_RED_SIZE] = 5; eds->settings[ALLEGRO_GREEN_SIZE] = 6; eds->settings[ALLEGRO_BLUE_SIZE] = 5; eds->settings[ALLEGRO_RED_SHIFT] = 11; eds->settings[ALLEGRO_GREEN_SHIFT] = 5; eds->settings[ALLEGRO_BLUE_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 16; } if (single_buffer) { eds->settings[ALLEGRO_SINGLE_BUFFER] = 1; eds->settings[ALLEGRO_UPDATE_DISPLAY_REGION] = 1; } if (vsync) { eds->settings[ALLEGRO_VSYNC] = 1; } eds->settings[ALLEGRO_DEPTH_SIZE] = ds->d; eds->settings[ALLEGRO_STENCIL_SIZE] = ds->s; if (k > 1) { eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 1; // TODO: Is it ok to use the quality level here? eds->settings[ALLEGRO_SAMPLES] = k; } } } } } ALLEGRO_INFO("found %d format combinations\n", _al_vector_size(&eds_list)); } void _al_d3d_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) { for (int i = 0; i < (int)_al_vector_size(&eds_list); i++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds; peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_ref(&eds_list, i); eds = *peds; eds->score = _al_score_display_settings(eds, ref); eds->index = i; } qsort(eds_list._items, eds_list._size, eds_list._itemsize, _al_display_settings_sorter); } /* Helper function for sorting pixel formats by index */ static int d3d_display_list_resorter(const void *p0, const void *p1) { const ALLEGRO_EXTRA_DISPLAY_SETTINGS *f0 = *((ALLEGRO_EXTRA_DISPLAY_SETTINGS **)p0); const ALLEGRO_EXTRA_DISPLAY_SETTINGS *f1 = *((ALLEGRO_EXTRA_DISPLAY_SETTINGS **)p1); if (!f0) return 1; if (!f1) return -1; if (f0->index == f1->index) { return 0; } else if (f0->index < f1->index) { return -1; } else { return 1; } } void _al_d3d_resort_display_settings(void) { qsort(eds_list._items, eds_list._size, eds_list._itemsize, d3d_display_list_resorter); } ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_d3d_get_display_settings(int i) { if (i < (int)_al_vector_size(&eds_list)) return *(ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_ref(&eds_list, i); return NULL; } allegro-5.0.10/src/win/d3d_disp.cpp0000644000175000001440000024707012146027215016201 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Direct3D display driver * * By Trent Gamblin. * */ #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/system.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/platform/aintwin.h" #include "d3d.h" static const char* _al_d3d_module_name = "d3d9.dll"; ALLEGRO_DEBUG_CHANNEL("d3d") static ALLEGRO_DISPLAY_INTERFACE *vt = 0; static HMODULE _al_d3d_module = 0; typedef LPDIRECT3D9 (WINAPI *DIRECT3DCREATE9PROC)(UINT); static DIRECT3DCREATE9PROC _al_d3d_create = (DIRECT3DCREATE9PROC)NULL; #ifdef ALLEGRO_CFG_D3D9EX typedef HRESULT (WINAPI *DIRECT3DCREATE9EXPROC)(UINT, LPDIRECT3D9EX*); static DIRECT3DCREATE9EXPROC _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)NULL; #endif LPDIRECT3D9 _al_d3d = 0; static D3DPRESENT_PARAMETERS d3d_pp; static float d3d_ortho_w; static float d3d_ortho_h; static HWND fullscreen_focus_window; static bool ffw_set = false; static bool d3d_can_wait_for_vsync; static bool render_to_texture_supported = true; static bool is_vista = false; static int num_faux_fullscreen_windows = 0; static bool already_fullscreen = false; /* real fullscreen */ static ALLEGRO_MUTEX *present_mutex; ALLEGRO_MUTEX *_al_d3d_lost_device_mutex; /* * These parameters cannot be gotten by the display thread because * they're thread local. We get them in the calling thread first. */ typedef struct D3D_DISPLAY_PARAMETERS { ALLEGRO_DISPLAY_D3D *display; volatile bool init_failed; HANDLE AckEvent; int window_x, window_y; } D3D_DISPLAY_PARAMETERS; static int allegro_formats[] = { ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_XRGB_8888, ALLEGRO_PIXEL_FORMAT_ARGB_8888, //ALLEGRO_PIXEL_FORMAT_ARGB_4444, this format seems not to be allowed ALLEGRO_PIXEL_FORMAT_RGB_565, //ALLEGRO_PIXEL_FORMAT_ARGB_1555, this format seems not to be allowed ALLEGRO_PIXEL_FORMAT_ABGR_F32, -1 }; /* Mapping of Allegro formats to D3D formats */ static int d3d_formats[] = { ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, //D3DFMT_A4R4G4B4, D3DFMT_R5G6B5, //D3DFMT_A1R5G5B5, D3DFMT_A32B32G32R32F, -1 }; #define ERR(e) case e: return #e; static char const *_al_d3d_error_string(HRESULT e) { switch (e) { ERR(D3D_OK) ERR(D3DERR_NOTAVAILABLE) ERR(D3DERR_DEVICELOST) ERR(D3DERR_INVALIDCALL) ERR(D3DERR_OUTOFVIDEOMEMORY) ERR(E_OUTOFMEMORY) } return "UNKNOWN"; } #undef ERR static D3DFORMAT d3d_get_depth_stencil_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings) { struct DEPTH_STENCIL_DESC { int d; int s; D3DFORMAT format; }; DEPTH_STENCIL_DESC formats[] = { { 0, 0, (D3DFORMAT)0 }, { 32, 0, D3DFMT_D32 }, { 15, 1, D3DFMT_D15S1 }, { 24, 8, D3DFMT_D24S8 }, { 24, 0, D3DFMT_D24X8 }, { 24, 4, D3DFMT_D24X4S4 }, { 16, 0, D3DFMT_D16 }, { -1, -1, (D3DFORMAT)0 } }; for (int i = 0; formats[i].d >= 0; i++) { if (settings->settings[ALLEGRO_DEPTH_SIZE] == formats[i].d && settings->settings[ALLEGRO_STENCIL_SIZE] == formats[i].s) return formats[i].format; } return (D3DFORMAT)0; } bool _al_d3d_supports_separate_alpha_blend(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)display; return d3d_disp->supports_separate_alpha_blend; } /* Function: al_have_d3d_non_pow2_texture_support */ bool al_have_d3d_non_pow2_texture_support(void) { D3DCAPS9 caps; int adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; /* This might have to change for multihead */ if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { return false; } } if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0) { return true; } return false; } static int d3d_get_max_texture_size(int adapter) { D3DCAPS9 caps; if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { return -1; } } return _ALLEGRO_MIN(caps.MaxTextureWidth, caps.MaxTextureHeight); } /* Function: al_have_d3d_non_square_texture_support */ bool al_have_d3d_non_square_texture_support(void) { D3DCAPS9 caps; int adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; /* This might have to change for multihead */ if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { return false; } } if ((caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0) { return true; } return false; } int _al_pixel_format_to_d3d(int format) { int i; for (i = 0; allegro_formats[i] >= 0; i++) { if (!_al_pixel_format_is_real(allegro_formats[i])) continue; if (allegro_formats[i] == format) { return d3d_formats[i]; } } //return D3DFMT_R5G6B5; return -1; } int _al_d3d_format_to_allegro(int d3d_fmt) { int i; for (i = 0; d3d_formats[i] >= 0; i++) { if (!_al_pixel_format_is_real(allegro_formats[i])) continue; if (d3d_formats[i] == d3d_fmt) { return allegro_formats[i]; } } return -1; } static int d3d_al_color_to_d3d(ALLEGRO_COLOR color) { unsigned char r, g, b, a; int result; al_unmap_rgba(color, &r, &g, &b, &a); result = D3DCOLOR_ARGB(a, r, g, b); return result; } int _al_d3d_num_display_formats(void) { return sizeof(d3d_formats) / sizeof(d3d_formats[0]); } void _al_d3d_get_nth_format(int i, int *allegro, D3DFORMAT *d3d) { *allegro = allegro_formats[i]; *d3d = (D3DFORMAT)d3d_formats[i]; } static void d3d_reset_state(ALLEGRO_DISPLAY_D3D *disp) { if (disp->device_lost) return; disp->blender_state_op = -1; disp->blender_state_src = -1; disp->blender_state_dst = -1; disp->blender_state_alpha_op = -1; disp->blender_state_alpha_src = -1; disp->blender_state_alpha_dst = -1; disp->scissor_state.bottom = -1; disp->scissor_state.top = -1; disp->scissor_state.left = -1; disp->scissor_state.right = -1; disp->device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); disp->device->SetRenderState(D3DRS_ZWRITEENABLE, true); disp->device->SetRenderState(D3DRS_LIGHTING, false); disp->device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); disp->device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); /* Set texture address mode to clamp */ if (disp->device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP) != D3D_OK) ALLEGRO_ERROR("SetSamplerState failed\n"); if (disp->device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) != D3D_OK) ALLEGRO_ERROR("SetSamplerState failed\n"); } void _al_d3d_get_current_ortho_projection_parameters(float *w, float *h) { *w = d3d_ortho_w; *h = d3d_ortho_h; } static void d3d_get_ortho_matrix(float w, float h, D3DMATRIX *matrix) { float left = 0.0f; float right = w; float top = 0.0f; float bottom = h; float neer = -1.0f; float farr = 1.0f; matrix->m[1][0] = 0.0f; matrix->m[2][0] = 0.0f; matrix->m[0][1] = 0.0f; matrix->m[2][1] = 0.0f; matrix->m[0][2] = 0.0f; matrix->m[1][2] = 0.0f; matrix->m[0][3] = 0.0f; matrix->m[1][3] = 0.0f; matrix->m[2][3] = 0.0f; matrix->m[0][0] = 2.0f / (right - left); matrix->m[1][1] = 2.0f / (top - bottom); matrix->m[2][2] = 2.0f / (farr - neer); matrix->m[3][0] = -((right+left)/(right-left)); matrix->m[3][1] = -((top+bottom)/(top-bottom)); matrix->m[3][2] = -((farr+neer)/(farr-neer)); matrix->m[3][3] = 1.0f; } static void d3d_get_identity_matrix(D3DMATRIX *matrix) { int i, j; int one = 0; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (j == one) matrix->m[j][i] = 1.0f; else matrix->m[j][i] = 0.0f; } one++; } } static void _al_d3d_set_ortho_projection(ALLEGRO_DISPLAY_D3D *disp, float w, float h) { D3DMATRIX matOrtho; D3DMATRIX matIdentity; if (disp->device_lost) return; d3d_ortho_w = w; d3d_ortho_h = h; d3d_get_identity_matrix(&matIdentity); d3d_get_ortho_matrix(w, h, &matOrtho); disp->device->SetTransform(D3DTS_PROJECTION, &matOrtho); disp->device->SetTransform(D3DTS_WORLD, &matIdentity); } static bool d3d_display_mode_matches(D3DDISPLAYMODE *dm, int w, int h, int format, int refresh_rate) { if ((dm->Width == (unsigned int)w) && (dm->Height == (unsigned int)h) && ((!refresh_rate) || (dm->RefreshRate == (unsigned int)refresh_rate)) && ((int)dm->Format == (int)_al_pixel_format_to_d3d(format))) { return true; } return false; } static bool d3d_check_mode(int w, int h, int format, int refresh_rate, UINT adapter) { UINT num_modes; UINT i; D3DDISPLAYMODE display_mode; num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)_al_pixel_format_to_d3d(format)); for (i = 0; i < num_modes; i++) { if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)_al_pixel_format_to_d3d(format), i, &display_mode) != D3D_OK) { return false; } if (d3d_display_mode_matches(&display_mode, w, h, format, refresh_rate)) { return true; } } return false; } static int d3d_get_default_refresh_rate(UINT adapter) { D3DDISPLAYMODE d3d_dm; _al_d3d->GetAdapterDisplayMode(adapter, &d3d_dm); return d3d_dm.RefreshRate; } static bool d3d_create_fullscreen_device(ALLEGRO_DISPLAY_D3D *d, int format, int refresh_rate, int flags) { int ret; bool reset_all = false; ALLEGRO_DISPLAY_WIN *win_display = &d->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; (void)flags; if (!d3d_check_mode(al_display->w, al_display->h, format, refresh_rate, win_display->adapter)) { ALLEGRO_ERROR("d3d_create_fullscreen_device: Mode not supported.\n"); return 0; } ZeroMemory(&d3d_pp, sizeof(d3d_pp)); d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(format); d3d_pp.BackBufferWidth = al_display->w; d3d_pp.BackBufferHeight = al_display->h; d3d_pp.BackBufferCount = 1; d3d_pp.Windowed = 0; if (d->vsync) { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } if (d->depth_stencil_format) { d3d_pp.EnableAutoDepthStencil = true; d3d_pp.AutoDepthStencilFormat = d->depth_stencil_format; } if (d->samples) { d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; d3d_pp.MultiSampleQuality = d->samples; } else d3d_pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; if (d->single_buffer) { d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; } else { d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; } d3d_pp.hDeviceWindow = win_display->window; if (refresh_rate) { d3d_pp.FullScreen_RefreshRateInHz = refresh_rate; } else { d3d_pp.FullScreen_RefreshRateInHz = d3d_get_default_refresh_rate(win_display->adapter); al_display->refresh_rate = d3d_pp.FullScreen_RefreshRateInHz; } if (ffw_set == false) { fullscreen_focus_window = win_display->window; ffw_set = true; } else { reset_all = true; } #ifdef ALLEGRO_CFG_D3D9EX if (is_vista) { D3DDISPLAYMODEEX mode; IDirect3D9Ex *d3d = (IDirect3D9Ex *)_al_d3d; mode.Size = sizeof(D3DDISPLAYMODEEX); mode.Width = al_display->w; mode.Height = al_display->h; mode.RefreshRate = d3d_pp.FullScreen_RefreshRateInHz; mode.Format = d3d_pp.BackBufferFormat; mode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; if ((ret = d3d->CreateDeviceEx(win_display->adapter, D3DDEVTYPE_HAL, fullscreen_focus_window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { if ((ret = d3d->CreateDeviceEx(win_display->adapter, D3DDEVTYPE_HAL, fullscreen_focus_window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { if ((ret = d3d->CreateDeviceEx(win_display->adapter, D3DDEVTYPE_REF, fullscreen_focus_window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { if ((ret = d3d->CreateDeviceEx(win_display->adapter, D3DDEVTYPE_REF, fullscreen_focus_window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { switch (ret) { case D3DERR_INVALIDCALL: ALLEGRO_ERROR("D3DERR_INVALIDCALL in create_device.\n"); break; case D3DERR_NOTAVAILABLE: ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in create_device.\n"); break; case D3DERR_OUTOFVIDEOMEMORY: ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in create_device.\n"); break; case D3DERR_DEVICELOST: ALLEGRO_ERROR("D3DERR_DEVICELOST in create_device.\n"); break; default: ALLEGRO_ERROR("Direct3D Device creation failed.\n"); break; } return 0; } } } } } else #endif { if ((ret = _al_d3d->CreateDevice(win_display->adapter, D3DDEVTYPE_HAL, fullscreen_focus_window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, &d->device)) != D3D_OK) { if ((ret = _al_d3d->CreateDevice(win_display->adapter, D3DDEVTYPE_HAL, fullscreen_focus_window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, &d->device)) != D3D_OK) { if ((ret = _al_d3d->CreateDevice(win_display->adapter, D3DDEVTYPE_REF, fullscreen_focus_window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, &d->device)) != D3D_OK) { if ((ret = _al_d3d->CreateDevice(win_display->adapter, D3DDEVTYPE_REF, fullscreen_focus_window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, &d->device)) != D3D_OK) { switch (ret) { case D3DERR_INVALIDCALL: ALLEGRO_ERROR("D3DERR_INVALIDCALL in create_device.\n"); break; case D3DERR_NOTAVAILABLE: ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in create_device.\n"); break; case D3DERR_OUTOFVIDEOMEMORY: ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in create_device.\n"); break; case D3DERR_DEVICELOST: ALLEGRO_ERROR("D3DERR_DEVICELOST in create_device.\n"); break; default: ALLEGRO_ERROR("Direct3D Device creation failed.\n"); break; } return 0; } } } } } d->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d->render_target); if (d->depth_stencil_format) d->device->GetDepthStencilSurface(&d->depth_stencil); //d->device->GetRenderTarget(0, &d->render_target); ALLEGRO_INFO("Fullscreen Direct3D device created.\n"); d->device->BeginScene(); ALLEGRO_SYSTEM *system = (ALLEGRO_SYSTEM *)al_get_system_driver(); if (reset_all) { int i; for (i = 0; i < (int)system->displays._size; i++) { ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); ALLEGRO_DISPLAY_D3D *disp = *dptr; if (disp != d) { if (disp != d && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { disp->do_reset = true; while (!disp->reset_done) { al_rest(0.001); } disp->reset_done = false; } } } } return 1; } static void d3d_destroy_device(ALLEGRO_DISPLAY_D3D *disp) { while (disp->device->Release() != 0) { ALLEGRO_WARN("d3d_destroy_device: ref count not 0\n"); } disp->device = NULL; } bool _al_d3d_render_to_texture_supported(void) { return render_to_texture_supported; } bool _al_d3d_init_display() { D3DDISPLAYMODE d3d_dm; OSVERSIONINFO info; _al_d3d_module = _al_win_safe_load_library(_al_d3d_module_name); if (_al_d3d_module == NULL) { ALLEGRO_ERROR("Failed to open '%s' library\n", _al_d3d_module_name); return false; } info.dwOSVersionInfoSize = sizeof(info); GetVersionEx(&info); is_vista = info.dwMajorVersion >= 6; #ifdef ALLEGRO_CFG_D3D9EX if (is_vista) { _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9Ex"); if (_al_d3d_create_ex != NULL) { if (_al_d3d_create_ex(D3D_SDK_VERSION, (LPDIRECT3D9EX *)&_al_d3d) != D3D_OK) { ALLEGRO_ERROR("Direct3DCreate9Ex failed\n"); FreeLibrary(_al_d3d_module); return false; } } else { ALLEGRO_INFO("Direct3DCreate9Ex not in %s\n", _al_d3d_module_name); is_vista = false; } } if (!is_vista) #endif { _al_d3d_create = (DIRECT3DCREATE9PROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9"); if (_al_d3d_create != NULL) { if ((_al_d3d = _al_d3d_create(D3D9b_SDK_VERSION)) == NULL) { ALLEGRO_ERROR("Direct3DCreate9 failed.\n"); FreeLibrary(_al_d3d_module); return false; } } else { ALLEGRO_ERROR("Direct3DCreate9 not in %s\n", _al_d3d_module_name); FreeLibrary(_al_d3d_module); return false; } } _al_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3d_dm); if (_al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d_dm.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3d_dm.Format) != D3D_OK) { if (_al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, d3d_dm.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3d_dm.Format) != D3D_OK) { render_to_texture_supported = false; } else render_to_texture_supported = true; } else render_to_texture_supported = true; ALLEGRO_INFO("Render-to-texture: %d\n", render_to_texture_supported); present_mutex = al_create_mutex(); _al_d3d_lost_device_mutex = al_create_mutex(); _al_d3d_bmp_init(); return true; } static ALLEGRO_DISPLAY_D3D *d3d_create_display_internals(ALLEGRO_DISPLAY_D3D *d3d_display, bool free_on_error); static void d3d_destroy_display_internals(ALLEGRO_DISPLAY_D3D *display); static void d3d_make_faux_fullscreen_stage_one(ALLEGRO_DISPLAY_D3D *d3d_display) { ALLEGRO_SYSTEM *system = al_get_system_driver(); if (already_fullscreen || num_faux_fullscreen_windows) { int i; for (i = 0; i < (int)system->displays._size; i++) { ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); ALLEGRO_DISPLAY_D3D *disp = *dptr; if (disp != d3d_display) {// && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { d3d_destroy_display_internals(disp); disp->win_display.end_thread = false; disp->win_display.thread_ended = false; } } } } static void d3d_make_faux_fullscreen_stage_two(ALLEGRO_DISPLAY_D3D *d3d_display) { ALLEGRO_SYSTEM *system = al_get_system_driver(); if (already_fullscreen || num_faux_fullscreen_windows) { int i; already_fullscreen = false; for (i = 0; i < (int)system->displays._size; i++) { ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); ALLEGRO_DISPLAY_D3D *disp = *dptr; if (disp != d3d_display) {// && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { if (disp->win_display.display.flags & ALLEGRO_FULLSCREEN) disp->faux_fullscreen = true; disp = d3d_create_display_internals(disp, true); if (!disp) { ALLEGRO_ERROR("d3d_create_display_internals failed.\n"); /* XXX we don't try to recover from this yet */ abort(); } ASSERT(disp); _al_d3d_recreate_bitmap_textures(disp); } } } } static bool d3d_create_device(ALLEGRO_DISPLAY_D3D *d, int format, int refresh_rate, int flags, bool convert_to_faux) { HRESULT hr; ALLEGRO_DISPLAY_WIN *win_display = &d->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; int adapter = win_display->adapter; (void)refresh_rate; (void)flags; /* Ideally if you're targetting vanilla Direct3D 9 you should create * your windowed displays before any fullscreen ones. If you don't, * your fullscreen displays will be turned into "faux-fullscreen" * displays, basically screen-filling windows set out in front of * everything else. */ #ifdef ALLEGRO_CFG_D3D9EX if (convert_to_faux) d3d_make_faux_fullscreen_stage_one(d); #else (void)convert_to_faux; #endif ZeroMemory(&d3d_pp, sizeof(d3d_pp)); d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(format); d3d_pp.BackBufferWidth = al_display->w; d3d_pp.BackBufferHeight = al_display->h; d3d_pp.BackBufferCount = 1; d3d_pp.Windowed = 1; if (d->vsync) { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } if (d->depth_stencil_format) { d3d_pp.EnableAutoDepthStencil = true; d3d_pp.AutoDepthStencilFormat = d->depth_stencil_format; ALLEGRO_INFO("Chose depth stencil format %d\n", d->depth_stencil_format); } else { ALLEGRO_INFO("Using no depth stencil buffer\n"); } if (d->samples) { d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; d3d_pp.MultiSampleQuality = d->samples; } else d3d_pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; if (d->single_buffer) { d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; } else { d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; } d3d_pp.hDeviceWindow = win_display->window; if (adapter < 0) adapter = 0; if ((hr = _al_d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, win_display->window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { ALLEGRO_DEBUG("trying D3DCREATE_SOFTWARE_VERTEXPROCESSING\n"); if ((hr = _al_d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, win_display->window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { ALLEGRO_DEBUG("trying D3DDEVTYPE_REF\n"); if ((hr = _al_d3d->CreateDevice(adapter, D3DDEVTYPE_REF, win_display->window, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { ALLEGRO_DEBUG("trying D3DDEVTYPE_REF|D3DCREATE_SOFTWARE_VERTEXPROCESSING\n"); if ((hr = _al_d3d->CreateDevice(adapter, D3DDEVTYPE_REF, win_display->window, D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { ALLEGRO_ERROR("CreateDevice failed: %s\n", _al_d3d_error_string(hr)); return 0; } } } } if (d->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d->render_target) != D3D_OK) { //if (d->device->GetRenderTarget(0, &d->render_target) != D3D_OK) { ALLEGRO_ERROR("d3d_create_device: GetBackBuffer failed.\n"); return 0; } if (d->depth_stencil_format) { if (d->device->GetDepthStencilSurface(&d->depth_stencil) != D3D_OK) { ALLEGRO_ERROR("d3d_create_device: GetDepthStencilSurface failed.\n"); return 0; } } if (d->device->BeginScene() != D3D_OK) { ALLEGRO_ERROR("BeginScene failed in create_device\n"); } else { ALLEGRO_DEBUG("BeginScene succeeded in create_device\n"); } #ifdef ALLEGRO_CFG_D3D9EX if (convert_to_faux) d3d_make_faux_fullscreen_stage_two(d); #endif ALLEGRO_DEBUG("Success\n"); return 1; } /* When a display is destroyed, its bitmaps get converted * to memory bitmaps */ static void d3d_release_bitmaps(ALLEGRO_DISPLAY *display) { while (display->bitmaps._size > 0) { ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&display->bitmaps); ALLEGRO_BITMAP *b = *bptr; _al_convert_to_memory_bitmap(b); } } static void d3d_destroy_display_internals(ALLEGRO_DISPLAY_D3D *d3d_display) { ALLEGRO_DISPLAY *al_display = (ALLEGRO_DISPLAY *)d3d_display; ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; if (d3d_display->device) { if (al_display->display_invalidated) al_display->display_invalidated(al_display); d3d_display->device->EndScene(); } d3d_release_bitmaps((ALLEGRO_DISPLAY *)d3d_display); ALLEGRO_DEBUG("waiting for display %p's thread to end\n", d3d_display); if (win_display->window) { SendMessage(win_display->window, _al_win_msg_suicide, 0, 0); while (!win_display->thread_ended) al_rest(0.001); } ASSERT(al_display->vt); } static void d3d_destroy_display(ALLEGRO_DISPLAY *display) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; ALLEGRO_DISPLAY *old_disp = al_get_current_display(); ALLEGRO_INFO("destroying display %p (current %p)\n", display, old_disp); if (old_disp != display) _al_set_current_display_only(display); if (system->mouse_grab_display == display) al_ungrab_mouse(); d3d_destroy_display_internals(d3d_display); _al_vector_find_and_delete(&system->system.displays, &display); if (system->system.displays._size <= 0) { ffw_set = false; already_fullscreen = false; } if (d3d_display->es_inited) { _al_event_source_free(&display->es); d3d_display->es_inited = false; } _al_vector_free(&display->bitmaps); if (old_disp != display) _al_set_current_display_only(old_disp); al_free(display->vertex_cache); al_free(display); } void _al_d3d_prepare_for_reset(ALLEGRO_DISPLAY_D3D *disp) { _al_d3d_release_default_pool_textures(); while (disp->render_target && disp->render_target->Release() != 0) { ALLEGRO_WARN("_al_d3d_prepare_for_reset: (bb) ref count not 0\n"); } disp->render_target = NULL; if (disp->depth_stencil_format) { disp->depth_stencil->Release(); } } static bool _al_d3d_reset_device(ALLEGRO_DISPLAY_D3D *d3d_display) { ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; al_lock_mutex(_al_d3d_lost_device_mutex); _al_d3d_prepare_for_reset(d3d_display); if (al_display->flags & ALLEGRO_FULLSCREEN) { HRESULT hr; ZeroMemory(&d3d_pp, sizeof(d3d_pp)); d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(_al_deduce_color_format(&al_display->extra_settings)); d3d_pp.BackBufferWidth = al_display->w; d3d_pp.BackBufferHeight = al_display->h; d3d_pp.BackBufferCount = 1; d3d_pp.Windowed = 0; d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3d_pp.hDeviceWindow = win_display->window; if (d3d_display->vsync) { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } if (d3d_display->depth_stencil_format) { d3d_pp.EnableAutoDepthStencil = true; d3d_pp.AutoDepthStencilFormat = d3d_display->depth_stencil_format; } if (d3d_display->samples) { d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; d3d_pp.MultiSampleQuality = d3d_display->samples; } else d3d_pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; if (d3d_display->single_buffer) { d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; } else { d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; } if (al_display->refresh_rate) { d3d_pp.FullScreen_RefreshRateInHz = al_display->refresh_rate; } else { d3d_pp.FullScreen_RefreshRateInHz = d3d_get_default_refresh_rate(win_display->adapter); } #ifdef ALLEGRO_CFG_D3D9EX if (is_vista) { D3DDISPLAYMODEEX mode; IDirect3DDevice9Ex *dev = (IDirect3DDevice9Ex *)d3d_display->device; mode.Size = sizeof(D3DDISPLAYMODEEX); mode.Width = d3d_pp.BackBufferWidth; mode.Height = d3d_pp.BackBufferHeight; mode.RefreshRate = d3d_pp.FullScreen_RefreshRateInHz; mode.Format = d3d_pp.BackBufferFormat; mode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; hr = dev->ResetEx(&d3d_pp, &mode); } else #endif { hr = d3d_display->device->Reset(&d3d_pp); } if (hr != D3D_OK) { switch (hr) { case D3DERR_INVALIDCALL: ALLEGRO_ERROR("D3DERR_INVALIDCALL in reset.\n"); break; case D3DERR_NOTAVAILABLE: ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in reset.\n"); break; case D3DERR_OUTOFVIDEOMEMORY: ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in reset.\n"); break; case D3DERR_DEVICELOST: ALLEGRO_ERROR("D3DERR_DEVICELOST in reset.\n"); break; default: ALLEGRO_ERROR("Direct3D Device reset failed (unknown reason).\n"); break; } al_unlock_mutex(_al_d3d_lost_device_mutex); return 0; } } else { ZeroMemory(&d3d_pp, sizeof(d3d_pp)); d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(_al_deduce_color_format(&al_display->extra_settings)); d3d_pp.BackBufferWidth = al_display->w; d3d_pp.BackBufferHeight = al_display->h; d3d_pp.BackBufferCount = 1; d3d_pp.Windowed = 1; d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3d_pp.hDeviceWindow = win_display->window; if (d3d_display->vsync) { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } if (d3d_display->depth_stencil_format) { d3d_pp.EnableAutoDepthStencil = true; d3d_pp.AutoDepthStencilFormat = d3d_display->depth_stencil_format; } if (d3d_display->samples) { d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; d3d_pp.MultiSampleQuality = d3d_display->samples; } else d3d_pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; if (d3d_display->single_buffer) { d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; } else { d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; } /* Must be 0 for windowed modes */ d3d_pp.FullScreen_RefreshRateInHz = 0; if (d3d_display->device->Reset(&d3d_pp) != D3D_OK) { ALLEGRO_WARN("Reset failed\n"); al_unlock_mutex(_al_d3d_lost_device_mutex); return 0; } } d3d_display->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3d_display->render_target); if (d3d_display->depth_stencil_format) { d3d_display->device->GetDepthStencilSurface(&d3d_display->depth_stencil); } _al_d3d_refresh_texture_memory(); d3d_display->device->BeginScene(); d3d_reset_state(d3d_display); al_unlock_mutex(_al_d3d_lost_device_mutex); return 1; } static int d3d_choose_display_format(int fake) { /* Pick an appropriate format if the user is vague */ switch (fake) { case ALLEGRO_PIXEL_FORMAT_ANY: case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: fake = ALLEGRO_PIXEL_FORMAT_XRGB_8888; break; case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: fake = ALLEGRO_PIXEL_FORMAT_RGB_565; break; default: break; } return fake; } static BOOL IsTextureFormatOk(D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat) { HRESULT hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, AdapterFormat, 0, D3DRTYPE_TEXTURE, TextureFormat); if (hr != D3D_OK) { hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, AdapterFormat, 0, D3DRTYPE_TEXTURE, TextureFormat); } return SUCCEEDED(hr); } static int real_choose_bitmap_format(ALLEGRO_DISPLAY_D3D *d3d_display, int bits, bool alpha) { int i; for (i = 0; allegro_formats[i] >= 0; i++) { int aformat = allegro_formats[i]; D3DFORMAT dformat; D3DFORMAT adapter_format; int adapter_format_allegro; if (!_al_pixel_format_is_real(aformat)) { ALLEGRO_DEBUG("Fake format\n"); continue; } if (bits && al_get_pixel_format_bits(aformat) != bits) { ALLEGRO_DEBUG("#Bits don't match\n"); continue; } if (alpha && !_al_pixel_format_has_alpha(aformat)) { ALLEGRO_DEBUG("Alpha doesn't match\n"); continue; } dformat = (D3DFORMAT)d3d_formats[i]; adapter_format_allegro = d3d_display->format; if (!_al_pixel_format_is_real(adapter_format_allegro)) adapter_format_allegro = d3d_choose_display_format(adapter_format_allegro); ALLEGRO_DEBUG("Adapter format is %d\n", adapter_format_allegro); adapter_format = (D3DFORMAT)_al_pixel_format_to_d3d(adapter_format_allegro); if (IsTextureFormatOk(dformat, adapter_format)) { ALLEGRO_DEBUG("Found a format\n"); return aformat; } ALLEGRO_DEBUG("Texture format not OK\n"); } ALLEGRO_WARN("Failed to find format\n"); return -1; } static int d3d_choose_bitmap_format(ALLEGRO_DISPLAY_D3D *d3d_display, int fake) { switch (fake) { case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: fake = real_choose_bitmap_format(d3d_display, 0, false); break; case ALLEGRO_PIXEL_FORMAT_ANY: case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: fake = real_choose_bitmap_format(d3d_display, 0, true); break; case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: fake = real_choose_bitmap_format(d3d_display, 32, false); break; case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: fake = real_choose_bitmap_format(d3d_display, 32, true); break; case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: fake = real_choose_bitmap_format(d3d_display, 24, false); break; case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: fake = real_choose_bitmap_format(d3d_display, 16, false); break; case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: fake = real_choose_bitmap_format(d3d_display, 16, true); break; case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: fake = real_choose_bitmap_format(d3d_display, 15, false); break; default: fake = -1; } return fake; } struct CREATE_WINDOW_INFO { ALLEGRO_DISPLAY *display; DISPLAY_DEVICE dd; ALLEGRO_MONITOR_INFO mi; int w; int h; int refresh_rate; int flags; bool inited; bool quit; int window_x, window_y; }; static void d3d_create_window_proc(CREATE_WINDOW_INFO *info) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)info->display; al_set_new_window_position(info->window_x, info->window_y); win_display->window = _al_win_create_window( info->display, info->w, info->h, info->flags ); } static void *d3d_create_faux_fullscreen_window_proc(void *arg) { CREATE_WINDOW_INFO *info = (CREATE_WINDOW_INFO *)arg; ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)info->display; win_display->window = _al_win_create_faux_fullscreen_window( info->dd.DeviceName, info->display, info->mi.x1, info->mi.y1, info->w, info->h, info->refresh_rate, info->flags ); return NULL; } /* * Display must be created in same thread that resets it */ static void *d3d_display_thread_proc(void *arg) { ALLEGRO_DISPLAY_D3D *d3d_display; ALLEGRO_DISPLAY_WIN *win_display; ALLEGRO_DISPLAY *al_display; D3D_DISPLAY_PARAMETERS *params = (D3D_DISPLAY_PARAMETERS *)arg; int new_format; bool convert_to_faux; CREATE_WINDOW_INFO *info = (CREATE_WINDOW_INFO *)al_calloc(1, sizeof(*info)); HRESULT hr; bool lost_event_generated = false; D3DCAPS9 caps; MSG msg; info->window_x = params->window_x; info->window_y = params->window_y; d3d_display = params->display; win_display = &d3d_display->win_display; al_display = &win_display->display; if (al_display->flags & ALLEGRO_FULLSCREEN) { convert_to_faux = true; } else { convert_to_faux = false; } /* So that we can call the functions using TLS from this thread. */ al_set_new_display_flags(al_display->flags); new_format = _al_deduce_color_format(&al_display->extra_settings); /* This should never happen, I think */ if (!_al_pixel_format_is_real(_al_deduce_color_format(&al_display->extra_settings))) { int f = d3d_choose_display_format(_al_deduce_color_format(&al_display->extra_settings)); if (f < 0) { d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } new_format = f; _al_set_color_components(new_format, &al_display->extra_settings, ALLEGRO_REQUIRE); } ALLEGRO_INFO("Chose a display format: %d\n", new_format); d3d_display->format = new_format; if (d3d_display->faux_fullscreen) { DEVMODE dm; bool found = true; int refresh_rate; num_faux_fullscreen_windows++; d3d_make_faux_fullscreen_stage_one(d3d_display); al_get_monitor_info(win_display->adapter, &info->mi); /* Yes this is an "infinite" loop (suggested by MS on msdn) */ for (int i = 0; ; i++) { info->dd.cb = sizeof(info->dd); if (!EnumDisplayDevices(NULL, i, &info->dd, 0)) { found = false; break; } if (!EnumDisplaySettings(info->dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { continue; } if (info->mi.x1 == dm.dmPosition.x && info->mi.y1 == dm.dmPosition.y) { break; } } if (!found) { ALLEGRO_ERROR("d3d_display_thread_proc: Error setting faux fullscreen mode.\n"); num_faux_fullscreen_windows--; d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } if (al_display->refresh_rate) { refresh_rate = al_display->refresh_rate; } else { refresh_rate = d3d_get_default_refresh_rate(win_display->adapter); } d3d_display->device_name = (TCHAR *)al_malloc(sizeof(TCHAR)*32); strcpy(d3d_display->device_name, info->dd.DeviceName); ALLEGRO_DEBUG("going to call _al_win_create_faux_fullscreen_window\n"); info->display = al_display; info->w = al_display->w; info->h = al_display->h; info->refresh_rate = refresh_rate; info->flags = al_display->flags; d3d_create_faux_fullscreen_window_proc(info); if (!win_display->window) { ALLEGRO_DEBUG("Failed to create window (faux)fullscreen.\n"); d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } ALLEGRO_DEBUG("Called _al_win_create_faux_fullscreen_window.\n"); d3d_make_faux_fullscreen_stage_two(d3d_display); convert_to_faux = false; } else { ALLEGRO_INFO("Normal window.\n"); info->display = al_display; info->w = al_display->w; info->h = al_display->h; info->flags = al_display->flags; d3d_create_window_proc(info); } if (!win_display->window) { ALLEGRO_DEBUG("Failed to create regular window.\n"); d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } if (!(al_display->flags & ALLEGRO_FULLSCREEN) || d3d_display->faux_fullscreen) { if (!d3d_create_device(d3d_display, _al_deduce_color_format(&al_display->extra_settings), al_display->refresh_rate, al_display->flags, convert_to_faux)) { d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } } else { ALLEGRO_DEBUG("Creating real fullscreen device\n"); if (!d3d_create_fullscreen_device(d3d_display, _al_deduce_color_format(&al_display->extra_settings), al_display->refresh_rate, al_display->flags)) { d3d_destroy_display(al_display); params->init_failed = true; SetEvent(params->AckEvent); return NULL; } ALLEGRO_INFO("Real fullscreen device created\n"); } al_display->backbuffer_format = _al_deduce_color_format(&al_display->extra_settings); d3d_display->device->GetDeviceCaps(&caps); d3d_can_wait_for_vsync = ((caps.Caps & D3DCAPS_READ_SCANLINE) != 0); params->init_failed = false; win_display->thread_ended = false; win_display->end_thread = false; SetEvent(params->AckEvent); while (!win_display->end_thread) { al_rest(0.001); if (PeekMessage(&msg, NULL, 0, 0, FALSE)) { if (GetMessage(&msg, NULL, 0, 0) != 0) DispatchMessage(&msg); else break; /* WM_QUIT received or error (GetMessage returned -1) */ } if (!d3d_display->device) { continue; } hr = d3d_display->device->TestCooperativeLevel(); if (hr == D3D_OK) { d3d_display->device_lost = false; } else if (hr == D3DERR_DEVICELOST) { /* device remains lost */ /* Set device_lost flag immediately. This prevents a crash in * the DrawPrimitiveUP call in d3d_flush_vertex_cache. */ d3d_display->device_lost = true; if (!lost_event_generated) { ALLEGRO_DEBUG("D3DERR_DEVICELOST: d3d_display=%p\n", d3d_display); lost_event_generated = true; if (d3d_display->suppress_lost_events) { ALLEGRO_DEBUG("DISPLAY_LOST event suppressed\n"); } else { _al_event_source_lock(&al_display->es); if (_al_event_source_needs_to_generate_event(&al_display->es)) { ALLEGRO_EVENT event; memset(&event, 0, sizeof(event)); event.display.type = ALLEGRO_EVENT_DISPLAY_LOST; event.display.timestamp = al_get_time(); _al_event_source_emit_event(&al_display->es, &event); } _al_event_source_unlock(&al_display->es); al_rest(0.5); // give user time to respond } } } else if (hr == D3DERR_DEVICENOTRESET) { if (_al_d3d_reset_device(d3d_display)) { d3d_display->device_lost = false; d3d_reset_state(d3d_display); _al_d3d_set_ortho_projection(d3d_display, al_display->w, al_display->h); _al_event_source_lock(&al_display->es); if (_al_event_source_needs_to_generate_event(&al_display->es)) { ALLEGRO_EVENT event; memset(&event, 0, sizeof(event)); event.display.type = ALLEGRO_EVENT_DISPLAY_FOUND; event.display.timestamp = al_get_time(); _al_event_source_emit_event(&al_display->es, &event); } _al_event_source_unlock(&al_display->es); lost_event_generated = false; } } if (d3d_display->do_reset) { d3d_display->reset_success = _al_d3d_reset_device(d3d_display); d3d_display->do_reset = false; d3d_display->reset_done = true; } } d3d_destroy_device(d3d_display); if (d3d_display->faux_fullscreen) { ChangeDisplaySettingsEx(d3d_display->device_name, NULL, NULL, 0, NULL); al_free(d3d_display->device_name); num_faux_fullscreen_windows--; } win_display->thread_ended = true; al_free(info); ALLEGRO_INFO("d3d display thread exits\n"); return NULL; } static ALLEGRO_DISPLAY_D3D *d3d_create_display_helper(int w, int h) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)al_malloc(sizeof(ALLEGRO_DISPLAY_D3D)); ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; memset(d3d_display, 0, sizeof *d3d_display); win_display->adapter = _al_win_determine_adapter(); /* w/h may be reset below if ALLEGRO_FULLSCREEN_WINDOW is set */ al_display->w = w; al_display->h = h; al_display->refresh_rate = al_get_new_display_refresh_rate(); al_display->flags = al_get_new_display_flags(); al_display->vt = vt; ASSERT(al_display->vt); #ifdef ALLEGRO_CFG_D3D9EX if (!is_vista) #endif { if (al_display->flags & ALLEGRO_FULLSCREEN) { if (already_fullscreen || system->system.displays._size != 0) { d3d_display->faux_fullscreen = true; } else { already_fullscreen = true; d3d_display->faux_fullscreen = false; } } else { if (al_display->flags & ALLEGRO_FULLSCREEN_WINDOW) { ALLEGRO_MONITOR_INFO mi; al_get_monitor_info(win_display->adapter, &mi); al_display->w = mi.x2 - mi.x1; al_display->h = mi.y2 - mi.y1; d3d_display->faux_fullscreen = true; } else { d3d_display->faux_fullscreen = false; } win_display->toggle_w = w; win_display->toggle_h = h; } } #ifdef ALLEGRO_CFG_D3D9EX else { d3d_display->faux_fullscreen = false; } #endif return d3d_display; } /* This function may return the original d3d_display argument, * or a new one, or NULL on error. */ static ALLEGRO_DISPLAY_D3D *d3d_create_display_internals( ALLEGRO_DISPLAY_D3D *d3d_display, bool free_on_error) { D3D_DISPLAY_PARAMETERS params; ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref = _al_get_new_display_settings(); int num_modes; int i; int window_x, window_y; /* save width and height in case new fullscreen-mode * fails inside d3d_display_thread_proc and destroys al_display */ int pre_destroy_w = al_display->w; int pre_destroy_h = al_display->h; params.display = d3d_display; /* The window is created in a separate thread so we need to pass this * TLS on */ al_get_new_window_position(&window_x, &window_y); params.window_x = window_x; params.window_y = window_y; _al_d3d_generate_display_format_list(); _al_d3d_score_display_settings(ref); /* Checking each mode is slow, so do a resolution check first */ if (al_display->flags & ALLEGRO_FULLSCREEN) { num_modes = al_get_num_display_modes(); while (num_modes >= 0) { ALLEGRO_DISPLAY_MODE mode; al_get_display_mode(num_modes, &mode); if (mode.width == al_display->w && mode.height == al_display->h) { break; } num_modes--; } if (num_modes < 0) { // Failing resolution test is like failing to create a window // This helps determining if the window message thread needs // to be destroyed. win_display->window = NULL; if (free_on_error) { al_free(d3d_display); } return NULL; } } ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; for (i = 0; (eds = _al_d3d_get_display_settings(i)); i++) { ALLEGRO_DEBUG("Trying format %d.\n", eds->index); d3d_display->depth_stencil_format = d3d_get_depth_stencil_format(eds); d3d_display->samples = eds->settings[ALLEGRO_SAMPLES]; d3d_display->single_buffer = eds->settings[ALLEGRO_SINGLE_BUFFER] ? true : false; d3d_display->vsync = eds->settings[ALLEGRO_VSYNC] == 1; memcpy(&al_display->extra_settings, eds, sizeof al_display->extra_settings); params.init_failed = true; win_display->thread_ended = true; params.AckEvent = CreateEvent(NULL, false, false, NULL); al_run_detached_thread(d3d_display_thread_proc, ¶ms); /* Wait some _finite_ time (10 secs or so) for display thread to init, and * give up if something horrible happened to it, unless we're in debug mode * and we may have intentionally stopped the execution to analyze the code. */ #ifdef DEBUGMODE WaitForSingleObject(params.AckEvent, INFINITE); #else WaitForSingleObject(params.AckEvent, 10*1000); #endif ALLEGRO_DEBUG("Resumed after wait.\n"); CloseHandle(params.AckEvent); if (!params.init_failed) { break; } ALLEGRO_INFO("Format %d failed.\n", i); // Display has been destroyed in d3d_display_thread_proc, create empty template again d3d_display = d3d_create_display_helper(pre_destroy_w, pre_destroy_h); win_display = &d3d_display->win_display; al_display = &win_display->display; params.display = d3d_display; ALLEGRO_DEBUG("d3d_display = %p\n", d3d_display); ALLEGRO_DEBUG("win_display = %p\n", win_display); ALLEGRO_DEBUG("al_display = %p\n", al_display); ASSERT(al_display->vt); } // Re-sort the display format list for use later _al_d3d_resort_display_settings(); if (!eds) { ALLEGRO_WARN("All %d formats failed.\n", i); if (free_on_error) { al_free(d3d_display); } return NULL; } ALLEGRO_INFO("Format %d succeeded.\n", eds->index); d3d_reset_state(d3d_display); //d3d_display->backbuffer_bmp.render_target = d3d_display->render_target; d3d_display->backbuffer_bmp.is_backbuffer = true; d3d_display->backbuffer_bmp.bitmap.display = al_display; d3d_display->backbuffer_bmp.bitmap.format = _al_deduce_color_format(&al_display->extra_settings); d3d_display->backbuffer_bmp.bitmap.flags = 0; d3d_display->backbuffer_bmp.bitmap.w = al_display->w; d3d_display->backbuffer_bmp.bitmap.h = al_display->h; d3d_display->backbuffer_bmp.bitmap.cl = 0; d3d_display->backbuffer_bmp.bitmap.ct = 0; d3d_display->backbuffer_bmp.bitmap.cr_excl = al_display->w; d3d_display->backbuffer_bmp.bitmap.cb_excl = al_display->h; d3d_display->backbuffer_bmp.bitmap.vt = (ALLEGRO_BITMAP_INTERFACE *)_al_bitmap_d3d_driver(); d3d_display->backbuffer_bmp.display = d3d_display; /* Alpha blending is the default */ d3d_display->device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); d3d_display->device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); d3d_display->device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); ALLEGRO_DEBUG("Returning d3d_display: %p\n", d3d_display); return d3d_display; } static ALLEGRO_DISPLAY *d3d_create_display_locked(int w, int h) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_D3D *d3d_display = d3d_create_display_helper(w, h); ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; ALLEGRO_DISPLAY *al_display = &win_display->display; ALLEGRO_DISPLAY_D3D **add; D3DCAPS9 caps; ALLEGRO_INFO("faux_fullscreen=%d\n", d3d_display->faux_fullscreen); ALLEGRO_DEBUG("al_display=%p\n", al_display); ALLEGRO_DEBUG("al_display->vt=%p\n", al_display->vt); ASSERT(al_display->vt); d3d_display = d3d_create_display_internals(d3d_display, true); if (!d3d_display) { ALLEGRO_ERROR("d3d_create_display failed.\n"); return NULL; } win_display = &d3d_display->win_display; al_display = &win_display->display; ALLEGRO_DEBUG("al_display=%p\n", al_display); ALLEGRO_DEBUG("al_display->vt=%p\n", al_display->vt); ASSERT(al_display->vt); /* Add ourself to the list of displays. */ add = (ALLEGRO_DISPLAY_D3D **)_al_vector_alloc_back(&system->system.displays); *add = d3d_display; /* Each display is an event source. */ _al_event_source_init(&al_display->es); d3d_display->es_inited = true; #if 0 /* Setup the mouse */ if (al_display->flags & ALLEGRO_FULLSCREEN && al_is_mouse_installed()) { RAWINPUTDEVICE rid[1]; rid[0].usUsagePage = 0x01; rid[0].usUsage = 0x02; rid[0].dwFlags = RIDEV_NOLEGACY; rid[0].hwndTarget = 0; if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { ALLEGRO_WARN("Failed to init mouse.\n"); } } #endif win_display->mouse_selected_hcursor = 0; win_display->mouse_cursor_shown = false; win_display->can_acknowledge = false; SetForegroundWindow(win_display->window); _al_win_grab_input(win_display); _al_win_show_mouse_cursor(al_display); if (_al_d3d->GetDeviceCaps(win_display->adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK && _al_d3d->GetDeviceCaps(win_display->adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { d3d_display->supports_separate_alpha_blend = false; } else { d3d_display->supports_separate_alpha_blend = ((caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) != 0); } ASSERT(al_display->vt); return al_display; } static ALLEGRO_DISPLAY *d3d_create_display(int w, int h) { ALLEGRO_DISPLAY *display; ALLEGRO_DISPLAY_WIN *win_display; int *s; al_lock_mutex(present_mutex); display = d3d_create_display_locked(w, h); win_display = (ALLEGRO_DISPLAY_WIN *)display; al_unlock_mutex(present_mutex); if (!display) return NULL; ASSERT(display->vt); s = display->extra_settings.settings; s[ALLEGRO_MAX_BITMAP_SIZE] = d3d_get_max_texture_size(win_display->adapter); s[ALLEGRO_SUPPORT_SEPARATE_ALPHA] = _al_d3d_supports_separate_alpha_blend(display); s[ALLEGRO_SUPPORT_NPOT_BITMAP] = al_have_d3d_non_pow2_texture_support(); s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = render_to_texture_supported; return display; } static bool d3d_set_current_display(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)d; if (d3d_display->do_reset) return false; return true; } static int d3d_al_blender_to_d3d(int al_mode) { const int d3d_modes[ALLEGRO_NUM_BLEND_MODES] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_SRCCOLOR, D3DBLEND_DESTCOLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_INVDESTCOLOR }; return d3d_modes[al_mode]; } void _al_d3d_set_blender(ALLEGRO_DISPLAY_D3D *d3d_display) { bool blender_changed; int op, src, dst, alpha_op, alpha_src, alpha_dst; DWORD allegro_to_d3d_blendop[ALLEGRO_NUM_BLEND_OPERATIONS] = { D3DBLENDOP_ADD, D3DBLENDOP_SUBTRACT, D3DBLENDOP_REVSUBTRACT }; blender_changed = false; al_get_separate_blender(&op, &src, &dst, &alpha_op, &alpha_src, &alpha_dst); if (d3d_display->blender_state_op != op) { /* These may not be supported but they will always fall back to ADD * in that case. */ d3d_display->device->SetRenderState(D3DRS_BLENDOP, allegro_to_d3d_blendop[op]); d3d_display->blender_state_op = op; blender_changed = true; } if (d3d_display->blender_state_alpha_op != alpha_op) { /* These may not be supported but they will always fall back to ADD * in that case. */ d3d_display->device->SetRenderState(D3DRS_BLENDOPALPHA, allegro_to_d3d_blendop[alpha_op]); d3d_display->blender_state_alpha_op = alpha_op; blender_changed = true; } if (d3d_display->blender_state_src != src) { if (d3d_display->device->SetRenderState(D3DRS_SRCBLEND, d3d_al_blender_to_d3d(src)) != D3D_OK) ALLEGRO_ERROR("Failed to set source blender\n"); d3d_display->blender_state_src = src; blender_changed = true; } if (d3d_display->blender_state_dst != dst) { if (d3d_display->device->SetRenderState(D3DRS_DESTBLEND, d3d_al_blender_to_d3d(dst)) != D3D_OK) ALLEGRO_ERROR("Failed to set dest blender\n"); d3d_display->blender_state_dst = dst; blender_changed = true; } if (d3d_display->blender_state_alpha_src != alpha_src) { if (d3d_display->device->SetRenderState(D3DRS_SRCBLENDALPHA, d3d_al_blender_to_d3d(alpha_src)) != D3D_OK) ALLEGRO_ERROR("Failed to set source alpha blender\n"); d3d_display->blender_state_alpha_src = alpha_src; blender_changed = true; } if (d3d_display->blender_state_alpha_dst != alpha_dst) { if (d3d_display->device->SetRenderState(D3DRS_DESTBLENDALPHA, d3d_al_blender_to_d3d(alpha_dst)) != D3D_OK) ALLEGRO_ERROR("Failed to set dest alpha blender\n"); d3d_display->blender_state_alpha_dst = alpha_dst; blender_changed = true; } if (blender_changed) { bool enable_separate_blender = (op != alpha_op) || (src != alpha_src) || (dst != alpha_dst); if (enable_separate_blender) { if (d3d_display->device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true) != D3D_OK) ALLEGRO_ERROR("D3DRS_SEPARATEALPHABLENDENABLE failed\n"); } /* thedmd: Why is this function called anyway? */ d3d_display->device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); } } static void d3d_clear(ALLEGRO_DISPLAY *al_display, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; if (d3d_display->device_lost) return; if (d3d_display->device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB((int)(color->a*255), (int)(color->r*255), (int)(color->g*255), (int)(color->b*255)), 0, 0) != D3D_OK) { ALLEGRO_ERROR("Clear failed\n"); } } static void d3d_draw_pixel(ALLEGRO_DISPLAY *al_display, float x, float y, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)al_display; ALLEGRO_COLOR c; D3D_TL_VERTEX vertices[1]; vertices[0].x = x; vertices[0].y = y; vertices[0].z = 0; c.r = color->r; c.g = color->g; c.b = color->b; c.a = color->a; vertices[0].diffuse = d3d_al_color_to_d3d(c); _al_d3d_set_blender(disp); disp->device->SetTexture(0, NULL); disp->device->SetFVF(D3DFVF_TL_VERTEX); if (disp->device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, vertices, sizeof(D3D_TL_VERTEX)) != D3D_OK) { ALLEGRO_ERROR("d3d_draw_pixel: DrawPrimitive failed.\n"); return; } } static void d3d_flip_display(ALLEGRO_DISPLAY *al_display) { ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; HRESULT hr; if (d3d_display->device_lost) return; al_lock_mutex(present_mutex); d3d_display->device->EndScene(); hr = d3d_display->device->Present(NULL, NULL, win_display->window, NULL); d3d_display->device->BeginScene(); al_unlock_mutex(present_mutex); if (hr == D3DERR_DEVICELOST) { d3d_display->device_lost = true; return; } else { _al_d3d_prepare_bitmaps_for_reset(d3d_display); } } static void d3d_update_display_region(ALLEGRO_DISPLAY *al_display, int x, int y, int width, int height) { ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; HRESULT hr; RGNDATA *rgndata; if (d3d_display->device_lost) return; if (d3d_display->single_buffer) { RECT rect; rect.left = x; rect.right = x+width; rect.top = y; rect.bottom = y+height; rgndata = (RGNDATA *)al_malloc(sizeof(RGNDATA)+sizeof(RECT)-1); rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); rgndata->rdh.iType = RDH_RECTANGLES; rgndata->rdh.nCount = 1; rgndata->rdh.nRgnSize = sizeof(RECT); memcpy(&rgndata->rdh.rcBound, &rect, sizeof(RECT)); memcpy(rgndata->Buffer, &rect, sizeof(RECT)); d3d_display->device->EndScene(); hr = d3d_display->device->Present(&rect, &rect, win_display->window, rgndata); d3d_display->device->BeginScene(); al_free(rgndata); if (hr == D3DERR_DEVICELOST) { d3d_display->device_lost = true; return; } } else { d3d_flip_display(al_display); } } /* * Sets a clipping rectangle */ void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap) { ALLEGRO_DISPLAY_D3D *disp = ((ALLEGRO_BITMAP_D3D *)bitmap)->display; RECT rect; if (!disp) return; if (bitmap->parent) { rect.left = bitmap->xofs + bitmap->cl; rect.right = bitmap->xofs + bitmap->cr_excl; rect.top = bitmap->yofs + bitmap->ct; rect.bottom = bitmap->yofs + bitmap->cb_excl; } else { rect.left = bitmap->cl; rect.right = bitmap->cr_excl; rect.top = bitmap->ct; rect.bottom = bitmap->cb_excl; } if (memcmp(&disp->scissor_state, &rect, sizeof(RECT)) != 0) { if (rect.left == 0 && rect.top == 0 && rect.right == disp->win_display.display.w && rect.left == disp->win_display.display.h) { disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, false); return; } disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, true); disp->device->SetScissorRect(&rect); disp->scissor_state = rect; } } static bool d3d_acknowledge_resize(ALLEGRO_DISPLAY *d) { WINDOWINFO wi; ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)d; ALLEGRO_DISPLAY_WIN *win_display = &disp->win_display; int w, h; ALLEGRO_STATE state; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_display->window, &wi); w = wi.rcClient.right - wi.rcClient.left; h = wi.rcClient.bottom - wi.rcClient.top; if (w > 0 && h > 0) { d->w = w; d->h = h; } disp->backbuffer_bmp.bitmap.w = d->w; disp->backbuffer_bmp.bitmap.h = d->h; disp->backbuffer_bmp.bitmap.cl = 0; disp->backbuffer_bmp.bitmap.ct = 0; disp->backbuffer_bmp.bitmap.cr_excl = w; disp->backbuffer_bmp.bitmap.cb_excl = h; disp->do_reset = true; while (!disp->reset_done) { al_rest(0.001); } disp->reset_done = false; al_store_state(&state, ALLEGRO_STATE_DISPLAY | ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(al_get_backbuffer(d)); al_set_clipping_rectangle(0, 0, d->w, d->h); al_restore_state(&state); return disp->reset_success; } static bool d3d_resize_helper(ALLEGRO_DISPLAY *d, int width, int height) { ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)d; ALLEGRO_DISPLAY_WIN *win_display = &disp->win_display; ALLEGRO_DISPLAY_D3D *new_disp; int full_w, full_h; ALLEGRO_MONITOR_INFO mi; int adapter = win_display->adapter; ALLEGRO_STATE backup; al_get_monitor_info(adapter, &mi); full_w = mi.x2 - mi.x1; full_h = mi.y2 - mi.y1; if ((d->flags & ALLEGRO_FULLSCREEN_WINDOW) && (full_w != width || full_h != height)) { win_display->toggle_w = width; win_display->toggle_h = height; return true; } win_display->can_acknowledge = false; if (d->flags & ALLEGRO_FULLSCREEN) { /* Don't generate ALLEGRO_EVENT_DISPLAY_LOST events when destroying a * display for resizing. */ disp->suppress_lost_events = true; d3d_destroy_display_internals(disp); d->w = width; d->h = height; /* reset refresh rate (let new mode choose one) */ d->refresh_rate = 0; win_display->end_thread = false; win_display->thread_ended = false; /* What's this? */ ALLEGRO_SYSTEM *system = al_get_system_driver(); if (system->displays._size <= 1) { ffw_set = false; } /* The original display needs to remain intact so we can * recover if resizing a display fails. */ new_disp = d3d_create_display_internals(disp, false); if (!new_disp) { ALLEGRO_ERROR("d3d_create_display_internals failed.\n"); ASSERT(d->vt); return false; } ASSERT(new_disp == disp); ASSERT(d->vt); disp->suppress_lost_events = false; al_set_target_bitmap(al_get_backbuffer(d)); _al_d3d_recreate_bitmap_textures(disp); disp->backbuffer_bmp.bitmap.w = width; disp->backbuffer_bmp.bitmap.h = height; } else { RECT win_size; WINDOWINFO wi; win_size.left = 0; win_size.top = 0; win_size.right = width; win_size.bottom = height; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_display->window, &wi); AdjustWindowRectEx(&win_size, wi.dwStyle, false, wi.dwExStyle); // FIXME: Handle failure (for example if window constraints are active?) SetWindowPos(win_display->window, HWND_TOP, 0, 0, win_size.right-win_size.left, win_size.bottom-win_size.top, SWP_NOMOVE|SWP_NOZORDER); if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) { win_display->toggle_w = width; win_display->toggle_h = height; } /* * The clipping rectangle and bitmap size must be * changed to match the new size. */ al_store_state(&backup, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(&disp->backbuffer_bmp.bitmap); disp->backbuffer_bmp.bitmap.w = width; disp->backbuffer_bmp.bitmap.h = height; al_set_clipping_rectangle(0, 0, width, height); _al_d3d_set_bitmap_clip(&disp->backbuffer_bmp.bitmap); al_restore_state(&backup); } return true; } static bool d3d_resize_display(ALLEGRO_DISPLAY *d, int width, int height) { ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)d; ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; int orig_w = d->w; int orig_h = d->h; bool ret; _al_d3d_prepare_bitmaps_for_reset(d3d_display); win_display->ignore_resize = true; if (!d3d_resize_helper(d, width, height)) { ALLEGRO_WARN("trying to restore original size: %d, %d\n", orig_w, orig_h); if (!d3d_resize_helper(d, orig_w, orig_h)) { ALLEGRO_ERROR("failed to restore original size: %d, %d\n", orig_w, orig_h); } ret = false; } else { ret = true; d3d_acknowledge_resize(d); } win_display->ignore_resize = false; return ret; } ALLEGRO_BITMAP *_al_d3d_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h) { ALLEGRO_BITMAP_D3D *bitmap = (ALLEGRO_BITMAP_D3D*)al_malloc(sizeof *bitmap); int format; int flags; ASSERT(bitmap); (void)h; memset(bitmap, 0, sizeof(*bitmap)); bitmap->bitmap.size = sizeof *bitmap; format = al_get_new_bitmap_format(); flags = al_get_new_bitmap_flags(); if (!_al_pixel_format_is_real(format)) { format = d3d_choose_bitmap_format((ALLEGRO_DISPLAY_D3D *)d, format); if (format < 0) { return NULL; } } if (_al_pixel_format_to_d3d(format) < 0) { ALLEGRO_ERROR("Requested bitmap format not supported (%d).\n", format); return NULL; } ALLEGRO_INFO("Chose bitmap format %d\n", format); bitmap->bitmap.vt = _al_bitmap_d3d_driver(); bitmap->bitmap.memory = NULL; bitmap->bitmap.format = format; bitmap->bitmap.flags = flags; bitmap->bitmap.pitch = w * al_get_pixel_size(format); al_identity_transform(&bitmap->bitmap.transform); bitmap->bitmap.memory = (unsigned char *)al_malloc(bitmap->bitmap.pitch * h); bitmap->video_texture = 0; bitmap->system_texture = 0; bitmap->initialized = false; bitmap->is_backbuffer = false; bitmap->render_target = NULL; bitmap->modified = true; bitmap->display = (ALLEGRO_DISPLAY_D3D *)d; return &bitmap->bitmap; } static ALLEGRO_BITMAP *d3d_create_sub_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *parent, int x, int y, int width, int height) { ALLEGRO_BITMAP_D3D *bitmap = (ALLEGRO_BITMAP_D3D*)al_malloc(sizeof *bitmap); (void)x; (void)y; (void)width; (void)height; bitmap->texture_w = 0; bitmap->texture_h = 0; bitmap->video_texture = ((ALLEGRO_BITMAP_D3D *)parent)->video_texture; bitmap->system_texture = ((ALLEGRO_BITMAP_D3D *)parent)->system_texture; bitmap->initialized = false; bitmap->is_backbuffer = ((ALLEGRO_BITMAP_D3D *)parent)->is_backbuffer; bitmap->display = (ALLEGRO_DISPLAY_D3D *)display; bitmap->render_target = ((ALLEGRO_BITMAP_D3D *)parent)->render_target; bitmap->bitmap.vt = parent->vt; return (ALLEGRO_BITMAP *)bitmap; } static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP *target; ALLEGRO_BITMAP_D3D *d3d_target; ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; if (d3d_display->device_lost) return; if (bitmap->parent) { target = bitmap->parent; } else { target = bitmap; } d3d_target = (ALLEGRO_BITMAP_D3D *)target; /* Release the previous target bitmap if it was not the backbuffer */ ALLEGRO_BITMAP_D3D *currtarget = (ALLEGRO_BITMAP_D3D *)al_get_target_bitmap(); if (currtarget && !currtarget->is_backbuffer && currtarget->render_target) { currtarget->render_target->Release(); currtarget->render_target = NULL; } /* Set the render target */ if (d3d_target->is_backbuffer) { d3d_display = d3d_target->display; if (d3d_display->device->SetRenderTarget(0, d3d_display->render_target) != D3D_OK) { ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to set render target to texture surface.\n"); return; } d3d_target->render_target = d3d_display->render_target; d3d_display->device->SetDepthStencilSurface(d3d_display->depth_stencil); _al_d3d_set_ortho_projection(d3d_display, display->w, display->h); } else { d3d_display = (ALLEGRO_DISPLAY_D3D *)display; if (_al_d3d_render_to_texture_supported()) { if (!d3d_target->video_texture) { /* This can happen if the user tries to set the target bitmap as * the device is lost, before the DISPLAY_LOST event is received. */ ALLEGRO_WARN("d3d_set_target_bitmap: No video texture.\n"); return; } if (d3d_target->video_texture->GetSurfaceLevel(0, &d3d_target->render_target) != D3D_OK) { ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to get texture surface level.\n"); return; } if (d3d_display->device->SetRenderTarget(0, d3d_target->render_target) != D3D_OK) { ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to set render target to texture surface.\n"); d3d_target->render_target->Release(); return; } _al_d3d_set_ortho_projection(d3d_display, d3d_target->texture_w, d3d_target->texture_h); } if (d3d_display->samples) { d3d_display->device->SetDepthStencilSurface(NULL); } } d3d_reset_state(d3d_display); _al_d3d_set_bitmap_clip(bitmap); } static ALLEGRO_BITMAP *d3d_get_backbuffer(ALLEGRO_DISPLAY *display) { return (ALLEGRO_BITMAP *)&(((ALLEGRO_DISPLAY_D3D *)display)->backbuffer_bmp); } static bool d3d_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { return display == bitmap->display; } static void d3d_switch_out(ALLEGRO_DISPLAY *display) { (void)display; } static void d3d_switch_in(ALLEGRO_DISPLAY *display) { (void)display; } static bool d3d_wait_for_vsync(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_D3D *d3d_display; D3DRASTER_STATUS status; if (!d3d_can_wait_for_vsync) return false; d3d_display = (ALLEGRO_DISPLAY_D3D *)display; do { d3d_display->device->GetRasterStatus(0, &status); } while (!status.InVBlank); return true; } /* Exposed stuff */ /* Function: al_get_d3d_device */ LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; return d3d_display->device; } /* Function: al_get_d3d_system_texture */ LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap) { return ((ALLEGRO_BITMAP_D3D *)bitmap)->system_texture; } /* Function: al_get_d3d_video_texture */ LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap) { return ((ALLEGRO_BITMAP_D3D *)bitmap)->video_texture; } /* Function: al_get_d3d_texture_position */ void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) { ASSERT(bitmap); ASSERT(u); ASSERT(v); *u = bitmap->xofs; *v = bitmap->yofs; } /* Function: al_is_d3d_device_lost */ bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display) { return ((ALLEGRO_DISPLAY_D3D *)display)->device_lost; } static void d3d_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { _al_win_set_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); } static void d3d_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) { if (display->flags & ALLEGRO_FULLSCREEN) { ALLEGRO_MONITOR_INFO info; ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; al_get_monitor_info(win_display->adapter, &info); *x = info.x1; *y = info.y1; } else { _al_win_get_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); } } static void d3d_shutdown(void) { _al_d3d_destroy_display_format_list(); _al_d3d->Release(); al_destroy_mutex(present_mutex); al_destroy_mutex(_al_d3d_lost_device_mutex); _al_d3d_bmp_destroy(); FreeLibrary(_al_d3d_module); _al_d3d_module = NULL; al_free(vt); vt = NULL; } static void* d3d_prepare_vertex_cache(ALLEGRO_DISPLAY* disp, int num_new_vertices) { disp->num_cache_vertices += num_new_vertices; if (!disp->vertex_cache) { disp->vertex_cache = al_malloc(num_new_vertices * sizeof(D3D_TL_VERTEX)); disp->vertex_cache_size = num_new_vertices; } else if (disp->num_cache_vertices > disp->vertex_cache_size) { disp->vertex_cache = al_realloc(disp->vertex_cache, 2 * disp->num_cache_vertices * sizeof(D3D_TL_VERTEX)); disp->vertex_cache_size = 2 * disp->num_cache_vertices; } return (D3D_TL_VERTEX*)disp->vertex_cache + (disp->num_cache_vertices - num_new_vertices); } static void d3d_flush_vertex_cache(ALLEGRO_DISPLAY* disp) { if (!disp->vertex_cache) return; if (disp->num_cache_vertices == 0) return; ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp; ALLEGRO_BITMAP* cache_bmp = (ALLEGRO_BITMAP*)disp->cache_texture; ALLEGRO_BITMAP_D3D* d3d_bmp = (ALLEGRO_BITMAP_D3D*)cache_bmp; if (d3d_disp->device->SetTexture(0, (IDirect3DBaseTexture9 *)d3d_bmp->video_texture) != D3D_OK) { ALLEGRO_ERROR("d3d_flush_vertex_cache: SetTexture failed.\n"); return; } if (cache_bmp->flags & ALLEGRO_MIN_LINEAR) { d3d_disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } else { d3d_disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); } if (cache_bmp->flags & ALLEGRO_MAG_LINEAR) { d3d_disp->device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } else { d3d_disp->device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); } if (cache_bmp->flags & ALLEGRO_MIPMAP) { d3d_disp->device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); } else { d3d_disp->device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); } d3d_disp->device->SetFVF(D3DFVF_TL_VERTEX); if (d3d_disp->device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, disp->num_cache_vertices / 3, (D3D_TL_VERTEX*)disp->vertex_cache, sizeof(D3D_TL_VERTEX)) != D3D_OK) { ALLEGRO_ERROR("d3d_flush_vertex_cache: DrawPrimitive failed.\n"); return; } disp->num_cache_vertices = 0; d3d_disp->device->SetTexture(0, NULL); } static void d3d_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target) { ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp; D3DMATRIX matrix; ALLEGRO_TRANSFORM tmp_transform; al_copy_transform(&tmp_transform, &target->transform); if (target->parent) { al_translate_transform(&tmp_transform, target->xofs, target->yofs); } memcpy(matrix.m[0], tmp_transform.m[0], 16 * sizeof(float)); matrix.m[3][0] -= 0.5; matrix.m[3][1] -= 0.5; d3d_disp->device->SetTransform(D3DTS_VIEW, &matrix); } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_display_d3d_driver(void) { if (vt) return vt; vt = (ALLEGRO_DISPLAY_INTERFACE *)al_malloc(sizeof *vt); memset(vt, 0, sizeof *vt); vt->create_display = d3d_create_display; vt->destroy_display = d3d_destroy_display; vt->set_current_display = d3d_set_current_display; vt->clear = d3d_clear; vt->draw_pixel = d3d_draw_pixel; vt->flip_display = d3d_flip_display; vt->update_display_region = d3d_update_display_region; vt->acknowledge_resize = d3d_acknowledge_resize; vt->resize_display = d3d_resize_display; vt->create_bitmap = _al_d3d_create_bitmap; vt->set_target_bitmap = d3d_set_target_bitmap; vt->get_backbuffer = d3d_get_backbuffer; vt->is_compatible_bitmap = d3d_is_compatible_bitmap; vt->switch_out = d3d_switch_out; vt->switch_in = d3d_switch_in; vt->draw_memory_bitmap_region = NULL; vt->create_sub_bitmap = d3d_create_sub_bitmap; vt->wait_for_vsync = d3d_wait_for_vsync; vt->set_mouse_cursor = _al_win_set_mouse_cursor; vt->set_system_mouse_cursor = _al_win_set_system_mouse_cursor; vt->show_mouse_cursor = _al_win_show_mouse_cursor; vt->hide_mouse_cursor = _al_win_hide_mouse_cursor; vt->set_icons = _al_win_set_display_icons; vt->set_window_position = d3d_set_window_position; vt->get_window_position = d3d_get_window_position; vt->set_display_flag = _al_win_set_display_flag; vt->set_window_title = _al_win_set_window_title; vt->shutdown = d3d_shutdown; vt->flush_vertex_cache = d3d_flush_vertex_cache; vt->prepare_vertex_cache = d3d_prepare_vertex_cache; vt->update_transformation = d3d_update_transformation; return vt; } int _al_d3d_get_num_display_modes(int format, int refresh_rate, int flags) { UINT num_modes; UINT i, j; D3DDISPLAYMODE display_mode; int matches = 0; (void)flags; /* If any, go through all formats */ if (!_al_pixel_format_is_real(format)) { j = 0; } /* Else find the matching format */ else { for (j = 0; allegro_formats[j] != -1; j++) { if (allegro_formats[j] == format) break; } if (allegro_formats[j] == -1) return 0; } for (; allegro_formats[j] != -1; j++) { int adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; if (!_al_pixel_format_is_real(allegro_formats[j]) || _al_pixel_format_has_alpha(allegro_formats[j])) continue; num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)d3d_formats[j]); for (i = 0; i < num_modes; i++) { if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)d3d_formats[j], i, &display_mode) != D3D_OK) { return matches; } if (refresh_rate && display_mode.RefreshRate != (unsigned)refresh_rate) continue; matches++; } if (_al_pixel_format_is_real(format)) break; } return matches; } ALLEGRO_DISPLAY_MODE *_al_d3d_get_display_mode(int index, int format, int refresh_rate, int flags, ALLEGRO_DISPLAY_MODE *mode) { UINT num_modes; UINT i, j; D3DDISPLAYMODE display_mode; int matches = 0; (void)flags; /* If any, go through all formats */ if (!_al_pixel_format_is_real(format)) { j = 0; } /* Else find the matching format */ else { for (j = 0; allegro_formats[j] != -1; j++) { if (allegro_formats[j] == format) break; } if (allegro_formats[j] == -1) return NULL; } for (; allegro_formats[j] != -1; j++) { int adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; if (!_al_pixel_format_is_real(allegro_formats[j]) || _al_pixel_format_has_alpha(allegro_formats[j])) continue; num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)d3d_formats[j]); for (i = 0; i < num_modes; i++) { if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)d3d_formats[j], i, &display_mode) != D3D_OK) { return NULL; } if (refresh_rate && display_mode.RefreshRate != (unsigned)refresh_rate) continue; if (matches == index) { mode->width = display_mode.Width; mode->height = display_mode.Height; mode->format = allegro_formats[j]; mode->refresh_rate = display_mode.RefreshRate; return mode; } matches++; } if (_al_pixel_format_is_real(format)) break; } return mode; } /* int _al_d3d_get_num_video_adapters(void) { return _al_d3d->GetAdapterCount(); //return num_video_adapters; } */ /* void _al_d3d_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { HMONITOR mon = _al_d3d->GetAdapterMonitor(adapter); MONITORINFO mi; if (!mon) { info->x1 = info->y1 = info->x2 = info->y2 = -1; } else { mi.cbSize = sizeof(mi); GetMonitorInfo(mon, &mi); info->x1 = mi.rcMonitor.left; info->y1 = mi.rcMonitor.top; info->x2 = mi.rcMonitor.right; info->y2 = mi.rcMonitor.bottom; } } */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wtime.c0000644000175000001440000000634011771523242015272 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows time module. * * By Peter Wang. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/platform/aintwin.h" #include ALLEGRO_STATIC_ASSERT(wtime, sizeof(ALLEGRO_TIMEOUT_WIN) <= sizeof(ALLEGRO_TIMEOUT)); #define LARGE_INTEGER_TO_INT64(li) (((int64_t)li.HighPart << 32) | \ (int64_t)li.LowPart) static int64_t high_res_timer_freq; static int64_t _al_win_prev_time; static double _al_win_total_time; static double (*real_get_time_func)(void); static _AL_MUTEX time_mutex = _AL_MUTEX_UNINITED; static double low_res_current_time(void) { int64_t cur_time; double ellapsed_time; _al_mutex_lock(&time_mutex); cur_time = (int64_t) timeGetTime(); ellapsed_time = (double) (cur_time - _al_win_prev_time) / 1000; if (cur_time < _al_win_prev_time) { ellapsed_time += 4294967.295; } _al_win_total_time += ellapsed_time; _al_win_prev_time = cur_time; _al_mutex_unlock(&time_mutex); return _al_win_total_time; } static double high_res_current_time(void) { LARGE_INTEGER count; int64_t cur_time; double ellapsed_time; _al_mutex_lock(&time_mutex); QueryPerformanceCounter(&count); cur_time = LARGE_INTEGER_TO_INT64(count); ellapsed_time = (double)(cur_time - _al_win_prev_time) / (double)high_res_timer_freq; _al_win_total_time += ellapsed_time; _al_win_prev_time = cur_time; _al_mutex_unlock(&time_mutex); return _al_win_total_time; } double al_get_time(void) { return (*real_get_time_func)(); } void _al_win_init_time(void) { LARGE_INTEGER tmp_freq; _al_win_total_time = 0; _al_mutex_init(&time_mutex); if (QueryPerformanceFrequency(&tmp_freq) == 0) { real_get_time_func = low_res_current_time; _al_win_prev_time = (int64_t) timeGetTime(); } else { LARGE_INTEGER count; high_res_timer_freq = LARGE_INTEGER_TO_INT64(tmp_freq); real_get_time_func = high_res_current_time; QueryPerformanceCounter(&count); _al_win_prev_time = LARGE_INTEGER_TO_INT64(count); } } void _al_win_shutdown_time(void) { _al_mutex_destroy(&time_mutex); } /* al_rest: * Rests the specified amount of milliseconds. * Does nothing with values <= 0. */ void al_rest(double seconds) { if (seconds <= 0) return; Sleep((DWORD)(seconds * 1000.0)); } /* al_init_timeout: * Set a timeout value. */ void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) { ALLEGRO_TIMEOUT_WIN *wt = (ALLEGRO_TIMEOUT_WIN *) timeout; ASSERT(wt); if (seconds <= 0.0) { wt->abstime = timeGetTime(); } else { wt->abstime = timeGetTime() + (DWORD)(seconds * 1000.0); } } /* vim: set sts=3 sw=3 et */ allegro-5.0.10/src/win/wwindow.c0000644000175000001440000010657012132127367015651 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New Windows window handling * * By Trent Gamblin. * */ /* Raw input */ #define _WIN32_WINNT 0x0501 #ifndef WINVER #define WINVER 0x0501 #endif #include #include /* Only used for Vista and up. */ #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif #include #include #include "allegro5/allegro_windows.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/platform/aintwin.h" ALLEGRO_DEBUG_CHANNEL("wwindow") static WNDCLASS window_class; static bool resize_postponed = false; static bool we_hid_the_mouse = false; UINT _al_win_msg_call_proc = 0; UINT _al_win_msg_suicide = 0; static void display_flags_to_window_styles(int flags, DWORD *style, DWORD *ex_style) { if (flags & ALLEGRO_FULLSCREEN) { *style = WS_POPUP; *ex_style = WS_EX_APPWINDOW; } else if (flags & ALLEGRO_RESIZABLE) { *style = WS_OVERLAPPEDWINDOW; *ex_style = WS_EX_APPWINDOW | WS_EX_OVERLAPPEDWINDOW; } else { *style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; *ex_style = WS_EX_APPWINDOW; } } HWND _al_win_create_hidden_window() { HWND window = CreateWindowEx(0, "ALEX", "hidden", WS_POPUP, -5000, -5000, 0, 0, NULL,NULL,window_class.hInstance,0); return window; } static void _al_win_get_window_center( ALLEGRO_DISPLAY_WIN *win_display, int width, int height, int *out_x, int *out_y) { int a = win_display->adapter; bool *is_fullscreen; ALLEGRO_MONITOR_INFO info; RECT win_size; ALLEGRO_SYSTEM *sys = al_get_system_driver(); unsigned int num; unsigned int i; unsigned int fullscreen_found = 0; num = al_get_num_video_adapters(); is_fullscreen = al_calloc(num, sizeof(bool)); for (i = 0; i < sys->displays._size; i++) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&sys->displays, i); ALLEGRO_DISPLAY *d = *dptr; if (d->flags & ALLEGRO_FULLSCREEN) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; is_fullscreen[win_display->adapter] = true; fullscreen_found++; } } if (fullscreen_found && fullscreen_found < num) { for (i = 0; i < num; i++) { if (is_fullscreen[i] == false) { a = i; break; } } } al_free(is_fullscreen); al_get_monitor_info(a, &info); win_size.left = info.x1 + (info.x2 - info.x1 - width) / 2; win_size.top = info.y1 + (info.y2 - info.y1 - height) / 2; *out_x = win_size.left; *out_y = win_size.top; } HWND _al_win_create_window(ALLEGRO_DISPLAY *display, int width, int height, int flags) { HWND my_window; DWORD style; DWORD ex_style; int pos_x, pos_y; bool center = false; ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; WINDOWINFO wi; int lsize, rsize, tsize, bsize; // left, right, top, bottom border sizes wi.cbSize = sizeof(WINDOWINFO); display_flags_to_window_styles(flags, &style, &ex_style); al_get_new_window_position(&pos_x, &pos_y); if ((flags & ALLEGRO_FULLSCREEN) || (flags & ALLEGRO_FULLSCREEN_WINDOW)) { pos_x = pos_y = 0; } else if (pos_x == INT_MAX) { pos_x = pos_y = 0; center = true; } if (center) { _al_win_get_window_center(win_display, width, height, &pos_x, &pos_y); } my_window = CreateWindowEx(ex_style, "ALEX", "Allegro", style, pos_x, pos_y, width, height, NULL,NULL,window_class.hInstance,0); GetWindowInfo(my_window, &wi); lsize = (wi.rcClient.left - wi.rcWindow.left); tsize = (wi.rcClient.top - wi.rcWindow.top); rsize = (wi.rcWindow.right - wi.rcClient.right); bsize = (wi.rcWindow.bottom - wi.rcClient.bottom); SetWindowPos(my_window, 0, 0, 0, width+lsize+rsize, height+tsize+bsize, SWP_NOZORDER | SWP_NOMOVE); SetWindowPos(my_window, 0, pos_x-lsize, pos_y-tsize, 0, 0, SWP_NOZORDER | SWP_NOSIZE); if (flags & ALLEGRO_FRAMELESS) { SetWindowLong(my_window, GWL_STYLE, WS_VISIBLE); SetWindowLong(my_window, GWL_EXSTYLE, WS_EX_APPWINDOW); SetWindowPos(my_window, 0, pos_x, pos_y, width, height, SWP_NOZORDER | SWP_FRAMECHANGED); } ShowWindow(my_window, SW_SHOW); if (!(flags & ALLEGRO_RESIZABLE) && !(flags & ALLEGRO_FULLSCREEN)) { /* Make the window non-resizable */ HMENU menu; menu = GetSystemMenu(my_window, false); DeleteMenu(menu, SC_SIZE, MF_BYCOMMAND); DeleteMenu(menu, SC_MAXIMIZE, MF_BYCOMMAND); DrawMenuBar(my_window); } return my_window; } HWND _al_win_create_faux_fullscreen_window(LPCTSTR devname, ALLEGRO_DISPLAY *display, int x1, int y1, int width, int height, int refresh_rate, int flags) { HWND my_window; DWORD style; DWORD ex_style; DEVMODE mode; LONG temp; (void)display; (void)flags; style = WS_VISIBLE; ex_style = WS_EX_TOPMOST; my_window = CreateWindowEx(ex_style, "ALEX", "Allegro", style, x1, y1, width, height, NULL,NULL,window_class.hInstance,0); temp = GetWindowLong(my_window, GWL_STYLE); temp &= ~WS_CAPTION; SetWindowLong(my_window, GWL_STYLE, temp); SetWindowPos(my_window, HWND_TOP, 0, 0, width, height, SWP_NOMOVE | SWP_FRAMECHANGED); /* Go fullscreen */ memset(&mode, 0, sizeof(DEVMODE)); mode.dmSize = sizeof(DEVMODE); mode.dmDriverExtra = 0; mode.dmBitsPerPel = al_get_new_display_option(ALLEGRO_COLOR_SIZE, NULL); mode.dmPelsWidth = width; mode.dmPelsHeight = height; mode.dmDisplayFlags = 0; mode.dmDisplayFrequency = refresh_rate; mode.dmPosition.x = x1; mode.dmPosition.y = y1; mode.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS| DM_DISPLAYFREQUENCY|DM_POSITION; ChangeDisplaySettingsEx(devname, &mode, NULL, 0, NULL/*CDS_FULLSCREEN*/); return my_window; } /* _al_win_grab_input: * Makes the passed display grab the input. All consequent input events will be * generated the this display's window. The display's window must the the * foreground window. */ void _al_win_grab_input(ALLEGRO_DISPLAY_WIN *win_disp) { _al_win_wnd_schedule_proc(win_disp->window, _al_win_joystick_dinput_grab, win_disp); } /* Generate a resize event if the size has changed. We cannot asynchronously * change the display size here yet, since the user will only know about a * changed size after receiving the resize event. Here we merely add the * event to the queue. */ static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_display; ALLEGRO_EVENT_SOURCE *es = &display->es; WINDOWINFO wi; int x, y, w, h; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_display->window, &wi); x = wi.rcClient.left; y = wi.rcClient.top; w = wi.rcClient.right - wi.rcClient.left; h = wi.rcClient.bottom - wi.rcClient.top; /* Don't generate events when restoring after minimise. */ if (w == 0 && h == 0 && x == -32000 && y == -32000) return; if (display->w != w || display->h != h) { _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.timestamp = al_get_time(); event.display.x = x; event.display.y = y; event.display.width = w; event.display.height = h; event.display.source = display; _al_event_source_emit_event(es, &event); /* Generate an expose event. */ /* This seems a bit redundant after a resize. */ if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; _al_event_source_emit_event(es, &event); } } _al_event_source_unlock(es); } } static void postpone_thread_proc(void *arg) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)arg; ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; Sleep(50); if (win_display->ignore_resize) { win_display->ignore_resize = false; } else { win_generate_resize_event(win_display); } resize_postponed = false; win_display->can_acknowledge = true; } static void handle_mouse_capture(bool down, HWND hWnd) { int i; bool any_button_down = false; ALLEGRO_MOUSE_STATE state; if (!al_is_mouse_installed()) return; al_get_mouse_state(&state); for (i = 1; i <= 5; i++) { any_button_down |= al_mouse_button_down(&state, i); } if (down && GetCapture() != hWnd) { SetCapture(hWnd); } else if (!any_button_down) { ReleaseCapture(); } } static void break_window_message_pump(ALLEGRO_DISPLAY_WIN *win_display, HWND hWnd) { /* Get the ID of the thread which created the HWND and is processing its messages */ DWORD wnd_thread_id = GetWindowThreadProcessId(hWnd, NULL); /* Set the "end_thread" flag to stop the message pump */ win_display->end_thread = true; /* Wake-up the message pump so the thread can read the new value of "end_thread" */ PostThreadMessage(wnd_thread_id, WM_NULL, 0, 0); } static LRESULT CALLBACK window_callback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { ALLEGRO_DISPLAY *d = NULL; ALLEGRO_DISPLAY_WIN *win_display = NULL; unsigned int i; ALLEGRO_EVENT_SOURCE *es = NULL; ALLEGRO_SYSTEM *system = al_get_system_driver(); if (message == _al_win_msg_call_proc) { ((void (*)(void*))wParam) ((void*)lParam); return 0; } if (!system) { return DefWindowProc(hWnd,message,wParam,lParam); } if (message == _al_win_msg_suicide && wParam) { win_display = (ALLEGRO_DISPLAY_WIN*)wParam; break_window_message_pump(win_display, hWnd); DestroyWindow(hWnd); return 0; } for (i = 0; i < system->displays._size; i++) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, i); d = *dptr; win_display = (void*)d; if (win_display->window == hWnd) { es = &d->es; break; } } if (i == system->displays._size) return DefWindowProc(hWnd,message,wParam,lParam); if (message == _al_win_msg_suicide) { break_window_message_pump(win_display, hWnd); DestroyWindow(hWnd); return 0; } switch (message) { case WM_INPUT: { /* RAW Input is currently unused. */ UINT dwSize; LPBYTE lpb; RAWINPUT* raw; /* We can't uninstall WM_INPUT mesages. */ if (!al_is_mouse_installed()) break; GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); lpb = al_malloc(sizeof(BYTE)*dwSize); if (lpb == NULL) break; GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)); raw = (RAWINPUT*)lpb; if (raw->header.dwType != RIM_TYPEMOUSE) { al_free(lpb); break; } { RAWMOUSE *rm = &raw->data.mouse; int x = raw->data.mouse.lLastX; int y = raw->data.mouse.lLastY; bool abs = (rm->usFlags & (MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP)) != 0; if (abs || x || y) _al_win_mouse_handle_move(x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) _al_win_mouse_handle_button(1, true, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP) _al_win_mouse_handle_button(1, false, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) _al_win_mouse_handle_button(2, true, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP) _al_win_mouse_handle_button(2, false, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) _al_win_mouse_handle_button(3, true, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP) _al_win_mouse_handle_button(3, false, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) _al_win_mouse_handle_button(4, true, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP) _al_win_mouse_handle_button(4, false, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) _al_win_mouse_handle_button(5, true, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP) _al_win_mouse_handle_button(5, false, x, y, abs, win_display); if (rm->usButtonFlags & RI_MOUSE_WHEEL) { SHORT z = (SHORT)rm->usButtonData; _al_win_mouse_handle_wheel(z / WHEEL_DELTA, false, win_display); } } al_free(lpb); break; } case WM_LBUTTONDOWN: case WM_LBUTTONUP: { int mx = GET_X_LPARAM(lParam); int my = GET_Y_LPARAM(lParam); bool down = (message == WM_LBUTTONDOWN); _al_win_mouse_handle_button(1, down, mx, my, true, win_display); handle_mouse_capture(down, hWnd); break; } case WM_MBUTTONDOWN: case WM_MBUTTONUP: { int mx = GET_X_LPARAM(lParam); int my = GET_Y_LPARAM(lParam); bool down = (message == WM_MBUTTONDOWN); _al_win_mouse_handle_button(3, down, mx, my, true, win_display); handle_mouse_capture(down, hWnd); break; } case WM_RBUTTONDOWN: case WM_RBUTTONUP: { int mx = GET_X_LPARAM(lParam); int my = GET_Y_LPARAM(lParam); bool down = (message == WM_RBUTTONDOWN); _al_win_mouse_handle_button(2, down, mx, my, true, win_display); handle_mouse_capture(down, hWnd); break; } case WM_XBUTTONDOWN: case WM_XBUTTONUP: { int mx = GET_X_LPARAM(lParam); int my = GET_Y_LPARAM(lParam); int button = HIWORD(wParam); bool down = (message == WM_XBUTTONDOWN); if (button == XBUTTON1) _al_win_mouse_handle_button(4, down, mx, my, true, win_display); else if (button == XBUTTON2) _al_win_mouse_handle_button(5, down, mx, my, true, win_display); handle_mouse_capture(down, hWnd); return TRUE; } case WM_MOUSEWHEEL: { int d = GET_WHEEL_DELTA_WPARAM(wParam); _al_win_mouse_handle_wheel(d / WHEEL_DELTA, false, win_display); return TRUE; } case WM_MOUSEHWHEEL: { int d = GET_WHEEL_DELTA_WPARAM(wParam); _al_win_mouse_handle_hwheel(d / WHEEL_DELTA, false, win_display); return TRUE; } case WM_MOUSEMOVE: { TRACKMOUSEEVENT tme; int mx = GET_X_LPARAM(lParam); int my = GET_Y_LPARAM(lParam); if (win_display->mouse_cursor_shown && we_hid_the_mouse) { we_hid_the_mouse = false; win_display->display.vt->hide_mouse_cursor((void*)win_display); } _al_win_mouse_handle_move(mx, my, true, win_display); if (mx >= 0 && my >= 0 && mx < d->w && my < d->h) { tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; if (TrackMouseEvent(&tme) && !tme.hwndTrack) { tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; tme.dwHoverTime = 0; TrackMouseEvent(&tme); _al_win_mouse_handle_enter(win_display); } } /* WM_SETCURSOR messages are not received while the mouse is * captured. We call SetCursor here so that changing the mouse * cursor has an effect while the user is holding down the mouse * button. */ if (GetCapture() == hWnd && win_display->mouse_cursor_shown) { SetCursor(win_display->mouse_selected_hcursor); } break; } case WM_MOUSELEAVE: { _al_win_mouse_handle_leave(win_display); break; } case WM_CAPTURECHANGED: { if (al_is_mouse_installed()) { int i; ALLEGRO_MOUSE_STATE state; if (!lParam || (HWND)lParam == hWnd) break; al_get_mouse_state(&state); for (i = 1; i <= 5; i++) { if (al_mouse_button_down(&state, i)) _al_win_mouse_handle_button(i, 0, 0, 0, true, win_display); } } break; } case WM_NCMOUSEMOVE: { if (!win_display->mouse_cursor_shown) { we_hid_the_mouse = true; win_display->display.vt->show_mouse_cursor((void*)win_display); } break; } case WM_SYSKEYDOWN: { int vcode = wParam; bool extended = (lParam >> 24) & 0x1; bool repeated = (lParam >> 30) & 0x1; _al_win_kbd_handle_key_press(0, vcode, extended, repeated, win_display); break; } case WM_KEYDOWN: { int vcode = wParam; int scode = (lParam >> 16) & 0xff; bool extended = (lParam >> 24) & 0x1; bool repeated = (lParam >> 30) & 0x1; /* We can't use TranslateMessage() because we don't know if it will produce a WM_CHAR or not. */ _al_win_kbd_handle_key_press(scode, vcode, extended, repeated, win_display); break; } case WM_SYSKEYUP: case WM_KEYUP: { int vcode = wParam; int scode = (lParam >> 16) & 0xff; bool extended = (lParam >> 24) & 0x1; _al_win_kbd_handle_key_release(scode, vcode, extended, win_display); break; } case WM_SYSCOMMAND: { if (_al_win_disable_screensaver && ((wParam & 0xfff0) == SC_MONITORPOWER || (wParam & 0xfff0) == SC_SCREENSAVE)) { return 0; } else if ((wParam & 0xfff0) == SC_KEYMENU) { /* Prevent Windows from intercepting the ALT key. (Disables opening menus via the ALT key.) */ return 0; } break; } case WM_PAINT: { if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { RECT r; HRGN hrgn; GetWindowRect(win_display->window, &r); hrgn = CreateRectRgn(r.left, r.top, r.right, r.bottom); if (GetUpdateRgn(win_display->window, hrgn, false) != ERROR) { PAINTSTRUCT ps; DWORD size; LPRGNDATA rgndata; int n; int i; RECT *rects; BeginPaint(win_display->window, &ps); size = GetRegionData(hrgn, 0, NULL); rgndata = al_malloc(size); GetRegionData(hrgn, size, rgndata); n = rgndata->rdh.nCount; rects = (RECT *)rgndata->Buffer; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; event.display.timestamp = al_get_time(); for (i = 0; i < n; i++) { event.display.x = rects[i].left; event.display.y = rects[i].top; event.display.width = rects[i].right - rects[i].left; event.display.height = rects[i].bottom - rects[i].top; _al_event_source_emit_event(es, &event); } } _al_event_source_unlock(es); al_free(rgndata); EndPaint(win_display->window, &ps); DeleteObject(hrgn); } return 0; } break; } case WM_SETCURSOR: switch (LOWORD(lParam)) { case HTLEFT: case HTRIGHT: SetCursor(LoadCursor(NULL, IDC_SIZEWE)); break; case HTBOTTOM: case HTTOP: SetCursor(LoadCursor(NULL, IDC_SIZENS)); break; case HTBOTTOMLEFT: case HTTOPRIGHT: SetCursor(LoadCursor(NULL, IDC_SIZENESW)); break; case HTBOTTOMRIGHT: case HTTOPLEFT: SetCursor(LoadCursor(NULL, IDC_SIZENWSE)); break; default: if (win_display->mouse_cursor_shown) { SetCursor(win_display->mouse_selected_hcursor); } else { SetCursor(NULL); } break; } return 1; case WM_ACTIVATE: if (HIWORD(wParam) && LOWORD(wParam) != WA_INACTIVE) break; if (HIWORD(wParam)) d->flags |= ALLEGRO_MINIMIZED; else d->flags &= ~ALLEGRO_MINIMIZED; if (LOWORD(wParam) != WA_INACTIVE) { // Make fullscreen windows TOPMOST again if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { SetWindowPos(win_display->window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } if (d->vt->switch_in) d->vt->switch_in(d); _al_win_fix_modifiers(); _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; memset(&event, 0, sizeof(event)); event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); _al_win_grab_input(win_display); return 0; } else { // Remove TOPMOST flag from fullscreen windows so we can alt-tab. Also must raise the new activated window if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { SetWindowPos(win_display->window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(GetForegroundWindow(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } // Show the taskbar in case we hid it SetWindowPos(FindWindow("Shell_traywnd", ""), 0, 0, 0, 0, 0, SWP_SHOWWINDOW); if (d->flags & ALLEGRO_FULLSCREEN) { d->vt->switch_out(d); } _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; memset(&event, 0, sizeof(event)); event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); return 0; } break; case WM_MENUCHAR : return (MNC_CLOSE << 16) | (wParam & 0xffff); case WM_CLOSE: _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; memset(&event, 0, sizeof(event)); event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); return 0; case WM_SIZE: if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) { /* * Delay the resize event so we don't get bogged down with them */ if (!resize_postponed) { resize_postponed = true; _beginthread(postpone_thread_proc, 0, (void *)d); } } return 0; case WM_ENTERSIZEMOVE: /* DefWindowProc for WM_ENTERSIZEMOVE enters a modal loop, which also * ends up blocking the loop in d3d_display_thread_proc (which is * where we are called from, if using D3D). Rather than batching up * intermediate resize events which the user cannot acknowledge in the * meantime anyway, make it so only a single resize event is generated * at WM_EXITSIZEMOVE. */ if (d->flags & ALLEGRO_DIRECT3D_INTERNAL) { resize_postponed = true; } break; case WM_EXITSIZEMOVE: if (resize_postponed) { win_generate_resize_event(win_display); win_display->ignore_resize = false; resize_postponed = false; win_display->can_acknowledge = true; } break; } return DefWindowProc(hWnd,message,wParam,lParam); } int _al_win_init_window() { // Create A Window Class Structure window_class.cbClsExtra = 0; window_class.cbWndExtra = 0; window_class.hbrBackground = NULL; window_class.hCursor = NULL; window_class.hIcon = NULL; window_class.hInstance = GetModuleHandle(NULL); window_class.lpfnWndProc = window_callback; window_class.lpszClassName = "ALEX"; window_class.lpszMenuName = NULL; window_class.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC; RegisterClass(&window_class); if (_al_win_msg_call_proc == 0 && _al_win_msg_suicide == 0) { _al_win_msg_call_proc = RegisterWindowMessage("Allegro call proc"); _al_win_msg_suicide = RegisterWindowMessage("Allegro window suicide"); } return true; } static int win_choose_icon_bitmap(const int sys_w, const int sys_h, const int num_icons, ALLEGRO_BITMAP *bmps[]) { int best_i = 0; int best_score = INT_MAX; int i; for (i = 0; i < num_icons; i++) { int bmp_w = al_get_bitmap_width(bmps[i]); int bmp_h = al_get_bitmap_height(bmps[i]); int score; if (bmp_w == sys_w && bmp_h == sys_h) return i; /* We prefer to scale up smaller bitmaps to the desired size than to * scale down larger bitmaps. At these resolutions, scaled up bitmaps * look blocky, but scaled down bitmaps can look even worse due to to * dropping crucial pixels. */ if (bmp_w * bmp_h <= sys_w * sys_h) score = (sys_w * sys_h) - (bmp_w * bmp_h); else score = bmp_w * bmp_h; if (score < best_score) { best_score = score; best_i = i; } } return best_i; } static void win_set_display_icon(ALLEGRO_DISPLAY_WIN *win_display, const WPARAM icon_type, const int sys_w, const int sys_h, const int num_icons, ALLEGRO_BITMAP *bmps[]) { HICON icon; HICON old_icon; ALLEGRO_BITMAP *bmp; int bmp_w; int bmp_h; int i; i = win_choose_icon_bitmap(sys_w, sys_h, num_icons, bmps); bmp = bmps[i]; bmp_w = al_get_bitmap_width(bmp); bmp_h = al_get_bitmap_height(bmp); if (bmp_w == sys_w && bmp_h == sys_h) { icon = _al_win_create_icon(win_display->window, bmp, 0, 0, false, false); } else { ALLEGRO_BITMAP *tmp_bmp; ALLEGRO_STATE backup; tmp_bmp = al_create_bitmap(sys_w, sys_h); if (!tmp_bmp) return; al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888); al_set_target_bitmap(tmp_bmp); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_scaled_bitmap(bmp, 0, 0, bmp_w, bmp_h, 0, 0, sys_w, sys_h, 0); al_restore_state(&backup); icon = _al_win_create_icon(win_display->window, tmp_bmp, 0, 0, false, false); al_destroy_bitmap(tmp_bmp); } old_icon = (HICON)SendMessage(win_display->window, WM_SETICON, icon_type, (LPARAM)icon); if (old_icon) DestroyIcon(old_icon); } void _al_win_set_display_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bmps[]) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; int sys_w; int sys_h; sys_w = GetSystemMetrics(SM_CXSMICON); sys_h = GetSystemMetrics(SM_CYSMICON); win_set_display_icon(win_display, ICON_SMALL, sys_w, sys_h, num_icons, bmps); sys_w = GetSystemMetrics(SM_CXICON); sys_h = GetSystemMetrics(SM_CYICON); win_set_display_icon(win_display, ICON_BIG, sys_w, sys_h, num_icons, bmps); } void _al_win_set_window_position(HWND window, int x, int y) { SetWindowPos( window, HWND_TOP, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } void _al_win_get_window_position(HWND window, int *x, int *y) { RECT r; GetWindowRect(window, &r); if (x) { *x = r.left; } if (y) { *y = r.top; } } void _al_win_set_window_frameless(ALLEGRO_DISPLAY *display, HWND hWnd, bool frameless) { int w = display->w; int h = display->h; if (frameless) { SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE); SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); SetWindowPos(hWnd, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); } else { RECT r; DWORD style; DWORD exStyle; display_flags_to_window_styles(display->flags, &style, &exStyle); style |= WS_VISIBLE; GetWindowRect(hWnd, &r); AdjustWindowRectEx(&r, style, false, exStyle); w = r.right - r.left; h = r.bottom - r.top; SetWindowLong(hWnd, GWL_STYLE, style); SetWindowLong(hWnd, GWL_EXSTYLE, exStyle); SetWindowPos(hWnd, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); } } bool _al_win_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) { ALLEGRO_DISPLAY_WIN *win_display = (void*)display; //double timeout; ALLEGRO_MONITOR_INFO mi; memset(&mi, 0, sizeof(mi)); switch (flag) { case ALLEGRO_FRAMELESS: { if (onoff) { display->flags |= ALLEGRO_FRAMELESS; } else { display->flags &= ~ALLEGRO_FRAMELESS; } _al_win_set_window_frameless(display, win_display->window, (display->flags & ALLEGRO_FRAMELESS)); return true; } case ALLEGRO_FULLSCREEN_WINDOW: if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW) && onoff) { ALLEGRO_DEBUG("Already a fullscreen window\n"); return true; } if (!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) && !onoff) { ALLEGRO_DEBUG("Already a non-fullscreen window\n"); return true; } if (onoff) { /* Switch off frame in fullscreen window mode. */ _al_win_set_window_frameless(display, win_display->window, true); } else { /* Respect display flag in windowed mode. */ _al_win_set_window_frameless(display, win_display->window, (display->flags & ALLEGRO_FRAMELESS)); } if (onoff) { int adapter = win_display->adapter; al_get_monitor_info(adapter, &mi); display->flags |= ALLEGRO_FULLSCREEN_WINDOW; display->w = mi.x2 - mi.x1; display->h = mi.y2 - mi.y1; } else { display->flags &= ~ALLEGRO_FULLSCREEN_WINDOW; display->w = win_display->toggle_w; display->h = win_display->toggle_h; } ASSERT(!!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) == onoff); // Hide the window temporarily SetWindowPos(win_display->window, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); al_resize_display(display, display->w, display->h); if (onoff) { // Re-set the TOPMOST flag and move to position SetWindowPos(win_display->window, HWND_TOPMOST, mi.x1, mi.y1, 0, 0, SWP_NOSIZE); // Hide the taskbar if fullscreening on primary monitor if (win_display->adapter == 0) { SetWindowPos( FindWindow("Shell_traywnd", ""), 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); } } else { int pos_x = 0; int pos_y = 0; WINDOWINFO wi; int bw, bh; // Unset the topmost flag SetWindowPos(win_display->window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // Show the taskbar SetWindowPos( FindWindow("Shell_traywnd", ""), 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); // Center the window _al_win_get_window_center(win_display, display->w, display->h, &pos_x, &pos_y); GetWindowInfo(win_display->window, &wi); bw = (wi.rcClient.left - wi.rcWindow.left) + (wi.rcWindow.right - wi.rcClient.right), bh = (wi.rcClient.top - wi.rcWindow.top) + (wi.rcWindow.bottom - wi.rcClient.bottom), SetWindowPos( win_display->window, HWND_TOP, 0, 0, display->w+bw, display->h+bh, SWP_NOMOVE ); SetWindowPos( win_display->window, HWND_TOP, pos_x-bw/2, pos_y-bh/2, 0, 0, SWP_NOSIZE ); } // Show the window again SetWindowPos(win_display->window, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); ASSERT(!!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) == onoff); return true; } return false; } void _al_win_set_window_title(ALLEGRO_DISPLAY *display, const char *title) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; SetWindowText(win_display->window, title); } /* _al_win_wnd_call_proc: * instructs the specifed window thread to call the specified procedure. Waits * until the procedure has returned. */ void _al_win_wnd_call_proc(HWND wnd, void (*proc) (void*), void* param) { ASSERT(_al_win_msg_call_proc); SendMessage(wnd, _al_win_msg_call_proc, (WPARAM)proc, (LPARAM)param); } /* _al_win_wnd_schedule_proc: * instructs the specifed window thread to call the specified procedure but * doesn't wait until the procedure has returned. */ void _al_win_wnd_schedule_proc(HWND wnd, void (*proc) (void*), void* param) { ASSERT(_al_win_msg_call_proc); if (!PostMessage(wnd, _al_win_msg_call_proc, (WPARAM)proc, (LPARAM)param)) { ALLEGRO_ERROR("_al_win_wnd_schedule_proc failed.\n"); } } /* Function: al_get_win_window_handle */ HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display) { if (!display) return NULL; return ((ALLEGRO_DISPLAY_WIN *)display)->window; } int _al_win_determine_adapter(void) { int a = al_get_new_display_adapter(); if (a == -1) { int num_screens = al_get_num_video_adapters(); int cScreen = 0; ALLEGRO_MONITOR_INFO temp_info; for (cScreen = 0; cScreen < num_screens; cScreen++) { al_get_monitor_info(cScreen, &temp_info); if (temp_info.x1 == 0 && temp_info.y1 == 0) { // ..probably found primary display return cScreen; } } return 0; // safety measure, probably not necessary } return a; } /* vi: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/win/d3d.h0000644000175000001440000000767412124553574014643 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_direct3d.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_direct3d.h" #include "allegro5/platform/aintwin.h" #include #include /* The MinGW copy of d3d9.h doesn't currently define this constant. */ #ifndef D3D9b_SDK_VERSION #ifdef D3D_DEBUG_INFO #define D3D9b_SDK_VERSION (31 | 0x80000000) #else #define D3D9b_SDK_VERSION 31 #endif #endif #ifdef __cplusplus extern "C" { #endif /* Flexible vertex formats */ #define D3DFVF_COLORED_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) #define D3DFVF_TL_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) typedef struct ALLEGRO_SYSTEM_D3D ALLEGRO_SYSTEM_D3D; typedef struct ALLEGRO_BITMAP_D3D { ALLEGRO_BITMAP bitmap; /* This must be the first member. */ /* Driver specifics. */ unsigned int texture_w; unsigned int texture_h; LPDIRECT3DTEXTURE9 video_texture; LPDIRECT3DTEXTURE9 system_texture; bool initialized; bool is_backbuffer; D3DLOCKED_RECT locked_rect; struct ALLEGRO_DISPLAY_D3D *display; IDirect3DSurface9 *render_target; bool modified; } ALLEGRO_BITMAP_D3D; typedef struct ALLEGRO_DISPLAY_D3D { ALLEGRO_DISPLAY_WIN win_display; /* This must be the first member. */ bool es_inited; /* Driver specifics */ LPDIRECT3DDEVICE9 device; LPDIRECT3DSURFACE9 render_target; LPDIRECT3DSURFACE9 depth_stencil; bool do_reset; bool reset_done; bool reset_success; ALLEGRO_BITMAP_D3D backbuffer_bmp; bool device_lost; bool suppress_lost_events; bool faux_fullscreen; bool supports_separate_alpha_blend; TCHAR *device_name; int format; D3DFORMAT depth_stencil_format; int samples; bool single_buffer; bool vsync; int blender_state_op; int blender_state_src; int blender_state_dst; int blender_state_alpha_op; int blender_state_alpha_src; int blender_state_alpha_dst; RECT scissor_state; } ALLEGRO_DISPLAY_D3D; /* Colored vertex */ typedef struct D3D_COLORED_VERTEX { float x; float y; float z; D3DCOLOR color; } D3D_COLORED_VERTEX; /* Transformed & lit vertex */ typedef struct D3D_TL_VERTEX { float x; /* x position */ float y; /* y position */ float z; /* z position */ D3DCOLOR diffuse; /* diffuse color */ float tu; /* texture coordinate */ float tv; /* texture coordinate */ } D3D_TL_VERTEX; extern LPDIRECT3D9 _al_d3d; ALLEGRO_BITMAP_INTERFACE *_al_bitmap_d3d_driver(void); AL_FUNC(ALLEGRO_BITMAP *, _al_d3d_create_bitmap, (ALLEGRO_DISPLAY *d, int w, int h)); //bool _al_d3d_is_device_lost(void); //void _al_d3d_lock_device(); //void _al_d3d_unlock_device(); int _al_pixel_format_to_d3d(int format); int _al_d3d_format_to_allegro(int d3d_fmt); bool _al_d3d_render_to_texture_supported(void); void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap); void _al_d3d_release_default_pool_textures(void); void _al_d3d_prepare_bitmaps_for_reset(ALLEGRO_DISPLAY_D3D *disp); void _al_d3d_refresh_texture_memory(void); bool _al_d3d_recreate_bitmap_textures(ALLEGRO_DISPLAY_D3D *disp); void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap); bool _al_d3d_supports_separate_alpha_blend(ALLEGRO_DISPLAY *display); void _al_d3d_bmp_init(void); void _al_d3d_bmp_destroy(void); void _al_d3d_generate_display_format_list(void); int _al_d3d_num_display_formats(void); void _al_d3d_get_nth_format(int i, int *allegro, D3DFORMAT *d3d); void _al_d3d_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref); void _al_d3d_destroy_display_format_list(void); ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_d3d_get_display_settings(int i); void _al_d3d_resort_display_settings(void); extern ALLEGRO_MUTEX *_al_d3d_lost_device_mutex; /* Helper to get smallest fitting power of two. */ AL_INLINE_STATIC(int, pot, (int x), { int y = 1; while (y < x) y *= 2; return y; }) #ifdef __cplusplus } #endif allegro-5.0.10/src/win/wjoydrv.c0000644000175000001440000000173211426530105015642 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * List of Windows joystick drivers, kept in a seperate file so that * they can be overriden by user programs. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_joystick.h" #ifndef ALLEGRO_WINDOWS #error something is wrong with the makefile #endif _AL_BEGIN_JOYSTICK_DRIVER_LIST _AL_JOYSTICK_DRIVER_DIRECTX _AL_END_JOYSTICK_DRIVER_LIST allegro-5.0.10/src/win/wgl.h0000644000175000001440000000051611454421721014737 0ustar tjadenusers#include "allegro5/internal/aintern_display.h" #include "allegro5/platform/aintwin.h" #include typedef struct ALLEGRO_DISPLAY_WGL { ALLEGRO_DISPLAY_WIN win_display; /* This must be the first member. */ /* Driver specifics */ HDC dc; HGLRC glrc; } ALLEGRO_DISPLAY_WGL; int _al_win_determine_adapter(void); allegro-5.0.10/src/win/wxthread.c0000644000175000001440000002367611431556561016011 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Internal cross-platform threading API for Windows. * * By Peter Wang. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_thread.h" #include #include /* threads */ static unsigned __stdcall thread_proc_trampoline(void *data) { _AL_THREAD *thread = data; (*thread->proc)(thread, thread->arg); /* _endthreadex does not automatically close the thread handle, * unlike _endthread. We rely on this in al_join_thread(). */ _endthreadex(0); return 0; } void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), void *arg) { ASSERT(thread); ASSERT(proc); { InitializeCriticalSection(&thread->cs); thread->should_stop = false; thread->proc = proc; thread->arg = arg; thread->thread = (void *)_beginthreadex(NULL, 0, thread_proc_trampoline, thread, 0, NULL); } } void _al_thread_set_should_stop(_AL_THREAD *thread) { ASSERT(thread); EnterCriticalSection(&thread->cs); { thread->should_stop = true; } LeaveCriticalSection(&thread->cs); } void _al_thread_join(_AL_THREAD *thread) { ASSERT(thread); _al_thread_set_should_stop(thread); WaitForSingleObject(thread->thread, INFINITE); CloseHandle(thread->thread); DeleteCriticalSection(&thread->cs); } void _al_thread_detach(_AL_THREAD *thread) { ASSERT(thread); CloseHandle(thread->thread); DeleteCriticalSection(&thread->cs); } /* mutexes */ void _al_mutex_init(_AL_MUTEX *mutex) { ASSERT(mutex); if (!mutex->cs) mutex->cs = al_malloc(sizeof *mutex->cs); ASSERT(mutex->cs); if (mutex->cs) InitializeCriticalSection(mutex->cs); else abort(); } void _al_mutex_init_recursive(_AL_MUTEX *mutex) { /* These are the same on Windows. */ _al_mutex_init(mutex); } void _al_mutex_destroy(_AL_MUTEX *mutex) { ASSERT(mutex); if (mutex->cs) { DeleteCriticalSection(mutex->cs); al_free(mutex->cs); mutex->cs = NULL; } } /* condition variables */ /* * The algorithm used was originally designed for the pthread-win32 * package. I translated the pseudo-code below line for line. * * --- From pthread-win32: --- * Algorithm: * The algorithm used in this implementation is that developed by * Alexander Terekhov in colaboration with Louis Thomas. The bulk * of the discussion is recorded in the file README.CV, which contains * several generations of both colaborators original algorithms. The final * algorithm used here is the one referred to as * * Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL * * presented below in pseudo-code as it appeared: * * [snip] * ------------------------------------------------------------- * * Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL * * presented below in pseudo-code; basically 8a... * ...BUT W/O "spurious wakes" prevention: * * * given: * semBlockLock - bin.semaphore * semBlockQueue - semaphore * mtxExternal - mutex or CS * mtxUnblockLock - mutex or CS * nWaitersGone - int * nWaitersBlocked - int * nWaitersToUnblock - int * * wait( timeout ) { * * [auto: register int result ] // error checking omitted * [auto: register int nSignalsWasLeft ] * * sem_wait( semBlockLock ); * ++nWaitersBlocked; * sem_post( semBlockLock ); * * unlock( mtxExternal ); * bTimedOut = sem_wait( semBlockQueue,timeout ); * * lock( mtxUnblockLock ); * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { * --nWaitersToUnblock; * } * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or * // spurious semaphore :-) * sem_wait( semBlockLock ); * nWaitersBlocked -= nWaitersGone; // something is going on here * // - test of timeouts? :-) * sem_post( semBlockLock ); * nWaitersGone = 0; * } * unlock( mtxUnblockLock ); * * if ( 1 == nSignalsWasLeft ) { * sem_post( semBlockLock ); // open the gate * } * * lock( mtxExternal ); * * return ( bTimedOut ) ? ETIMEOUT : 0; * } * * signal(bAll) { * * [auto: register int result ] * [auto: register int nSignalsToIssue] * * lock( mtxUnblockLock ); * * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!! * if ( 0 == nWaitersBlocked ) { // NO-OP * return unlock( mtxUnblockLock ); * } * if (bAll) { * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; * nWaitersBlocked = 0; * } * else { * nSignalsToIssue = 1; * ++nWaitersToUnblock; * --nWaitersBlocked; * } * } * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION! * sem_wait( semBlockLock ); // close the gate * if ( 0 != nWaitersGone ) { * nWaitersBlocked -= nWaitersGone; * nWaitersGone = 0; * } * if (bAll) { * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; * nWaitersBlocked = 0; * } * else { * nSignalsToIssue = nWaitersToUnblock = 1; * --nWaitersBlocked; * } * } * else { // NO-OP * return unlock( mtxUnblockLock ); * } * * unlock( mtxUnblockLock ); * sem_post( semBlockQueue,nSignalsToIssue ); * return result; * } * ------------------------------------------------------------- */ void _al_cond_init(_AL_COND *cond) { cond->nWaitersBlocked = 0; cond->nWaitersGone = 0; cond->nWaitersToUnblock = 0; cond->semBlockQueue = CreateSemaphore(NULL, 0, INT_MAX, NULL); InitializeCriticalSection(&cond->semBlockLock); InitializeCriticalSection(&cond->mtxUnblockLock); } void _al_cond_destroy(_AL_COND *cond) { DeleteCriticalSection(&cond->mtxUnblockLock); DeleteCriticalSection(&cond->semBlockLock); CloseHandle(cond->semBlockQueue); } /* returns -1 on timeout */ static int cond_wait(_AL_COND *cond, _AL_MUTEX *mtxExternal, DWORD timeout) { int nSignalsWasLeft; bool bTimedOut; DWORD dwWaitResult; EnterCriticalSection(&cond->semBlockLock); ++cond->nWaitersBlocked; LeaveCriticalSection(&cond->semBlockLock); _al_mutex_unlock(mtxExternal); dwWaitResult = WaitForSingleObject(cond->semBlockQueue, timeout); if (dwWaitResult == WAIT_TIMEOUT) bTimedOut = true; else if (dwWaitResult == WAIT_OBJECT_0) bTimedOut = false; else { /* bad! what to do? */ _al_mutex_lock(mtxExternal); ASSERT(false); return 0; } EnterCriticalSection(&cond->mtxUnblockLock); if (0 != (nSignalsWasLeft = cond->nWaitersToUnblock)) { --(cond->nWaitersToUnblock); } else if (INT_MAX/2 == ++(cond->nWaitersGone)) { /* timeout/canceled or spurious semaphore :-) */ EnterCriticalSection(&cond->semBlockLock); cond->nWaitersBlocked -= cond->nWaitersGone; /* something is going on here - test of timeouts? :-) */ LeaveCriticalSection(&cond->semBlockLock); cond->nWaitersGone = 0; } LeaveCriticalSection(&cond->mtxUnblockLock); if (1 == nSignalsWasLeft) { LeaveCriticalSection(&cond->semBlockLock); /* open the gate */ } _al_mutex_lock(mtxExternal); return bTimedOut ? -1 : 0; } void _al_cond_wait(_AL_COND *cond, _AL_MUTEX *mtxExternal) { int result; ASSERT(cond); ASSERT(mtxExternal); result = cond_wait(cond, mtxExternal, INFINITE); ASSERT(result != -1); (void)result; } int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mtxExternal, const ALLEGRO_TIMEOUT *timeout) { ALLEGRO_TIMEOUT_WIN *win_timeout = (ALLEGRO_TIMEOUT_WIN *) timeout; DWORD now; DWORD rel_msecs; ASSERT(cond); ASSERT(mtxExternal); now = timeGetTime(); rel_msecs = win_timeout->abstime - now; if (rel_msecs == INFINITE) { rel_msecs--; } return cond_wait(cond, mtxExternal, rel_msecs); } static void cond_signal(_AL_COND *cond, bool bAll) { int nSignalsToIssue; EnterCriticalSection(&cond->mtxUnblockLock); if (0 != cond->nWaitersToUnblock) { /* the gate is closed!!! */ if (0 == cond->nWaitersBlocked) { /* NO-OP */ LeaveCriticalSection(&cond->mtxUnblockLock); return; } if (bAll) { cond->nWaitersToUnblock += (nSignalsToIssue = cond->nWaitersBlocked); cond->nWaitersBlocked = 0; } else { nSignalsToIssue = 1; ++cond->nWaitersToUnblock; --cond->nWaitersBlocked; } } else if (cond->nWaitersBlocked > cond->nWaitersGone) { /* HARMLESS RACE CONDITION! */ EnterCriticalSection(&cond->semBlockLock); /* close the gate */ if (0 != cond->nWaitersGone) { cond->nWaitersBlocked -= cond->nWaitersGone; cond->nWaitersGone = 0; } if (bAll) { nSignalsToIssue = (cond->nWaitersToUnblock = cond->nWaitersBlocked); cond->nWaitersBlocked = 0; } else { nSignalsToIssue = cond->nWaitersToUnblock = 1; --cond->nWaitersBlocked; } } else { /* NO-OP */ LeaveCriticalSection(&cond->mtxUnblockLock); return; } LeaveCriticalSection(&cond->mtxUnblockLock); ReleaseSemaphore(cond->semBlockQueue, nSignalsToIssue, NULL); return; } void _al_cond_broadcast(_AL_COND *cond) { cond_signal(cond, true); } void _al_cond_signal(_AL_COND *cond) { cond_signal(cond, false); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wmouse.c0000644000175000001440000002117712125426002015457 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows mouse driver. * * By Milan Mimica. * * See readme.txt for copyright information. */ #if 0 /* Raw input */ #define _WIN32_WINNT 0x0501 #ifndef WINVER #define WINVER 0x0600 #endif #endif #include /* * Even the most recent MinGW at the moment of writing this is missing * this symbol. */ #ifndef SM_MOUSEHORIZONTALWHEELPRESENT #define SM_MOUSEHORIZONTALWHEELPRESENT 91 #endif #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/platform/aintwin.h" #include "allegro5/internal/aintern_display.h" static ALLEGRO_MOUSE_STATE mouse_state; static ALLEGRO_MOUSE the_mouse; static bool installed = false; static bool init_mouse(void) { ALLEGRO_DISPLAY *display; if (installed) return false; /* If the display was created before the mouse is installed and the mouse * cursor is initially within the window, then the display field has correct * and useful info so don't clobber it. */ display = mouse_state.display; memset(&mouse_state, 0, sizeof(mouse_state)); mouse_state.display = display; _al_event_source_init(&the_mouse.es); #if 0 if (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) { RAWINPUTDEVICE rid[1]; rid[0].usUsagePage = 0x01; rid[0].usUsage = 0x02; rid[0].dwFlags = RIDEV_NOLEGACY; rid[0].hwndTarget = 0; if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { return false; } } #endif installed = true; return true; } static void exit_mouse(void) { if (!installed) return; memset(&mouse_state, 0, sizeof(mouse_state)); _al_event_source_free(&the_mouse.es); installed = false; } static void generate_mouse_event(unsigned int type, int x, int y, int z, int w, int dx, int dy, int dz, int dw, unsigned int button, ALLEGRO_DISPLAY *source) { ALLEGRO_EVENT event; if (!_al_event_source_needs_to_generate_event(&the_mouse.es)) return; _al_event_source_lock(&the_mouse.es); event.mouse.type = type; event.mouse.timestamp = al_get_time(); event.mouse.display = source; event.mouse.x = x; event.mouse.y = y; event.mouse.z = z; event.mouse.w = w; event.mouse.dx = dx; event.mouse.dy = dy; event.mouse.dz = dz; event.mouse.dw = dw; event.mouse.button = button; event.mouse.pressure = 0.0; /* TODO */ _al_event_source_emit_event(&the_mouse.es, &event); _al_event_source_unlock(&the_mouse.es); } static ALLEGRO_MOUSE* get_mouse(void) { return &the_mouse; } static unsigned int get_num_buttons(void) { return GetSystemMetrics(SM_CMOUSEBUTTONS); } static unsigned int get_num_axes(void) { bool x = GetSystemMetrics(SM_MOUSEHORIZONTALWHEELPRESENT); bool z = GetSystemMetrics(SM_MOUSEWHEELPRESENT); if (x && z) return 4; if (x || z) return 3; return 2; } static bool set_mouse_xy(ALLEGRO_DISPLAY *disp, int x, int y) { int dx, dy; POINT pt; ALLEGRO_DISPLAY_WIN *win_disp = (void*)disp; if (!installed) return false; dx = x - mouse_state.x; dy = y - mouse_state.y; if (dx || dy) { mouse_state.x = x; mouse_state.y = y; generate_mouse_event( ALLEGRO_EVENT_MOUSE_WARPED, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, dx, dy, 0, 0, 0, (void*)win_disp); } pt.x = x; pt.y = y; ClientToScreen(win_disp->window, &pt); SetCursorPos(pt.x, pt.y); return true; } static bool set_mouse_axis(int which, int val) { /* Vertical mouse wheel. */ if (which == 2) { int dz = (val - mouse_state.z); if (dz != 0) { mouse_state.z = val; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, dz, 0, 0, mouse_state.display); } return true; } /* Horizontal mouse wheel. */ if (which == 3) { int dw = (val - mouse_state.w); if (dw != 0) { mouse_state.w = val; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, 0, dw, 0, mouse_state.display); } return true; } return false; } static void get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) { _al_event_source_lock(&the_mouse.es); *ret_state = mouse_state; _al_event_source_unlock(&the_mouse.es); } /* the driver vtable */ #define MOUSE_WINAPI AL_ID('W','A','P','I') static ALLEGRO_MOUSE_DRIVER mousedrv_winapi = { MOUSE_WINAPI, "", "", "WinAPI mouse", init_mouse, exit_mouse, get_mouse, get_num_buttons, get_num_axes, set_mouse_xy, set_mouse_axis, get_mouse_state }; _AL_DRIVER_INFO _al_mouse_driver_list[] = { {MOUSE_WINAPI, &mousedrv_winapi, true}, {0, NULL, 0} }; void _al_win_mouse_handle_leave(ALLEGRO_DISPLAY_WIN *win_disp) { /* The state should be updated even if the mouse is not installed so that * it will be correct if the mouse is installed later. */ if (mouse_state.display == (void*)win_disp) mouse_state.display = NULL; if (!installed) return; generate_mouse_event(ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, 0, 0, 0, (void*)win_disp); } void _al_win_mouse_handle_enter(ALLEGRO_DISPLAY_WIN *win_disp) { /* The state should be updated even if the mouse is not installed so that * it will be correct if the mouse is installed later. */ mouse_state.display = (void*)win_disp; if (!installed) return; generate_mouse_event(ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, 0, 0, 0, (void*)win_disp); } void _al_win_mouse_handle_move(int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) { int dx, dy; int oldx, oldy; oldx = mouse_state.x; oldy = mouse_state.y; if (!installed) return; if (!abs) { mouse_state.x += x; mouse_state.y += y; dx = x; dy = y; } else { dx = x - mouse_state.x; dy = y - mouse_state.y; mouse_state.x = x; mouse_state.y = y; } if (oldx != mouse_state.x || oldy != mouse_state.y) { generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, dx, dy, 0, 0, 0, (void*)win_disp); } } void _al_win_mouse_handle_wheel(int z, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) { int d; if (!installed) return; if (!abs) { mouse_state.z += z; d = z; } else { d = z - mouse_state.z; mouse_state.z = z; } generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, d, 0, 0, (void*)win_disp); } void _al_win_mouse_handle_hwheel(int w, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) { int d; if (!installed) return; if (!abs) { mouse_state.w += w; d = w; } else { d = w - mouse_state.w; mouse_state.w = w; } generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, 0, d, 0, (void*)win_disp); } void _al_win_mouse_handle_button(int button, bool down, int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) { int type = down ? ALLEGRO_EVENT_MOUSE_BUTTON_DOWN : ALLEGRO_EVENT_MOUSE_BUTTON_UP; if (!installed) return; if (!abs) { mouse_state.x += x; mouse_state.y += y; } else { mouse_state.x = x; mouse_state.y = y; } if (down) mouse_state.buttons |= (1 << (button-1)); else mouse_state.buttons &= ~(1 << (button-1)); generate_mouse_event(type, mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, 0, 0, 0, 0, button, (void*)win_disp); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wgl_disp.c0000644000175000001440000014067612144071126015762 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows OpenGL display driver * * By Milan Mimica. * Based on AllegroGL Windows display driver. * */ #if 0 /* Raw input */ #define _WIN32_WINNT 0x0501 #ifndef WINVER #define WINVER 0x0501 #endif #endif #include #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/system.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/platform/aintwin.h" #include "wgl.h" #include ALLEGRO_DEBUG_CHANNEL("display") static ALLEGRO_DISPLAY_INTERFACE vt; /* Forward declarations: */ static void display_thread_proc(void *arg); static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp); static bool wgl_acknowledge_resize(ALLEGRO_DISPLAY *d); /* Prevents switching to desktop resolution when destroying the display. Used on full screen resize. */ static bool _wgl_do_not_change_display_mode = false; /* * These parameters cannot be gotten by the display thread because * they're thread local. We get them in the calling thread first. */ typedef struct WGL_DISPLAY_PARAMETERS { ALLEGRO_DISPLAY_WGL *display; volatile bool init_failed; HANDLE AckEvent; int window_x, window_y; } WGL_DISPLAY_PARAMETERS; static char* get_error_desc(DWORD err) { #define MSGLEN 2048 static char err_msg[MSGLEN]; memset(err_msg, 0, MSGLEN); /* Get the formatting error string from Windows. Note that only the * bottom 14 bits matter - the rest are reserved for various library * IDs and type of error. */ if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err & 0x3FFF, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err_msg, MSGLEN, NULL)) { strcpy(err_msg, "(Unable to decode the error code)"); } else { /* Remove two trailing characters */ if (strlen(err_msg) > 1) *(err_msg + strlen(err_msg) - 2) = '\0'; } return err_msg; } /* Helper to set up GL state as we want it. */ static void setup_gl(ALLEGRO_DISPLAY *d) { glViewport(0, 0, d->w, d->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, d->w, d->h, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static bool is_wgl_extension_supported(const char *extension, HDC dc) { _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB; int ret; /* XXX deprecated in OpenGL 3.0 */ if (!glGetString(GL_EXTENSIONS)) return false; _wglGetExtensionsStringARB = (_ALLEGRO_wglGetExtensionsStringARB_t) wglGetProcAddress("wglGetExtensionsStringARB"); if (!_wglGetExtensionsStringARB) return false; ret = _al_ogl_look_for_an_extension(extension, (const GLubyte*)_wglGetExtensionsStringARB(dc)); return ret; } static HGLRC init_temp_context(HWND wnd) { PIXELFORMATDESCRIPTOR pfd; int pf; HDC dc; HGLRC glrc; dc = GetDC(wnd); memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE; pfd.iPixelType = PFD_TYPE_RGBA; pfd.iLayerType = PFD_MAIN_PLANE; pfd.cColorBits = 32; pf = ChoosePixelFormat(dc, &pfd); if (!pf) { ALLEGRO_ERROR("Unable to chose a temporary pixel format. %s\n", get_error_desc(GetLastError())); return NULL; } memset(&pfd, 0, sizeof(pfd)); if (!SetPixelFormat(dc, pf, &pfd)) { ALLEGRO_ERROR("Unable to set a temporary pixel format. %s\n", get_error_desc(GetLastError())); return NULL; } glrc = wglCreateContext(dc); if (!glrc) { ALLEGRO_ERROR("Unable to create a render context. %s\n", get_error_desc(GetLastError())); return NULL; } if (!wglMakeCurrent(dc, glrc)) { ALLEGRO_ERROR("Unable to set the render context as current. %s\n", get_error_desc(GetLastError())); wglDeleteContext(glrc); return NULL; } return glrc; } static _ALLEGRO_wglGetPixelFormatAttribivARB_t _wglGetPixelFormatAttribivARB = NULL; static _ALLEGRO_wglGetPixelFormatAttribivEXT_t _wglGetPixelFormatAttribivEXT = NULL; static bool init_pixel_format_extensions(void) { /* Load the ARB_p_f symbol - Note, we shouldn't use the extension * mechanism here, because it hasn't been initialized yet! */ _wglGetPixelFormatAttribivARB = (_ALLEGRO_wglGetPixelFormatAttribivARB_t)wglGetProcAddress("wglGetPixelFormatAttribivARB"); _wglGetPixelFormatAttribivEXT = (_ALLEGRO_wglGetPixelFormatAttribivEXT_t)wglGetProcAddress("wglGetPixelFormatAttribivEXT"); if (!_wglGetPixelFormatAttribivARB && !_wglGetPixelFormatAttribivEXT) { ALLEGRO_ERROR("WGL_ARB/EXT_pf not supported.\n"); return false; } return true; } static _ALLEGRO_wglCreateContextAttribsARB_t _wglCreateContextAttribsARB = NULL; static bool init_context_creation_extensions(void) { _wglCreateContextAttribsARB = (_ALLEGRO_wglCreateContextAttribsARB_t)wglGetProcAddress("wglCreateContextAttribsARB"); if (!_wglCreateContextAttribsARB) { ALLEGRO_ERROR("wglCreateContextAttribs not supported!\n"); return false; } return true; } static int get_pixel_formats_count_old(HDC dc) { PIXELFORMATDESCRIPTOR pfd; int ret; ret = DescribePixelFormat(dc, 1, sizeof(pfd), &pfd); if (!ret) { ALLEGRO_ERROR("DescribePixelFormat failed! %s\n", get_error_desc(GetLastError())); } return ret; } static int get_pixel_formats_count_ext(HDC dc) { int attrib[1]; int value[1]; attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; if ((_wglGetPixelFormatAttribivARB(dc, 0, 0, 1, attrib, value) == GL_FALSE) && (_wglGetPixelFormatAttribivEXT(dc, 0, 0, 1, attrib, value) == GL_FALSE)) { ALLEGRO_ERROR("WGL_ARB/EXT_pixel_format use failed! %s\n", get_error_desc(GetLastError())); } return value[0]; } static void display_pixel_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { ALLEGRO_INFO("Accelarated: %s\n", eds->settings[ALLEGRO_RENDER_METHOD] ? "yes" : "no"); ALLEGRO_INFO("Single-buffer: %s\n", eds->settings[ALLEGRO_SINGLE_BUFFER] ? "yes" : "no"); if (eds->settings[ALLEGRO_SWAP_METHOD] > 0) ALLEGRO_INFO("Swap method: %s\n", eds->settings[ALLEGRO_SWAP_METHOD] == 2 ? "flip" : "copy"); else ALLEGRO_INFO("Swap method: undefined\n"); ALLEGRO_INFO("Color format: r%i g%i b%i a%i, %i bit\n", eds->settings[ALLEGRO_RED_SIZE], eds->settings[ALLEGRO_GREEN_SIZE], eds->settings[ALLEGRO_BLUE_SIZE], eds->settings[ALLEGRO_ALPHA_SIZE], eds->settings[ALLEGRO_COLOR_SIZE]); ALLEGRO_INFO("Depth buffer: %i bits\n", eds->settings[ALLEGRO_DEPTH_SIZE]); ALLEGRO_INFO("Sample buffers: %s\n", eds->settings[ALLEGRO_SAMPLE_BUFFERS] ? "yes" : "no"); ALLEGRO_INFO("Samples: %i\n", eds->settings[ALLEGRO_SAMPLES]); } static int decode_pixel_format_old(PIXELFORMATDESCRIPTOR *pfd, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { ALLEGRO_INFO("Decoding:\n"); /* Not interested if it doesn't support OpenGL and RGBA */ if (!(pfd->dwFlags & PFD_SUPPORT_OPENGL)) { ALLEGRO_INFO("OpenGL Unsupported\n"); return false; } if (pfd->iPixelType != PFD_TYPE_RGBA) { ALLEGRO_INFO("Not RGBA mode\n"); return false; } /* hardware acceleration */ if (((pfd->dwFlags & PFD_GENERIC_ACCELERATED) && (pfd->dwFlags & PFD_GENERIC_FORMAT)) || (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT))) eds->settings[ALLEGRO_RENDER_METHOD] = 1; else eds->settings[ALLEGRO_RENDER_METHOD] = 0; /* Depths of colour buffers */ eds->settings[ALLEGRO_RED_SIZE] = pfd->cRedBits; eds->settings[ALLEGRO_GREEN_SIZE] = pfd->cGreenBits; eds->settings[ALLEGRO_BLUE_SIZE] = pfd->cBlueBits; eds->settings[ALLEGRO_ALPHA_SIZE] = pfd->cAlphaBits; /* Depths of accumulation buffer */ eds->settings[ALLEGRO_ACC_RED_SIZE] = pfd->cAccumRedBits; eds->settings[ALLEGRO_ACC_GREEN_SIZE] = pfd->cAccumGreenBits; eds->settings[ALLEGRO_ACC_BLUE_SIZE] = pfd->cAccumBlueBits; eds->settings[ALLEGRO_ACC_ALPHA_SIZE] = pfd->cAccumAlphaBits; /* Miscellaneous settings */ eds->settings[ALLEGRO_SINGLE_BUFFER] = !(pfd->dwFlags & PFD_DOUBLEBUFFER); eds->settings[ALLEGRO_DEPTH_SIZE] = pfd->cDepthBits; eds->settings[ALLEGRO_STENCIL_SIZE] = pfd->cStencilBits; eds->settings[ALLEGRO_COLOR_SIZE] = pfd->cColorBits; eds->settings[ALLEGRO_STEREO] = pfd->dwFlags & PFD_STEREO; eds->settings[ALLEGRO_AUX_BUFFERS] = pfd->cAuxBuffers; /* These are the component shifts. */ eds->settings[ALLEGRO_RED_SHIFT] = pfd->cRedShift; eds->settings[ALLEGRO_GREEN_SHIFT] = pfd->cGreenShift; eds->settings[ALLEGRO_BLUE_SHIFT] = pfd->cBlueShift; eds->settings[ALLEGRO_ALPHA_SHIFT] = pfd->cAlphaShift; /* Multisampling isn't supported under Windows if we don't also use * WGL_ARB_pixel_format or WGL_EXT_pixel_format. */ eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; eds->settings[ALLEGRO_SAMPLES] = 0; /* Swap method can't be detected without WGL_ARB_pixel_format or * WGL_EXT_pixel_format */ eds->settings[ALLEGRO_SWAP_METHOD] = 0; /* Float depth/color isn't supported under Windows if we don't also use * AGL_ARB_pixel_format or WGL_EXT_pixel_format. */ eds->settings[ALLEGRO_FLOAT_COLOR] = 0; eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; // FIXME eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; return true; } static bool decode_pixel_format_attrib(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, int num_attribs, const int *attrib, const int *value) { int i; ALLEGRO_INFO("Decoding:\n"); eds->settings[ALLEGRO_SAMPLES] = 0; eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; eds->settings[ALLEGRO_FLOAT_COLOR] = 0; eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; for (i = 0; i < num_attribs; i++) { /* Not interested if it doesn't support OpenGL or window drawing or RGBA. */ if (attrib[i] == WGL_SUPPORT_OPENGL_ARB && value[i] == 0) { ALLEGRO_INFO("OpenGL Unsupported\n"); return false; } else if (attrib[i] == WGL_DRAW_TO_WINDOW_ARB && value[i] == 0) { ALLEGRO_INFO("Can't draw to window\n"); return false; } else if (attrib[i] == WGL_PIXEL_TYPE_ARB && (value[i] != WGL_TYPE_RGBA_ARB && value[i] != WGL_TYPE_RGBA_FLOAT_ARB)) { ALLEGRO_INFO("Not RGBA mode\n"); return false; } /* hardware acceleration */ else if (attrib[i] == WGL_ACCELERATION_ARB) { eds->settings[ALLEGRO_RENDER_METHOD] = (value[i] == WGL_NO_ACCELERATION_ARB) ? 0 : 1; } /* Depths of colour buffers */ else if (attrib[i] == WGL_RED_BITS_ARB) { eds->settings[ALLEGRO_RED_SIZE] = value[i]; } else if (attrib[i] == WGL_GREEN_BITS_ARB) { eds->settings[ALLEGRO_GREEN_SIZE] = value[i]; } else if (attrib[i] == WGL_BLUE_BITS_ARB) { eds->settings[ALLEGRO_BLUE_SIZE] = value[i]; } else if (attrib[i] == WGL_ALPHA_BITS_ARB) { eds->settings[ALLEGRO_ALPHA_SIZE] = value[i]; } /* Shift of color components */ else if (attrib[i] == WGL_RED_SHIFT_ARB) { eds->settings[ALLEGRO_RED_SHIFT] = value[i]; } else if (attrib[i] == WGL_GREEN_SHIFT_ARB) { eds->settings[ALLEGRO_GREEN_SHIFT] = value[i]; } else if (attrib[i] == WGL_BLUE_SHIFT_ARB) { eds->settings[ALLEGRO_BLUE_SHIFT] = value[i]; } else if (attrib[i] == WGL_ALPHA_SHIFT_ARB) { eds->settings[ALLEGRO_ALPHA_SHIFT] = value[i]; } /* Miscellaneous settings */ else if (attrib[i] == WGL_DOUBLE_BUFFER_ARB) { eds->settings[ALLEGRO_SINGLE_BUFFER] = !(value[i]); } else if (attrib[i] == WGL_SWAP_METHOD_ARB) { if (value[i] == WGL_SWAP_UNDEFINED_ARB) eds->settings[ALLEGRO_SWAP_METHOD] = 0; else if (value[i] == WGL_SWAP_COPY_ARB) eds->settings[ALLEGRO_SWAP_METHOD] = 1; else if (value[i] == WGL_SWAP_EXCHANGE_ARB) eds->settings[ALLEGRO_SWAP_METHOD] = 2; } else if (attrib[i] == WGL_STEREO_ARB) { eds->settings[ALLEGRO_STEREO] = value[i]; } else if (attrib[i] == WGL_AUX_BUFFERS_ARB) { eds->settings[ALLEGRO_AUX_BUFFERS] = value[i]; } else if (attrib[i] == WGL_STENCIL_BITS_ARB) { eds->settings[ALLEGRO_STENCIL_SIZE] = value[i]; } /* Depths of accumulation buffer */ else if (attrib[i] == WGL_ACCUM_RED_BITS_ARB) { eds->settings[ALLEGRO_ACC_RED_SIZE] = value[i]; } else if (attrib[i] == WGL_ACCUM_GREEN_BITS_ARB) { eds->settings[ALLEGRO_ACC_GREEN_SIZE] = value[i]; } else if (attrib[i] == WGL_ACCUM_BLUE_BITS_ARB) { eds->settings[ALLEGRO_ACC_BLUE_SIZE] = value[i]; } else if (attrib[i] == WGL_ACCUM_ALPHA_BITS_ARB) { eds->settings[ALLEGRO_ACC_ALPHA_SIZE] = value[i]; } else if (attrib[i] == WGL_DEPTH_BITS_ARB) { eds->settings[ALLEGRO_DEPTH_SIZE] = value[i]; } else if (attrib[i] == WGL_COLOR_BITS_ARB) { eds->settings[ALLEGRO_COLOR_SIZE] = value[i]; } /* Multisampling bits */ else if (attrib[i] == WGL_SAMPLE_BUFFERS_ARB) { eds->settings[ALLEGRO_SAMPLE_BUFFERS] = value[i]; } else if (attrib[i] == WGL_SAMPLES_ARB) { eds->settings[ALLEGRO_SAMPLES] = value[i]; } /* Float color */ if (attrib[i] == WGL_PIXEL_TYPE_ARB && value[i] == WGL_TYPE_RGBA_FLOAT_ARB) { eds->settings[ALLEGRO_FLOAT_COLOR] = true; } /* Float depth */ else if (attrib[i] == WGL_DEPTH_FLOAT_EXT) { eds->settings[ALLEGRO_FLOAT_DEPTH] = value[i]; } } return true; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_pixel_format_old(int fmt, HDC dc) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; PIXELFORMATDESCRIPTOR pfd; int result; result = DescribePixelFormat(dc, fmt+1, sizeof(pfd), &pfd); if (!result) { ALLEGRO_WARN("DescribePixelFormat() failed. %s\n", get_error_desc(GetLastError())); return NULL; } eds = al_calloc(1, sizeof *eds); if (!decode_pixel_format_old(&pfd, eds)) { al_free(eds); return NULL; } return eds; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_pixel_format_ext(int fmt, HDC dc) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; /* Note: Even though we use te ARB suffix, all those enums are compatible * with EXT_pixel_format. */ int attrib[] = { WGL_SUPPORT_OPENGL_ARB, WGL_DRAW_TO_WINDOW_ARB, WGL_PIXEL_TYPE_ARB, WGL_ACCELERATION_ARB, WGL_DOUBLE_BUFFER_ARB, WGL_DEPTH_BITS_ARB, WGL_SWAP_METHOD_ARB, WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB, WGL_RED_SHIFT_ARB, WGL_GREEN_SHIFT_ARB, WGL_BLUE_SHIFT_ARB, WGL_ALPHA_SHIFT_ARB, WGL_STENCIL_BITS_ARB, WGL_STEREO_ARB, WGL_ACCUM_BITS_ARB, WGL_ACCUM_RED_BITS_ARB, WGL_ACCUM_GREEN_BITS_ARB, WGL_ACCUM_BLUE_BITS_ARB, WGL_ACCUM_ALPHA_BITS_ARB, WGL_AUX_BUFFERS_ARB, /* The following are used by extensions that add to WGL_pixel_format. * If WGL_p_f isn't supported though, we can't use the (then invalid) * enums. We can't use any magic number either, so we settle for * replicating one. The pixel format decoder * (decode_pixel_format_attrib()) doesn't care about duplicates. */ WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_SAMPLE_BUFFERS_ARB */ WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_SAMPLES_ARB */ WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_DEPTH_FLOAT_EXT */ }; const int num_attribs = sizeof(attrib) / sizeof(attrib[0]); int *value = (int*)al_malloc(sizeof(int) * num_attribs); int ret; if (!value) return NULL; /* If multisampling is supported, query for it. */ if (is_wgl_extension_supported("WGL_ARB_multisample", dc)) { attrib[num_attribs - 3] = WGL_SAMPLE_BUFFERS_ARB; attrib[num_attribs - 2] = WGL_SAMPLES_ARB; } if (is_wgl_extension_supported("WGL_EXT_depth_float", dc)) { attrib[num_attribs - 1] = WGL_DEPTH_FLOAT_EXT; } /* Get the pf attributes */ if (_wglGetPixelFormatAttribivARB) { ret = _wglGetPixelFormatAttribivARB(dc, fmt+1, 0, num_attribs, attrib, value); } else if (_wglGetPixelFormatAttribivEXT) { ret = _wglGetPixelFormatAttribivEXT(dc, fmt+1, 0, num_attribs, attrib, value); } else { ret = 0; } if (!ret) { ALLEGRO_ERROR("wglGetPixelFormatAttrib failed! %s\n", get_error_desc(GetLastError())); al_free(value); return NULL; } eds = al_calloc(1, sizeof *eds); if (!decode_pixel_format_attrib(eds, num_attribs, attrib, value)) { al_free(eds); eds = NULL; } al_free(value); /* Hack: for some reason this happens for me under Wine. */ if (eds && eds->settings[ALLEGRO_RED_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 0 && eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_ALPHA_SHIFT] == 0) { eds->settings[ALLEGRO_RED_SHIFT] = 0; eds->settings[ALLEGRO_GREEN_SHIFT] = 8; eds->settings[ALLEGRO_BLUE_SHIFT] = 16; eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; } return eds; } static bool change_display_mode(ALLEGRO_DISPLAY *d) { DEVMODE dm; DEVMODE fallback_dm; DISPLAY_DEVICE dd; char* dev_name = NULL; int i, modeswitch, result; int fallback_dm_valid = 0; int bpp; int adapter = al_get_new_display_adapter(); if (adapter >= 0) { memset(&dd, 0, sizeof(dd)); dd.cb = sizeof(dd); if (EnumDisplayDevices(NULL, adapter, &dd, 0) == false) return false; dev_name = dd.DeviceName; } memset(&fallback_dm, 0, sizeof(fallback_dm)); memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(DEVMODE); bpp = d->extra_settings.settings[ALLEGRO_COLOR_SIZE]; if (!bpp) bpp = 32; i = 0; do { modeswitch = EnumDisplaySettings(dev_name, i, &dm); if (!modeswitch) break; if ((dm.dmPelsWidth == (unsigned) d->w) && (dm.dmPelsHeight == (unsigned) d->h) && (dm.dmBitsPerPel == (unsigned) bpp) && (dm.dmDisplayFrequency != (unsigned) d->refresh_rate)) { /* Keep it as fallback if refresh rate request could not * be satisfied. Try to get as close to 60Hz as possible though, * it's a bit better for a fallback than just blindly picking * something like 47Hz or 200Hz. */ if (!fallback_dm_valid) { fallback_dm = dm; fallback_dm_valid = 1; } else if (dm.dmDisplayFrequency >= 60) { if (dm.dmDisplayFrequency < fallback_dm.dmDisplayFrequency) { fallback_dm = dm; } } } i++; } while ((dm.dmPelsWidth != (unsigned) d->w) || (dm.dmPelsHeight != (unsigned) d->h) || (dm.dmBitsPerPel != (unsigned) bpp) || (dm.dmDisplayFrequency != (unsigned) d->refresh_rate)); if (!modeswitch && !fallback_dm_valid) { ALLEGRO_ERROR("Mode not found.\n"); return false; } if (!modeswitch && fallback_dm_valid) dm = fallback_dm; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; result = ChangeDisplaySettingsEx(dev_name, &dm, NULL, CDS_FULLSCREEN, 0); if (result != DISP_CHANGE_SUCCESSFUL) { ALLEGRO_ERROR("Unable to set mode. %s\n", get_error_desc(GetLastError())); return false; } ALLEGRO_INFO("Mode seccessfuly set.\n"); return true; } static HGLRC init_ogl_context_ex(HDC dc, bool fc, int major, int minor) { HWND testwnd = NULL; HDC testdc = NULL; HGLRC testrc = NULL; HGLRC old_rc = NULL; HDC old_dc = NULL; HGLRC glrc = NULL; testwnd = _al_win_create_hidden_window(); if (!testwnd) return NULL; old_rc = wglGetCurrentContext(); old_dc = wglGetCurrentDC(); testdc = GetDC(testwnd); testrc = init_temp_context(testwnd); if (!testrc) goto bail; if (is_wgl_extension_supported("WGL_ARB_create_context", testdc)) { int attrib[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, major, WGL_CONTEXT_MINOR_VERSION_ARB, minor, WGL_CONTEXT_FLAGS_ARB, 0, 0}; if (fc) attrib[5] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (!init_context_creation_extensions()) goto bail; /* TODO: we could use the context sharing feature */ glrc = _wglCreateContextAttribsARB(dc, 0, attrib); } else goto bail; bail: wglMakeCurrent(NULL, NULL); if (testrc) { wglDeleteContext(testrc); } wglMakeCurrent(old_dc, old_rc); _wglCreateContextAttribsARB = NULL; if (testwnd) { ReleaseDC(testwnd, testdc); DestroyWindow(testwnd); } return glrc; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_available_pixel_formats_ext(int *count) { HWND testwnd = NULL; HDC testdc = NULL; HGLRC testrc = NULL; HGLRC old_rc = NULL; HDC old_dc = NULL; ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds_list = NULL; ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; int maxindex; int i, j; *count = 0; ref = _al_get_new_display_settings(); /* We need to create a dummy window with a pixel format to get the * list of valid PFDs */ testwnd = _al_win_create_hidden_window(); if (!testwnd) return false; old_rc = wglGetCurrentContext(); old_dc = wglGetCurrentDC(); testdc = GetDC(testwnd); testrc = init_temp_context(testwnd); if (!testrc) goto bail; if (!is_wgl_extension_supported("WGL_ARB_pixel_format", testdc) && !is_wgl_extension_supported("WGL_EXT_pixel_format", testdc)) { ALLEGRO_ERROR("WGL_ARB/EXT_pf not supported.\n"); goto bail; } if (!init_pixel_format_extensions()) goto bail; maxindex = get_pixel_formats_count_ext(testdc); if (maxindex < 1) goto bail; ALLEGRO_INFO("Got %i visuals.\n", maxindex); eds_list = al_calloc(maxindex, sizeof(*eds_list)); if (!eds_list) goto bail; for (j = i = 0; i < maxindex; i++) { ALLEGRO_INFO("-- \n"); ALLEGRO_INFO("Decoding visual no. %i...\n", i+1); eds_list[j] = read_pixel_format_ext(i, testdc); if (!eds_list[j]) continue; // Fill vsync setting here and enable/disable it after display creation eds_list[j]->settings[ALLEGRO_VSYNC] = ref->settings[ALLEGRO_VSYNC]; display_pixel_format(eds_list[j]); eds_list[j]->score = _al_score_display_settings(eds_list[j], ref); if (eds_list[j]->score == -1) { al_free(eds_list[j]); eds_list[j] = NULL; continue; } /* In WinAPI first index is 1 ::) */ eds_list[j]->index = i+1; j++; } ALLEGRO_INFO("%i visuals are good enough.\n", j); *count = j; bail: wglMakeCurrent(NULL, NULL); if (testrc) { wglDeleteContext(testrc); } wglMakeCurrent(old_dc, old_rc); _wglGetPixelFormatAttribivARB = NULL; _wglGetPixelFormatAttribivEXT = NULL; if (testwnd) { ReleaseDC(testwnd, testdc); DestroyWindow(testwnd); } return eds_list; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_available_pixel_formats_old(int *count, HDC dc) { ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds_list = NULL; ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; int maxindex; int i, j; *count = 0; ref = _al_get_new_display_settings(); maxindex = get_pixel_formats_count_old(dc); if (maxindex < 1) return NULL; ALLEGRO_INFO("Got %i visuals.\n", maxindex); eds_list = al_calloc(maxindex, sizeof(*eds_list)); if (!eds_list) return NULL; for (j = i = 0; i < maxindex; i++) { ALLEGRO_INFO("-- \n"); ALLEGRO_INFO("Decoding visual no. %i...\n", i+1); eds_list[j] = read_pixel_format_old(i, dc); if (!eds_list[j]) continue; #ifdef DEBUGMODE display_pixel_format(eds_list[j]); #endif eds_list[j]->score = _al_score_display_settings(eds_list[j], ref); if (eds_list[j]->score == -1) { al_free(eds_list[j]); eds_list[j] = NULL; continue; } /* In WinAPI first index is 1 ::) */ eds_list[j]->index = i+1; j++; } ALLEGRO_INFO("%i visuals are good enough.\n", j); *count = j; return eds_list; } static bool select_pixel_format(ALLEGRO_DISPLAY_WGL *d, HDC dc) { ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds = NULL; ALLEGRO_SYSTEM *system = (void *)al_get_system_driver(); int eds_count = 0; int i; bool force_old = false; if (system->config) { const char *selection_mode; selection_mode = al_get_config_value(system->config, "graphics", "config_selection"); if (selection_mode && selection_mode[0] != '\0') { if (!_al_stricmp(selection_mode, "old")) { ALLEGRO_INFO("Forcing OLD visual selection method.\n"); force_old = true; } else if (!_al_stricmp(selection_mode, "new")) force_old = false; } } if (!force_old) eds = get_available_pixel_formats_ext(&eds_count); if (!eds) eds = get_available_pixel_formats_old(&eds_count, dc); if (!eds || !eds_count) { ALLEGRO_ERROR("Didn't find any suitable pixel format!\n"); return false; } qsort(eds, eds_count, sizeof(eds[0]), _al_display_settings_sorter); for (i = 0; i < eds_count ; i++) { if (SetPixelFormat(d->dc, eds[i]->index, NULL)) { ALLEGRO_INFO("Chose visual no. %i\n\n", eds[i]->index); display_pixel_format(eds[i]); break; } else { ALLEGRO_WARN("Unable to set pixel format! %s\n", get_error_desc(GetLastError())); ALLEGRO_WARN("Trying next one.\n"); } } if (i == eds_count) { ALLEGRO_ERROR("Unable to set any pixel format! %s\n", get_error_desc(GetLastError())); for (i = 0; i < eds_count; i++) al_free(eds[i]); al_free(eds); return false; } memcpy(&d->win_display.display.extra_settings, eds[i], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); for (i = 0; i < eds_count; i++) al_free(eds[i]); if (eds) al_free(eds); return true; } static bool create_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp) { ALLEGRO_DISPLAY *disp = (void*)wgl_disp; ALLEGRO_DISPLAY_WIN *win_disp = (void*)wgl_disp; WGL_DISPLAY_PARAMETERS ndp; int window_x, window_y; /* The window is created in a separate thread so we need to pass this * TLS on */ al_get_new_window_position(&window_x, &window_y); ndp.window_x = window_x; ndp.window_y = window_y; /* _beginthread closes the handle automatically. */ ndp.display = wgl_disp; ndp.init_failed = true; ndp.AckEvent = CreateEvent(NULL, false, false, NULL); _beginthread(display_thread_proc, 0, &ndp); /* Wait some _finite_ time (10 secs or so) for display thread to init, and * give up if something horrible happened to it, unless we're in debug mode * and we may have intentionally stopped the execution to analyze the code. */ #ifdef DEBUGMODE WaitForSingleObject(ndp.AckEvent, INFINITE); #else WaitForSingleObject(ndp.AckEvent, 10*1000); #endif CloseHandle(ndp.AckEvent); if (ndp.init_failed) { ALLEGRO_ERROR("Failed to create display.\n"); return false; } /* WGL display lists cannot be shared with the API currently in use. */ disp->ogl_extras->is_shared = false; if (!select_pixel_format(wgl_disp, wgl_disp->dc)) { destroy_display_internals(wgl_disp); return false; } if (disp->flags & ALLEGRO_OPENGL_3_0) { bool fc = (disp->flags & ALLEGRO_OPENGL_FORWARD_COMPATIBLE) != 0; wgl_disp->glrc = init_ogl_context_ex(wgl_disp->dc, fc, 3, 0); } else { wgl_disp->glrc = wglCreateContext(wgl_disp->dc); } if (!wgl_disp->glrc) { ALLEGRO_ERROR("Unable to create a render context! %s\n", get_error_desc(GetLastError())); destroy_display_internals(wgl_disp); return false; } /* make the context the current one */ if (!wglMakeCurrent(wgl_disp->dc, wgl_disp->glrc)) { ALLEGRO_ERROR("Unable to make the context current! %s\n", get_error_desc(GetLastError())); destroy_display_internals(wgl_disp); return false; } _al_ogl_manage_extensions(disp); _al_ogl_set_extensions(disp->ogl_extras->extension_api); if (disp->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings(); if (eds->required & (1<extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; } disp->ogl_extras->backbuffer = _al_ogl_create_backbuffer(disp); if (!disp->ogl_extras->backbuffer) { ALLEGRO_ERROR("Failed to create a backbuffer.\n"); destroy_display_internals(wgl_disp); return false; } al_identity_transform(&al_get_backbuffer(disp)->transform); /* Try to enable or disable vsync as requested */ /* NOTE: my drivers claim I don't have WGL_EXT_swap_control * (according to al_have_opengl_extension), but wglSwapIntervalEXT * does get loaded, so just check for that. */ if (wglSwapIntervalEXT) { if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 1) { wglSwapIntervalEXT(1); } else if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 2) { wglSwapIntervalEXT(0); } } win_disp->mouse_selected_hcursor = 0; win_disp->mouse_cursor_shown = false; win_disp->can_acknowledge = false; _al_win_grab_input(win_disp); if (disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) setup_gl(disp); return true; } static ALLEGRO_DISPLAY* wgl_create_display(int w, int h) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_WGL **add; ALLEGRO_DISPLAY_WGL *wgl_display = al_calloc(1, sizeof *wgl_display); ALLEGRO_DISPLAY *ogl_display = (void*)wgl_display; ALLEGRO_DISPLAY *display = (void*)ogl_display; ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)display; win_disp->adapter = _al_win_determine_adapter(); display->w = w; display->h = h; display->refresh_rate = al_get_new_display_refresh_rate(); display->flags = al_get_new_display_flags(); display->vt = &vt; display->ogl_extras = al_calloc(1, sizeof(ALLEGRO_OGL_EXTRAS)); if (!create_display_internals(wgl_display)) { al_free(display->ogl_extras); al_free(display); return NULL; } /* Print out OpenGL version info */ ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION)); ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR)); ALLEGRO_INFO("Renderer: %s\n\n", (const char*)glGetString(GL_RENDERER)); /* Add ourself to the list of displays. */ add = _al_vector_alloc_back(&system->system.displays); *add = wgl_display; /* Each display is an event source. */ _al_event_source_init(&display->es); _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); _al_win_show_mouse_cursor(display); return display; } static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp) { ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY *)wgl_disp; ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)wgl_disp; /* We need to convert all our bitmaps to display independent (memory) * bitmaps because WGL driver doesn't support sharing of resources. */ while (disp->bitmaps._size > 0) { ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&disp->bitmaps); ALLEGRO_BITMAP *bmp = *bptr; _al_convert_to_memory_bitmap(bmp); } if (disp->ogl_extras->backbuffer) _al_ogl_destroy_backbuffer(disp->ogl_extras->backbuffer); disp->ogl_extras->backbuffer = NULL; _al_ogl_unmanage_extensions(disp); PostMessage(win_disp->window, _al_win_msg_suicide, (WPARAM)win_disp, 0); while (!win_disp->thread_ended) al_rest(0.001); if (wgl_disp->glrc) { wglDeleteContext(wgl_disp->glrc); wgl_disp->glrc = NULL; } if (wgl_disp->dc) { ReleaseDC(win_disp->window, wgl_disp->dc); wgl_disp->dc = NULL; } if (disp->flags & ALLEGRO_FULLSCREEN && !_wgl_do_not_change_display_mode) { ChangeDisplaySettings(NULL, 0); } if (win_disp->window) { DestroyWindow(win_disp->window); win_disp->window = NULL; } } static void wgl_destroy_display(ALLEGRO_DISPLAY *disp) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)disp; ALLEGRO_DISPLAY *old_disp = al_get_current_display(); if (old_disp != disp) _al_set_current_display_only(disp); if (system->mouse_grab_display == disp) system->mouse_grab_display = NULL; destroy_display_internals(wgl_disp); _al_event_source_free(&disp->es); _al_vector_find_and_delete(&system->system.displays, &disp); _al_vector_free(&disp->bitmaps); al_free(disp->ogl_extras); if (old_disp != disp) _al_set_current_display_only(old_disp); al_free(disp->vertex_cache); al_free(wgl_disp); } static bool wgl_set_current_display(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)d; HGLRC current_glrc; current_glrc = wglGetCurrentContext(); if (!current_glrc || (current_glrc && current_glrc != wgl_disp->glrc)) { /* make the context the current one */ if (!wglMakeCurrent(wgl_disp->dc, wgl_disp->glrc)) { ALLEGRO_ERROR("Unable to make the context current! %s\n", get_error_desc(GetLastError())); return false; } _al_ogl_set_extensions(d->ogl_extras->extension_api); } return true; } static void wgl_unset_current_display(ALLEGRO_DISPLAY *d) { (void)d; if (!wglMakeCurrent(NULL, NULL)) { ALLEGRO_ERROR("Unable unset the current context! %s\n", get_error_desc(GetLastError())); } } /* * The window must be created in the same thread that * runs the message loop. */ static void display_thread_proc(void *arg) { WGL_DISPLAY_PARAMETERS *ndp = arg; ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY*)ndp->display; ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; ALLEGRO_DISPLAY_WIN *win_disp = (void*)disp; MSG msg; al_set_new_window_position(ndp->window_x, ndp->window_y); /* So that we can call the functions using TLS from this thread. */ al_set_new_display_flags(disp->flags); if (disp->flags & ALLEGRO_FULLSCREEN) { if (!change_display_mode(disp)) { win_disp->thread_ended = true; destroy_display_internals(wgl_disp); SetEvent(ndp->AckEvent); return; } } else if (disp->flags & ALLEGRO_FULLSCREEN_WINDOW) { ALLEGRO_MONITOR_INFO mi; int adapter = win_disp->adapter; al_get_monitor_info(adapter, &mi); win_disp->toggle_w = disp->w; win_disp->toggle_h = disp->h; disp->w = mi.x2 - mi.x1; disp->h = mi.y2 - mi.y1; } else { win_disp->toggle_w = disp->w; win_disp->toggle_h = disp->h; } win_disp->window = _al_win_create_window(disp, disp->w, disp->h, disp->flags); if (!win_disp->window) { win_disp->thread_ended = true; destroy_display_internals(wgl_disp); SetEvent(ndp->AckEvent); return; } /* FIXME: can't _al_win_create_window() do this? */ if ((disp->flags & ALLEGRO_FULLSCREEN) || (disp->flags & ALLEGRO_FULLSCREEN_WINDOW)) { RECT rect; rect.left = 0; rect.right = disp->w; rect.top = 0; rect.bottom = disp->h; SetWindowPos(win_disp->window, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); } if (disp->flags & ALLEGRO_FULLSCREEN_WINDOW) { bool frameless = true; _al_win_set_window_frameless(disp, win_disp->window, frameless); } /* Yep, the following is really needed sometimes. */ /* ... Or is it now that we have dumped DInput? */ /* Win98/2k/XP's window forground rules don't let us * make our window the topmost window on launch. This causes issues on * full-screen apps, as DInput loses input focus on them. * We use this trick to force the window to be topmost, when switching * to full-screen only. Note that this only works for Win98 and greater. * Win95 will ignore our SystemParametersInfo() calls. * * See http://support.microsoft.com:80/support/kb/articles/Q97/9/25.asp * for details. */ { DWORD lock_time; HWND wnd = win_disp->window; #define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 #define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 if (disp->flags & ALLEGRO_FULLSCREEN) { SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)&lock_time, 0); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); } ShowWindow(wnd, SW_SHOWNORMAL); SetForegroundWindow(wnd); /* In some rare cases, it doesn't seem to work without the loop. And we * absolutely need this to succeed, else we trap the user in a * fullscreen window without input. */ while (GetForegroundWindow() != wnd) { al_rest(0.01); SetForegroundWindow(wnd); } UpdateWindow(wnd); if (disp->flags & ALLEGRO_FULLSCREEN) { SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)(DWORD)lock_time, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); } #undef SPI_GETFOREGROUNDLOCKTIMEOUT #undef SPI_SETFOREGROUNDLOCKTIMEOUT } #if 0 if (disp->flags & ALLEGRO_FULLSCREEN && al_is_mouse_installed()) { RAWINPUTDEVICE rid[1]; rid[0].usUsagePage = 0x01; rid[0].usUsage = 0x02; rid[0].dwFlags = RIDEV_NOLEGACY; rid[0].hwndTarget = 0; if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { ALLEGRO_ERROR( "Failed to init mouse. %s\n", get_error_desc(GetLastError())); } } #endif /* get the device context of our window */ wgl_disp->dc = GetDC(win_disp->window); win_disp->thread_ended = false; win_disp->end_thread = false; ndp->init_failed = false; SetEvent(ndp->AckEvent); while (!win_disp->end_thread) { /* get a message from the queue */ if (GetMessage(&msg, NULL, 0, 0) != 0) DispatchMessage(&msg); else break; /* WM_QUIT received or error (GetMessage returned -1) */ } ALLEGRO_INFO("wgl display thread exits\n"); win_disp->thread_ended = true; } static void wgl_flip_display(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_WGL* disp = (ALLEGRO_DISPLAY_WGL*)d; glFlush(); if (!d->extra_settings.settings[ALLEGRO_SINGLE_BUFFER]) SwapBuffers(disp->dc); } static void wgl_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, int width, int height) { if (al_get_opengl_extension_list()->ALLEGRO_WGL_WIN_swap_hint) { /* FIXME: This is just a driver hint and there is no guarantee that the * contens of the front buffer outside the given rectangle will be preserved, * thus we should really return false here and do nothing. */ ALLEGRO_DISPLAY_WGL* disp = (ALLEGRO_DISPLAY_WGL*)d; wglAddSwapHintRectWIN(x, y, width, height); glFlush(); SwapBuffers(disp->dc); return; } wgl_flip_display(d); } static bool wgl_resize_helper(ALLEGRO_DISPLAY *d, int width, int height) { ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)d; ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)d; int full_w, full_h; ALLEGRO_MONITOR_INFO mi; int adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; al_get_monitor_info(adapter, &mi); full_w = mi.x2 - mi.x1; full_h = mi.y2 - mi.y1; if ((d->flags & ALLEGRO_FULLSCREEN_WINDOW) && (full_w != width || full_h != height)) { win_disp->toggle_w = width; win_disp->toggle_h = height; return true; } win_disp->can_acknowledge = false; if (d->flags & ALLEGRO_FULLSCREEN) { ALLEGRO_BITMAP *target_bmp; _AL_VECTOR disp_bmps; bool was_backbuffer = false; size_t i; target_bmp = al_get_target_bitmap(); if (target_bmp && target_bmp->vt) was_backbuffer = ((ALLEGRO_BITMAP_OGL*)target_bmp)->is_backbuffer; /* Remeber display bitmaps. */ _al_vector_init(&disp_bmps, sizeof(ALLEGRO_BITMAP*)); for (i = 0; i < _al_vector_size(&d->bitmaps); i++) { ALLEGRO_BITMAP **dis = _al_vector_ref(&d->bitmaps, i); ALLEGRO_BITMAP **mem = _al_vector_alloc_back(&disp_bmps); *mem = *dis; } /* This flag prevents from switching to desktop resolution in between. */ _wgl_do_not_change_display_mode = true; destroy_display_internals(wgl_disp); _wgl_do_not_change_display_mode = false; d->w = width; d->h = height; if (!create_display_internals(wgl_disp)) return false; /* We have a new backbuffer now. */ if (was_backbuffer) al_set_target_bitmap(al_get_backbuffer(d)); /* Reupload bitmaps. */ while (_al_vector_is_nonempty(&disp_bmps)) { ALLEGRO_BITMAP **back = _al_vector_ref_back(&disp_bmps); _al_convert_to_display_bitmap(*back); _al_vector_delete_at(&disp_bmps, _al_vector_size(&disp_bmps) - 1); } } else { RECT win_size; WINDOWINFO wi; win_size.left = 0; win_size.top = 0; win_size.right = width; win_size.bottom = height; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_disp->window, &wi); AdjustWindowRectEx(&win_size, wi.dwStyle, false, wi.dwExStyle); if (!SetWindowPos(win_disp->window, HWND_TOP, 0, 0, win_size.right - win_size.left, win_size.bottom - win_size.top, SWP_NOMOVE|SWP_NOZORDER)) return false; d->w = width; d->h = height; if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) { win_disp->toggle_w = width; win_disp->toggle_h = height; } } return true; } static bool wgl_resize_display(ALLEGRO_DISPLAY *d, int width, int height) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; int orig_w = d->w; int orig_h = d->h; bool ret; win_display->ignore_resize = true; if (!wgl_resize_helper(d, width, height)) { wgl_resize_helper(d, orig_w, orig_h); ret = false; } else { ret = true; wgl_acknowledge_resize(d); } win_display->ignore_resize = false; return ret; } static bool wgl_acknowledge_resize(ALLEGRO_DISPLAY *d) { WINDOWINFO wi; ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)d; ALLEGRO_DISPLAY *ogl_disp = (ALLEGRO_DISPLAY *)d; int w, h; ALLEGRO_STATE state; wi.cbSize = sizeof(WINDOWINFO); GetWindowInfo(win_disp->window, &wi); w = wi.rcClient.right - wi.rcClient.left; h = wi.rcClient.bottom - wi.rcClient.top; d->w = w; d->h = h; setup_gl(d); _al_ogl_resize_backbuffer(ogl_disp->ogl_extras->backbuffer, w, h); al_store_state(&state, ALLEGRO_STATE_DISPLAY | ALLEGRO_STATE_TARGET_BITMAP); al_set_target_backbuffer(d); al_set_clipping_rectangle(0, 0, w, h); al_restore_state(&state); return true; } static bool wgl_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { /* Note: WGL driver doesn't support sharing of resources between contexts, * thus all bitmaps are tied to the display which was current at the time * al_create_bitmap was called. */ return display == bitmap->display; } static void wgl_switch_in(ALLEGRO_DISPLAY *display) { (void)display; /* ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)display; if (al_is_mouse_installed()) al_set_mouse_range(win_disp->mouse_range_x1, win_disp->mouse_range_y1, win_disp->mouse_range_x2, win_disp->mouse_range_y2); */ } static void wgl_switch_out(ALLEGRO_DISPLAY *display) { (void)display; } static void wgl_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { _al_win_set_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); } static void wgl_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) { _al_win_get_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_display_wgl_driver(void) { if (vt.create_display) return &vt; vt.create_display = wgl_create_display; vt.destroy_display = wgl_destroy_display; vt.resize_display = wgl_resize_display; vt.set_current_display = wgl_set_current_display; vt.unset_current_display = wgl_unset_current_display; vt.flip_display = wgl_flip_display; vt.update_display_region = wgl_update_display_region; vt.acknowledge_resize = wgl_acknowledge_resize; vt.create_bitmap = _al_ogl_create_bitmap; vt.create_sub_bitmap = _al_ogl_create_sub_bitmap; vt.get_backbuffer = _al_ogl_get_backbuffer; vt.set_target_bitmap = _al_ogl_set_target_bitmap; vt.is_compatible_bitmap = wgl_is_compatible_bitmap; vt.switch_in = wgl_switch_in; vt.switch_out = wgl_switch_out; vt.set_mouse_cursor = _al_win_set_mouse_cursor; vt.set_system_mouse_cursor = _al_win_set_system_mouse_cursor; vt.show_mouse_cursor = _al_win_show_mouse_cursor; vt.hide_mouse_cursor = _al_win_hide_mouse_cursor; vt.set_icons = _al_win_set_display_icons; vt.set_window_position = wgl_set_window_position; vt.get_window_position = wgl_get_window_position; vt.set_display_flag = _al_win_set_display_flag; vt.set_window_title = _al_win_set_window_title; _al_ogl_add_drawing_functions(&vt); return &vt; } int _al_wgl_get_num_display_modes(int format, int refresh_rate, int flags) { DEVMODE dm; int count = 0; /* FIXME: Ignoring format. * To get a list of pixel formats we have to create a window with a valid DC, which * would even require to change the video mode in fullscreen cases and we really * don't want to do that. */ (void)format; (void)refresh_rate; (void)flags; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); while (EnumDisplaySettings(NULL, count, &dm) != false) { count++; } return count; } ALLEGRO_DISPLAY_MODE *_al_wgl_get_display_mode(int index, int format, int refresh_rate, int flags, ALLEGRO_DISPLAY_MODE *mode) { DEVMODE dm; /* * FIXME: see the comment in _al_wgl_get_num_display_modes */ (void)format; (void)refresh_rate; (void)flags; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); if (!EnumDisplaySettings(NULL, index, &dm)) return NULL; mode->width = dm.dmPelsWidth; mode->height = dm.dmPelsHeight; mode->refresh_rate = dm.dmDisplayFrequency; mode->format = format; switch (dm.dmBitsPerPel) { case 32: if (format == ALLEGRO_PIXEL_FORMAT_ANY) mode->format = ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA; else if (format == ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA) mode->format = ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA; break; case 24: mode->format = ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA; break; case 16: if (format == ALLEGRO_PIXEL_FORMAT_ANY) mode->format = ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA; else if(format == ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA) mode->format = ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA; break; default: break; } return mode; } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wunicode.c0000644000175000001440000000343112061103376015753 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows "UNICODE" helper routines. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_wunicode.h" ALLEGRO_DEBUG_CHANNEL("wunicode") wchar_t *_al_win_utf16(const char *s) { int wslen; wchar_t *ws; wslen = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0); if (wslen == 0) { ALLEGRO_ERROR("MultiByteToWideChar failed\n"); return NULL; } ws = al_malloc(sizeof(wchar_t) * wslen); if (!ws) { ALLEGRO_ERROR("Out of memory\n"); return NULL; } if (0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ws, wslen)) { al_free(ws); ALLEGRO_ERROR("MultiByteToWideChar failed\n"); return NULL; } return ws; } char *_al_win_utf8(const wchar_t *ws) { int slen; char *s; slen = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL); if (slen == 0) { ALLEGRO_ERROR("WideCharToMultiByte failed\n"); return NULL; } s = al_malloc(sizeof(char) * slen); if (!s) { ALLEGRO_ERROR("Out of memory\n"); return NULL; } if (0 == WideCharToMultiByte(CP_UTF8, 0, ws, -1, s, slen, NULL, NULL)) { al_free(s); ALLEGRO_ERROR("WideCharToMultiByte failed\n"); return NULL; } return s; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wmcursor.c0000644000175000001440000003273112117225044016023 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows mouse cursors. * * By Evert Glebbeek. * * Adapted for Allegro 4.9 by Peter Wang. * * GDI code adapted from src/win/gdi.c. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/platform/aintwin.h" static void local_stretch_blit_to_hdc(ALLEGRO_BITMAP *bitmap, HDC dc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h); static void local_draw_to_hdc(HDC dc, ALLEGRO_BITMAP *bitmap, int x, int y); HICON _al_win_create_icon(HWND wnd, ALLEGRO_BITMAP *sprite, int xfocus, int yfocus, bool is_cursor, bool resize) { int x, y; int sys_sm_cx, sys_sm_cy; HDC h_dc; HDC h_and_dc; HDC h_xor_dc; ICONINFO iconinfo; HBITMAP and_mask; HBITMAP xor_mask; HBITMAP hOldAndMaskBitmap; HBITMAP hOldXorMaskBitmap; HICON icon; bool was_locked; ALLEGRO_BITMAP *tmp = sprite; if (resize) { if (is_cursor) { /* Get allowed cursor size - Windows can't make cursors of arbitrary size */ sys_sm_cx = GetSystemMetrics(SM_CXCURSOR); sys_sm_cy = GetSystemMetrics(SM_CYCURSOR); } else { sys_sm_cx = GetSystemMetrics(SM_CXICON); sys_sm_cy = GetSystemMetrics(SM_CYICON); } if ((tmp->w > sys_sm_cx) || (tmp->h > sys_sm_cy)) { float ratio = tmp->w / (float)tmp->h; int w, h; ALLEGRO_STATE state; if (ratio > 1) { w = sys_sm_cx; h = sys_sm_cy / ratio; } else { w = sys_sm_cx * ratio; h = sys_sm_cy; } al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_NEW_BITMAP_PARAMETERS | ALLEGRO_STATE_BLENDER); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(al_get_bitmap_format(tmp)); tmp = al_create_bitmap(w, h); al_set_target_bitmap(tmp); al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); al_draw_scaled_bitmap( sprite, 0, 0, sprite->w, sprite->h, 0, 0, w, h, 0 ); al_restore_state(&state); } } else { sys_sm_cx = al_get_bitmap_width(tmp); sys_sm_cy = al_get_bitmap_height(tmp); } /* Create bitmap */ h_dc = GetDC(wnd); h_xor_dc = CreateCompatibleDC(h_dc); h_and_dc = CreateCompatibleDC(h_dc); /* Prepare AND (monochrome) and XOR (colour) mask */ and_mask = CreateBitmap(sys_sm_cx, sys_sm_cy, 1, 1, NULL); xor_mask = CreateCompatibleBitmap(h_dc, sys_sm_cx, sys_sm_cy); hOldAndMaskBitmap = (HBITMAP) SelectObject(h_and_dc, and_mask); hOldXorMaskBitmap = (HBITMAP) SelectObject(h_xor_dc, xor_mask); /* Create transparent cursor */ for (y = 0; y < sys_sm_cy; y++) { for (x = 0; x < sys_sm_cx; x++) { SetPixel(h_and_dc, x, y, WINDOWS_RGB(255, 255, 255)); SetPixel(h_xor_dc, x, y, WINDOWS_RGB(0, 0, 0)); } } /* Lock sprite to speed up repeated get pixel calls. */ was_locked = al_is_bitmap_locked(tmp); if (!was_locked) { al_lock_bitmap(tmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); } local_draw_to_hdc(h_xor_dc, tmp, 0, 0); /* Make cursor background transparent */ for (y = 0; y < tmp->h; y++) { for (x = 0; x < tmp->w; x++) { ALLEGRO_COLOR c; unsigned char r, g, b, a; c = al_get_pixel(tmp, x, y); al_unmap_rgba(c, &r, &g, &b, &a); if (a != 0) { /* Don't touch XOR value */ SetPixel(h_and_dc, x, y, 0); } else { /* No need to touch AND value */ SetPixel(h_xor_dc, x, y, WINDOWS_RGB(0, 0, 0)); } } } if (!was_locked) { al_unlock_bitmap(tmp); } SelectObject(h_and_dc, hOldAndMaskBitmap); SelectObject(h_xor_dc, hOldXorMaskBitmap); DeleteDC(h_and_dc); DeleteDC(h_xor_dc); ReleaseDC(wnd, h_dc); iconinfo.fIcon = is_cursor ? false : true; iconinfo.xHotspot = xfocus; iconinfo.yHotspot = yfocus; iconinfo.hbmMask = and_mask; iconinfo.hbmColor = xor_mask; icon = CreateIconIndirect(&iconinfo); DeleteObject(and_mask); DeleteObject(xor_mask); if (sprite != tmp) { al_destroy_bitmap(tmp); } return icon; } ALLEGRO_MOUSE_CURSOR *_al_win_create_mouse_cursor(ALLEGRO_BITMAP *sprite, int xfocus, int yfocus) { HWND wnd; HCURSOR hcursor; ALLEGRO_MOUSE_CURSOR_WIN *win_cursor; /* A null HWND retrieves the DC for the entire screen. */ wnd = NULL; hcursor = (HCURSOR)_al_win_create_icon(wnd, sprite, xfocus, yfocus, true, true); if (!hcursor) { return NULL; } win_cursor = al_malloc(sizeof *win_cursor); if (!win_cursor) { DestroyIcon(hcursor); return NULL; } win_cursor->hcursor = hcursor; return (ALLEGRO_MOUSE_CURSOR *)win_cursor; } void _al_win_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_MOUSE_CURSOR_WIN *win_cursor = (ALLEGRO_MOUSE_CURSOR_WIN *) cursor; ALLEGRO_SYSTEM *sys = al_get_system_driver(); unsigned i; ASSERT(win_cursor); /* XXX not at all thread safe */ for (i = 0; i < _al_vector_size(&sys->displays); i++) { ALLEGRO_DISPLAY_WIN **slot = _al_vector_ref(&sys->displays, i); ALLEGRO_DISPLAY_WIN *win_display = *slot; if (win_cursor->hcursor == win_display->mouse_selected_hcursor) { _al_win_set_system_mouse_cursor((ALLEGRO_DISPLAY *)win_display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); } } DestroyIcon(win_cursor->hcursor); al_free(win_cursor); } bool _al_win_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; ALLEGRO_MOUSE_CURSOR_WIN *win_cursor = (ALLEGRO_MOUSE_CURSOR_WIN *) cursor; ASSERT(win_cursor); ASSERT(win_cursor->hcursor); win_display->mouse_selected_hcursor = win_cursor->hcursor; if (win_display->mouse_cursor_shown) { POINT p; SetCursor(win_cursor->hcursor); /* Windows is too stupid to actually display the mouse pointer when we * change it and waits until it is moved, so we have to generate a fake * mouse move to actually show the cursor. */ GetCursorPos(&p); SetCursorPos(p.x, p.y); } return true; } bool _al_win_show_mouse_cursor(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; ALLEGRO_MOUSE_CURSOR_WIN tmp_cursor; ALLEGRO_MOUSE_CURSOR_WIN *tmp_cursor_ptr = &tmp_cursor; /* XXX do we need this? */ if (!win_display->mouse_selected_hcursor) { _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); } tmp_cursor.hcursor = win_display->mouse_selected_hcursor; win_display->mouse_cursor_shown = true; _al_win_set_mouse_cursor(display, (ALLEGRO_MOUSE_CURSOR *)tmp_cursor_ptr); return true; } bool _al_win_hide_mouse_cursor(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; win_display->mouse_cursor_shown = false; PostMessage(win_display->window, WM_SETCURSOR, 0, 0); return true; } static HCURSOR system_cursor_to_hcursor(ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { switch (cursor_id) { case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: return LoadCursor(NULL, IDC_ARROW); case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: return LoadCursor(NULL, IDC_WAIT); case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: return LoadCursor(NULL, IDC_HELP); case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: return LoadCursor(NULL, IDC_IBEAM); case ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE: return LoadCursor(NULL, IDC_SIZEALL); case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: return LoadCursor(NULL, IDC_SIZENS); case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: return LoadCursor(NULL, IDC_SIZEWE); case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: return LoadCursor(NULL, IDC_SIZENESW); case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: return LoadCursor(NULL, IDC_SIZENWSE); case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: return LoadCursor(NULL, IDC_APPSTARTING); case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: return LoadCursor(NULL, IDC_CROSS); case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: return LoadCursor(NULL, IDC_HAND); case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: return LoadCursor(NULL, IDC_UPARROW); case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: return LoadCursor(NULL, IDC_NO); default: return NULL; } } bool _al_win_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; HCURSOR wc; wc = system_cursor_to_hcursor(cursor_id); if (!wc) { return false; } win_display->mouse_selected_hcursor = wc; if (win_display->mouse_cursor_shown) { /* MySetCursor(wc); PostMessage(wgl_display->window, WM_MOUSEMOVE, 0, 0); */ ALLEGRO_MOUSE_CURSOR_WIN tmp_cursor; ALLEGRO_MOUSE_CURSOR_WIN *tmp_cursor_ptr = &tmp_cursor; tmp_cursor.hcursor = wc; _al_win_set_mouse_cursor(display, (ALLEGRO_MOUSE_CURSOR *)tmp_cursor_ptr); } return true; } /* GDI stuff - this really belongs elsewhere */ /* get_bitmap_info: * Returns a BITMAPINFO structure suited to an ALLEGRO_BITMAP. * You have to free the memory allocated by this function. * * This version always returns a 32-bit BITMAPINFO. */ static BITMAPINFO *get_bitmap_info(ALLEGRO_BITMAP *bitmap) { BITMAPINFO *bi; int i; bi = (BITMAPINFO *) al_malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 256); ZeroMemory(&bi->bmiHeader, sizeof(BITMAPINFOHEADER)); bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi->bmiHeader.biBitCount = 32; bi->bmiHeader.biPlanes = 1; bi->bmiHeader.biWidth = al_get_bitmap_width(bitmap); bi->bmiHeader.biHeight = -al_get_bitmap_height(bitmap); bi->bmiHeader.biClrUsed = 256; bi->bmiHeader.biCompression = BI_RGB; for (i = 0; i < 256; i++) { bi->bmiColors[i].rgbRed = 0; bi->bmiColors[i].rgbGreen = 0; bi->bmiColors[i].rgbBlue = 0; bi->bmiColors[i].rgbReserved = 0; } return bi; } /* get_dib_from_bitmap_32: * Creates a Windows device-independent bitmap (DIB) from an Allegro BITMAP. * You have to free the memory allocated by this function. * * This version always creates a 32-bit DIB. */ static BYTE *get_dib_from_bitmap_32(ALLEGRO_BITMAP *bitmap) { int w, h; int x, y; int pitch; BYTE *pixels; BYTE *dst; w = al_get_bitmap_width(bitmap); h = al_get_bitmap_height(bitmap); pitch = w * 4; pixels = (BYTE *) al_malloc(h * pitch); if (!pixels) return NULL; for (y = 0; y < h; y++) { dst = pixels + y * pitch; for (x = 0; x < w; x++) { ALLEGRO_COLOR col; unsigned char r, g, b, a; col = al_get_pixel(bitmap, x, y); al_unmap_rgba(col, &r, &g, &b, &a); /* BGR */ dst[0] = b; dst[1] = g; dst[2] = r; dst[3] = a; dst += 4; } } return pixels; } /* draw_to_hdc: * Draws an entire Allegro BITMAP to a Windows DC. Has a syntax similar to * draw_sprite(). */ static void local_draw_to_hdc(HDC dc, ALLEGRO_BITMAP *bitmap, int x, int y) { int w = al_get_bitmap_width(bitmap); int h = al_get_bitmap_height(bitmap); local_stretch_blit_to_hdc(bitmap, dc, 0, 0, w, h, x, y, w, h); } /* stretch_blit_to_hdc: * Blits an Allegro BITMAP to a Windows DC. Has a syntax similar to * stretch_blit(). */ static void local_stretch_blit_to_hdc(ALLEGRO_BITMAP *bitmap, HDC dc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h) { const int bitmap_h = al_get_bitmap_height(bitmap); const int bottom_up_src_y = bitmap_h - src_y - src_h; BYTE *pixels; BITMAPINFO *bi; bi = get_bitmap_info(bitmap); pixels = get_dib_from_bitmap_32(bitmap); /* Windows treats all source bitmaps as bottom-up when using StretchDIBits * unless the source (x,y) is (0,0). To work around this buggy behavior, we * can use negative heights to reverse the direction of the blits. * * See for a detailed explanation. */ if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) { StretchDIBits(dc, dest_x, dest_h+dest_y-1, dest_w, -dest_h, src_x, bitmap_h - src_y + 1, src_w, -src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY); } else { StretchDIBits(dc, dest_x, dest_y, dest_w, dest_h, src_x, bottom_up_src_y, src_w, src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY); } al_free(pixels); al_free(bi); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/wsystem.c0000644000175000001440000004344012132127367015662 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New Windows system driver * * Based on the X11 OpenGL driver by Elias Pschernig. * * Heavily modified by Trent Gamblin. */ #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/platform/aintwin.h" #if defined ALLEGRO_CFG_OPENGL #include "allegro5/allegro_opengl.h" #endif #include #include ALLEGRO_DEBUG_CHANNEL("system") /* FIXME: should we check for psapi _WIN32_IE and shlobj? { */ #include #if _WIN32_IE < 0x500 #undef _WIN32_IE #define _WIN32_IE 0x500 #endif #include #include /* } */ bool _al_win_disable_screensaver = false; static ALLEGRO_SYSTEM_INTERFACE *vt = 0; static bool using_higher_res_timer; static ALLEGRO_SYSTEM_WIN *_al_win_system; static bool d3d_available = true; /* _WinMain: * Entry point for Windows GUI programs, hooked by a macro in alwin.h, * which makes it look as if the application can still have a normal * main() function. */ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow) { int (*mainfunc) (int argc, char *argv[]) = (int (*)(int, char *[]))_main; char *argbuf; char *cmdline; char **argv; int argc; int argc_max; int i, q; (void)hInst; (void)hPrev; (void)Cmd; (void)nShow; /* can't use parameter because it doesn't include the executable name */ cmdline = GetCommandLine(); i = strlen(cmdline) + 1; argbuf = al_malloc(i); memcpy(argbuf, cmdline, i); argc = 0; argc_max = 64; argv = al_malloc(sizeof(char *) * argc_max); if (!argv) { al_free(argbuf); return 1; } i = 0; /* parse commandline into argc/argv format */ while (argbuf[i]) { while ((argbuf[i]) && (isspace(argbuf[i]))) i++; if (argbuf[i]) { if ((argbuf[i] == '\'') || (argbuf[i] == '"')) { q = argbuf[i++]; if (!argbuf[i]) break; } else q = 0; argv[argc++] = &argbuf[i]; if (argc >= argc_max) { argc_max += 64; argv = al_realloc(argv, sizeof(char *) * argc_max); if (!argv) { al_free(argbuf); return 1; } } while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (!isspace(argbuf[i])))) i++; if (argbuf[i]) { argbuf[i] = 0; i++; } } } argv[argc] = NULL; /* call the application entry point */ i = mainfunc(argc, argv); al_free(argv); al_free(argbuf); return i; } static bool maybe_d3d_init_display(void) { #ifdef ALLEGRO_CFG_D3D return _al_d3d_init_display(); #else return false; #endif } /* Create a new system object. */ static ALLEGRO_SYSTEM *win_initialize(int flags) { (void)flags; _al_win_system = al_calloc(1, sizeof *_al_win_system); // Request a 1ms resolution from our timer if (timeBeginPeriod(1) != TIMERR_NOCANDO) { using_higher_res_timer = true; } _al_win_init_time(); _al_win_init_window(); _al_vector_init(&_al_win_system->system.displays, sizeof (ALLEGRO_SYSTEM_WIN *)); _al_win_system->system.vt = vt; d3d_available = maybe_d3d_init_display(); return &_al_win_system->system; } static void win_shutdown(void) { ALLEGRO_SYSTEM *s; ALLEGRO_DISPLAY_INTERFACE *display_driver; ASSERT(vt); /* Close all open displays. */ s = al_get_system_driver(); while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); display_driver = vt->get_display_driver(); if (display_driver && display_driver->shutdown) { display_driver->shutdown(); } _al_win_shutdown_time(); if (using_higher_res_timer) { timeEndPeriod(1); } al_free(vt); vt = NULL; ASSERT(_al_win_system); al_free(_al_win_system); } static ALLEGRO_DISPLAY_INTERFACE *win_get_display_driver(void) { const int flags = al_get_new_display_flags(); ALLEGRO_SYSTEM *sys = al_get_system_driver(); ALLEGRO_SYSTEM_WIN *syswin = (ALLEGRO_SYSTEM_WIN *)sys; /* Look up the toggle_mouse_grab_key binding. This isn't such a great place * to do it, but the config file is not available in win_initialize, * and this is neutral between the D3D and OpenGL display drivers. */ if (sys->config && !syswin->toggle_mouse_grab_keycode) { const char *binding = al_get_config_value(sys->config, "keyboard", "toggle_mouse_grab_key"); if (binding) { syswin->toggle_mouse_grab_keycode = _al_parse_key_binding(binding, &syswin->toggle_mouse_grab_modifiers); if (syswin->toggle_mouse_grab_keycode) { ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding); } else { ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding); } } } /* Programmatic selection. */ #ifdef ALLEGRO_CFG_D3D if (flags & ALLEGRO_DIRECT3D_INTERNAL) { if (d3d_available) { return _al_display_d3d_driver(); } ALLEGRO_WARN("Direct3D graphics driver not available.\n"); return NULL; } #endif #ifdef ALLEGRO_CFG_OPENGL if (flags & ALLEGRO_OPENGL) { return _al_display_wgl_driver(); } #endif /* Selection by configuration file. The configuration value is non-binding. * The user may unknowingly set a value which was configured out at compile * time. The value should have no effect instead of causing a failure. */ if (sys->config) { const char *s = al_get_config_value(sys->config, "graphics", "driver"); if (s) { ALLEGRO_DEBUG("Configuration value graphics.driver = %s\n", s); if (0 == _al_stricmp(s, "DIRECT3D") || 0 == _al_stricmp(s, "D3D")) { #ifdef ALLEGRO_CFG_D3D if (d3d_available) { al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL); return _al_display_d3d_driver(); } #endif } else if (0 == _al_stricmp(s, "OPENGL")) { #ifdef ALLEGRO_CFG_OPENGL al_set_new_display_flags(flags | ALLEGRO_OPENGL); return _al_display_wgl_driver(); #endif } else if (0 != _al_stricmp(s, "DEFAULT")) { ALLEGRO_WARN("Graphics driver selection unrecognised: %s\n", s); } } } /* Automatic graphics driver selection. */ /* XXX is implicitly setting new_display_flags the desired behaviour? */ #ifdef ALLEGRO_CFG_D3D if (d3d_available) { al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL); return _al_display_d3d_driver(); } #endif #ifdef ALLEGRO_CFG_OPENGL { al_set_new_display_flags(flags | ALLEGRO_OPENGL); return _al_display_wgl_driver(); } #endif ALLEGRO_WARN("No graphics driver available.\n"); return NULL; } /* FIXME: use the list */ static ALLEGRO_KEYBOARD_DRIVER *win_get_keyboard_driver(void) { return _al_keyboard_driver_list[0].driver; } static ALLEGRO_JOYSTICK_DRIVER *win_get_joystick_driver(void) { return _al_joystick_driver_list[0].driver; } static int win_get_num_display_modes(void) { int format = _al_deduce_color_format(_al_get_new_display_settings()); int refresh_rate = al_get_new_display_refresh_rate(); int flags = al_get_new_display_flags(); #if defined ALLEGRO_CFG_OPENGL if (flags & ALLEGRO_OPENGL) { return _al_wgl_get_num_display_modes(format, refresh_rate, flags); } #endif #if defined ALLEGRO_CFG_D3D return _al_d3d_get_num_display_modes(format, refresh_rate, flags); #endif return 0; } static ALLEGRO_DISPLAY_MODE *win_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) { int format = _al_deduce_color_format(_al_get_new_display_settings()); int refresh_rate = al_get_new_display_refresh_rate(); int flags = al_get_new_display_flags(); #if defined ALLEGRO_CFG_OPENGL if (flags & ALLEGRO_OPENGL) { return _al_wgl_get_display_mode(index, format, refresh_rate, flags, mode); } #endif #if defined ALLEGRO_CFG_D3D return _al_d3d_get_display_mode(index, format, refresh_rate, flags, mode); #endif return NULL; } static int win_get_num_video_adapters(void) { DISPLAY_DEVICE dd; int count = 0; int c = 0; memset(&dd, 0, sizeof(dd)); dd.cb = sizeof(dd); while (EnumDisplayDevices(NULL, count, &dd, 0) != false) { if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) c++; count++; } return c; } static bool win_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { DISPLAY_DEVICE dd; DEVMODE dm; memset(&dd, 0, sizeof(dd)); dd.cb = sizeof(dd); if (!EnumDisplayDevices(NULL, adapter, &dd, 0)) { return false; } memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); if (!EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { return false; } ASSERT(dm.dmFields & DM_PELSHEIGHT); ASSERT(dm.dmFields & DM_PELSWIDTH); /* Disabled this assertion for now as it fails under Wine 1.2. */ /* ASSERT(dm.dmFields & DM_POSITION); */ info->x1 = dm.dmPosition.x; info->y1 = dm.dmPosition.y; info->x2 = info->x1 + dm.dmPelsWidth; info->y2 = info->y1 + dm.dmPelsHeight; return true; } static bool win_get_cursor_position(int *ret_x, int *ret_y) { POINT p; GetCursorPos(&p); *ret_x = p.x; *ret_y = p.y; return true; } static bool win_grab_mouse(ALLEGRO_DISPLAY *display) { ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_WIN *win_disp = (void *)display; RECT rect; GetWindowRect(win_disp->window, &rect); if (ClipCursor(&rect) != 0) { system->mouse_grab_display = display; return true; } return false; } static bool win_ungrab_mouse(void) { ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); ClipCursor(NULL); system->mouse_grab_display = NULL; return true; } static ALLEGRO_MOUSE_DRIVER *win_get_mouse_driver(void) { return _al_mouse_driver_list[0].driver; } /* _al_win_get_path: * Returns full path to various system and user diretories */ ALLEGRO_PATH *_al_win_get_path(int id) { char path[MAX_PATH]; uint32_t csidl = 0; HRESULT ret = 0; ALLEGRO_PATH *cisdl_path = NULL; switch (id) { case ALLEGRO_TEMP_PATH: { /* Check: TMP, TMPDIR, TEMP or TEMPDIR */ DWORD ret = GetTempPath(MAX_PATH, path); if (ret > MAX_PATH) { /* should this ever happen, windows is more broken than I ever thought */ return NULL; } return al_create_path_for_directory(path); } break; case ALLEGRO_RESOURCES_PATH: { /* where the program is in */ HANDLE process = GetCurrentProcess(); char *ptr; GetModuleFileNameEx(process, NULL, path, MAX_PATH); ptr = strrchr(path, '\\'); if (!ptr) { /* shouldn't happen */ return NULL; } /* chop off everything including and after the last slash */ /* should this not chop the slash? */ *ptr = '\0'; return al_create_path_for_directory(path); } break; case ALLEGRO_USER_DATA_PATH: /* CSIDL_APPDATA */ case ALLEGRO_USER_SETTINGS_PATH: csidl = CSIDL_APPDATA; break; case ALLEGRO_USER_HOME_PATH: /* CSIDL_PROFILE */ csidl = CSIDL_PROFILE; break; case ALLEGRO_USER_DOCUMENTS_PATH: /* CSIDL_PERSONAL */ csidl = CSIDL_PERSONAL; break; case ALLEGRO_EXENAME_PATH: { /* full path to the exe including its name */ HANDLE process = GetCurrentProcess(); GetModuleFileNameEx(process, NULL, path, MAX_PATH); return al_create_path(path); } break; default: return NULL; } ret = SHGetFolderPath(NULL, csidl, NULL, SHGFP_TYPE_CURRENT, path); if (ret != S_OK) { return NULL; } cisdl_path = al_create_path_for_directory(path); if (!cisdl_path) return NULL; if (csidl == CSIDL_APPDATA) { const char *org_name = al_get_org_name(); const char *app_name = al_get_app_name(); if (!app_name || !app_name[0]) { /* this shouldn't ever happen. */ al_destroy_path(cisdl_path); return NULL; } if (org_name && org_name[0]) { al_append_path_component(cisdl_path, org_name); } al_append_path_component(cisdl_path, app_name); } return cisdl_path; } static bool win_inhibit_screensaver(bool inhibit) { _al_win_disable_screensaver = inhibit; return true; } static HMODULE load_library_at_path(const char *path_str) { HMODULE lib; /* * XXX LoadLibrary will search the current directory for any dependencies of * the library we are loading. Using LoadLibraryEx with the appropriate * flags would fix that, but when I tried it I was unable to load dsound.dll * on Vista. */ ALLEGRO_DEBUG("Calling LoadLibrary %s\n", path_str); lib = LoadLibraryA(path_str); if (lib) { ALLEGRO_INFO("Loaded %s\n", path_str); } else { DWORD error = GetLastError(); HRESULT hr = HRESULT_FROM_WIN32(error); /* XXX do something with it */ (void)hr; ALLEGRO_WARN("Failed to load %s (error: %ld)\n", path_str, error); } return lib; } static bool is_build_config_name(const char *s) { return s && ( 0 == strcmp(s, "Debug") || 0 == strcmp(s, "Release") || 0 == strcmp(s, "RelWithDebInfo") || 0 == strcmp(s, "Profile")); } static ALLEGRO_PATH *maybe_parent_dir(const ALLEGRO_PATH *path) { ALLEGRO_PATH *path2; if (!path) return NULL; if (!is_build_config_name(al_get_path_tail(path))) return NULL; path2 = al_clone_path(path); if (path2) { al_drop_path_tail(path2); al_set_path_filename(path2, NULL); ALLEGRO_DEBUG("Also searching %s\n", al_path_cstr(path2, '\\')); } return path2; } /* * Calling LoadLibrary with a relative file name is a security risk: * see e.g. Microsoft Security Advisory (2269637) * "Insecure Library Loading Could Allow Remote Code Execution" */ HMODULE _al_win_safe_load_library(const char *filename) { ALLEGRO_PATH *path1 = NULL; ALLEGRO_PATH *path2 = NULL; char buf[MAX_PATH]; const char *other_dirs[3]; HMODULE lib = NULL; bool msvc_only = false; /* MSVC only: if the executable is in the build configuration directory, * which is also just under the current directory, then also try to load the * library from the current directory. This leads to less surprises when * running example programs. */ #if defined(ALLEGRO_MSVC) msvc_only = true; #endif /* Try to load the library from the directory containing the running * executable, the Windows system directories, or directories on the PATH. * Do NOT try to load the library from the current directory. */ if (al_is_system_installed()) { path1 = al_get_standard_path(ALLEGRO_RESOURCES_PATH); } else if (GetModuleFileName(NULL, buf, sizeof(buf)) < sizeof(buf)) { path1 = al_create_path(buf); } if (msvc_only) { path2 = maybe_parent_dir(path1); } other_dirs[0] = path1 ? al_path_cstr(path1, '\\') : NULL; other_dirs[1] = path2 ? al_path_cstr(path2, '\\') : NULL; other_dirs[2] = NULL; /* sentinel */ _al_sane_strncpy(buf, filename, sizeof(buf)); if (PathFindOnPath(buf, other_dirs)) { ALLEGRO_DEBUG("PathFindOnPath found: %s\n", buf); lib = load_library_at_path(buf); } else { ALLEGRO_WARN("PathFindOnPath failed to find %s\n", filename); } al_destroy_path(path1); al_destroy_path(path2); return lib; } static void *win_open_library(const char *filename) { return _al_win_safe_load_library(filename); } static void *win_import_symbol(void *library, const char *symbol) { ASSERT(library); return GetProcAddress(library, symbol); } static void win_close_library(void *library) { ASSERT(library); FreeLibrary(library); } static ALLEGRO_SYSTEM_INTERFACE *_al_system_win_driver(void) { if (vt) return vt; vt = al_calloc(1, sizeof *vt); vt->initialize = win_initialize; vt->get_display_driver = win_get_display_driver; vt->get_keyboard_driver = win_get_keyboard_driver; vt->get_mouse_driver = win_get_mouse_driver; vt->get_joystick_driver = win_get_joystick_driver; vt->get_num_display_modes = win_get_num_display_modes; vt->get_display_mode = win_get_display_mode; vt->shutdown_system = win_shutdown; vt->get_num_video_adapters = win_get_num_video_adapters; vt->create_mouse_cursor = _al_win_create_mouse_cursor; vt->destroy_mouse_cursor = _al_win_destroy_mouse_cursor; vt->get_monitor_info = win_get_monitor_info; vt->get_cursor_position = win_get_cursor_position; vt->grab_mouse = win_grab_mouse; vt->ungrab_mouse = win_ungrab_mouse; vt->get_path = _al_win_get_path; vt->inhibit_screensaver = win_inhibit_screensaver; vt->open_library = win_open_library; vt->import_symbol = win_import_symbol; vt->close_library = win_close_library; return vt; } void _al_register_system_interfaces() { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_win_driver(); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/win/d3d_bmp.cpp0000644000175000001440000006163612125155766016034 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Direct3D bitmap driver * * By Trent Gamblin. * */ #include #include #include #include "allegro5/allegro.h" #include "allegro5/system.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_memblit.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/platform/aintwin.h" #include "d3d.h" extern "C" { ALLEGRO_DEBUG_CHANNEL("d3d") static ALLEGRO_BITMAP_INTERFACE *vt; static _AL_VECTOR created_bitmaps; void _al_d3d_bmp_init(void) { _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_BITMAP_D3D *)); } void _al_d3d_bmp_destroy(void) { while (!_al_vector_is_empty(&created_bitmaps)) _al_vector_delete_at(&created_bitmaps, _al_vector_size(&created_bitmaps)-1); _al_vector_free(&created_bitmaps); _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); al_free(vt); vt = NULL; } static INLINE void transform_vertex(float* x, float* y) { al_transform_coordinates(al_get_current_transform(), x, y); } /* * Draw a textured quad */ static void d3d_draw_textured_quad( ALLEGRO_DISPLAY_D3D *disp, ALLEGRO_BITMAP_D3D *bmp, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, int flags) { float right; float bottom; float tu_start; float tv_start; float tu_end; float tv_end; int texture_w; int texture_h; DWORD d3d_color; const float z = 0.0f; ALLEGRO_DISPLAY* aldisp = (ALLEGRO_DISPLAY*)disp; if (aldisp->num_cache_vertices != 0 && (uintptr_t)bmp != aldisp->cache_texture) { aldisp->vt->flush_vertex_cache(aldisp); } aldisp->cache_texture = (uintptr_t)bmp; D3D_TL_VERTEX* vertices = (D3D_TL_VERTEX*)aldisp->vt->prepare_vertex_cache(aldisp, 6); right = sw; bottom = sh; texture_w = bmp->texture_w; texture_h = bmp->texture_h; tu_start = sx / texture_w; tv_start = sy / texture_h; tu_end = sw / texture_w + tu_start; tv_end = sh / texture_h + tv_start; if (flags & ALLEGRO_FLIP_HORIZONTAL) { float temp = tu_start; tu_start = tu_end; tu_end = temp; } if (flags & ALLEGRO_FLIP_VERTICAL) { float temp = tv_start; tv_start = tv_end; tv_end = temp; } d3d_color = D3DCOLOR_COLORVALUE(tint.r, tint.g, tint.b, tint.a); vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = z; vertices[0].diffuse = d3d_color; vertices[0].tu = tu_start; vertices[0].tv = tv_start; vertices[1].x = right; vertices[1].y = 0; vertices[1].z = z; vertices[1].diffuse = d3d_color; vertices[1].tu = tu_end; vertices[1].tv = tv_start; vertices[2].x = right; vertices[2].y = bottom; vertices[2].z = z; vertices[2].diffuse = d3d_color; vertices[2].tu = tu_end; vertices[2].tv = tv_end; vertices[5].x = 0; vertices[5].y = bottom; vertices[5].z = z; vertices[5].diffuse = d3d_color; vertices[5].tu = tu_start; vertices[5].tv = tv_end; if (aldisp->cache_enabled) { transform_vertex(&vertices[0].x, &vertices[0].y); transform_vertex(&vertices[1].x, &vertices[1].y); transform_vertex(&vertices[2].x, &vertices[2].y); transform_vertex(&vertices[5].x, &vertices[5].y); } vertices[3] = vertices[0]; vertices[4] = vertices[2]; if(!aldisp->cache_enabled) aldisp->vt->flush_vertex_cache(aldisp); } /* Copy texture memory to bitmap->memory */ static void d3d_sync_bitmap_memory(ALLEGRO_BITMAP *bitmap) { D3DLOCKED_RECT locked_rect; ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; LPDIRECT3DTEXTURE9 texture; if (_al_d3d_render_to_texture_supported()) texture = d3d_bmp->system_texture; else texture = d3d_bmp->video_texture; if (texture->LockRect(0, &locked_rect, NULL, 0) == D3D_OK) { _al_convert_bitmap_data(locked_rect.pBits, bitmap->format, locked_rect.Pitch, bitmap->memory, bitmap->format, al_get_pixel_size(bitmap->format)*bitmap->w, 0, 0, 0, 0, bitmap->w, bitmap->h); texture->UnlockRect(0); } else { ALLEGRO_ERROR("d3d_sync_bitmap_memory: Couldn't lock texture.\n"); } } /* Copy bitmap->memory to texture memory */ static void d3d_sync_bitmap_texture(ALLEGRO_BITMAP *bitmap, int x, int y, int width, int height) { D3DLOCKED_RECT locked_rect; RECT rect; ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; LPDIRECT3DTEXTURE9 texture; rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; if (_al_d3d_render_to_texture_supported()) texture = d3d_bmp->system_texture; else texture = d3d_bmp->video_texture; if (texture->LockRect(0, &locked_rect, &rect, 0) == D3D_OK) { _al_convert_bitmap_data(bitmap->memory, bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format), locked_rect.pBits, bitmap->format, locked_rect.Pitch, x, y, 0, 0, width, height); /* Copy an extra row and column so the texture ends nicely */ if (rect.bottom > bitmap->h) { _al_convert_bitmap_data( bitmap->memory, bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format), locked_rect.pBits, bitmap->format, locked_rect.Pitch, 0, bitmap->h-1, 0, height, width, 1); } if (rect.right > bitmap->w) { _al_convert_bitmap_data( bitmap->memory, bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format), locked_rect.pBits, bitmap->format, locked_rect.Pitch, bitmap->w-1, 0, width, 0, 1, height); } if (rect.bottom > bitmap->h && rect.right > bitmap->w) { _al_convert_bitmap_data( bitmap->memory, bitmap->format, bitmap->w*al_get_pixel_size(bitmap->format), locked_rect.pBits, bitmap->format, locked_rect.Pitch, bitmap->w-1, bitmap->h-1, width, height, 1, 1); } texture->UnlockRect(0); } else { ALLEGRO_ERROR("d3d_sync_bitmap_texture: Couldn't lock texture to upload.\n"); } } static void d3d_do_upload(ALLEGRO_BITMAP_D3D *d3d_bmp, int x, int y, int width, int height, bool sync_from_memory) { ALLEGRO_BITMAP *bmp = (ALLEGRO_BITMAP *)d3d_bmp; if (sync_from_memory) { d3d_sync_bitmap_texture(bmp, x, y, width, height); } if (_al_d3d_render_to_texture_supported()) { if (d3d_bmp->display->device->UpdateTexture( (IDirect3DBaseTexture9 *)d3d_bmp->system_texture, (IDirect3DBaseTexture9 *)d3d_bmp->video_texture) != D3D_OK) { ALLEGRO_ERROR("d3d_do_upload: Couldn't update texture.\n"); return; } } } /* * Release all default pool textures. This must be done before * resetting the device. */ void _al_d3d_release_default_pool_textures(void) { unsigned int i; for (i = 0; i < created_bitmaps._size; i++) { ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&created_bitmaps, i); ALLEGRO_BITMAP *albmp = *bptr; ALLEGRO_BITMAP_D3D *d3d_bmp; if ((albmp->flags & ALLEGRO_MEMORY_BITMAP) || (albmp->parent)) continue; d3d_bmp = (ALLEGRO_BITMAP_D3D *)albmp; if (!d3d_bmp->is_backbuffer && d3d_bmp->render_target) { d3d_bmp->render_target->Release(); d3d_bmp->render_target = NULL; } if (d3d_bmp->video_texture) { d3d_bmp->video_texture->Release(); d3d_bmp->video_texture = NULL; } } } static bool d3d_create_textures(ALLEGRO_DISPLAY_D3D *disp, int w, int h, int flags, LPDIRECT3DTEXTURE9 *video_texture, LPDIRECT3DTEXTURE9 *system_texture, int format) { int levels; int autogenmipmap; int err; if (flags & ALLEGRO_MIPMAP) { /* "0" for all possible levels, required for auto mipmap generation. */ levels = 0; autogenmipmap = D3DUSAGE_AUTOGENMIPMAP; } else { levels = 1; autogenmipmap = 0; } if (_al_d3d_render_to_texture_supported()) { if (video_texture) { err = disp->device->CreateTexture(w, h, levels, D3DUSAGE_RENDERTARGET | autogenmipmap, (D3DFORMAT)_al_pixel_format_to_d3d(format), D3DPOOL_DEFAULT, video_texture, NULL); if (err != D3D_OK && err != D3DOK_NOAUTOGEN) { ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture.\n"); return false; } } if (system_texture) { err = disp->device->CreateTexture(w, h, 1, 0, (D3DFORMAT)_al_pixel_format_to_d3d(format), D3DPOOL_SYSTEMMEM, system_texture, NULL); if (err != D3D_OK) { ALLEGRO_ERROR("d3d_create_textures: Unable to create system texture.\n"); if (video_texture && (*video_texture)) { (*video_texture)->Release(); *video_texture = NULL; } return false; } } return true; } else { if (video_texture) { err = disp->device->CreateTexture(w, h, 1, 0, (D3DFORMAT)_al_pixel_format_to_d3d(format), D3DPOOL_MANAGED, video_texture, NULL); if (err != D3D_OK) { ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture (no render-to-texture).\n"); return false; } } return true; } } static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface, int format, int flags) { ALLEGRO_BITMAP *bitmap; ALLEGRO_BITMAP_D3D *d3d_bmp; D3DSURFACE_DESC desc; D3DLOCKED_RECT surf_locked_rect; D3DLOCKED_RECT sys_locked_rect; ALLEGRO_STATE backup; unsigned int y; if (surface->GetDesc(&desc) != D3D_OK) { ALLEGRO_ERROR("d3d_create_bitmap_from_surface: GetDesc failed.\n"); return NULL; } if (surface->LockRect(&surf_locked_rect, 0, D3DLOCK_READONLY) != D3D_OK) { ALLEGRO_ERROR("d3d_create_bitmap_from_surface: LockRect failed.\n"); return NULL; } al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(format); al_set_new_bitmap_flags(flags); bitmap = al_create_bitmap(desc.Width, desc.Height); d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; al_restore_state(&backup); if (!bitmap) { surface->UnlockRect(); return NULL; } if (d3d_bmp->system_texture->LockRect(0, &sys_locked_rect, 0, 0) != D3D_OK) { surface->UnlockRect(); al_destroy_bitmap(bitmap); ALLEGRO_ERROR("d3d_create_bitmap_from_surface: Lock system texture failed.\n"); return NULL; } for (y = 0; y < desc.Height; y++) { memcpy( ((char*)sys_locked_rect.pBits)+(sys_locked_rect.Pitch*y), ((char*)surf_locked_rect.pBits)+(surf_locked_rect.Pitch*y), desc.Width*al_get_pixel_size(format) ); } surface->UnlockRect(); d3d_bmp->system_texture->UnlockRect(0); if (d3d_bmp->display->device->UpdateTexture( (IDirect3DBaseTexture9 *)d3d_bmp->system_texture, (IDirect3DBaseTexture9 *)d3d_bmp->video_texture) != D3D_OK) { ALLEGRO_ERROR("d3d_create_bitmap_from_texture: Couldn't update texture.\n"); } return bitmap; } /* Copies video texture to system texture and bitmap->memory */ static bool _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest) { ALLEGRO_BITMAP_D3D *d3d_dest; LPDIRECT3DSURFACE9 system_texture_surface; LPDIRECT3DSURFACE9 video_texture_surface; bool ok; UINT i; if (!_al_d3d_render_to_texture_supported()) { ALLEGRO_ERROR("Render-to-texture not supported.\n"); return false; } if (dest->locked) { ALLEGRO_ERROR("Already locked.\n"); return false; } d3d_dest = (ALLEGRO_BITMAP_D3D *)dest; if (d3d_dest->system_texture == NULL || d3d_dest->video_texture == NULL) { ALLEGRO_ERROR("A texture is null.\n"); return false; } if (dest->parent) { dest = dest->parent; } ok = true; system_texture_surface = NULL; video_texture_surface = NULL; if (d3d_dest->system_texture->GetSurfaceLevel( 0, &system_texture_surface) != D3D_OK) { ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n"); ok = false; } if (ok && d3d_dest->video_texture->GetSurfaceLevel( 0, &video_texture_surface) != D3D_OK) { ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating video texture.\n"); ok = false; } if (ok && d3d_dest->display->device->GetRenderTargetData( video_texture_surface, system_texture_surface) != D3D_OK) { ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetRenderTargetData failed.\n"); ok = false; } if (system_texture_surface) { if ((i = system_texture_surface->Release()) != 0) { ALLEGRO_DEBUG("_al_d3d_sync_bitmap (system) ref count == %d\n", i); } } if (video_texture_surface) { if ((i = video_texture_surface->Release()) != 0) { // This can be non-zero ALLEGRO_DEBUG("_al_d3d_sync_bitmap (video) ref count == %d\n", i); } } if (ok) { d3d_sync_bitmap_memory(dest); } return ok; } /* * Must be called before the D3D device is reset (e.g., when * resizing a window). All non-synced display bitmaps must be * synced to memory. */ void _al_d3d_prepare_bitmaps_for_reset(ALLEGRO_DISPLAY_D3D *disp) { unsigned int i; if (disp->device_lost) return; if (!_al_d3d_render_to_texture_supported()) return; al_lock_mutex(_al_d3d_lost_device_mutex); for (i = 0; i < created_bitmaps._size; i++) { ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i); ALLEGRO_BITMAP_D3D *bmp = *bptr; ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp; if (bmp->display == disp) { //d3d_sync_bitmap_memory(al_bmp); if (!al_bmp->preserve_texture) { bmp->modified = false; } else if (!bmp->is_backbuffer && bmp->modified && !(al_bmp->flags & ALLEGRO_MEMORY_BITMAP)) { _al_d3d_sync_bitmap(al_bmp); bmp->modified = false; } } } al_unlock_mutex(_al_d3d_lost_device_mutex); } /* * Called after the resize is done. */ bool _al_d3d_recreate_bitmap_textures(ALLEGRO_DISPLAY_D3D *disp) { unsigned int i; for (i = 0; i < created_bitmaps._size; i++) { ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i); ALLEGRO_BITMAP_D3D *bmp = *bptr; ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp; if (bmp->display == disp) { if (!d3d_create_textures(disp, bmp->texture_w, bmp->texture_h, al_bmp->flags, &bmp->video_texture, &bmp->system_texture, al_bmp->format)) return false; d3d_do_upload(bmp, 0, 0, al_bmp->w, al_bmp->h, true); } } return true; } /* * Refresh the texture memory. This must be done after a device is * lost or after it is reset. */ void _al_d3d_refresh_texture_memory(void) { unsigned int i; for (i = 0; i < created_bitmaps._size; i++) { ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i); ALLEGRO_BITMAP_D3D *bmp = *bptr; ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp; ALLEGRO_DISPLAY_D3D *bmps_display = (ALLEGRO_DISPLAY_D3D *)al_bmp->display; if ((al_bmp->flags & ALLEGRO_MEMORY_BITMAP) || (al_bmp->parent)) { continue; } d3d_create_textures(bmps_display, bmp->texture_w, bmp->texture_h, al_bmp->flags, &bmp->video_texture, /*&bmp->system_texture*/0, al_bmp->format); d3d_sync_bitmap_texture(al_bmp, 0, 0, al_bmp->w, al_bmp->h); if (_al_d3d_render_to_texture_supported()) { bmps_display->device->UpdateTexture( (IDirect3DBaseTexture9 *)bmp->system_texture, (IDirect3DBaseTexture9 *)bmp->video_texture); } } } static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; int w = bitmap->w; int h = bitmap->h; if (d3d_bmp->display->device_lost) return false; if (d3d_bmp->initialized != true) { bool non_pow2 = al_have_d3d_non_pow2_texture_support(); bool non_square = al_have_d3d_non_square_texture_support(); if (non_pow2 && non_square) { // Any shape and size d3d_bmp->texture_w = w; d3d_bmp->texture_h = h; } else if (non_pow2) { // Must be sqaure int max = _ALLEGRO_MAX(w, h); d3d_bmp->texture_w = max; d3d_bmp->texture_h = max; } else { // Must be POW2 d3d_bmp->texture_w = pot(w); d3d_bmp->texture_h = pot(h); } // Some cards/drivers don't like small textures if (d3d_bmp->texture_w < 16) d3d_bmp->texture_w = 16; if (d3d_bmp->texture_h < 16) d3d_bmp->texture_h = 16; if (d3d_bmp->video_texture == 0) if (!d3d_create_textures(d3d_bmp->display, d3d_bmp->texture_w, d3d_bmp->texture_h, d3d_bmp->bitmap.flags, &d3d_bmp->video_texture, &d3d_bmp->system_texture, bitmap->format)) { return false; } /* * Keep track of created bitmaps, in case the display is lost * or resized. */ *(ALLEGRO_BITMAP_D3D **)_al_vector_alloc_back(&created_bitmaps) = d3d_bmp; d3d_bmp->initialized = true; } d3d_do_upload(d3d_bmp, 0, 0, w, h, false); return true; } static void d3d_draw_bitmap_region( ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, int flags) { ALLEGRO_BITMAP *dest = al_get_target_bitmap(); ALLEGRO_BITMAP_D3D *d3d_dest = (ALLEGRO_BITMAP_D3D *)dest; ALLEGRO_BITMAP_D3D *d3d_src = (ALLEGRO_BITMAP_D3D *)src; if (!_al_d3d_render_to_texture_supported()) { _al_draw_bitmap_region_memory(src, tint, (int)sx, (int)sy, (int)sw, (int)sh, 0, 0, (int)flags); return; } if (d3d_dest->display->device_lost) return; _al_d3d_set_bitmap_clip(dest); /* For sub-bitmaps */ if (src->parent) { sx += src->xofs; sy += src->yofs; src = src->parent; d3d_src = (ALLEGRO_BITMAP_D3D *)src; } if (dest->parent) { dest = dest->parent; d3d_dest = (ALLEGRO_BITMAP_D3D *)dest; } if (d3d_src->is_backbuffer) { IDirect3DSurface9 *surface; D3DSURFACE_DESC desc; if (d3d_src->display->render_target->GetDesc(&desc) != D3D_OK) { ALLEGRO_ERROR("d3d_draw_bitmap_region: GetDesc failed.\n"); return; } if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) { surface = d3d_src->display->render_target; } else { RECT r; if (d3d_src->display->device->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL ) != D3D_OK) { ALLEGRO_ERROR( "d3d_draw_bitmap_region: CreateRenderTarget failed.\n"); return; } r.top = 0; r.left = 0; r.right = desc.Width; r.bottom = desc.Height; if (d3d_src->display->device->StretchRect( d3d_src->display->render_target, &r, surface, &r, D3DTEXF_NONE ) != D3D_OK) { ALLEGRO_ERROR("d3d_draw_bitmap_region: StretchRect failed.\n"); surface->Release(); return; } } ALLEGRO_BITMAP *tmp_bmp = d3d_create_bitmap_from_surface( surface, src->format, src->flags ); if (tmp_bmp) { d3d_draw_bitmap_region((ALLEGRO_BITMAP *)tmp_bmp, tint, sx, sy, sw, sh, flags); al_destroy_bitmap(tmp_bmp); if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) { surface->Release(); } } return; } _al_d3d_set_blender(d3d_dest->display); d3d_draw_textured_quad( d3d_dest->display, d3d_src, tint, sx, sy, sw, sh, flags); d3d_dest->modified = true; } static void d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; if (!al_is_sub_bitmap(bitmap)) { if (d3d_bmp->video_texture) { if (d3d_bmp->video_texture->Release() != 0) { ALLEGRO_WARN("d3d_destroy_bitmap: Release video texture failed.\n"); } } if (d3d_bmp->system_texture) { if (d3d_bmp->system_texture->Release() != 0) { ALLEGRO_WARN("d3d_destroy_bitmap: Release system texture failed.\n"); } } if (d3d_bmp->render_target) { if (d3d_bmp->render_target->Release() != 0) { ALLEGRO_WARN("d3d_destroy_bitmap: Release render target failed.\n"); } } } _al_vector_find_and_delete(&created_bitmaps, &d3d_bmp); } static ALLEGRO_LOCKED_REGION *d3d_lock_region(ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, int format, int flags) { ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; if (d3d_bmp->display->device_lost) return NULL; RECT rect; DWORD Flags = flags & ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0; int f = _al_get_real_pixel_format(al_get_current_display(), format); if (f < 0) { return NULL; } rect.left = x; rect.right = x + w; rect.top = y; rect.bottom = y + h; if (d3d_bmp->is_backbuffer) { ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)bitmap->display; if (d3d_disp->render_target->LockRect(&d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) { ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n"); return NULL; } } else { LPDIRECT3DTEXTURE9 texture; if (_al_d3d_render_to_texture_supported()) { /* * Sync bitmap->memory with texture */ bitmap->locked = false; if (!_al_d3d_sync_bitmap(bitmap)) { return NULL; } bitmap->locked = true; texture = d3d_bmp->system_texture; } else { texture = d3d_bmp->video_texture; } if (texture->LockRect(0, &d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) { ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n"); return NULL; } } if (format == ALLEGRO_PIXEL_FORMAT_ANY || bitmap->format == format || f == bitmap->format) { bitmap->locked_region.data = d3d_bmp->locked_rect.pBits; bitmap->locked_region.format = bitmap->format; bitmap->locked_region.pitch = d3d_bmp->locked_rect.Pitch; bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap->format); } else { bitmap->locked_region.pitch = al_get_pixel_size(f) * w; bitmap->locked_region.data = al_malloc(bitmap->locked_region.pitch*h); bitmap->locked_region.format = f; bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap->format); if (!(bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY)) { _al_convert_bitmap_data( d3d_bmp->locked_rect.pBits, bitmap->format, d3d_bmp->locked_rect.Pitch, bitmap->locked_region.data, f, bitmap->locked_region.pitch, 0, 0, 0, 0, w, h); } } return &bitmap->locked_region; } static void d3d_unlock_region(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; d3d_bmp->modified = true; if (bitmap->locked_region.format != 0 && bitmap->locked_region.format != bitmap->format) { if (!(bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) { _al_convert_bitmap_data( bitmap->locked_region.data, bitmap->locked_region.format, bitmap->locked_region.pitch, d3d_bmp->locked_rect.pBits, bitmap->format, d3d_bmp->locked_rect.Pitch, 0, 0, 0, 0, bitmap->lock_w, bitmap->lock_h); } al_free(bitmap->locked_region.data); } if (d3d_bmp->is_backbuffer) { ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)bitmap->display; d3d_disp->render_target->UnlockRect(); } else { LPDIRECT3DTEXTURE9 texture; if (_al_d3d_render_to_texture_supported()) texture = d3d_bmp->system_texture; else texture = d3d_bmp->video_texture; texture->UnlockRect(0); if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY) return; d3d_do_upload(d3d_bmp, bitmap->lock_x, bitmap->lock_y, bitmap->lock_w, bitmap->lock_h, false); } } static void d3d_update_clipping_rectangle(ALLEGRO_BITMAP *bitmap) { _al_d3d_set_bitmap_clip(bitmap); } /* Obtain a reference to this driver. */ ALLEGRO_BITMAP_INTERFACE *_al_bitmap_d3d_driver(void) { if (vt) return vt; vt = (ALLEGRO_BITMAP_INTERFACE *)al_malloc(sizeof *vt); memset(vt, 0, sizeof *vt); vt->draw_bitmap_region = d3d_draw_bitmap_region; vt->upload_bitmap = d3d_upload_bitmap; vt->update_clipping_rectangle = NULL; vt->destroy_bitmap = d3d_destroy_bitmap; vt->lock_region = d3d_lock_region; vt->unlock_region = d3d_unlock_region; vt->update_clipping_rectangle = d3d_update_clipping_rectangle; return vt; } } // end extern "C" allegro-5.0.10/src/win/wthread.c0000644000175000001440000000436111476664537015623 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread management. * * By Stefan Schimanski. * * Synchronization functions added by Eric Botcazou. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintwin.h" #include #ifndef ALLEGRO_WINDOWS #error something is wrong with the makefile #endif ALLEGRO_DEBUG_CHANNEL("system") /* COINIT_MULTITHREADED is not defined in objbase.h for MSVC */ #define _COINIT_MULTITHREADED 0 typedef HRESULT(CALLBACK * _CoInitializeEx_ptr) (LPVOID, DWORD); static _CoInitializeEx_ptr _CoInitializeEx = NULL; static int first_call = 1; /* _al_win_thread_init: * Initializes COM interface for the calling thread. * Attempts to use Distributed COM if available (installed by default * on every 32-bit Windows starting with Win98 and Win NT4). */ void _al_win_thread_init(void) { HMODULE ole32 = NULL; if (first_call) { first_call = 0; ole32 = GetModuleHandle("OLE32.DLL"); if (ole32 != NULL) { _CoInitializeEx = (_CoInitializeEx_ptr) GetProcAddress( ole32, "CoInitializeEx"); } else { ALLEGRO_WARN("OLE32.DLL can't be loaded.\n"); } if (_CoInitializeEx == NULL) { ALLEGRO_WARN("Microsoft Distributed COM is not installed on this system. If you have problems "); ALLEGRO_WARN("with this application, please install the DCOM update. You can find it on the "); ALLEGRO_WARN("Microsoft homepage\n"); } } if (_CoInitializeEx != NULL) _CoInitializeEx(NULL, _COINIT_MULTITHREADED); else CoInitialize(NULL); } /* _al_win_thread_exit: * Shuts down COM interface for the calling thread. */ void _al_win_thread_exit(void) { CoUninitialize(); } allegro-5.0.10/src/bitmap.c0000644000175000001440000003632412137141362014625 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New bitmap routines. * * By Elias Pschernig and Trent Gamblin. * * See readme.txt for copyright information. */ /* Title: Bitmap routines */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_system.h" ALLEGRO_DEBUG_CHANNEL("bitmap") /* Creates a memory bitmap. */ static ALLEGRO_BITMAP *create_memory_bitmap(int w, int h) { ALLEGRO_BITMAP *bitmap; int pitch; int format = al_get_new_bitmap_format(); format = _al_get_real_pixel_format(al_get_current_display(), format); bitmap = al_calloc(1, sizeof *bitmap); bitmap->size = sizeof(*bitmap); pitch = w * al_get_pixel_size(format); bitmap->vt = NULL; bitmap->format = format; bitmap->flags = (al_get_new_bitmap_flags() | ALLEGRO_MEMORY_BITMAP) & ~ALLEGRO_VIDEO_BITMAP; bitmap->w = w; bitmap->h = h; bitmap->pitch = pitch; bitmap->display = NULL; bitmap->locked = false; bitmap->cl = bitmap->ct = 0; bitmap->cr_excl = w; bitmap->cb_excl = h; al_identity_transform(&bitmap->transform); bitmap->parent = NULL; bitmap->xofs = bitmap->yofs = 0; bitmap->memory = al_malloc(pitch * h); bitmap->preserve_texture = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PRESERVE_TEXTURE); return bitmap; } static void destroy_memory_bitmap(ALLEGRO_BITMAP *bmp) { al_free(bmp->memory); al_free(bmp); } static ALLEGRO_BITMAP *do_create_bitmap(int w, int h) { ALLEGRO_BITMAP *bitmap; ALLEGRO_BITMAP **back; ALLEGRO_SYSTEM *system = al_get_system_driver(); ALLEGRO_DISPLAY *current_display = al_get_current_display(); int64_t mul; /* Reject bitmaps where a calculation pixel_size*w*h would overflow * int. Supporting such bitmaps would require a lot more work. */ mul = 4 * (int64_t) w * (int64_t) h; if (mul > (int64_t) INT_MAX) { ALLEGRO_WARN("Rejecting %dx%d bitmap\n", w, h); return NULL; } if ((al_get_new_bitmap_flags() & ALLEGRO_MEMORY_BITMAP) || (!current_display || !current_display->vt || current_display->vt->create_bitmap == NULL) || (system->displays._size < 1)) { return create_memory_bitmap(w, h); } /* Else it's a display bitmap */ bitmap = current_display->vt->create_bitmap(current_display, w, h); if (!bitmap) { ALLEGRO_ERROR("failed to create display bitmap\n"); return NULL; } /* XXX the ogl_display driver sets some of these variables. It's not clear * who should be responsible for setting what. * The pitch must be set by the driver. */ bitmap->display = current_display; bitmap->w = w; bitmap->h = h; bitmap->locked = false; bitmap->cl = 0; bitmap->ct = 0; bitmap->cr_excl = w; bitmap->cb_excl = h; al_identity_transform(&bitmap->transform); bitmap->parent = NULL; bitmap->xofs = 0; bitmap->yofs = 0; bitmap->preserve_texture = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PRESERVE_TEXTURE); ASSERT(bitmap->pitch >= w * al_get_pixel_size(bitmap->format)); /* The display driver should have set the bitmap->memory field if * appropriate; video bitmaps may leave it NULL. */ if (!bitmap->vt->upload_bitmap(bitmap)) { al_destroy_bitmap(bitmap); return NULL; } /* We keep a list of bitmaps depending on the current display so that we can * convert them to memory bimaps when the display is destroyed. */ back = _al_vector_alloc_back(¤t_display->bitmaps); *back = bitmap; return bitmap; } /* Function: al_create_bitmap */ ALLEGRO_BITMAP *al_create_bitmap(int w, int h) { ALLEGRO_BITMAP *bitmap = do_create_bitmap(w, h); if (bitmap) { _al_register_destructor(_al_dtor_list, bitmap, (void (*)(void *))al_destroy_bitmap); } return bitmap; } /* Function: al_destroy_bitmap */ void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap) { if (!bitmap) { return; } /* As a convenience, implicitly untarget the bitmap on the calling thread * before it is destroyed, but maintain the current display. */ if (bitmap == al_get_target_bitmap()) { ALLEGRO_DISPLAY *display = al_get_current_display(); if (display) al_set_target_bitmap(al_get_backbuffer(display)); else al_set_target_bitmap(NULL); } _al_unregister_destructor(_al_dtor_list, bitmap); if (bitmap->parent) { /* It's a sub-bitmap */ if (bitmap->display) _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap); al_free(bitmap); return; } if (bitmap->flags & ALLEGRO_MEMORY_BITMAP) { destroy_memory_bitmap(bitmap); return; } /* Else it's a display bitmap */ if (bitmap->locked) al_unlock_bitmap(bitmap); if (bitmap->vt) bitmap->vt->destroy_bitmap(bitmap); if (bitmap->display) _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap); if (bitmap->memory) al_free(bitmap->memory); al_free(bitmap); } /* Function: al_convert_mask_to_alpha */ void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color) { ALLEGRO_LOCKED_REGION *lr; int x, y; ALLEGRO_COLOR pixel; ALLEGRO_COLOR alpha_pixel; ALLEGRO_STATE state; if (!(lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, 0))) { ALLEGRO_ERROR("Couldn't lock bitmap."); return; } al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(bitmap); alpha_pixel = al_map_rgba(0, 0, 0, 0); for (y = 0; y < bitmap->h; y++) { for (x = 0; x < bitmap->w; x++) { pixel = al_get_pixel(bitmap, x, y); if (memcmp(&pixel, &mask_color, sizeof(ALLEGRO_COLOR)) == 0) { al_put_pixel(x, y, alpha_pixel); } } } al_unlock_bitmap(bitmap); al_restore_state(&state); } /* Function: al_get_bitmap_width */ int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap) { return bitmap->w; } /* Function: al_get_bitmap_height */ int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap) { return bitmap->h; } /* Function: al_get_bitmap_format */ int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap) { return bitmap->format; } /* Function: al_get_bitmap_flags */ int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap) { return bitmap->flags; } /* Function: al_set_clipping_rectangle */ void al_set_clipping_rectangle(int x, int y, int width, int height) { ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); ASSERT(bitmap); if (x < 0) { width += x; x = 0; } if (y < 0) { height += y; y = 0; } if (x + width > bitmap->w) { width = bitmap->w - x; } if (y + height > bitmap->h) { height = bitmap->h - y; } bitmap->cl = x; bitmap->ct = y; bitmap->cr_excl = x + width; bitmap->cb_excl = y + height; if (bitmap->vt && bitmap->vt->update_clipping_rectangle) { bitmap->vt->update_clipping_rectangle(bitmap); } } /* Function: al_reset_clipping_rectangle */ void al_reset_clipping_rectangle(void) { ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); if (bitmap) { int w = al_get_bitmap_width(bitmap); int h = al_get_bitmap_height(bitmap); al_set_clipping_rectangle(0, 0, w, h); } } /* Function: al_get_clipping_rectangle */ void al_get_clipping_rectangle(int *x, int *y, int *w, int *h) { ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); ASSERT(bitmap); if (x) *x = bitmap->cl; if (y) *y = bitmap->ct; if (w) *w = bitmap->cr_excl - bitmap->cl; if (h) *h = bitmap->cb_excl - bitmap->ct; } /* Function: al_create_sub_bitmap */ ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, int x, int y, int w, int h) { ALLEGRO_BITMAP *bitmap; if (parent->parent) { x += parent->xofs; y += parent->yofs; parent = parent->parent; } if (parent->display && parent->display->vt && parent->display->vt->create_sub_bitmap) { bitmap = parent->display->vt->create_sub_bitmap( parent->display, parent, x, y, w, h); } else { bitmap = al_calloc(1, sizeof *bitmap); bitmap->size = sizeof *bitmap; bitmap->vt = parent->vt; } bitmap->format = parent->format; bitmap->flags = parent->flags; bitmap->w = w; bitmap->h = h; bitmap->display = parent->display; bitmap->locked = false; bitmap->cl = bitmap->ct = 0; bitmap->cr_excl = w; bitmap->cb_excl = h; al_identity_transform(&bitmap->transform); bitmap->parent = parent; bitmap->xofs = x; bitmap->yofs = y; bitmap->memory = NULL; if (bitmap->display) { ALLEGRO_BITMAP **back; back = _al_vector_alloc_back(&bitmap->display->bitmaps); *back = bitmap; } return bitmap; } /* Function: al_is_sub_bitmap */ bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap) { return (bitmap->parent != NULL); } /* Function: al_get_parent_bitmap */ ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap) { ASSERT(bitmap); return bitmap->parent; } /* Function: al_clone_bitmap */ ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP *clone; ALLEGRO_LOCKED_REGION *dst_region; ALLEGRO_LOCKED_REGION *src_region; ASSERT(bitmap); clone = al_create_bitmap(bitmap->w, bitmap->h); if (!clone) return NULL; if (!(src_region = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY))) return NULL; if (!(dst_region = al_lock_bitmap(clone, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY))) { al_unlock_bitmap(bitmap); return NULL; } _al_convert_bitmap_data( src_region->data, src_region->format, src_region->pitch, dst_region->data, dst_region->format, dst_region->pitch, 0, 0, 0, 0, bitmap->w, bitmap->h); al_unlock_bitmap(bitmap); al_unlock_bitmap(clone); return clone; } /* Converts a memory bitmap to a display bitmap preserving its contents. * The created bitmap belongs to the current display. A converted sub * bitmap is invalid until its parent is converted. * WARNING: This function will fail for any memory bitmap not previously * processed by _al_convert_to_memory_bitmap(). */ void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP *tmp; ALLEGRO_BITMAP **vid; ALLEGRO_STATE backup; ALLEGRO_DISPLAY *d = al_get_current_display(); /* Do nothing if it is a display bitmap already. */ if (!(bitmap->flags & ALLEGRO_MEMORY_BITMAP)) return; if (bitmap->parent) { /* FIXME * We cannot safely assume that the backbuffer and bitmaps use the same * vtable. */ bitmap->vt = al_get_backbuffer(d)->vt; bitmap->display = d; bitmap->flags &= !ALLEGRO_MEMORY_BITMAP; return; } ALLEGRO_DEBUG("converting memory bitmap %p to display bitmap\n", bitmap); /* Allocate a temporary bitmap which will hold the data during the * conversion process. */ al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); al_set_new_bitmap_format(bitmap->format); tmp = do_create_bitmap(bitmap->w, bitmap->h); /* Preserve bitmap contents. */ al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_set_target_bitmap(tmp); al_draw_bitmap(bitmap, 0, 0, 0); tmp->cb_excl = bitmap->cb_excl; tmp->cr_excl = bitmap->cr_excl; tmp->cl = bitmap->cl; tmp->ct = bitmap->ct; al_restore_state(&backup); /* Free the memory bitmap's memory. */ al_free(bitmap->memory); /* Put the contents back to the bitmap. */ ASSERT(tmp->size > sizeof(ALLEGRO_BITMAP)); ASSERT(bitmap->size > sizeof(ALLEGRO_BITMAP)); ASSERT(tmp->size == bitmap->size); memcpy(bitmap, tmp, tmp->size); vid = _al_vector_alloc_back(&d->bitmaps); *vid = bitmap; /* Remove the temporary bitmap from the display bitmap list, added * automatically by al_create_bitmap() */ _al_vector_find_and_delete(&d->bitmaps, &tmp); al_free(tmp); } /* Converts a display bitmap to a memory bitmap preserving its contents. * Driver specific resources occupied by the display bitmap are freed. * A converted sub bitmap is invalid until its parent is converted. */ void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP *tmp; ALLEGRO_STATE backup; size_t old_size; /* Do nothing if it is a memory bitmap already. */ if (bitmap->flags & ALLEGRO_MEMORY_BITMAP) return; if (bitmap->parent) { _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap); //al_realloc(bitmap, sizeof(ALLEGRO_BITMAP)); bitmap->display = NULL; bitmap->flags |= ALLEGRO_MEMORY_BITMAP; return; } ALLEGRO_DEBUG("converting display bitmap %p to memory bitmap\n", bitmap); /* Allocate a temporary bitmap which will hold the data * during the conversion process. */ al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(bitmap->format); tmp = create_memory_bitmap(bitmap->w, bitmap->h); /* Preserve bitmap contents. */ al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_set_target_bitmap(tmp); al_draw_bitmap(bitmap, 0, 0, 0); tmp->cb_excl = bitmap->cb_excl; tmp->cr_excl = bitmap->cr_excl; tmp->cl = bitmap->cl; tmp->ct = bitmap->ct; al_restore_state(&backup); /* Destroy the display bitmap to free driver-specific resources. */ if (bitmap->vt) bitmap->vt->destroy_bitmap(bitmap); _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap); /* Do not shrink the bitmap object. This way we can convert back to the * display bitmap. */ /*al_realloc(bitmap, tmp->size); bitmap->size = tmp->size*/ /* Put the contents back to the bitmap. */ old_size = bitmap->size; memcpy(bitmap, tmp, tmp->size); bitmap->size = old_size; al_free(tmp); } void _al_convert_bitmap_data( void *src, int src_format, int src_pitch, void *dst, int dst_format, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { ASSERT(src); ASSERT(dst); ASSERT(_al_pixel_format_is_real(dst_format)); /* Use memcpy if no conversion is needed. */ if (src_format == dst_format) { int y; int size = al_get_pixel_size(src_format); char *src_ptr = ((char *)src) + sy * src_pitch + sx * size; char *dst_ptr = ((char *)dst) + dy * dst_pitch + dx * size; width *= size; for (y = 0; y < height; y++) { memcpy(dst_ptr, src_ptr, width); src_ptr += src_pitch; dst_ptr += dst_pitch; } return; } (_al_convert_funcs[src_format][dst_format])(src, src_pitch, dst, dst_pitch, sx, sy, dx, dy, width, height); } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/file.c0000644000175000001440000002145312057121634014266 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File I/O routines. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_file.h" /* Function: al_fopen */ ALLEGRO_FILE *al_fopen(const char *path, const char *mode) { return al_fopen_interface(al_get_new_file_interface(), path, mode); } /* Function: al_fopen_interface */ ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv, const char *path, const char *mode) { ALLEGRO_FILE *f = NULL; ASSERT(drv); ASSERT(path); ASSERT(mode); if (drv->fi_fopen) { f = al_malloc(sizeof(*f)); if (!f) { al_set_errno(ENOMEM); } else { f->vtable = drv; f->userdata = drv->fi_fopen(path, mode); f->ungetc_len = 0; if (!f->userdata) { al_free(f); f = NULL; } } } return f; } /* Function: al_create_file_handle */ ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv, void *userdata) { ALLEGRO_FILE *f; ASSERT(drv); f = al_malloc(sizeof(*f)); if (!f) { al_set_errno(ENOMEM); } else { f->vtable = drv; f->userdata = userdata; f->ungetc_len = 0; } return f; } /* Function: al_fclose */ void al_fclose(ALLEGRO_FILE *f) { if (f) { f->vtable->fi_fclose(f); al_free(f); } } /* Function: al_fread */ size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { ASSERT(f); ASSERT(ptr); if (f->ungetc_len) { int bytes_ungetc = 0; unsigned char *cptr = ptr; while (f->ungetc_len > 0 && size > 0) { *cptr++ = f->ungetc[--f->ungetc_len]; ++bytes_ungetc; --size; } return bytes_ungetc + f->vtable->fi_fread(f, cptr, size); } else { return f->vtable->fi_fread(f, ptr, size); } } /* Function: al_fwrite */ size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) { ASSERT(f); ASSERT(ptr); f->ungetc_len = 0; return f->vtable->fi_fwrite(f, ptr, size); } /* Function: al_fflush */ bool al_fflush(ALLEGRO_FILE *f) { ASSERT(f); return f->vtable->fi_fflush(f); } /* Function: al_ftell */ int64_t al_ftell(ALLEGRO_FILE *f) { ASSERT(f); return f->vtable->fi_ftell(f) - f->ungetc_len; } /* Function: al_fseek */ bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) { ASSERT(f); /* offset can be negative */ ASSERT( whence == ALLEGRO_SEEK_SET || whence == ALLEGRO_SEEK_CUR || whence == ALLEGRO_SEEK_END ); if (f->ungetc_len) { if (whence == ALLEGRO_SEEK_CUR) { offset -= f->ungetc_len; } f->ungetc_len = 0; } return f->vtable->fi_fseek(f, offset, whence); } /* Function: al_feof */ bool al_feof(ALLEGRO_FILE *f) { ASSERT(f); return f->ungetc_len == 0 && f->vtable->fi_feof(f); } /* Function: al_ferror */ bool al_ferror(ALLEGRO_FILE *f) { ASSERT(f); return f->vtable->fi_ferror(f); } /* Function: al_fclearerr */ void al_fclearerr(ALLEGRO_FILE *f) { ASSERT(f); f->vtable->fi_fclearerr(f); } /* Function: al_fgetc */ int al_fgetc(ALLEGRO_FILE *f) { uint8_t c; ASSERT(f); if (al_fread(f, &c, 1) != 1) { return EOF; } return c; } /* Function: al_fputc */ int al_fputc(ALLEGRO_FILE *f, int c) { uint8_t b = (c & 0xff); ASSERT(f); if (al_fwrite(f, &b, 1) != 1) { return EOF; } return b; } /* Function: al_fread16le */ int16_t al_fread16le(ALLEGRO_FILE *f) { unsigned char b[2]; ASSERT(f); if (al_fread(f, b, 2) == 2) { return (((int16_t)b[1] << 8) | (int16_t)b[0]); } return EOF; } /* Function: al_fread32le */ int32_t al_fread32le(ALLEGRO_FILE *f) { unsigned char b[4]; ASSERT(f); if (al_fread(f, b, 4) == 4) { return (((int32_t)b[3] << 24) | ((int32_t)b[2] << 16) | ((int32_t)b[1] << 8) | (int32_t)b[0]); } return EOF; } /* Function: al_fwrite16le */ size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w) { uint8_t b1, b2; ASSERT(f); b1 = (w & 0xFF00) >> 8; b2 = w & 0x00FF; if (al_fputc(f, b2) == b2) { if (al_fputc(f, b1) == b1) { return 2; } return 1; } return 0; } /* Function: al_fwrite32le */ size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l) { uint8_t b1, b2, b3, b4; ASSERT(f); b1 = ((l & 0xFF000000L) >> 24); b2 = ((l & 0x00FF0000L) >> 16); b3 = ((l & 0x0000FF00L) >> 8); b4 = l & 0x00FF; if (al_fputc(f, b4) == b4) { if (al_fputc(f, b3) == b3) { if (al_fputc(f, b2) == b2) { if (al_fputc(f, b1) == b1) { return 4; } return 3; } return 2; } return 1; } return 0; } /* Function: al_fread16be */ int16_t al_fread16be(ALLEGRO_FILE *f) { unsigned char b[2]; ASSERT(f); if (al_fread(f, b, 2) == 2) { return (((int16_t)b[0] << 8) | (int16_t)b[1]); } return EOF; } /* Function: al_fread32be */ int32_t al_fread32be(ALLEGRO_FILE *f) { unsigned char b[4]; ASSERT(f); if (al_fread(f, b, 4) == 4) { return (((int32_t)b[0] << 24) | ((int32_t)b[1] << 16) | ((int32_t)b[2] << 8) | (int32_t)b[3]); } return EOF; } /* Function: al_fwrite16be */ size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w) { uint8_t b1, b2; ASSERT(f); b1 = (w & 0xFF00) >> 8; b2 = w & 0x00FF; if (al_fputc(f, b1) == b1) { if (al_fputc(f, b2) == b2) { return 2; } return 1; } return 0; } /* Function: al_fwrite32be */ size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l) { uint8_t b1, b2, b3, b4; ASSERT(f); b1 = ((l & 0xFF000000L) >> 24); b2 = ((l & 0x00FF0000L) >> 16); b3 = ((l & 0x0000FF00L) >> 8); b4 = l & 0x00FF; if (al_fputc(f, b1) == b1) { if (al_fputc(f, b2) == b2) { if (al_fputc(f, b3) == b3) { if (al_fputc(f, b4) == b4) { return 4; } return 3; } return 2; } return 1; } return 0; } /* Function: al_fgets */ char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max) { char *p = buf; int c; ASSERT(f); ASSERT(buf); /* Handle silly cases. */ if (max == 0) { return NULL; } if (max == 1) { *buf = '\0'; return buf; } /* Return NULL if already at end of file. */ if ((c = al_fgetc(f)) == EOF) { return NULL; } /* Fill buffer until empty, or we reach a newline or EOF or error. */ do { *p++ = c; max--; if (max == 1 || c == '\n') break; c = al_fgetc(f); } while (c != EOF); /* Return NULL on error. */ if (c == EOF && al_ferror(f)) { return NULL; } /* Add null terminator. */ ASSERT(max >= 1); *p = '\0'; return buf; } /* Function: al_fget_ustr */ ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f) { ALLEGRO_USTR *us; char buf[128]; if (!al_fgets(f, buf, sizeof(buf))) { return NULL; } us = al_ustr_new(""); do { al_ustr_append_cstr(us, buf); if (al_ustr_has_suffix_cstr(us, "\n")) break; } while (al_fgets(f, buf, sizeof(buf))); return us; } /* Function: al_fputs */ int al_fputs(ALLEGRO_FILE *f, char const *p) { size_t n; ASSERT(f); ASSERT(p); n = strlen(p); if (al_fwrite(f, p, n) != n) { return EOF; } return n; } /* Function: al_fungetc */ int al_fungetc(ALLEGRO_FILE *f, int c) { ASSERT(f != NULL); if (f->vtable->fi_fungetc) { return f->vtable->fi_fungetc(f, c); } else { /* If the interface does not provide an implementation for ungetc, * then a default one will be used. (Note that if the interface does * implement it, then this ungetc buffer will never be filled, and all * other references to it within this file will always be ignored.) */ if (f->ungetc_len == ALLEGRO_UNGETC_SIZE) { return EOF; } f->ungetc[f->ungetc_len++] = (unsigned char) c; return c; } } /* Function: al_fsize */ int64_t al_fsize(ALLEGRO_FILE *f) { ASSERT(f != NULL); return f->vtable->fi_fsize(f); } /* Function: al_get_file_userdata */ void *al_get_file_userdata(ALLEGRO_FILE *f) { ASSERT(f != NULL); return f->userdata; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/dtor.c0000644000175000001440000001443111465256750014327 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Destructors. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Destructors * * This file records a list of objects created by the user and/or Allegro * itself, that need to be destroyed when Allegro is shut down. Strictly * speaking, this list should not be necessary if the user is careful to * destroy all the objects he creates. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_tls.h" #include "allegro5/internal/aintern_vector.h" /* XXX The dependency on tls.c is not nice but the DllMain stuff for Windows * does not it easy to make abstract away TLS API differences. */ ALLEGRO_DEBUG_CHANNEL("dtor") struct _AL_DTOR_LIST { _AL_MUTEX mutex; _AL_VECTOR dtors; }; typedef struct DTOR { void *object; void (*func)(void*); } DTOR; /* Internal function: _al_init_destructors * Initialise a list of destructors. */ _AL_DTOR_LIST *_al_init_destructors(void) { _AL_DTOR_LIST *dtors = al_malloc(sizeof(*dtors)); _AL_MARK_MUTEX_UNINITED(dtors->mutex); _al_mutex_init(&dtors->mutex); _al_vector_init(&dtors->dtors, sizeof(DTOR)); return dtors; } /* _al_push_destructor_owner: * Increase the owner count for the current thread. When it is greater than * zero, _al_register_destructor will do nothing. * * This is required if an object to-be-registered (B) should be "owned" by an * object (A), which is responsible for destroying (B). (B) should not be * destroyed independently of (A). */ void _al_push_destructor_owner(void) { int *dtor_owner_count = _al_tls_get_dtor_owner_count(); (*dtor_owner_count)++; } /* _al_push_destructor_owner: * Decrease the owner count for the current thread. */ void _al_pop_destructor_owner(void) { int *dtor_owner_count = _al_tls_get_dtor_owner_count(); (*dtor_owner_count)--; ASSERT(*dtor_owner_count >= 0); } /* _al_run_destructors: * Run all the destructors on the list in reverse order. */ void _al_run_destructors(_AL_DTOR_LIST *dtors) { if (!dtors) { return; } /* call the destructors in reverse order */ _al_mutex_lock(&dtors->mutex); { while (!_al_vector_is_empty(&dtors->dtors)) { DTOR *dtor = _al_vector_ref_back(&dtors->dtors); void *object = dtor->object; void (*func)(void *) = dtor->func; ALLEGRO_DEBUG("calling dtor for object %p, func %p\n", object, func); _al_mutex_unlock(&dtors->mutex); { (*func)(object); } _al_mutex_lock(&dtors->mutex); } } _al_mutex_unlock(&dtors->mutex); } /* _al_shutdown_destructors: * Free the list of destructors. The list should be empty now. */ void _al_shutdown_destructors(_AL_DTOR_LIST *dtors) { if (!dtors) { return; } /* free resources used by the destructor subsystem */ ASSERT(_al_vector_size(&dtors->dtors) == 0); _al_vector_free(&dtors->dtors); _al_mutex_destroy(&dtors->mutex); al_free(dtors); } /* Internal function: _al_register_destructor * Register OBJECT to be destroyed by FUNC during Allegro shutdown. * This would be done in the object's constructor function. * * [thread-safe] */ void _al_register_destructor(_AL_DTOR_LIST *dtors, void *object, void (*func)(void*)) { int *dtor_owner_count; ASSERT(object); ASSERT(func); dtor_owner_count = _al_tls_get_dtor_owner_count(); if (*dtor_owner_count > 0) return; _al_mutex_lock(&dtors->mutex); { #ifdef DEBUGMODE /* make sure the object is not registered twice */ { unsigned int i; for (i = 0; i < _al_vector_size(&dtors->dtors); i++) { DTOR *dtor = _al_vector_ref(&dtors->dtors, i); ASSERT(dtor->object != object); } } #endif /* DEBUGMODE */ /* add the destructor to the list */ { DTOR *new_dtor = _al_vector_alloc_back(&dtors->dtors); if (new_dtor) { new_dtor->object = object; new_dtor->func = func; ALLEGRO_DEBUG("added dtor for object %p, func %p\n", object, func); } else { ALLEGRO_WARN("failed to add dtor for object %p\n", object); } } } _al_mutex_unlock(&dtors->mutex); } /* Internal function: _al_unregister_destructor * Unregister a previously registered object. This must be called * in the normal object destroyer routine, e.g. al_destroy_timer. * * [thread-safe] */ void _al_unregister_destructor(_AL_DTOR_LIST *dtors, void *object) { ASSERT(object); _al_mutex_lock(&dtors->mutex); { unsigned int i; for (i = 0; i < _al_vector_size(&dtors->dtors); i++) { DTOR *dtor = _al_vector_ref(&dtors->dtors, i); if (dtor->object == object) { _al_vector_delete_at(&dtors->dtors, i); ALLEGRO_DEBUG("removed dtor for object %p\n", object); break; } } /* We cannot assert that the destructor was found because it might not * have been registered if the owner count was non-zero at the time. */ } _al_mutex_unlock(&dtors->mutex); } /* Internal function: _al_foreach_destructor * Call the callback for each registered object. * [thread-safe] */ void _al_foreach_destructor(_AL_DTOR_LIST *dtors, void (*callback)(void *object, void (*func)(void *), void *udata), void *userdata) { _al_mutex_lock(&dtors->mutex); { unsigned int i; for (i = 0; i < _al_vector_size(&dtors->dtors); i++) { DTOR *dtor = _al_vector_ref(&dtors->dtors, i); callback(dtor->object, dtor->func, userdata); } } _al_mutex_unlock(&dtors->mutex); } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/keybdnu.c0000644000175000001440000002261212125160224015000 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New keyboard API. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Keyboard routines */ #define ALLEGRO_NO_COMPATIBILITY #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_system.h" /* the active keyboard driver */ static ALLEGRO_KEYBOARD_DRIVER *new_keyboard_driver = NULL; /* mode flags */ /* TODO: use the config system for these */ bool _al_three_finger_flag = true; bool _al_key_led_flag = true; /* Provide a default naming for the most common keys. Keys whose * mapping changes dependind on the layout aren't listed - it's up to * the keyboard driver to do that. All keyboard drivers should * provide their own implementation though, especially if they use * positional mapping. */ const char *_al_keyboard_common_names[/* leave empty */] = { "(none)", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "PAD 0", "PAD 1", "PAD 2", "PAD 3", "PAD 4", "PAD 5", "PAD 6", "PAD 7", "PAD 8", "PAD 9", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "ESCAPE", "KEY60", "KEY61", "KEY62", "BACKSPACE", "TAB", "KEY65", "KEY66", "ENTER", "KEY68", "KEY69", "BACKSLASH", "KEY71", "KEY72", "KEY73", "KEY74", "SPACE", "INSERT", "DELETE", "HOME", "END", "PGUP", "PGDN", "LEFT", "RIGHT", "UP", "DOWN", "PAD /", "PAD *", "PAD -", "PAD +", "PAD DELETE", "PAD ENTER", "PRINTSCREEN","PAUSE", "KEY94", "KEY95", "KEY96", "KEY97", "KEY98", "KEY99", "KEY100", "KEY101", "KEY102", "PAD =", "KEY104", "KEY105", "KEY106", "KEY107", "KEY108", "KEY109", "KEY110", "KEY111", "KEY112", "KEY113", "KEY114", "KEY115", "KEY116", "KEY117", "KEY118", "KEY119", "KEY120", "KEY121", "KEY122", "KEY123", "KEY124", "KEY125", "KEY126", "KEY127", "KEY128", "KEY129", "KEY130", "KEY131", "KEY132", "KEY133", "KEY134", "KEY135", "KEY136", "KEY137", "KEY138", "KEY139", "KEY140", "KEY141", "KEY142", "KEY143", "KEY144", "KEY145", "KEY146", "KEY147", "KEY148", "KEY149", "KEY150", "KEY151", "KEY152", "KEY153", "KEY154", "KEY155", "KEY156", "KEY157", "KEY158", "KEY159", "KEY160", "KEY161", "KEY162", "KEY163", "KEY164", "KEY165", "KEY166", "KEY167", "KEY168", "KEY169", "KEY170", "KEY171", "KEY172", "KEY173", "KEY174", "KEY175", "KEY176", "KEY177", "KEY178", "KEY179", "KEY180", "KEY181", "KEY182", "KEY183", "KEY184", "KEY185", "KEY186", "KEY187", "KEY188", "KEY189", "KEY190", "KEY191", "KEY192", "KEY193", "KEY194", "KEY195", "KEY196", "KEY197", "KEY198", "KEY199", "KEY200", "KEY201", "KEY202", "KEY203", "KEY204", "KEY205", "KEY206", "KEY207", "KEY208", "KEY209", "KEY210", "KEY211", "KEY212", "KEY213", "KEY214", "LSHIFT", "RSHIFT", "LCTRL", "RCTRL", "ALT", "ALTGR", "LWIN", "RWIN", "MENU", "SCROLLLOCK", "NUMLOCK", "CAPSLOCK" }; ALLEGRO_STATIC_ASSERT(keybdnu, sizeof(_al_keyboard_common_names) / sizeof(_al_keyboard_common_names[0]) == ALLEGRO_KEY_MAX); /* Function: al_is_keyboard_installed */ bool al_is_keyboard_installed(void) { return (new_keyboard_driver ? true : false); } /* Function: al_install_keyboard */ bool al_install_keyboard(void) { if (new_keyboard_driver) return true; //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now if (al_get_system_driver()->vt->get_keyboard_driver) { new_keyboard_driver = al_get_system_driver()->vt->get_keyboard_driver(); if (!new_keyboard_driver->init_keyboard()) { new_keyboard_driver = NULL; return false; } _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); return true; } return false; /* if (system_driver->keyboard_drivers) driver_list = system_driver->keyboard_drivers(); else driver_list = _al_keyboard_driver_list; for (i=0; driver_list[i].driver; i++) { new_keyboard_driver = driver_list[i].driver; name = get_config_text(new_keyboard_driver->keydrv_ascii_name); new_keyboard_driver->keydrv_name = name; new_keyboard_driver->keydrv_desc = name; if (new_keyboard_driver->init_keyboard()) break; } if (!driver_list[i].driver) { new_keyboard_driver = NULL; return false; } //set_leds(-1); _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); return true; */ } /* Function: al_uninstall_keyboard */ void al_uninstall_keyboard(void) { if (!new_keyboard_driver) return; //set_leds(-1); new_keyboard_driver->exit_keyboard(); new_keyboard_driver = NULL; } /* This was in the public API but its only purpose is now served by * al_get_keyboard_event_source(). */ static ALLEGRO_KEYBOARD *al_get_keyboard(void) { ASSERT(new_keyboard_driver); { ALLEGRO_KEYBOARD *kbd = new_keyboard_driver->get_keyboard(); ASSERT(kbd); return kbd; } } /* Function: al_set_keyboard_leds */ bool al_set_keyboard_leds(int leds) { ASSERT(new_keyboard_driver); if (new_keyboard_driver->set_keyboard_leds) return new_keyboard_driver->set_keyboard_leds(leds); return false; } /* Function: al_keycode_to_name */ const char *al_keycode_to_name(int keycode) { const char *name = NULL; ASSERT(new_keyboard_driver); ASSERT((keycode >= 0) && (keycode < ALLEGRO_KEY_MAX)); if (new_keyboard_driver->keycode_to_name) name = new_keyboard_driver->keycode_to_name(keycode); if (!name) name = _al_keyboard_common_names[keycode]; ASSERT(name); return name; } /* Function: al_get_keyboard_state */ void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { ASSERT(new_keyboard_driver); ASSERT(ret_state); new_keyboard_driver->get_keyboard_state(ret_state); } /* Function: al_key_down */ bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode) { return _AL_KEYBOARD_STATE_KEY_DOWN(*state, keycode); } /* Function: al_get_keyboard_event_source */ ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void) { ALLEGRO_KEYBOARD *keyboard = al_get_keyboard(); return (keyboard) ? &keyboard->es : NULL; } static int match_key_name(const char *s) { int i; /* Some key names are not intuitive, but this is all we've got. */ for (i = 1; i < ALLEGRO_KEY_MAX; i++) { if (0 == _al_stricmp(s, _al_keyboard_common_names[i])) return i; } return 0; } static unsigned int match_modifier(const char *s) { if (0 == _al_stricmp(s, "SHIFT")) return ALLEGRO_KEYMOD_SHIFT; if (0 == _al_stricmp(s, "CTRL")) return ALLEGRO_KEYMOD_CTRL; if (0 == _al_stricmp(s, "ALT")) return ALLEGRO_KEYMOD_ALT; if (0 == _al_stricmp(s, "LWIN")) return ALLEGRO_KEYMOD_LWIN; if (0 == _al_stricmp(s, "RWIN")) return ALLEGRO_KEYMOD_RWIN; if (0 == _al_stricmp(s, "ALTGR")) return ALLEGRO_KEYMOD_ALTGR; if (0 == _al_stricmp(s, "COMMAND")) return ALLEGRO_KEYMOD_COMMAND; return 0; } int _al_parse_key_binding(const char *s, unsigned int *modifiers) { ALLEGRO_USTR *us; unsigned start = 0; int keycode = 0; us = al_ustr_new(s); al_ustr_trim_ws(us); *modifiers = 0; while (start < al_ustr_size(us)) { /* XXX not all keys can be bound due to a conflict with the delimiter * characters */ int end = al_ustr_find_set_cstr(us, start, "+-"); unsigned int mod; /* Last component must be a key. */ if (end == -1) { keycode = match_key_name(al_cstr(us) + start); break; } /* Otherwise must be a modifier. */ al_ustr_set_chr(us, end, '\0'); mod = match_modifier(al_cstr(us) + start); if (!mod) { break; } (*modifiers) |= mod; start = end + 1; } al_ustr_free(us); return keycode; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/0000755000175000001440000000000012157230741013446 5ustar tjadenusersallegro-5.0.10/src/x/xsystem.c0000644000175000001440000001626212074124267015340 0ustar tjadenusers#ifdef DEBUG_X11 extern int _Xdebug; /* part of Xlib */ #endif #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xcursor.h" #include "allegro5/internal/aintern_xevents.h" #include "allegro5/internal/aintern_xfullscreen.h" #include "allegro5/internal/aintern_xkeyboard.h" #include "allegro5/internal/aintern_xmouse.h" #include "allegro5/internal/aintern_xsystem.h" #include "allegro5/platform/aintunix.h" #include "allegro5/platform/aintxglx.h" ALLEGRO_DEBUG_CHANNEL("system") static ALLEGRO_SYSTEM_INTERFACE *xglx_vt; static ALLEGRO_SYSTEM *xglx_initialize(int flags) { Display *x11display; Display *gfxdisplay; ALLEGRO_SYSTEM_XGLX *s; (void)flags; #ifdef DEBUG_X11 _Xdebug = 1; #endif XInitThreads(); /* Get an X11 display handle. */ x11display = XOpenDisplay(0); if (x11display) { /* Never ask. */ gfxdisplay = XOpenDisplay(0); if (!gfxdisplay) { ALLEGRO_ERROR("XOpenDisplay failed second time.\n"); XCloseDisplay(x11display); return NULL; } } else { ALLEGRO_INFO("XOpenDisplay failed; assuming headless mode.\n"); gfxdisplay = NULL; } _al_unix_init_time(); s = al_calloc(1, sizeof *s); _al_mutex_init_recursive(&s->lock); _al_cond_init(&s->resized); s->inhibit_screensaver = false; _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY_XGLX *)); s->gfxdisplay = gfxdisplay; s->x11display = x11display; s->system.vt = xglx_vt; if (s->x11display) { ALLEGRO_INFO("XGLX driver connected to X11 (%s %d).\n", ServerVendor(s->x11display), VendorRelease(s->x11display)); ALLEGRO_INFO("X11 protocol version %d.%d.\n", ProtocolVersion(s->x11display), ProtocolRevision(s->x11display)); /* We need to put *some* atom into the ClientMessage we send for * faking mouse movements with al_set_mouse_xy - so let's ask X11 * for one here. */ s->AllegroAtom = XInternAtom(x11display, "AllegroAtom", False); _al_thread_create(&s->thread, _al_xwin_background_thread, s); ALLEGRO_INFO("events thread spawned.\n"); } return &s->system; } static void xglx_shutdown_system(void) { ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); if (sx->x11display) { /* Events thread only runs if we are connected to an X server. */ _al_thread_join(&sx->thread); } /* Close all open displays. */ while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); // Makes sure we wait for any commands sent to the X server when destroying the displays. // Should make sure we don't shutdown before modes are restored. if (sx->x11display) { XSync(sx->x11display, False); } _al_xsys_mmon_exit(sx); if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; ALLEGRO_DEBUG("xsys: close x11display.\n"); } if (sx->gfxdisplay) { XCloseDisplay(sx->gfxdisplay); sx->gfxdisplay = None; } al_free(sx); } static ALLEGRO_DISPLAY_INTERFACE *xglx_get_display_driver(void) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); /* Look up the toggle_mouse_grab_key binding. This isn't such a great place * to do it, but the config file is not available until after the system driver * is initialised. */ if (system->system.config && !system->toggle_mouse_grab_keycode) { const char *binding = al_get_config_value(system->system.config, "keyboard", "toggle_mouse_grab_key"); if (binding) { system->toggle_mouse_grab_keycode = _al_parse_key_binding(binding, &system->toggle_mouse_grab_modifiers); if (system->toggle_mouse_grab_keycode) { ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding); } else { ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding); } } } return _al_display_xglx_driver(); } static ALLEGRO_KEYBOARD_DRIVER *xglx_get_keyboard_driver(void) { return _al_xwin_keyboard_driver(); } static ALLEGRO_MOUSE_DRIVER *xglx_get_mouse_driver(void) { return _al_xwin_mouse_driver(); } static ALLEGRO_JOYSTICK_DRIVER *xglx_get_joystick_driver(void) { return _al_joystick_driver_list[0].driver; } static int xglx_get_num_video_adapters(void) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); return _al_xglx_get_num_video_adapters(system); } static bool xglx_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); return _al_xglx_get_monitor_info(system, adapter, info); } static bool xglx_get_cursor_position(int *ret_x, int *ret_y) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); Window root = RootWindow(system->x11display, 0); Window child; int wx, wy; unsigned int mask; _al_mutex_lock(&system->lock); XQueryPointer(system->x11display, root, &root, &child, ret_x, ret_y, &wx, &wy, &mask); _al_mutex_unlock(&system->lock); return true; } static bool xglx_inhibit_screensaver(bool inhibit) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); system->inhibit_screensaver = inhibit; return true; } static int xglx_get_num_display_modes(void) { int adapter = al_get_new_display_adapter(); ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); return _al_xglx_get_num_display_modes(s, adapter); } static ALLEGRO_DISPLAY_MODE *xglx_get_display_mode(int mode, ALLEGRO_DISPLAY_MODE *dm) { int adapter = al_get_new_display_adapter(); ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); return _al_xglx_get_display_mode(s, adapter, mode, dm); } /* Internal function to get a reference to this driver. */ ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void) { if (xglx_vt) return xglx_vt; xglx_vt = al_calloc(1, sizeof *xglx_vt); xglx_vt->initialize = xglx_initialize; xglx_vt->get_display_driver = xglx_get_display_driver; xglx_vt->get_keyboard_driver = xglx_get_keyboard_driver; xglx_vt->get_mouse_driver = xglx_get_mouse_driver; xglx_vt->get_joystick_driver = xglx_get_joystick_driver; xglx_vt->get_num_display_modes = xglx_get_num_display_modes; xglx_vt->get_display_mode = xglx_get_display_mode; xglx_vt->shutdown_system = xglx_shutdown_system; xglx_vt->get_num_video_adapters = xglx_get_num_video_adapters; xglx_vt->get_monitor_info = xglx_get_monitor_info; xglx_vt->create_mouse_cursor = _al_xwin_create_mouse_cursor; xglx_vt->destroy_mouse_cursor = _al_xwin_destroy_mouse_cursor; xglx_vt->get_cursor_position = xglx_get_cursor_position; xglx_vt->grab_mouse = _al_xwin_grab_mouse; xglx_vt->ungrab_mouse = _al_xwin_ungrab_mouse; xglx_vt->get_path = _al_unix_get_path; xglx_vt->inhibit_screensaver = xglx_inhibit_screensaver; return xglx_vt; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/xcursor.c0000644000175000001440000001764212104442100015313 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xcursor.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xsystem.h" #include #ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR #include #else /* This requirement could be lifted for compatibility with older systems at the * expense of functionality, but it's probably not worthwhile. */ #error This file requires Xcursor. #endif ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); Display *xdisplay = system->x11display; int bmp_w; int bmp_h; ALLEGRO_MOUSE_CURSOR_XWIN *xcursor; XcursorImage *image; int c, ix, iy; bool was_locked; bmp_w = al_get_bitmap_width(bmp); bmp_h = al_get_bitmap_height(bmp); xcursor = al_malloc(sizeof *xcursor); if (!xcursor) { return NULL; } image = XcursorImageCreate(bmp->w, bmp->h); if (image == None) { al_free(xcursor); return NULL; } was_locked = al_is_bitmap_locked(bmp); if (!was_locked) { al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); } c = 0; for (iy = 0; iy < bmp_h; iy++) { for (ix = 0; ix < bmp_w; ix++) { ALLEGRO_COLOR col; unsigned char r, g, b, a; col = al_get_pixel(bmp, ix, iy); al_unmap_rgba(col, &r, &g, &b, &a); image->pixels[c++] = (a<<24) | (r<<16) | (g<<8) | (b); } } if (!was_locked) { al_unlock_bitmap(bmp); } image->xhot = x_focus; image->yhot = y_focus; _al_mutex_lock(&system->lock); xcursor->cursor = XcursorImageLoadCursor(xdisplay, image); _al_mutex_unlock(&system->lock); XcursorImageDestroy(image); return (ALLEGRO_MOUSE_CURSOR *)xcursor; } void _al_xwin_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_MOUSE_CURSOR_XWIN *xcursor = (ALLEGRO_MOUSE_CURSOR_XWIN *)cursor; ALLEGRO_SYSTEM *sys = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sysx = (ALLEGRO_SYSTEM_XGLX *)sys; unsigned i; _al_mutex_lock(&sysx->lock); for (i = 0; i < _al_vector_size(&sys->displays); i++) { ALLEGRO_DISPLAY_XGLX **slot = _al_vector_ref(&sys->displays, i); ALLEGRO_DISPLAY_XGLX *glx = *slot; if (glx->current_cursor == xcursor->cursor) { if (!glx->cursor_hidden) XUndefineCursor(sysx->x11display, glx->window); glx->current_cursor = None; } } XFreeCursor(sysx->x11display, xcursor->cursor); al_free(xcursor); _al_mutex_unlock(&sysx->lock); } static bool xdpy_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; ALLEGRO_MOUSE_CURSOR_XWIN *xcursor = (ALLEGRO_MOUSE_CURSOR_XWIN *)cursor; ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); Display *xdisplay = system->x11display; Window xwindow = glx->window; glx->current_cursor = xcursor->cursor; if (!glx->cursor_hidden) { _al_mutex_lock(&system->lock); XDefineCursor(xdisplay, xwindow, glx->current_cursor); _al_mutex_unlock(&system->lock); } return true; } static bool xdpy_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); Display *xdisplay = system->x11display; Window xwindow = glx->window; unsigned int cursor_shape; switch (cursor_id) { case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: cursor_shape = XC_left_ptr; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: cursor_shape = XC_watch; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: cursor_shape = XC_question_arrow; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: cursor_shape = XC_xterm; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE: cursor_shape = XC_fleur; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: cursor_shape = XC_top_side; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: cursor_shape = XC_bottom_side; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: cursor_shape = XC_right_side; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: cursor_shape = XC_left_side; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: cursor_shape = XC_top_right_corner; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: cursor_shape = XC_bottom_left_corner; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: cursor_shape = XC_top_left_corner; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: cursor_shape = XC_bottom_right_corner; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: cursor_shape = XC_crosshair; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: cursor_shape = XC_hand2; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: cursor_shape = XC_hand1; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: cursor_shape = XC_X_cursor; break; default: return false; } _al_mutex_lock(&system->lock); glx->current_cursor = XCreateFontCursor(xdisplay, cursor_shape); /* XXX: leak? */ if (!glx->cursor_hidden) { XDefineCursor(xdisplay, xwindow, glx->current_cursor); } _al_mutex_unlock(&system->lock); return true; } /* Show the system mouse cursor. */ static bool xdpy_show_mouse_cursor(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_XGLX *glx = (void *)display; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); Display *xdisplay = system->x11display; Window xwindow = glx->window; if (!glx->cursor_hidden) return true; _al_mutex_lock(&system->lock); XDefineCursor(xdisplay, xwindow, glx->current_cursor); glx->cursor_hidden = false; _al_mutex_unlock(&system->lock); return true; } /* Hide the system mouse cursor. */ static bool xdpy_hide_mouse_cursor(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_XGLX *glx = (void *)display; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); Display *xdisplay = system->x11display; Window xwindow = glx->window; if (glx->cursor_hidden) return true; _al_mutex_lock(&system->lock); if (glx->invisible_cursor == None) { unsigned long gcmask; XGCValues gcvalues; Pixmap pixmap = XCreatePixmap(xdisplay, xwindow, 1, 1, 1); GC temp_gc; XColor color; gcmask = GCFunction | GCForeground | GCBackground; gcvalues.function = GXcopy; gcvalues.foreground = 0; gcvalues.background = 0; temp_gc = XCreateGC(xdisplay, pixmap, gcmask, &gcvalues); XDrawPoint(xdisplay, pixmap, temp_gc, 0, 0); XFreeGC(xdisplay, temp_gc); color.pixel = 0; color.red = color.green = color.blue = 0; color.flags = DoRed | DoGreen | DoBlue; glx->invisible_cursor = XCreatePixmapCursor(xdisplay, pixmap, pixmap, &color, &color, 0, 0); XFreePixmap(xdisplay, pixmap); } XDefineCursor(xdisplay, xwindow, glx->invisible_cursor); glx->cursor_hidden = true; _al_mutex_unlock(&system->lock); return true; } void _al_xwin_add_cursor_functions(ALLEGRO_DISPLAY_INTERFACE *vt) { vt->set_mouse_cursor = xdpy_set_mouse_cursor; vt->set_system_mouse_cursor = xdpy_set_system_mouse_cursor; vt->show_mouse_cursor = xdpy_show_mouse_cursor; vt->hide_mouse_cursor = xdpy_hide_mouse_cursor; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/icon.xpm0000644000175000001440000000511310655104526015126 0ustar tjadenusers/* XPM */ static char *icon_xpm[] = { "48 48 6 1", " c None", ". c #080808", "+ c #FCFCFC", "@ c #486028", "# c #587834", "$ c #A4C47C", " .... .... ", " .... .... ", " .++++.. .++++.. ", " .++++.. .++++.. ", " ...... ...++.......++... ", " ...... ...++.......++... ", "..@@####............@@###....##@.. ", "..@@####............@@###....##@.. ", "..###########################..#@@.. ", "..###########################..#@@.. ", ".............................#####.. ", ".............................#####.. ", " ...#########@@.. ", " ......#####..#######.. ", " ......#####..#######.. ", " .....######.....$$#######.. ", " .....######.....$$#######.. ", " .....#####...... ..$$#######.. ", " .....#####...... ..$$#######.. ", " ..#####..... .$$##..###@@.. ", " ..#####..... .$$##..###@@.. ", " ..... .......###@@.. ", " ..... .......###@@.. ", " ..#########.@@.. ", " ..##.......@##.. ", " ..##.......@##.. ", " ...$$$$#####.. ", " ...$$$$#####.. ", " .$$$$#####.. .. ", " .$$$$#####.. .. ", " .$$$$#####.. ..@@.", " .$$$$#####.. ..@@.", " .$$..#####@@.. ..@@.", " .$$..#####@@.. ..@@.", " ..####@..##.. ..##@@.", " ..####@..##.. ..##@@.", " ..####@..####...##@@$$.", " .####@@.$$#######@@$$.. ", " .####@@.$$#######@@$$.. ", " .##@@.....$$$$$$$$$.. ", " .##@@.....$$$$$$$$$.. ", " ..##@@............ ", " ..##@@............ ", " ...######.@@.. ", " ...######.@@.. ", " ..#####@@###..@@.. ", " ..#####@@###..@@.. ", " .................. "}; allegro-5.0.10/src/x/xrandr.c0000644000175000001440000007147212104442100015105 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xfullscreen.h" #include "allegro5/internal/aintern_xsystem.h" #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR ALLEGRO_DEBUG_CHANNEL("xrandr") typedef struct xrandr_screen xrandr_screen; typedef struct xrandr_crtc xrandr_crtc; typedef struct xrandr_output xrandr_output; typedef struct xrandr_mode xrandr_mode; struct xrandr_screen { int id; Time timestamp; Time configTimestamp; _AL_VECTOR crtcs; // xrandr_crtc _AL_VECTOR outputs; // xrandr_output _AL_VECTOR modes; // xrandr_mode XRRScreenResources *res; }; enum xrandr_crtc_position { CRTC_POS_NONE = 0, CRTC_POS_ABOVE, CRTC_POS_LEFTOF, CRTC_POS_BELOW, CRTC_POS_RIGHTOF }; struct xrandr_crtc { RRCrtc id; Time timestamp; int x, y; unsigned int width, height; RRMode mode; Rotation rotation; _AL_VECTOR connected; _AL_VECTOR possible; RRMode original_mode; int original_xoff; int original_yoff; RRCrtc align_to; int align; }; struct xrandr_output { RROutput id; Time timestamp; RRCrtc crtc; char *name; int namelen; unsigned long mm_width; unsigned long mm_height; Connection connection; SubpixelOrder subpixel_order; _AL_VECTOR crtcs; // RRCrtc _AL_VECTOR clones; // RROutput RRMode prefered_mode; _AL_VECTOR modes; // RRMode }; struct xrandr_mode { RRMode id; unsigned int width; unsigned int height; unsigned int refresh; }; struct xrandr_rect { int x1; int y1; int x2; int y2; }; static void xrandr_copy_mode(xrandr_mode *mode, XRRModeInfo *rrmode) { mode->id = rrmode->id; mode->width = rrmode->width; mode->height = rrmode->height; if (rrmode->hTotal && rrmode->vTotal) { mode->refresh = ((float) rrmode->dotClock / ((float) rrmode->hTotal * (float) rrmode->vTotal)); } else { mode->refresh = 0; } } static void xrandr_clear_fake_refresh_rates(xrandr_mode *modes, int nmode) { int i; if (nmode < 2) return; /* The Nvidia proprietary driver may return fake refresh rates when * DynamicTwinView is enabled, so that all modes are unique. The user has * no use for that wrong information so zero it out if we detect it. */ for (i = 1; i < nmode; i++) { if (modes[i].refresh != modes[i-1].refresh + 1) { return; } } ALLEGRO_WARN("Zeroing out fake refresh rates from nvidia proprietary driver.\n"); ALLEGRO_WARN("Disable the DynamicTwinView driver option to avoid this.\n"); for (i = 0; i < nmode; i++) { modes[i].refresh = 0; } } static void xrandr_copy_output(xrandr_output *output, RROutput id, XRROutputInfo *rroutput) { output->id = id; output->timestamp = rroutput->timestamp; output->crtc = rroutput->crtc; output->name = strdup(rroutput->name); output->namelen = rroutput->nameLen; output->mm_width = rroutput->mm_width; output->mm_height = rroutput->mm_height; output->connection = rroutput->connection; output->subpixel_order = rroutput->subpixel_order; ALLEGRO_DEBUG("output[%s] %s on crtc %i.\n", output->name, output->connection == RR_Connected ? "Connected" : "Not Connected", (int)output->crtc); _al_vector_init(&output->crtcs, sizeof(RRCrtc)); if(rroutput->ncrtc) { _al_vector_append_array(&output->crtcs, rroutput->ncrtc, rroutput->crtcs); } _al_vector_init(&output->clones, sizeof(RROutput)); if(rroutput->nclone) { _al_vector_append_array(&output->clones, rroutput->nclone, rroutput->clones); } _al_vector_init(&output->modes, sizeof(RRMode)); if(rroutput->nmode) { _al_vector_append_array(&output->modes, rroutput->nmode, rroutput->modes); } /* npreferred isn't the prefered mode index, it's the number of prefered modes * starting from 0. So just load up the first prefered mode. * We don't actually use it yet anyway, so it's not really important. */ if(rroutput->npreferred) { output->prefered_mode = rroutput->modes[0]; } } static void xrandr_copy_crtc(xrandr_crtc *crtc, RRCrtc id, XRRCrtcInfo *rrcrtc) { crtc->id = id; crtc->timestamp = rrcrtc->timestamp; crtc->x = rrcrtc->x; crtc->y = rrcrtc->y; crtc->width = rrcrtc->width; crtc->height = rrcrtc->height; crtc->mode = rrcrtc->mode; crtc->rotation = rrcrtc->rotation; _al_vector_init(&crtc->connected, sizeof(RROutput)); if(rrcrtc->noutput) { _al_vector_append_array(&crtc->connected, rrcrtc->noutput, rrcrtc->outputs); } ALLEGRO_DEBUG("found %i outputs.\n", rrcrtc->noutput); _al_vector_init(&crtc->possible, sizeof(RROutput)); if(rrcrtc->npossible) { _al_vector_append_array(&crtc->possible, rrcrtc->npossible, rrcrtc->possible); int i; for(i = 0; i < rrcrtc->npossible; i++) { ALLEGRO_DEBUG("output[%i] %i.\n", i, (int)rrcrtc->possible[i]); } } crtc->original_mode = crtc->mode; crtc->original_xoff = crtc->x; crtc->original_yoff = crtc->y; crtc->align_to = 0; crtc->align = CRTC_POS_NONE; } static void xrandr_copy_screen(ALLEGRO_SYSTEM_XGLX *s, xrandr_screen *screen, XRRScreenResources *res) { int j; _al_vector_init(&screen->modes, sizeof(xrandr_mode)); if(res->nmode) { for(j = 0; j < res->nmode; j++) { xrandr_mode *mode = _al_vector_alloc_back(&screen->modes); xrandr_copy_mode(mode, &res->modes[j]); } xrandr_clear_fake_refresh_rates(_al_vector_ref_front(&screen->modes), res->nmode); } _al_vector_init(&screen->crtcs, sizeof(xrandr_crtc)); if(res->ncrtc) { ALLEGRO_DEBUG("found %i crtcs.\n", res->ncrtc); for(j = 0; j < res->ncrtc; j++) { ALLEGRO_DEBUG("crtc[%i] %i.\n", j, (int)res->crtcs[j]); xrandr_crtc *crtc = _al_vector_alloc_back(&screen->crtcs); XRRCrtcInfo *rrcrtc = XRRGetCrtcInfo(s->x11display, res, res->crtcs[j]); xrandr_copy_crtc(crtc, res->crtcs[j], rrcrtc); XRRFreeCrtcInfo(rrcrtc); } } _al_vector_init(&screen->outputs, sizeof(xrandr_output)); if(res->noutput) { ALLEGRO_DEBUG("found %i outputs.\n", res->noutput); for(j = 0; j < res->noutput; j++) { ALLEGRO_DEBUG("output[%i] %i.\n", j, (int)res->outputs[j]); xrandr_output *output = _al_vector_alloc_back(&screen->outputs); XRROutputInfo *rroutput = XRRGetOutputInfo(s->x11display, res, res->outputs[j]); xrandr_copy_output(output, res->outputs[j], rroutput); XRRFreeOutputInfo(rroutput); XSync(s->x11display, False); } } } static xrandr_crtc *xrandr_fetch_crtc(ALLEGRO_SYSTEM_XGLX *s, int sid, RRCrtc id) { unsigned int i; xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); for(i = 0; i < _al_vector_size(&screen->crtcs); i++) { xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, i); if(crtc->id == id) return crtc; } return NULL; } static xrandr_output *xrandr_fetch_output(ALLEGRO_SYSTEM_XGLX *s, int sid, RROutput id) { unsigned int i; xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); for(i = 0; i < _al_vector_size(&screen->outputs); i++) { xrandr_output *output = _al_vector_ref(&screen->outputs, i); if(output->id == id) return output; } return NULL; } static xrandr_mode *xrandr_fetch_mode(ALLEGRO_SYSTEM_XGLX *s, int sid, RRMode id) { unsigned int i; xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); for(i = 0; i < _al_vector_size(&screen->modes); i++) { xrandr_mode *mode = _al_vector_ref(&screen->modes, i); if(mode->id == id) return mode; } return NULL; } static inline xrandr_crtc *xrandr_map_to_crtc(ALLEGRO_SYSTEM_XGLX *s, int sid, int adapter) { return xrandr_fetch_crtc(s, sid, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, adapter)); } static inline xrandr_output *xrandr_map_adapter(ALLEGRO_SYSTEM_XGLX *s, int sid, int adapter) { xrandr_crtc *crtc = xrandr_map_to_crtc(s, sid, adapter); return xrandr_fetch_output(s, sid, *(RROutput*)_al_vector_ref(&crtc->connected, 0)); } static void xrandr_combine_output_rect(struct xrandr_rect *rect, xrandr_crtc *crtc) { if(rect->x1 > crtc->x) rect->x1 = crtc->x; if(rect->y1 > crtc->y) rect->y1 = crtc->y; if(crtc->x + (int)crtc->width > rect->x2) rect->x2 = crtc->x + crtc->width; if(crtc->y + (int)crtc->height > rect->y2) rect->y2 = crtc->y + crtc->height; } /* begin vtable methods */ static int xrandr_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); static bool xrandr_query(ALLEGRO_SYSTEM_XGLX *s) { int screen_count = ScreenCount(s->x11display); int i; bool ret = true; _al_vector_init(&s->xrandr_screens, sizeof(xrandr_screen)); _al_vector_init(&s->xrandr_adaptermap, sizeof(RROutput)); for(i = 0; i < screen_count; i++) { xrandr_screen *screen = _al_vector_alloc_back(&s->xrandr_screens); XRRScreenResources *res = XRRGetScreenResources(s->x11display, XRootWindow(s->x11display, i)); if(!res) { ALLEGRO_DEBUG("failed to get screen resources for screen %i\n", i); continue; } if(!res->noutput) { ALLEGRO_DEBUG("screen %i doesn't have any outputs.\n", i); continue; } xrandr_copy_screen(s, screen, res); screen->res = res; /* Detect clones */ int j; for(j = 0; j < (int)_al_vector_size(&screen->crtcs); j++) { xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, j); /* Skip crtc with no connected outputs. */ if(_al_vector_size(&crtc->connected) < 1) continue; // XXX it might be nessesary to do something more clever about detecting clones // XXX for now I'm going with a plain origin test, it aught to work for most cases. // the other alternative is to check the crtc's connected outputs's clone's list... // sounds like pain to me. int k; bool not_clone = true; for(k = 0; k < j; k++) { xrandr_crtc *crtc_k = _al_vector_ref(&screen->crtcs, k); /* Skip crtc with no connected outputs. */ if(_al_vector_size(&crtc_k->connected) < 1) continue; if(crtc->x == crtc_k->x && crtc->y == crtc_k->y) not_clone = false; } if(not_clone) { RRCrtc *crtc_ptr = _al_vector_alloc_back(&s->xrandr_adaptermap); ALLEGRO_DEBUG("Map Allegro Adadpter %i to RandR CRTC %i.\n", (int)(_al_vector_size(&s->xrandr_adaptermap)-1), (int)crtc->id); *crtc_ptr = crtc->id; } else { ALLEGRO_DEBUG("RandR CRTC %i is a clone, ignoring.\n", (int)crtc->id); } } int mask = RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask; XRRSelectInput( s->x11display, RootWindow(s->x11display, i), 0); XRRSelectInput( s->x11display, RootWindow(s->x11display, i), mask); } /* map out crtc positions and alignments */ /* this code makes Adapter 0 the root display, everything will hang off it */ for(i = 1; i < (int)_al_vector_size(&s->xrandr_adaptermap); i++) { int xscreen = xrandr_get_xscreen(s, i); xrandr_crtc *crtc = xrandr_fetch_crtc(s, xscreen, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, i)); int j; for(j = 0; j < (int)_al_vector_size(&s->xrandr_adaptermap); j++) { int xscreen_j = xrandr_get_xscreen(s, j); xrandr_crtc *crtc_j = xrandr_fetch_crtc(s, xscreen_j, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, j)); if(crtc->x == crtc_j->x + (int)crtc_j->width) { crtc->align_to = crtc_j->id; crtc->align = CRTC_POS_RIGHTOF; ALLEGRO_DEBUG("Adapter %i is RightOf Adapter %i.\n", i, j); } else if(crtc->x + (int)crtc->width == crtc_j->x) { crtc->align_to = crtc_j->id; crtc->align = CRTC_POS_LEFTOF; ALLEGRO_DEBUG("Adapter %i is LeftOf Adapter %i.\n", i, j); } else if(crtc->y == crtc_j->y + (int)crtc_j->height) { crtc->align_to = crtc_j->id; crtc->align = CRTC_POS_BELOW; ALLEGRO_DEBUG("Adapter %i is Below Adapter %i.\n", i, j); } else if(crtc->y + (int)crtc->height == crtc_j->y) { crtc->align_to = crtc_j->id; crtc->align = CRTC_POS_ABOVE; ALLEGRO_DEBUG("Adapter %i is Above Adapter %i.\n", i, j); } } } #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available && s->xinerama_screen_count != (int)_al_vector_size(&s->xrandr_adaptermap)) { ALLEGRO_WARN("XRandR and Xinerama seem to disagree on how many screens there are (%i vs %i), going to ignore XRandR.\n", (int)_al_vector_size(&s->xrandr_adaptermap), s->xinerama_screen_count); // only actually going to ignore the output count, and setting of modes on the extra xinerama screens. ret = false; } #endif return ret; } static int xrandr_get_num_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) { if(adapter < 0 || adapter >= (int)_al_vector_size(&s->xrandr_adaptermap)) return 0; int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); return _al_vector_size(&output->modes); } static ALLEGRO_DISPLAY_MODE *xrandr_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int id, ALLEGRO_DISPLAY_MODE *amode) { int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); if(id < 0 || id > (int)_al_vector_size(&output->modes)) return NULL; xrandr_mode *mode = xrandr_fetch_mode(s, xscreen, *(RRMode*)_al_vector_ref(&output->modes, id)); amode->width = mode->width; amode->height = mode->height; amode->format = 0; amode->refresh_rate = mode->refresh; return amode; } static bool xrandr_realign_crtc_origin(ALLEGRO_SYSTEM_XGLX *s, int xscreen, xrandr_crtc *crtc, int new_w, int new_h, int *x, int *y) { bool ret; if(crtc->align_to == 0) return false; xrandr_crtc *align_to = xrandr_fetch_crtc(s, xscreen, crtc->align_to); switch(crtc->align) { case CRTC_POS_RIGHTOF: *x = align_to->x + align_to->width; *y = align_to->y; ret = true; break; case CRTC_POS_LEFTOF: *x = align_to->x - new_w; *y = align_to->y; ret = true; break; case CRTC_POS_BELOW: *x = align_to->x; *y = align_to->y + align_to->height; ret = true; break; case CRTC_POS_ABOVE: *x = align_to->x; *y = align_to->y - new_h; ret = true; break; default: ALLEGRO_WARN("unknown crtc alignment flag (%i)!", crtc->align); ret = false; break; } return ret; } static bool xrandr_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh) { int adapter = _al_xglx_get_adapter(s, d, false); int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen); xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); xrandr_mode *cur_mode = xrandr_fetch_mode(s, xscreen, crtc->mode); if((int)cur_mode->width == w && (int)cur_mode->height == h && (refresh == 0 || refresh == (int)cur_mode->refresh)) { ALLEGRO_DEBUG("mode already set, good to go\n"); return true; } else { ALLEGRO_DEBUG("new mode: %dx%d@%d old mode: %dx%d@%d.\n", w, h, refresh, cur_mode->width, cur_mode->height, cur_mode->refresh); } int mode_idx = _al_xglx_fullscreen_select_mode(s, adapter, w, h, format, refresh); if(mode_idx == -1) { ALLEGRO_DEBUG("mode %dx%d@%d not found\n", w, h, refresh); return false; } xrandr_output *output = xrandr_fetch_output(s, xscreen, *(RROutput*)_al_vector_ref(&crtc->connected, 0)); xrandr_mode *mode = xrandr_fetch_mode(s, xscreen, *(RRMode*)_al_vector_ref(&output->modes, mode_idx)); int new_x = crtc->x, new_y = crtc->y; xrandr_realign_crtc_origin(s, xscreen, crtc, w, h, &new_x, &new_y); ALLEGRO_DEBUG("xrandr: set mode %i+%i-%ix%i on adapter %i\n", new_x, new_y, w, h, adapter); _al_mutex_lock(&s->lock); int ok = XRRSetCrtcConfig( s->x11display, screen->res, crtc->id, crtc->timestamp, new_x, new_y, mode->id, crtc->rotation, _al_vector_ref_front(&crtc->connected), _al_vector_size(&crtc->connected) ); if (ok != RRSetConfigSuccess) { ALLEGRO_ERROR("XRandR failed to set mode.\n"); _al_mutex_unlock(&s->lock); return false; } /* make sure the virtual screen size is large enough after setting our mode */ int i; struct xrandr_rect rect = { 0, 0, 0, 0 }; for(i = 0; i < (int)_al_vector_size(&screen->crtcs); i++) { xrandr_crtc *c = _al_vector_ref(&screen->crtcs, i); if(_al_vector_size(&c->connected) > 0) { xrandr_combine_output_rect(&rect, crtc); } } int new_width = rect.x2 - rect.x1; int new_height = rect.y2 - rect.y1; if(new_width > DisplayWidth(s->x11display, xscreen) || new_height > DisplayHeight(s->x11display, xscreen)) { XRRSetScreenSize(s->x11display, RootWindow(s->x11display, xscreen), new_width, new_height, DisplayWidthMM(s->x11display, xscreen), DisplayHeightMM(s->x11display, xscreen)); } _al_mutex_unlock(&s->lock); return true; } static void xrandr_restore_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) { int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen); xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); if(crtc->mode == crtc->original_mode) { ALLEGRO_DEBUG("current crtc mode (%i) equals the original mode (%i), not restoring.\n", (int)crtc->mode, (int)crtc->original_mode); return; } xrandr_mode *orig_mode = xrandr_fetch_mode(s, xscreen, crtc->original_mode); ALLEGRO_DEBUG("restore mode %i+%i-%ix%i@%i on adapter %i\n", crtc->original_xoff, crtc->original_yoff, orig_mode->width, orig_mode->height, orig_mode->refresh, adapter); _al_mutex_lock(&s->lock); int ok = XRRSetCrtcConfig ( s->x11display, screen->res, crtc->id, crtc->timestamp, crtc->original_xoff, crtc->original_yoff, orig_mode->id, crtc->rotation, _al_vector_ref_front(&crtc->connected), _al_vector_size(&crtc->connected) ); if(ok != RRSetConfigSuccess) { ALLEGRO_ERROR("failed to restore mode.\n"); } // XSync(s->x11display, False); _al_mutex_unlock(&s->lock); } static void xrandr_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) { int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); // XXX Should we always return original_[xy]off here? // When does a user want to query the offset after the modes are set? *x = crtc->x; *y = crtc->y; ALLEGRO_DEBUG("display offset: %ix%i.\n", *x, *y); } static int xrandr_get_num_adapters(ALLEGRO_SYSTEM_XGLX *s) { return _al_vector_size(&s->xrandr_adaptermap); } static bool xrandr_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) { if(adapter < 0 || adapter >= (int)_al_vector_size(&s->xrandr_adaptermap)) return false; int xscreen = _al_xglx_get_xscreen(s, adapter); xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); xrandr_crtc *crtc = xrandr_fetch_crtc(s, xscreen, output->crtc); mi->x1 = crtc->x; mi->y1 = crtc->y; mi->x2 = crtc->x + crtc->width; mi->y2 = crtc->y + crtc->height; return true; } static int xrandr_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) { // if we have more than one xrandr_screen, we're in multi-head x mode if(_al_vector_size(&s->xrandr_screens) > 1) return _al_xsys_mheadx_get_default_adapter(s); int center_x = 0, center_y = 0; _al_xsys_get_active_window_center(s, ¢er_x, ¢er_y); int i, default_adapter = 0; for(i = 0; i < (int)_al_vector_size(&s->xrandr_adaptermap); i++) { xrandr_crtc *crtc = xrandr_map_to_crtc(s, 0, i); if(center_x >= (int)crtc->x && center_x <= (int)(crtc->x + crtc->width) && center_y >= (int)crtc->y && center_y <= (int)(crtc->y + crtc->height)) { default_adapter = i; break; } } ALLEGRO_DEBUG("selected default adapter: %i.\n", default_adapter); return default_adapter; } static int xrandr_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) { // more than one screen means we have multi-head x mode if(_al_vector_size(&s->xrandr_screens) > 1) return _al_xsys_mheadx_get_xscreen(s, adapter); // Normal XRandR will normally give us one X screen, so return 0 always. return 0; } static void xrandr_handle_xevent(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e) { if(e->type == s->xrandr_event_base + RRNotify) { XRRNotifyEvent *rre = (XRRNotifyEvent*)e; if(rre->subtype == RRNotify_CrtcChange) { XRRCrtcChangeNotifyEvent *rrce = (XRRCrtcChangeNotifyEvent*)rre; ALLEGRO_DEBUG("RRNotify_CrtcChange!\n"); xrandr_crtc *crtc = xrandr_fetch_crtc(s, d->xscreen, rrce->crtc); if(!crtc) { ALLEGRO_DEBUG("invalid RRCrtc(%i).\n", (int)rrce->crtc); return; } if(rrce->mode != crtc->mode) { ALLEGRO_DEBUG("mode changed from %i to %i.\n", (int)crtc->mode, (int)rrce->mode); crtc->mode = rrce->mode; } if(rrce->rotation != crtc->rotation) { ALLEGRO_DEBUG("rotation changed from %i to %i.\n", crtc->rotation, rrce->rotation); crtc->rotation = rrce->rotation; } if(rrce->x != crtc->x || rrce->y != crtc->y) { ALLEGRO_DEBUG("origin changed from %i+%i to %i+%i.\n", crtc->x, crtc->y, rrce->x, rrce->y); crtc->x = rrce->x; crtc->y = rrce->y; } if(rrce->width != crtc->width || rrce->height != crtc->height) { ALLEGRO_DEBUG("size changed from %ix%i to %ix%i.\n", crtc->width, crtc->height, rrce->width, rrce->height); crtc->width = rrce->width; crtc->height = rrce->height; } xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); crtc->timestamp = screen->timestamp; } else if(rre->subtype == RRNotify_OutputChange) { XRROutputChangeNotifyEvent *rroe = (XRROutputChangeNotifyEvent*)rre; xrandr_output *output = xrandr_fetch_output(s, d->xscreen, rroe->output); if(!output) { ALLEGRO_DEBUG("invalid RROutput(%i).\n", (int)rroe->output); return; } ALLEGRO_DEBUG("xrandr: RRNotify_OutputChange %s!\n", output->name); if(rroe->crtc != output->crtc) { ALLEGRO_DEBUG("crtc changed from %i to %i.\n", (int)output->crtc, (int)rroe->crtc); output->crtc = rroe->crtc; } // XXX I'm not sure how monitor connections are handled here, // that is, what happens when a monitor is connected, and disconnected... // IE: CHECK! if(rroe->connection != output->connection) { ALLEGRO_DEBUG("connection changed from %i to %i.\n", output->connection, rroe->connection); output->connection = rroe->connection; } xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); output->timestamp = screen->timestamp; } else if(rre->subtype == RRNotify_OutputProperty) { ALLEGRO_DEBUG("xrandr: RRNotify_OutputProperty!\n"); } else { ALLEGRO_DEBUG("xrandr: RRNotify_Unknown(%i)!\n", rre->subtype); } } else if(e->type == s->xrandr_event_base + RRScreenChangeNotify) { XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)e; XRRUpdateConfiguration( e ); ALLEGRO_DEBUG("RRScreenChangeNotify!\n"); /* XXX I don't think we need to actually handle this event fully, * it only really deals with the virtual screen as a whole it seems * The interesting changes get sent with the RRNotify event. */ /* update the timestamps */ xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); screen->timestamp = rre->timestamp; screen->configTimestamp = rre->config_timestamp; } } /* begin "public" ctor/dtor methods */ void _al_xsys_xrandr_init(ALLEGRO_SYSTEM_XGLX *s) { int error_base = 0; _al_mutex_lock(&s->lock); if (XRRQueryExtension(s->x11display, &s->xrandr_event_base, &error_base)) { int minor_version = 0, major_version = 0; int status = XRRQueryVersion(s->x11display, &major_version, &minor_version); ALLEGRO_INFO("XRandR version: %i.%i\n", major_version, minor_version); if (!status) { ALLEGRO_WARN("XRandR not available, XRRQueryVersion failed.\n"); } else if (major_version == 1 && minor_version < 2) { /* this is unlikely to happen, unless the user has an ancient Xorg, Xorg will just emulate the latest version and return that instead of what the driver actually supports, stupid. */ ALLEGRO_WARN("XRandR not available, unsupported version: %i.%i\n", major_version, minor_version); } else { bool ret = xrandr_query(s); if (ret) { ALLEGRO_INFO("XRandR is active\n"); s->xrandr_available = 1; } else { ALLEGRO_INFO("XRandR is not active\n"); } } } else { ALLEGRO_WARN("XRandR extension is not available.\n"); } if (s->xrandr_available) { memset(&_al_xglx_mmon_interface, 0, sizeof(_al_xglx_mmon_interface)); _al_xglx_mmon_interface.get_num_display_modes = xrandr_get_num_modes; _al_xglx_mmon_interface.get_display_mode = xrandr_get_mode; _al_xglx_mmon_interface.set_mode = xrandr_set_mode; _al_xglx_mmon_interface.restore_mode = xrandr_restore_mode; _al_xglx_mmon_interface.get_display_offset = xrandr_get_display_offset; _al_xglx_mmon_interface.get_num_adapters = xrandr_get_num_adapters; _al_xglx_mmon_interface.get_monitor_info = xrandr_get_monitor_info; _al_xglx_mmon_interface.get_default_adapter = xrandr_get_default_adapter; _al_xglx_mmon_interface.get_xscreen = xrandr_get_xscreen; _al_xglx_mmon_interface.handle_xevent = xrandr_handle_xevent; } _al_mutex_unlock(&s->lock); } void _al_xsys_xrandr_exit(ALLEGRO_SYSTEM_XGLX *s) { #if 0 // int i; ALLEGRO_DEBUG("XRandR exiting.\n"); // for (i = 0; i < s->xrandr_output_count; i++) { // XRRFreeOutputInfo(s->xrandr_outputs[i]); // } // for (i = 0; i < s->xrandr_res_count; i++) { // XRRFreeScreenResources(s->xrandr_res[i]); // } ALLEGRO_DEBUG("XRRFreeScreenResources\n"); //if (s->xrandr_res) // XRRFreeScreenResources(s->xrandr_res); al_free(s->xrandr_outputs); al_free(s->xrandr_res); s->xrandr_available = 0; s->xrandr_res_count = 0; s->xrandr_res = NULL; s->xrandr_output_count = 0; s->xrandr_outputs = NULL; ALLEGRO_DEBUG("XRandR exit finished.\n"); #endif /* 0 */ int i; for(i = 0; i < (int)_al_vector_size(&s->xrandr_screens); i++) { xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, i); int j; for (j = 0; j < (int)_al_vector_size(&screen->crtcs); j++) { xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, j); _al_vector_free(&crtc->connected); _al_vector_free(&crtc->possible); } for(j = 0; j < (int)_al_vector_size(&screen->outputs); j++) { xrandr_output *output = _al_vector_ref(&screen->outputs, j); free(output->name); _al_vector_free(&output->crtcs); _al_vector_free(&output->clones); _al_vector_free(&output->modes); } _al_vector_free(&screen->crtcs); _al_vector_free(&screen->outputs); _al_vector_free(&screen->modes); XRRFreeScreenResources(screen->res); screen->res = NULL; } _al_vector_free(&s->xrandr_screens); _al_vector_free(&s->xrandr_adaptermap); } #endif /* ALLEGRO_XWINDOWS_WITH_XRANDR */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/xglx_config.c0000644000175000001440000004467212104442100016120 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/opengl/gl_ext.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xglx_config.h" #include "allegro5/internal/aintern_xsystem.h" ALLEGRO_DEBUG_CHANNEL("xglx_config") #ifdef DEBUGMODE static void display_pixel_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { ALLEGRO_DEBUG("Single-buffer: %s\n", eds->settings[ALLEGRO_SINGLE_BUFFER] ? "yes" : "no"); if (eds->settings[ALLEGRO_SWAP_METHOD] > 0) ALLEGRO_DEBUG("Swap method: %s\n", eds->settings[ALLEGRO_SWAP_METHOD] == 2 ? "flip" : "copy"); else ALLEGRO_DEBUG("Swap method: undefined\n"); ALLEGRO_DEBUG("Color format: r%i g%i b%i a%i, %i bit\n", eds->settings[ALLEGRO_RED_SIZE], eds->settings[ALLEGRO_GREEN_SIZE], eds->settings[ALLEGRO_BLUE_SIZE], eds->settings[ALLEGRO_ALPHA_SIZE], eds->settings[ALLEGRO_COLOR_SIZE]); ALLEGRO_DEBUG("Depth buffer: %i bits\n", eds->settings[ALLEGRO_DEPTH_SIZE]); ALLEGRO_DEBUG("Sample buffers: %s\n", eds->settings[ALLEGRO_SAMPLE_BUFFERS] ? "yes" : "no"); ALLEGRO_DEBUG("Samples: %i\n", eds->settings[ALLEGRO_SAMPLES]); } #endif static int get_shift(int mask) { int i = 0, j = 1; if (!mask) return -1; while (!(j & mask)) { i++; j <<= 1; } return i; } static void figure_out_colors(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, XVisualInfo *v) { eds->settings[ALLEGRO_RED_SHIFT] = get_shift(v->red_mask); eds->settings[ALLEGRO_GREEN_SHIFT] = get_shift(v->green_mask); eds->settings[ALLEGRO_BLUE_SHIFT] = get_shift(v->blue_mask); eds->settings[ALLEGRO_ALPHA_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 0; if (eds->settings[ALLEGRO_RED_SIZE] == 3 && eds->settings[ALLEGRO_GREEN_SIZE] == 3 && eds->settings[ALLEGRO_BLUE_SIZE] == 2) { eds->settings[ALLEGRO_COLOR_SIZE] = 8; } if (eds->settings[ALLEGRO_RED_SIZE] == 5 && eds->settings[ALLEGRO_BLUE_SIZE] == 5) { if (eds->settings[ALLEGRO_GREEN_SIZE] == 5) { eds->settings[ALLEGRO_COLOR_SIZE] = 15; } if (eds->settings[ALLEGRO_GREEN_SIZE] == 6) { eds->settings[ALLEGRO_COLOR_SIZE] = 16; } } if (eds->settings[ALLEGRO_RED_SIZE] == 8 && eds->settings[ALLEGRO_GREEN_SIZE] == 8 && eds->settings[ALLEGRO_BLUE_SIZE] == 8) { if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0) { eds->settings[ALLEGRO_COLOR_SIZE] = 24; } if (eds->settings[ALLEGRO_ALPHA_SIZE] == 8) { eds->settings[ALLEGRO_COLOR_SIZE] = 32; /* small hack that tries to guess alpha shifting */ eds->settings[ALLEGRO_ALPHA_SHIFT] = 48 - eds->settings[ALLEGRO_RED_SHIFT] - eds->settings[ALLEGRO_GREEN_SHIFT] - eds->settings[ALLEGRO_BLUE_SHIFT]; } } } static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_fbconfig(Display *dpy, GLXFBConfig fbc) { int render_type, visual_type, buffer_size, sbuffers, samples; int drawable_type, renderable, swap_method, double_buffer; ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds; XVisualInfo *v; eds = al_calloc(1, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); eds->settings[ALLEGRO_RENDER_METHOD] = 2; if (glXGetFBConfigAttrib (dpy, fbc, GLX_RENDER_TYPE, &render_type) || glXGetFBConfigAttrib (dpy, fbc, GLX_X_RENDERABLE, &renderable) || glXGetFBConfigAttrib (dpy, fbc, GLX_DRAWABLE_TYPE, &drawable_type) || glXGetFBConfigAttrib (dpy, fbc, GLX_X_VISUAL_TYPE, &visual_type) || glXGetFBConfigAttrib (dpy, fbc, GLX_BUFFER_SIZE, &buffer_size) || glXGetFBConfigAttrib (dpy, fbc, GLX_DEPTH_SIZE, &eds->settings[ALLEGRO_DEPTH_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_STEREO, &eds->settings[ALLEGRO_STEREO]) || glXGetFBConfigAttrib (dpy, fbc, GLX_RED_SIZE, &eds->settings[ALLEGRO_RED_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_GREEN_SIZE, &eds->settings[ALLEGRO_GREEN_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_BLUE_SIZE, &eds->settings[ALLEGRO_BLUE_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_ALPHA_SIZE, &eds->settings[ALLEGRO_ALPHA_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_DOUBLEBUFFER, &double_buffer) || glXGetFBConfigAttrib (dpy, fbc, GLX_AUX_BUFFERS, &eds->settings[ALLEGRO_AUX_BUFFERS]) || glXGetFBConfigAttrib (dpy, fbc, GLX_STENCIL_SIZE, &eds->settings[ALLEGRO_STENCIL_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_RED_SIZE, &eds->settings[ALLEGRO_ACC_RED_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_GREEN_SIZE, &eds->settings[ALLEGRO_ACC_GREEN_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_BLUE_SIZE, &eds->settings[ALLEGRO_ACC_BLUE_SIZE]) || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_ALPHA_SIZE, &eds->settings[ALLEGRO_ACC_ALPHA_SIZE])) { ALLEGRO_DEBUG("Incomplete glX mode ...\n"); al_free(eds); return NULL; } eds->settings[ALLEGRO_SINGLE_BUFFER] = !double_buffer; if (!(render_type & GLX_RGBA_BIT) && !(render_type & GLX_RGBA_FLOAT_BIT_ARB)) { ALLEGRO_DEBUG("Not RGBA mode\n"); al_free(eds); return NULL; } if (!(drawable_type & GLX_WINDOW_BIT)) { ALLEGRO_DEBUG("Cannot render to a window.\n"); al_free(eds); return NULL; } if (renderable == False) { ALLEGRO_DEBUG("GLX windows not supported.\n"); al_free(eds); return NULL; } if (visual_type != GLX_TRUE_COLOR && visual_type != GLX_DIRECT_COLOR) { ALLEGRO_DEBUG("visual type other than TrueColor and " "DirectColor.\n"); al_free(eds); return NULL; } /* Floating-point depth is not supported as glx extension (yet). */ eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; eds->settings[ALLEGRO_FLOAT_COLOR] = (render_type & GLX_RGBA_FLOAT_BIT_ARB); v = glXGetVisualFromFBConfig(dpy, fbc); if (!v) { ALLEGRO_DEBUG("Cannot get associated visual for the FBConfig.\n"); al_free(eds); return NULL; } figure_out_colors(eds, v); if (glXGetConfig(dpy, v, GLX_SAMPLE_BUFFERS, &sbuffers)) { /* Multisample extension is not supported */ eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; } else { eds->settings[ALLEGRO_SAMPLE_BUFFERS] = sbuffers; } if (glXGetConfig(dpy, v, GLX_SAMPLES, &samples)) { /* Multisample extension is not supported */ eds->settings[ALLEGRO_SAMPLES] = 0; } else { eds->settings[ALLEGRO_SAMPLES] = samples; } if (glXGetFBConfigAttrib(dpy, fbc, GLX_SWAP_METHOD_OML, &swap_method) == GLX_BAD_ATTRIBUTE) { /* GLX_OML_swap_method extension is not supported */ eds->settings[ALLEGRO_SWAP_METHOD] = 0; } else { eds->settings[ALLEGRO_SWAP_METHOD] = swap_method; } /* We can only guarantee vsync is off. */ eds->settings[ALLEGRO_VSYNC] = 2; eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = (_al_deduce_color_format(eds) != ALLEGRO_PIXEL_FORMAT_ANY); XFree(v); return eds; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_visuals_new(ALLEGRO_DISPLAY_XGLX *glx, int *eds_count) { int num_fbconfigs, i, j; GLXFBConfig *fbconfig; ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds = NULL; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ref = _al_get_new_display_settings(); fbconfig = glXGetFBConfigs(system->gfxdisplay, glx->xscreen, &num_fbconfigs); if (!fbconfig || !num_fbconfigs) { if (fbconfig) { XFree(fbconfig); } ALLEGRO_DEBUG("glXGetFBConfigs(xscreen=%d) returned NULL.\n", glx->xscreen); return NULL; } eds = al_malloc(num_fbconfigs * sizeof(*eds)); ALLEGRO_INFO("%i formats.\n", num_fbconfigs); for (i = j = 0; i < num_fbconfigs; i++) { ALLEGRO_DEBUG("-- \n"); ALLEGRO_DEBUG("Decoding visual no. %i...\n", i); eds[j] = read_fbconfig(system->gfxdisplay, fbconfig[i]); if (!eds[j]) continue; #ifdef DEBUGMODE display_pixel_format(eds[j]); #endif eds[j]->score = _al_score_display_settings(eds[j], ref); if (eds[j]->score == -1) { al_free(eds[j]); continue; } eds[j]->index = i; eds[j]->info = al_malloc(sizeof(GLXFBConfig)); memcpy(eds[j]->info, &fbconfig[i], sizeof(GLXFBConfig)); j++; } *eds_count = j; ALLEGRO_INFO("%i visuals are good enough.\n", j); if (j == 0) { al_free(eds); eds = NULL; } XFree(fbconfig); return eds; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_xvisual(Display *dpy, XVisualInfo *v) { int rgba, buffer_size, use_gl, sbuffers, samples, double_buffer; ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds; /* We can only support TrueColor and DirectColor visuals -- * we only support RGBA mode */ if (v->class != TrueColor && v->class != DirectColor) return NULL; eds = al_calloc(1, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); eds->settings[ALLEGRO_RENDER_METHOD] = 2; if (glXGetConfig (dpy, v, GLX_RGBA, &rgba) || glXGetConfig (dpy, v, GLX_USE_GL, &use_gl) || glXGetConfig (dpy, v, GLX_BUFFER_SIZE, &buffer_size) || glXGetConfig (dpy, v, GLX_RED_SIZE, &eds->settings[ALLEGRO_RED_SIZE]) || glXGetConfig (dpy, v, GLX_GREEN_SIZE, &eds->settings[ALLEGRO_GREEN_SIZE]) || glXGetConfig (dpy, v, GLX_BLUE_SIZE, &eds->settings[ALLEGRO_BLUE_SIZE]) || glXGetConfig (dpy, v, GLX_ALPHA_SIZE, &eds->settings[ALLEGRO_ALPHA_SIZE]) || glXGetConfig (dpy, v, GLX_DOUBLEBUFFER, &double_buffer) || glXGetConfig (dpy, v, GLX_STEREO, &eds->settings[ALLEGRO_STEREO]) || glXGetConfig (dpy, v, GLX_AUX_BUFFERS, &eds->settings[ALLEGRO_AUX_BUFFERS]) || glXGetConfig (dpy, v, GLX_DEPTH_SIZE, &eds->settings[ALLEGRO_DEPTH_SIZE]) || glXGetConfig (dpy, v, GLX_STENCIL_SIZE, &eds->settings[ALLEGRO_STENCIL_SIZE]) || glXGetConfig (dpy, v, GLX_ACCUM_RED_SIZE, &eds->settings[ALLEGRO_ACC_RED_SIZE]) || glXGetConfig (dpy, v, GLX_ACCUM_GREEN_SIZE, &eds->settings[ALLEGRO_ACC_GREEN_SIZE]) || glXGetConfig (dpy, v, GLX_ACCUM_BLUE_SIZE, &eds->settings[ALLEGRO_ACC_BLUE_SIZE]) || glXGetConfig (dpy, v, GLX_ACCUM_ALPHA_SIZE, &eds->settings[ALLEGRO_ACC_ALPHA_SIZE])) { ALLEGRO_DEBUG("Incomplete glX mode ...\n"); al_free(eds); return NULL; } eds->settings[ALLEGRO_SINGLE_BUFFER] = !double_buffer; if (!rgba) { ALLEGRO_DEBUG("Not RGBA mode\n"); al_free(eds); return NULL; } if (!use_gl) { ALLEGRO_DEBUG("OpenGL Unsupported\n"); al_free(eds); return NULL; } eds->settings[ALLEGRO_COLOR_SIZE] = 0; figure_out_colors(eds, v); eds->settings[ALLEGRO_FLOAT_COLOR] = 0; eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; if (glXGetConfig(dpy, v, GLX_SAMPLE_BUFFERS, &sbuffers) == GLX_BAD_ATTRIBUTE) { /* Multisample extension is not supported */ eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; } else { eds->settings[ALLEGRO_SAMPLE_BUFFERS] = sbuffers; } if (glXGetConfig(dpy, v, GLX_SAMPLES, &samples) == GLX_BAD_ATTRIBUTE) { /* Multisample extension is not supported */ eds->settings[ALLEGRO_SAMPLES] = 0; } else { eds->settings[ALLEGRO_SAMPLES] = samples; } eds->settings[ALLEGRO_SWAP_METHOD] = 0; eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = (_al_deduce_color_format(eds) != ALLEGRO_PIXEL_FORMAT_ANY); return eds; } static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_visuals_old(int *eds_count) { int i, j, num_visuals; XVisualInfo *xv; ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ref = _al_get_new_display_settings(); xv = XGetVisualInfo(system->gfxdisplay, 0, NULL, &num_visuals); if (!xv || !num_visuals) return NULL; eds = al_malloc(num_visuals * sizeof(*eds)); ALLEGRO_INFO("%i formats.\n", num_visuals); for (i = j = 0; i < num_visuals; i++) { ALLEGRO_DEBUG("-- \n"); ALLEGRO_DEBUG("Decoding visual no. %i...\n", i); eds[j] = read_xvisual(system->gfxdisplay, xv + i); if (!eds[j]) continue; #ifdef DEBUGMODE display_pixel_format(eds[j]); #endif eds[j]->score = _al_score_display_settings(eds[j], ref); if (eds[j]->score == -1) { al_free(eds[j]); continue; } eds[j]->index = i; /* Seems that XVinfo is static. */ eds[j]->info = al_malloc(sizeof(XVisualInfo)); memcpy(eds[j]->info, xv + i, sizeof(XVisualInfo)); j++; } *eds_count = j; ALLEGRO_INFO("%i visuals are good enough.\n", j); if (j == 0) { al_free(eds); eds = NULL; } XFree(xv); return eds; } static void select_best_visual(ALLEGRO_DISPLAY_XGLX *glx, ALLEGRO_EXTRA_DISPLAY_SETTINGS* *eds, int eds_count, bool using_fbc) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); qsort(eds, eds_count, sizeof(*eds), _al_display_settings_sorter); ASSERT(eds_count > 0); ASSERT(eds[0] != NULL); if (!eds[0]->info) { ALLEGRO_ERROR("No matching displays found.\n"); glx->xvinfo = NULL; return; } ALLEGRO_INFO("Chose visual no. %i\n", eds[0]->index); #ifdef DEBUGMODE display_pixel_format(eds[0]); #endif if (using_fbc) { glx->fbc = al_malloc(sizeof(GLXFBConfig)); memcpy(glx->fbc, eds[0]->info, sizeof(GLXFBConfig)); glx->xvinfo = glXGetVisualFromFBConfig(system->gfxdisplay, *glx->fbc); } else { glx->xvinfo = al_malloc(sizeof(XVisualInfo)); memcpy(glx->xvinfo, eds[0]->info, sizeof(XVisualInfo)); } ALLEGRO_INFO("Corresponding X11 visual id: %lu\n", glx->xvinfo->visualid); memcpy(&glx->display.extra_settings, eds[0], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); } void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds; int eds_count, i; bool force_old = false; bool using_fbc; if (system->system.config) { const char *selection_mode; selection_mode = al_get_config_value(system->system.config, "graphics", "config_selection"); if (selection_mode && selection_mode[0] != '\0') { if (!_al_stricmp(selection_mode, "old")) { ALLEGRO_WARN("Forcing OLD visual selection method.\n"); force_old = true; } else if (!_al_stricmp(selection_mode, "new")) force_old = false; } } if (glx->glx_version >= 130 && !force_old) eds = get_visuals_new(glx, &eds_count); else eds = NULL; if (!eds) { eds = get_visuals_old(&eds_count); using_fbc = false; } else using_fbc = true; if (!eds) { ALLEGRO_ERROR("Failed to get any visual info.\n"); return; } select_best_visual(glx, eds, eds_count, using_fbc); for (i = 0; i < eds_count; i++) { if (eds[i]) { al_free(eds[i]->info); al_free(eds[i]); } } al_free(eds); } static GLXContext create_context_new(int ver, Display *dpy, GLXFBConfig fb, GLXContext ctx, bool forward_compat, int major, int minor) { typedef GLXContext (*GCCA_PROC) (Display*, GLXFBConfig, GLXContext, Bool, const int*); GCCA_PROC _xglx_glXCreateContextAttribsARB = NULL; if (ver >= 140) { /* GLX 1.4 should have this */ _xglx_glXCreateContextAttribsARB = glXCreateContextAttribsARB; } if (!_xglx_glXCreateContextAttribsARB) { /* Load the extension manually. */ _xglx_glXCreateContextAttribsARB = (GCCA_PROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); } if (!_xglx_glXCreateContextAttribsARB) { ALLEGRO_ERROR("GLX_ARB_create_context not supported and needed for OpenGL 3\n"); return NULL; } int attrib[] = {GLX_CONTEXT_MAJOR_VERSION_ARB, major, GLX_CONTEXT_MINOR_VERSION_ARB, minor, GLX_CONTEXT_FLAGS_ARB, 0, 0}; if (forward_compat) attrib[5] = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; return _xglx_glXCreateContextAttribsARB(dpy, fb, ctx, True, attrib); } bool _al_xglx_config_create_context(ALLEGRO_DISPLAY_XGLX *glx) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY *disp = (void*)glx; GLXContext existing_ctx = NULL; /* Find an existing context with which to share display lists. */ if (_al_vector_size(&system->system.displays) > 1) { ALLEGRO_DISPLAY_XGLX **existing_dpy; existing_dpy = _al_vector_ref_front(&system->system.displays); if (*existing_dpy != glx) existing_ctx = (*existing_dpy)->context; } if (glx->fbc) { /* Create a GLX context from FBC. */ if (disp->flags & ALLEGRO_OPENGL_3_0) { bool forward_compat = (disp->flags & ALLEGRO_OPENGL_FORWARD_COMPATIBLE) != 0; glx->context = create_context_new(glx->glx_version, system->gfxdisplay, *glx->fbc, existing_ctx, forward_compat, 3, 0); disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = !forward_compat; } else { glx->context = glXCreateNewContext(system->gfxdisplay, *glx->fbc, GLX_RGBA_TYPE, existing_ctx, True); } /* Create a GLX subwindow inside our window. */ glx->glxwindow = glXCreateWindow(system->gfxdisplay, *glx->fbc, glx->window, 0); } else { /* Create a GLX context from visual info. */ glx->context = glXCreateContext(system->gfxdisplay, glx->xvinfo, existing_ctx, True); glx->glxwindow = glx->window; } if (!glx->context || !glx->glxwindow) { ALLEGRO_ERROR("Failed to create GLX context.\n"); return false; } disp->ogl_extras->is_shared = true; ALLEGRO_DEBUG("Got GLX context.\n"); return true; } allegro-5.0.10/src/x/xevents.c0000644000175000001440000001434712104442100015301 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/platform/aintunix.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xevents.h" #include "allegro5/internal/aintern_xfullscreen.h" #include "allegro5/internal/aintern_xkeyboard.h" #include "allegro5/internal/aintern_xmouse.h" #include "allegro5/internal/aintern_xsystem.h" ALLEGRO_DEBUG_CHANNEL("xevents") /* Handle an X11 close button event. [X11 thread] * Only called from the event handler with the system locked. */ static void _al_display_xglx_closebutton(ALLEGRO_DISPLAY *d, XEvent *xevent) { ALLEGRO_EVENT_SOURCE *es = &d->es; (void)xevent; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); } static void process_x11_event(ALLEGRO_SYSTEM_XGLX *s, XEvent event) { unsigned int i; ALLEGRO_DISPLAY_XGLX *d = NULL; /* With many windows, it's bad to loop through them all, but typically * we have one or at most two or so. */ for (i = 0; i < _al_vector_size(&s->system.displays); i++) { ALLEGRO_DISPLAY_XGLX **dptr = _al_vector_ref(&s->system.displays, i); d = *dptr; if (d->window == event.xany.window) { break; } } if (!d) { /* The display was probably destroyed already. */ return; } switch (event.type) { case KeyPress: _al_xwin_keyboard_handler(&event.xkey, &d->display); break; case KeyRelease: _al_xwin_keyboard_handler(&event.xkey, &d->display); break; case MotionNotify: _al_xwin_mouse_motion_notify_handler( event.xmotion.x, event.xmotion.y, &d->display); break; case ButtonPress: _al_xwin_mouse_button_press_handler(event.xbutton.button, &d->display); break; case ButtonRelease: _al_xwin_mouse_button_release_handler(event.xbutton.button, &d->display); break; case ClientMessage: if (event.xclient.message_type == s->AllegroAtom) { d->mouse_warp = true; break; } if ((Atom)event.xclient.data.l[0] == d->wm_delete_window_atom) { _al_display_xglx_closebutton(&d->display, &event); break; } break; case EnterNotify: _al_xwin_mouse_switch_handler(&d->display, &event.xcrossing); break; case LeaveNotify: _al_xwin_mouse_switch_handler(&d->display, &event.xcrossing); break; case FocusIn: _al_xwin_display_switch_handler(&d->display, &event.xfocus); _al_xwin_keyboard_switch_handler(&d->display, true); break; case FocusOut: _al_xwin_display_switch_handler(&d->display, &event.xfocus); _al_xwin_keyboard_switch_handler(&d->display, false); break; case ConfigureNotify: _al_xglx_display_configure_event(&d->display, &event); d->resize_count++; _al_cond_signal(&s->resized); break; case MapNotify: d->display.flags &= ~ALLEGRO_MINIMIZED; d->is_mapped = true; _al_cond_signal(&d->mapped); break; case UnmapNotify: d->display.flags |= ALLEGRO_MINIMIZED; break; case Expose: if (d->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { _al_xwin_display_expose(&d->display, &event.xexpose); } break; default: _al_xglx_handle_mmon_event(s, d, &event); break; } } void _al_xwin_background_thread(_AL_THREAD *self, void *arg) { ALLEGRO_SYSTEM_XGLX *s = arg; XEvent event; double last_reset_screensaver_time = 0.0; while (!_al_get_thread_should_stop(self)) { /* Note: * Most older X11 implementations are not thread-safe no matter what, so * we simply cannot sit inside a blocking XNextEvent from another thread * if another thread also uses X11 functions. * * The usual use of XNextEvent is to only call it from the main thread. We * could of course do this for A5, just needs some slight adjustments to * the events system (polling for an Allegro event would call a function * of the system driver). * * As an alternative, we can use locking. This however can never fully * work, as for example OpenGL implementations also will access X11, in a * way we cannot know and cannot control (and we can't require users to * only call graphics functions inside a lock). * * However, most X11 implementations are somewhat thread safe, and do * use locking quite a bit themselves, so locking mostly does work. * * (Yet another alternative might be to use a separate X11 display * connection for graphics output.) * */ _al_mutex_lock(&s->lock); while (XEventsQueued(s->x11display, QueuedAfterFlush)) { XNextEvent(s->x11display, &event); process_x11_event(s, event); } /* The Xlib manual is particularly useless about the XResetScreenSaver() * function. Nevertheless, this does seem to work to inhibit the native * screensaver facility. Probably it won't do anything for other * systems, though. */ if (s->inhibit_screensaver) { double now = al_get_time(); if (now - last_reset_screensaver_time > 10.0) { XResetScreenSaver(s->x11display); last_reset_screensaver_time = now; } } _al_mutex_unlock(&s->lock); /* If no X11 events are there, unlock so other threads can run. We use * a select call to wake up when as soon as anything is available on * the X11 connection - and just for safety also wake up 10 times * a second regardless. */ int x11_fd = ConnectionNumber(s->x11display); fd_set fdset; FD_ZERO(&fdset); FD_SET(x11_fd, &fdset); struct timeval small_time = {0, 100000}; /* 10 times a second */ select(x11_fd + 1, &fdset, NULL, NULL, &small_time); } } allegro-5.0.10/src/x/xmousenu.c0000644000175000001440000003426712104442100015473 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * X-Windows mouse module. * * By Peter Wang. * * Original by Michael Bukin. * * See readme.txt for copyright information. */ #define ALLEGRO_NO_COMPATIBILITY #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xmouse.h" #include "allegro5/internal/aintern_xsystem.h" ALLEGRO_DEBUG_CHANNEL("mouse") typedef struct ALLEGRO_MOUSE_XWIN { ALLEGRO_MOUSE parent; ALLEGRO_MOUSE_STATE state; int min_x, min_y; int max_x, max_y; } ALLEGRO_MOUSE_XWIN; static bool xmouse_installed = false; /* the one and only mouse object */ static ALLEGRO_MOUSE_XWIN the_mouse; /* forward declarations */ static bool xmouse_init(void); static void xmouse_exit(void); static ALLEGRO_MOUSE *xmouse_get_mouse(void); static unsigned int xmouse_get_mouse_num_buttons(void); static unsigned int xmouse_get_mouse_num_axes(void); static bool xmouse_set_mouse_xy(ALLEGRO_DISPLAY *,int x, int y); static bool xmouse_set_mouse_axis(int which, int z); static void xmouse_get_state(ALLEGRO_MOUSE_STATE *ret_state); static void wheel_motion_handler(int x_button, ALLEGRO_DISPLAY *display); static unsigned int x_button_to_al_button(unsigned int x_button); static void generate_mouse_event(unsigned int type, int x, int y, int z, int w, int dx, int dy, int dz, int dw, unsigned int button, ALLEGRO_DISPLAY *display); /* the driver vtable */ #define MOUSEDRV_XWIN AL_ID('X','W','I','N') static ALLEGRO_MOUSE_DRIVER mousedrv_xwin = { MOUSEDRV_XWIN, "", "", "X-Windows mouse", xmouse_init, xmouse_exit, xmouse_get_mouse, xmouse_get_mouse_num_buttons, xmouse_get_mouse_num_axes, xmouse_set_mouse_xy, xmouse_set_mouse_axis, xmouse_get_state }; ALLEGRO_MOUSE_DRIVER *_al_xwin_mouse_driver(void) { return &mousedrv_xwin; } /* xmouse_init: * Initialise the driver. */ static bool xmouse_init(void) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY *display; int x, y; if (system->x11display == NULL) return false; if (xmouse_installed) return false; /* Don't clobber mouse position in case the display was created before * the mouse is installed. */ display = the_mouse.state.display; x = the_mouse.state.x; y = the_mouse.state.y; memset(&the_mouse, 0, sizeof the_mouse); the_mouse.state.display = display; the_mouse.state.x = x; the_mouse.state.y = y; _al_event_source_init(&the_mouse.parent.es); xmouse_installed = true; return true; } /* xmouse_exit: * Shut down the mouse driver. */ static void xmouse_exit(void) { if (!xmouse_installed) return; xmouse_installed = false; _al_event_source_free(&the_mouse.parent.es); } /* xmouse_get_mouse: * Returns the address of a ALLEGRO_MOUSE structure representing the mouse. */ static ALLEGRO_MOUSE *xmouse_get_mouse(void) { ASSERT(xmouse_installed); return (ALLEGRO_MOUSE *)&the_mouse; } /* xmouse_get_mouse_num_buttons: * Return the number of buttons on the mouse. */ static unsigned int xmouse_get_mouse_num_buttons(void) { int num_buttons; unsigned char map[32]; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ASSERT(xmouse_installed); _al_mutex_lock(&system->lock); num_buttons = XGetPointerMapping(system->x11display, map, sizeof(map)); _al_mutex_unlock(&system->lock); if (num_buttons > (int)sizeof(map)) num_buttons = sizeof(map); #ifdef DEBUGMODE char debug[num_buttons * 4 + 1]; debug[0] = 0; int i; for (i = 0; i < num_buttons; i++) { sprintf(debug + strlen(debug), "%2d,", map[i]); } ALLEGRO_DEBUG("XGetPointerMapping: %s\n", debug); #endif if (num_buttons < 1) num_buttons = 1; return num_buttons; } /* xmouse_get_mouse_num_axes: * Return the number of axes on the mouse. */ static unsigned int xmouse_get_mouse_num_axes(void) { ASSERT(xmouse_installed); /* TODO: is there a way to detect whether z/w axis actually exist? */ return 4; } /* xmouse_set_mouse_xy: * Set the mouse position. Return true if successful. */ static bool xmouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) { if (!xmouse_installed) return false; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); Display *x11display = system->x11display; ALLEGRO_DISPLAY_XGLX *d = (void *)display; int window_width = al_get_display_width(display); int window_height = al_get_display_height(display); if (x < 0 || y < 0 || x >= window_width || y >= window_height) return false; _al_mutex_lock(&system->lock); /* We prepend the mouse motion event generated by XWarpPointer * with our own event to distinguish real and generated * events. */ XEvent event; memset(&event, 0, sizeof event); event.xclient.type = ClientMessage; event.xclient.serial = 0; event.xclient.send_event = True; event.xclient.display = x11display; event.xclient.window = d->window; event.xclient.message_type = system->AllegroAtom; event.xclient.format = 32; XSendEvent(x11display, d->window, False, NoEventMask, &event); XWarpPointer(x11display, None, d->window, 0, 0, 0, 0, x, y); _al_mutex_unlock(&system->lock); return true; } /* xmouse_set_mouse_axis: * Set the mouse wheel position. Return true if successful. */ static bool xmouse_set_mouse_axis(int which, int v) { ASSERT(xmouse_installed); if (which != 2 && which != 3) { return false; } _al_event_source_lock(&the_mouse.parent.es); { int z = which == 2 ? v : the_mouse.state.z; int w = which == 3 ? v : the_mouse.state.w; int dz = z - the_mouse.state.z; int dw = w - the_mouse.state.w; if (dz != 0 || dw != 0) { the_mouse.state.z = z; the_mouse.state.w = w; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, 0, 0, dz, dw, 0, the_mouse.state.display); } } _al_event_source_unlock(&the_mouse.parent.es); return true; } /* xmouse_get_state: * Copy the current mouse state into RET_STATE, with any necessary locking. */ static void xmouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) { ASSERT(xmouse_installed); _al_event_source_lock(&the_mouse.parent.es); { *ret_state = the_mouse.state; } _al_event_source_unlock(&the_mouse.parent.es); } /* _al_xwin_mouse_button_press_handler: [bgman thread] * Called by _xwin_process_event() for ButtonPress events received from the X * server. */ void _al_xwin_mouse_button_press_handler(int x_button, ALLEGRO_DISPLAY *display) { unsigned int al_button; if (!xmouse_installed) return; wheel_motion_handler(x_button, display); /* Is this button supported by the Allegro API? */ al_button = x_button_to_al_button(x_button); if (al_button == 0) return; _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.buttons |= (1 << (al_button - 1)); generate_mouse_event( ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, 0, 0, 0, 0, al_button, display); } _al_event_source_unlock(&the_mouse.parent.es); } /* wheel_motion_handler: [bgman thread] * Called by _al_xwin_mouse_button_press_handler() if the ButtonPress event * received from the X server is actually for a mouse wheel movement. */ static void wheel_motion_handler(int x_button, ALLEGRO_DISPLAY *display) { int dz = 0, dw = 0; if (x_button == Button4) dz = 1; if (x_button == Button5) dz = -1; if (x_button == 6) dw = -1; if (x_button == 7) dw = 1; if (dz == 0 && dw == 0) return; _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.z += dz; the_mouse.state.w += dw; generate_mouse_event( ALLEGRO_EVENT_MOUSE_AXES, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, 0, 0, dz, dw, 0, display); } _al_event_source_unlock(&the_mouse.parent.es); } /* _al_xwin_mouse_button_release_handler: [bgman thread] * Called by _xwin_process_event() for ButtonRelease events received from the * X server. */ void _al_xwin_mouse_button_release_handler(int x_button, ALLEGRO_DISPLAY *display) { int al_button; if (!xmouse_installed) return; al_button = x_button_to_al_button(x_button); if (al_button == 0) return; _al_event_source_lock(&the_mouse.parent.es); { the_mouse.state.buttons &=~ (1 << (al_button - 1)); generate_mouse_event( ALLEGRO_EVENT_MOUSE_BUTTON_UP, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, 0, 0, 0, 0, al_button, display); } _al_event_source_unlock(&the_mouse.parent.es); } /* _al_xwin_mouse_motion_notify_handler: [bgman thread] * Called by _xwin_process_event() for MotionNotify events received from the X * server. */ void _al_xwin_mouse_motion_notify_handler(int x, int y, ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_XGLX *glx = (void *)display; int event_type = ALLEGRO_EVENT_MOUSE_AXES; if (!xmouse_installed) return; /* Is this an event generated in response to al_set_mouse_xy? */ if (glx->mouse_warp) { glx->mouse_warp = false; event_type = ALLEGRO_EVENT_MOUSE_WARPED; } _al_event_source_lock(&the_mouse.parent.es); int dx = x - the_mouse.state.x; int dy = y - the_mouse.state.y; the_mouse.state.x = x; the_mouse.state.y = y; the_mouse.state.display = display; generate_mouse_event( event_type, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, dx, dy, 0, 0, 0, display); _al_event_source_unlock(&the_mouse.parent.es); } /* x_button_to_al_button: [bgman thread] * Map a X button number to an Allegro button number. */ static unsigned int x_button_to_al_button(unsigned int x_button) { switch (x_button) { case Button1: return 1; case Button2: return 3; case Button3: return 2; case Button4: case Button5: case 6: case 7: // hardcoded for z and w wheel return 0; default: if (x_button >= 8 && x_button <= 36) { return 4 + x_button - 8; } return 0; } } /* generate_mouse_event: [bgman thread] * Helper to generate a mouse event. */ static void generate_mouse_event(unsigned int type, int x, int y, int z, int w, int dx, int dy, int dz, int dw, unsigned int button, ALLEGRO_DISPLAY *display) { ALLEGRO_EVENT event; if (!_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) return; event.mouse.type = type; event.mouse.timestamp = al_get_time(); event.mouse.display = display; event.mouse.x = x; event.mouse.y = y; event.mouse.z = z; event.mouse.w = w; event.mouse.dx = dx; event.mouse.dy = dy; event.mouse.dz = dz; event.mouse.dw = dw; event.mouse.button = button; event.mouse.pressure = 0.0; /* TODO */ _al_event_source_emit_event(&the_mouse.parent.es, &event); } /* _al_xwin_mouse_switch_handler: * Handle a focus switch event. */ void _al_xwin_mouse_switch_handler(ALLEGRO_DISPLAY *display, const XCrossingEvent *event) { int event_type; /* Ignore events where any of the buttons are held down. */ if (event->state & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask)) { return; } _al_event_source_lock(&the_mouse.parent.es); switch (event->type) { case EnterNotify: the_mouse.state.display = display; the_mouse.state.x = event->x; the_mouse.state.y = event->y; event_type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; break; case LeaveNotify: the_mouse.state.display = NULL; the_mouse.state.x = event->x; the_mouse.state.y = event->y; event_type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; break; default: ASSERT(false); event_type = 0; break; } generate_mouse_event( event_type, the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.w, 0, 0, 0, 0, 0, display); _al_event_source_unlock(&the_mouse.parent.es); } bool _al_xwin_grab_mouse(ALLEGRO_DISPLAY *display) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; int grab; bool ret; _al_mutex_lock(&system->lock); grab = XGrabPointer(system->x11display, glx->window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, glx->window, None, CurrentTime); if (grab == GrabSuccess) { system->mouse_grab_display = display; ret = true; } else { ret = false; } _al_mutex_unlock(&system->lock); return ret; } bool _al_xwin_ungrab_mouse(void) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); _al_mutex_lock(&system->lock); XUngrabPointer(system->x11display, CurrentTime); system->mouse_grab_display = NULL; _al_mutex_unlock(&system->lock); return true; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/xkeyboard.c0000644000175000001440000007535712113302065015612 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * X keyboard driver. * * By Elias Pschernig. * * Modified for the new keyboard API by Peter Wang. * * See readme.txt for copyright information. */ #define ALLEGRO_NO_COMPATIBILITY #include #include #include #include #include #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xkeyboard.h" #include "allegro5/internal/aintern_xsystem.h" ALLEGRO_DEBUG_CHANNEL("keyboard") /*----------------------------------------------------------------------*/ static void handle_key_press(int mycode, int unichar, int filtered, unsigned int modifiers, ALLEGRO_DISPLAY *display); static void handle_key_release(int mycode, ALLEGRO_DISPLAY *display); static int _key_shifts; /*----------------------------------------------------------------------*/ typedef struct ALLEGRO_KEYBOARD_XWIN { ALLEGRO_KEYBOARD parent; ALLEGRO_KEYBOARD_STATE state; } ALLEGRO_KEYBOARD_XWIN; /* the one and only keyboard object */ static ALLEGRO_KEYBOARD_XWIN the_keyboard; #ifdef ALLEGRO_XWINDOWS_WITH_XIM static XIM xim = NULL; static XIC xic = NULL; #endif static XModifierKeymap *xmodmap = NULL; static int xkeyboard_installed = 0; static int used[ALLEGRO_KEY_MAX]; static int sym_per_key; static int min_keycode, max_keycode; static KeySym *keysyms = NULL; static int main_pid; /* The pid to kill with ctrl-alt-del. */ static int pause_key = 0; /* Allegro's special pause key state. */ static int keycode_to_scancode[256]; /* This table can be ammended to provide more reasonable defaults for * mappings other than US/UK. They are used to map X11 KeySyms as found in * X11/keysym.h to Allegro's ALLEGRO_KEY_* codes. This will only work well on US/UK * keyboards since Allegro simply doesn't have ALLEGRO_KEY_* codes for non US/UK * keyboards. So with other mappings, the unmapped keys will be distributed * arbitrarily to the remaining ALLEGRO_KEY_* codes. * * Double mappings should be avoided, else they can lead to different keys * producing the same ALLEGRO_KEY_* code on some mappings. * * In cases where there is no other way to detect a key, since we have no * ASCII applied to it, like ALLEGRO_KEY_LEFT or ALLEGRO_KEY_PAUSE, multiple mappings should * be ok though. This table will never be able to be 100% perfect, so just * try to make it work for as many as possible, using additional hacks in * some cases. There is also still the possibility to override keys with * the [xkeyboard] config section, so users can always re-map keys. (E.g. * to play an Allegro game which hard-coded ALLEGRO_KEY_Y and ALLEGRO_KEY_X for left and * right.) */ static struct { KeySym keysym; int allegro_key; } translation_table[] = { {XK_a, ALLEGRO_KEY_A}, {XK_b, ALLEGRO_KEY_B}, {XK_c, ALLEGRO_KEY_C}, {XK_d, ALLEGRO_KEY_D}, {XK_e, ALLEGRO_KEY_E}, {XK_f, ALLEGRO_KEY_F}, {XK_g, ALLEGRO_KEY_G}, {XK_h, ALLEGRO_KEY_H}, {XK_i, ALLEGRO_KEY_I}, {XK_j, ALLEGRO_KEY_J}, {XK_k, ALLEGRO_KEY_K}, {XK_l, ALLEGRO_KEY_L}, {XK_m, ALLEGRO_KEY_M}, {XK_n, ALLEGRO_KEY_N}, {XK_o, ALLEGRO_KEY_O}, {XK_p, ALLEGRO_KEY_P}, {XK_q, ALLEGRO_KEY_Q}, {XK_r, ALLEGRO_KEY_R}, {XK_s, ALLEGRO_KEY_S}, {XK_t, ALLEGRO_KEY_T}, {XK_u, ALLEGRO_KEY_U}, {XK_v, ALLEGRO_KEY_V}, {XK_w, ALLEGRO_KEY_W}, {XK_x, ALLEGRO_KEY_X}, {XK_y, ALLEGRO_KEY_Y}, {XK_z, ALLEGRO_KEY_Z}, {XK_0, ALLEGRO_KEY_0}, {XK_1, ALLEGRO_KEY_1}, {XK_2, ALLEGRO_KEY_2}, {XK_3, ALLEGRO_KEY_3}, {XK_4, ALLEGRO_KEY_4}, {XK_5, ALLEGRO_KEY_5}, {XK_6, ALLEGRO_KEY_6}, {XK_7, ALLEGRO_KEY_7}, {XK_8, ALLEGRO_KEY_8}, {XK_9, ALLEGRO_KEY_9}, /* Double mappings for numeric keyboard. * If an X server actually uses both at the same time, Allegro will * detect them as the same. But normally, an X server just reports it as * either of them, and therefore we always get the keys as ALLEGRO_KEY_PAD_*. */ {XK_KP_0, ALLEGRO_KEY_PAD_0}, {XK_KP_Insert, ALLEGRO_KEY_PAD_0}, {XK_KP_1, ALLEGRO_KEY_PAD_1}, {XK_KP_End, ALLEGRO_KEY_PAD_1}, {XK_KP_2, ALLEGRO_KEY_PAD_2}, {XK_KP_Down, ALLEGRO_KEY_PAD_2}, {XK_KP_3, ALLEGRO_KEY_PAD_3}, {XK_KP_Page_Down, ALLEGRO_KEY_PAD_3}, {XK_KP_4, ALLEGRO_KEY_PAD_4}, {XK_KP_Left, ALLEGRO_KEY_PAD_4}, {XK_KP_5, ALLEGRO_KEY_PAD_5}, {XK_KP_Begin, ALLEGRO_KEY_PAD_5}, {XK_KP_6, ALLEGRO_KEY_PAD_6}, {XK_KP_Right, ALLEGRO_KEY_PAD_6}, {XK_KP_7, ALLEGRO_KEY_PAD_7}, {XK_KP_Home, ALLEGRO_KEY_PAD_7}, {XK_KP_8, ALLEGRO_KEY_PAD_8}, {XK_KP_Up, ALLEGRO_KEY_PAD_8}, {XK_KP_9, ALLEGRO_KEY_PAD_9}, {XK_KP_Page_Up, ALLEGRO_KEY_PAD_9}, {XK_KP_Delete, ALLEGRO_KEY_PAD_DELETE}, {XK_KP_Decimal, ALLEGRO_KEY_PAD_DELETE}, /* Double mapping! * Same as above - but normally, the X server just reports one or the * other for the Pause key, and the other is not reported for any key. */ {XK_Pause, ALLEGRO_KEY_PAUSE}, {XK_Break, ALLEGRO_KEY_PAUSE}, {XK_F1, ALLEGRO_KEY_F1}, {XK_F2, ALLEGRO_KEY_F2}, {XK_F3, ALLEGRO_KEY_F3}, {XK_F4, ALLEGRO_KEY_F4}, {XK_F5, ALLEGRO_KEY_F5}, {XK_F6, ALLEGRO_KEY_F6}, {XK_F7, ALLEGRO_KEY_F7}, {XK_F8, ALLEGRO_KEY_F8}, {XK_F9, ALLEGRO_KEY_F9}, {XK_F10, ALLEGRO_KEY_F10}, {XK_F11, ALLEGRO_KEY_F11}, {XK_F12, ALLEGRO_KEY_F12}, {XK_Escape, ALLEGRO_KEY_ESCAPE}, {XK_grave, ALLEGRO_KEY_TILDE}, /* US left of 1 */ {XK_minus, ALLEGRO_KEY_MINUS}, /* US right of 0 */ {XK_equal, ALLEGRO_KEY_EQUALS}, /* US 2 right of 0 */ {XK_BackSpace, ALLEGRO_KEY_BACKSPACE}, {XK_Tab, ALLEGRO_KEY_TAB}, {XK_bracketleft, ALLEGRO_KEY_OPENBRACE}, /* US right of P */ {XK_bracketright, ALLEGRO_KEY_CLOSEBRACE}, /* US 2 right of P */ {XK_Return, ALLEGRO_KEY_ENTER}, {XK_semicolon, ALLEGRO_KEY_SEMICOLON}, /* US right of L */ {XK_apostrophe, ALLEGRO_KEY_QUOTE}, /* US 2 right of L */ {XK_backslash, ALLEGRO_KEY_BACKSLASH}, /* US 3 right of L */ {XK_less, ALLEGRO_KEY_BACKSLASH2}, /* US left of Y */ {XK_comma, ALLEGRO_KEY_COMMA}, /* US right of M */ {XK_period, ALLEGRO_KEY_FULLSTOP}, /* US 2 right of M */ {XK_slash, ALLEGRO_KEY_SLASH}, /* US 3 right of M */ {XK_space, ALLEGRO_KEY_SPACE}, {XK_Insert, ALLEGRO_KEY_INSERT}, {XK_Delete, ALLEGRO_KEY_DELETE}, {XK_Home, ALLEGRO_KEY_HOME}, {XK_End, ALLEGRO_KEY_END}, {XK_Page_Up, ALLEGRO_KEY_PGUP}, {XK_Page_Down, ALLEGRO_KEY_PGDN}, {XK_Left, ALLEGRO_KEY_LEFT}, {XK_Right, ALLEGRO_KEY_RIGHT}, {XK_Up, ALLEGRO_KEY_UP}, {XK_Down, ALLEGRO_KEY_DOWN}, {XK_KP_Divide, ALLEGRO_KEY_PAD_SLASH}, {XK_KP_Multiply, ALLEGRO_KEY_PAD_ASTERISK}, {XK_KP_Subtract, ALLEGRO_KEY_PAD_MINUS}, {XK_KP_Add, ALLEGRO_KEY_PAD_PLUS}, {XK_KP_Enter, ALLEGRO_KEY_PAD_ENTER}, {XK_Print, ALLEGRO_KEY_PRINTSCREEN}, //{, ALLEGRO_KEY_ABNT_C1}, //{, ALLEGRO_KEY_YEN}, //{, ALLEGRO_KEY_KANA}, //{, ALLEGRO_KEY_CONVERT}, //{, ALLEGRO_KEY_NOCONVERT}, //{, ALLEGRO_KEY_AT}, //{, ALLEGRO_KEY_CIRCUMFLEX}, //{, ALLEGRO_KEY_COLON2}, //{, ALLEGRO_KEY_KANJI}, {XK_KP_Equal, ALLEGRO_KEY_PAD_EQUALS}, /* MacOS X */ //{, ALLEGRO_KEY_BACKQUOTE}, /* MacOS X */ //{, ALLEGRO_KEY_SEMICOLON}, /* MacOS X */ //{, ALLEGRO_KEY_COMMAND}, /* MacOS X */ {XK_Shift_L, ALLEGRO_KEY_LSHIFT}, {XK_Shift_R, ALLEGRO_KEY_RSHIFT}, {XK_Control_L, ALLEGRO_KEY_LCTRL}, {XK_Control_R, ALLEGRO_KEY_RCTRL}, {XK_Alt_L, ALLEGRO_KEY_ALT}, /* Double mappings. This is a bit of a problem, since you can configure * X11 differently to what report for those keys. */ {XK_Alt_R, ALLEGRO_KEY_ALTGR}, {XK_ISO_Level3_Shift, ALLEGRO_KEY_ALTGR}, {XK_Meta_L, ALLEGRO_KEY_LWIN}, {XK_Super_L, ALLEGRO_KEY_LWIN}, {XK_Meta_R, ALLEGRO_KEY_RWIN}, {XK_Super_R, ALLEGRO_KEY_RWIN}, {XK_Menu, ALLEGRO_KEY_MENU}, {XK_Scroll_Lock, ALLEGRO_KEY_SCROLLLOCK}, {XK_Num_Lock, ALLEGRO_KEY_NUMLOCK}, {XK_Caps_Lock, ALLEGRO_KEY_CAPSLOCK} }; /* Table of: Allegro's modifier flag, associated X11 flag, toggle method. */ static int modifier_flags[8][3] = { {ALLEGRO_KEYMOD_SHIFT, ShiftMask, 0}, {ALLEGRO_KEYMOD_CAPSLOCK, LockMask, 1}, {ALLEGRO_KEYMOD_CTRL, ControlMask, 0}, {ALLEGRO_KEYMOD_ALT, Mod1Mask, 0}, {ALLEGRO_KEYMOD_NUMLOCK, Mod2Mask, 1}, {ALLEGRO_KEYMOD_SCROLLLOCK, Mod3Mask, 1}, {ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN, Mod4Mask, 0}, /* Should we use only one? */ {ALLEGRO_KEYMOD_MENU, Mod5Mask, 0} /* AltGr */ }; /* Table of key names. */ static char const *key_names[ALLEGRO_KEY_MAX]; /* update_shifts * Update Allegro's key_shifts variable, directly from the corresponding * X11 modifiers state. */ static void update_shifts(XKeyEvent *event) { int mask = 0; int i; for (i = 0; i < 8; i++) { int j; /* This is the state of the modifiers just before the key * press/release. */ if (event->state & modifier_flags[i][1]) mask |= modifier_flags[i][0]; /* In case a modifier key itself was pressed, we now need to update * the above state for Allegro, which wants the state after the * press, not before as reported by X. */ for (j = 0; j < xmodmap->max_keypermod; j++) { if (event->keycode && event->keycode == xmodmap->modifiermap[i * xmodmap->max_keypermod + j]) { if (event->type == KeyPress) { /* Modifier key pressed - toggle or set flag. */ if (modifier_flags[i][2]) mask ^= modifier_flags[i][0]; else mask |= modifier_flags[i][0]; } else if (event->type == KeyRelease) { /* Modifier key of non-toggle key released - remove flag. */ if (!modifier_flags[i][2]) mask &= ~modifier_flags[i][0]; } } } } _key_shifts = mask; } /* find_unknown_key_assignment * In some cases, X11 doesn't report any KeySym for a key - so the earliest * time we can map it to an Allegro key is when it is first pressed. */ static int find_unknown_key_assignment(int i) { int j; for (j = 1; j < ALLEGRO_KEY_MAX; j++) { if (!used[j]) { const char *str; keycode_to_scancode[i] = j; str = XKeysymToString(keysyms[sym_per_key * (i - min_keycode)]); if (str) key_names[j] = str; else { key_names[j] = _al_keyboard_common_names[j]; } used[j] = 1; break; } } if (j == ALLEGRO_KEY_MAX) { ALLEGRO_ERROR("You have more keys reported by X than Allegro's " "maximum of %i keys. Please send a bug report.\n", ALLEGRO_KEY_MAX); keycode_to_scancode[i] = 0; } char str[1024]; sprintf(str, "Key %i missing:", i); for (j = 0; j < sym_per_key; j++) { char *sym_str = XKeysymToString(keysyms[sym_per_key * (i - min_keycode) + j]); sprintf(str + strlen(str), " %s", sym_str ? sym_str : "NULL"); } ALLEGRO_DEBUG("%s assigned to %i.\n", str, keycode_to_scancode[i]); return keycode_to_scancode[i]; } /* _al_xwin_keyboard_handler: * Keyboard "interrupt" handler. */ void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display) { int keycode; if (!xkeyboard_installed) return; keycode = keycode_to_scancode[event->keycode]; if (keycode == -1) keycode = find_unknown_key_assignment(event->keycode); update_shifts(event); /* Special case the pause key. */ if (keycode == ALLEGRO_KEY_PAUSE) { /* Allegro ignore's releasing of the pause key. */ if (event->type == KeyRelease) return; if (pause_key) { event->type = KeyRelease; pause_key = 0; } else { pause_key = 1; } } if (event->type == KeyPress) { /* Key pressed. */ int len; char buffer[16]; int unicode = 0; int filtered = 0; #if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING) if (xic) { len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL); } else #endif { /* XLookupString is supposed to only use ASCII. */ len = XLookupString(event, buffer, sizeof buffer, NULL, NULL); } buffer[len] = '\0'; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *ustr = al_ref_cstr(&info, buffer); unicode = al_ustr_get(ustr, 0); if (unicode < 0) unicode = 0; #ifdef ALLEGRO_XWINDOWS_WITH_XIM ALLEGRO_DISPLAY_XGLX *glx = (void *)display; filtered = XFilterEvent((XEvent *)event, glx->window); #endif if (keycode || unicode) { handle_key_press(keycode, unicode, filtered, _key_shifts, display); } } else { /* Key release. */ /* HACK: * Detect key repeat by looking forward to see if this release * is followed directly by a press event, in which case we assume * that this release event was generated in response to that key * press event. Events are simultaneous if they are separated by * less than 4 ms (a value that worked well on one machine where * this hack was needed). * * This is unnecessary on systems where XkbSetDetectableAutorepeat * works. */ if (XPending(event->display) > 0) { XEvent next_event; XPeekEvent(event->display, &next_event); if ((next_event.type == KeyPress) && (next_event.xkey.keycode == event->keycode) && (next_event.xkey.time - event->time) < 4) { return; } } handle_key_release(keycode, display); } } /* _al_xwin_keyboard_switch_handler: * Handle a focus switch event. */ void _al_xwin_keyboard_switch_handler(ALLEGRO_DISPLAY *display, bool focus_in) { _al_event_source_lock(&the_keyboard.parent.es); if (focus_in) { the_keyboard.state.display = display; #ifdef ALLEGRO_XWINDOWS_WITH_XIM if (xic) { ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; XSetICValues(xic, XNClientWindow, display_glx->window, NULL); } #endif } else { the_keyboard.state.display = NULL; } _al_event_source_unlock(&the_keyboard.parent.es); } /* find_allegro_key * Search the translation table for the Allegro key corresponding to the * given KeySym. */ static int find_allegro_key(KeySym sym) { int i; int n = sizeof translation_table / sizeof *translation_table; for (i = 0; i < n; i++) { if (translation_table[i].keysym == sym) return translation_table[i].allegro_key; } return 0; } /* scancode_to_name: * Converts the given scancode to a description of the key. */ static const char *x_scancode_to_name(int scancode) { ASSERT (scancode >= 0 && scancode < ALLEGRO_KEY_MAX); return key_names[scancode]; } /* _al_xwin_get_keyboard_mapping: * Generate a mapping from X11 keycodes to Allegro ALLEGRO_KEY_* codes. We have * two goals: Every keypress should be mapped to a distinct Allegro ALLEGRO_KEY_* * code. And we want the ALLEGRO_KEY_* codes to match the pressed * key to some extent. To do the latter, the X11 KeySyms produced by a key * are examined. If a match is found in the table above, the mapping is * added to the mapping table. If no known KeySym is found for a key (or * the same KeySym is found for more keys) - the remaining keys are * distributed arbitrarily to the remaining ALLEGRO_KEY_* codes. * * In a future version, this could be simplified by mapping *all* the X11 * KeySyms to ALLEGRO_KEY_* codes. */ static bool _al_xwin_get_keyboard_mapping(void) { int i; int count; int missing = 0; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); memset(used, 0, sizeof used); memset(keycode_to_scancode, 0, sizeof keycode_to_scancode); XDisplayKeycodes(system->x11display, &min_keycode, &max_keycode); count = 1 + max_keycode - min_keycode; if (keysyms) { XFree(keysyms); } keysyms = XGetKeyboardMapping(system->x11display, min_keycode, count, &sym_per_key); ALLEGRO_INFO("%i keys, %i symbols per key.\n", count, sym_per_key); if (sym_per_key <= 0) { return false; } missing = 0; for (i = min_keycode; i <= max_keycode; i++) { KeySym sym = keysyms[sym_per_key * (i - min_keycode)]; KeySym sym2 = keysyms[sym_per_key * (i - min_keycode) + 1]; char *sym_str, *sym2_str; int allegro_key = 0; char str[1024]; sym_str = XKeysymToString(sym); sym2_str = XKeysymToString(sym2); snprintf(str, sizeof str, "key [%i: %s %s]", i, sym_str ? sym_str : "NULL", sym2_str ? sym2_str : "NULL"); /* Hack for French keyboards, to correctly map ALLEGRO_KEY_0 to ALLEGRO_KEY_9. */ if (sym2 >= XK_0 && sym2 <= XK_9) { allegro_key = find_allegro_key(sym2); } if (!allegro_key) { if (sym != NoSymbol) { allegro_key = find_allegro_key(sym); if (allegro_key == 0) { missing++; ALLEGRO_DEBUG("%s defering.\n", str); } } else { /* No KeySym for this key - ignore it. */ keycode_to_scancode[i] = -1; ALLEGRO_DEBUG("%s not assigned.\n", str); } } if (allegro_key) { bool is_double = false; if (used[allegro_key]) { is_double = true; } keycode_to_scancode[i] = allegro_key; key_names[allegro_key] = XKeysymToString(keysyms[sym_per_key * (i - min_keycode)]); used[allegro_key] = 1; ALLEGRO_DEBUG("%s%s assigned to %i.\n", str, is_double ? " *double*" : "", allegro_key); } } if (missing) { /* The keys still not assigned are just assigned arbitrarily now. */ for (i = min_keycode; i <= max_keycode; i++) { if (keycode_to_scancode[i] == 0) { find_unknown_key_assignment(i); } } } if (xmodmap) XFreeModifiermap(xmodmap); xmodmap = XGetModifierMapping(system->x11display); for (i = 0; i < 8; i++) { int j; char str[1024]; sprintf(str, "Modifier %d:", i + 1); for (j = 0; j < xmodmap->max_keypermod; j++) { KeyCode keycode = xmodmap->modifiermap[i * xmodmap->max_keypermod + j]; // XKeycodeToKeysym is deprecated //KeySym sym = XKeycodeToKeysym(system->x11display, keycode, 0); KeySym sym = XkbKeycodeToKeysym(system->x11display, keycode, 0, 0); char *sym_str = XKeysymToString(sym); sprintf(str + strlen(str), " %s", sym_str ? sym_str : "NULL"); } ALLEGRO_DEBUG("%s\n", str); } /* The [xkeymap] section can be useful, e.g. if trying to play a * game which has X and Y hardcoded as ALLEGRO_KEY_X and ALLEGRO_KEY_Y to mean * left/right movement, but on the X11 keyboard X and Y are far apart. * For normal use, a user never should have to touch [xkeymap] anymore * though, and proper written programs will not hardcode such mappings. */ ALLEGRO_CONFIG *c = system->system.config; char const *key; ALLEGRO_CONFIG_ENTRY *it; key = al_get_first_config_entry(c, "xkeymap", &it); while (key) { char const *val; val = al_get_config_value(c, "xkeymap", key); int keycode = strtol(key, NULL, 10); int scancode = strtol(val, NULL, 10); if (keycode > 0 && scancode > 0) { keycode_to_scancode[keycode] = scancode; ALLEGRO_WARN("User override: KeySym %i assigned to %i.\n", keycode, scancode); } key = al_get_next_config_entry(&it); } return true; } /* x_set_leds: * Update the keyboard LEDs. */ static void x_set_leds(int leds) { XKeyboardControl values; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ASSERT(xkeyboard_installed); _al_mutex_lock(&system->lock); values.led = 1; values.led_mode = leds & ALLEGRO_KEYMOD_NUMLOCK ? LedModeOn : LedModeOff; XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); values.led = 2; values.led_mode = leds & ALLEGRO_KEYMOD_CAPSLOCK ? LedModeOn : LedModeOff; XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); values.led = 3; values.led_mode = leds & ALLEGRO_KEYMOD_SCROLLLOCK ? LedModeOn : LedModeOff; XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); _al_mutex_unlock(&system->lock); } /* x_keyboard_init * Initialise the X11 keyboard driver. */ static int x_keyboard_init(void) { #ifdef ALLEGRO_XWINDOWS_WITH_XIM char *old_locale; XIMStyles *xim_styles; XIMStyle xim_style = 0; char *imvalret; int i; #endif ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); if (xkeyboard_installed) return 0; if (s->x11display == NULL) return 0; main_pid = getpid(); memcpy(key_names, _al_keyboard_common_names, sizeof key_names); _al_mutex_lock(&s->lock); /* HACK: XkbSetDetectableAutoRepeat is broken in some versions of X.Org Bool supported; XkbSetDetectableAutoRepeat(s->x11display, True, &supported); if (!supported) { ALLEGRO_WARN("XkbSetDetectableAutoRepeat failed.\n"); } */ #ifdef ALLEGRO_XWINDOWS_WITH_XIM ALLEGRO_INFO("Using X Input Method.\n"); old_locale = setlocale(LC_CTYPE, NULL); ALLEGRO_DEBUG("Old locale: %s\n", old_locale ? old_locale : "(null)"); if (old_locale) { /* The return value of setlocale() may be clobbered by the next call * to setlocale() so we must copy it. */ old_locale = strdup(old_locale); } /* Otherwise we are restricted to ISO-8859-1 characters. */ if (setlocale(LC_CTYPE, "") == NULL) { ALLEGRO_WARN("Could not set default locale.\n"); } /* TODO: is this needed? modifiers = XSetLocaleModifiers("@im=none"); if (modifiers == NULL) { ALLEGRO_WARN("XSetLocaleModifiers failed.\n"); } */ xim = XOpenIM(s->x11display, NULL, NULL, NULL); if (xim == NULL) { ALLEGRO_WARN("XOpenIM failed.\n"); } if (old_locale) { ALLEGRO_DEBUG("Restoring old locale: %s\n", old_locale); setlocale(LC_CTYPE, old_locale); free(old_locale); } if (xim) { imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); if (imvalret != NULL || xim_styles == NULL) { ALLEGRO_WARN("Input method doesn't support any styles.\n"); } if (xim_styles) { xim_style = 0; for (i = 0; i < xim_styles->count_styles; i++) { if (xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) { xim_style = xim_styles->supported_styles[i]; break; } } if (xim_style == 0) { ALLEGRO_WARN("Input method doesn't support the style we support.\n"); } else { ALLEGRO_INFO("Input method style = %ld\n", xim_style); } XFree(xim_styles); } } if (xim && xim_style) { xic = XCreateIC(xim, XNInputStyle, xim_style, NULL); if (xic == NULL) { ALLEGRO_WARN("XCreateIC failed.\n"); } else { ALLEGRO_INFO("XCreateIC succeeded.\n"); } /* In case al_install_keyboard() is called when there already is * a display, we set it as client window. */ ALLEGRO_DISPLAY *display = al_get_current_display(); ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; if (display_glx && xic) XSetICValues(xic, XNClientWindow, display_glx->window, NULL); } #endif if (!_al_xwin_get_keyboard_mapping()) { return 1; } _al_mutex_unlock(&s->lock); xkeyboard_installed = 1; return 0; } /* x_keyboard_exit * Shut down the X11 keyboard driver. */ static void x_keyboard_exit(void) { if (!xkeyboard_installed) return; xkeyboard_installed = 0; ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); _al_mutex_lock(&s->lock); #ifdef ALLEGRO_XWINDOWS_WITH_XIM if (xic) { XDestroyIC(xic); xic = NULL; } if (xim) { XCloseIM(xim); xim = NULL; } #endif if (xmodmap) { XFreeModifiermap(xmodmap); xmodmap = NULL; } if (keysyms) { XFree(keysyms); keysyms = NULL; } _al_mutex_unlock(&s->lock); } /*---------------------------------------------------------------------- * * Supports for new API. For now this code is kept separate from the * above to ease merging changes made in the trunk. * */ /* forward declarations */ static bool xkeybd_init_keyboard(void); static void xkeybd_exit_keyboard(void); static ALLEGRO_KEYBOARD *xkeybd_get_keyboard(void); static bool xkeybd_set_keyboard_leds(int leds); static const char *xkeybd_keycode_to_name(int keycode); static void xkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); /* the driver vtable */ #define KEYDRV_XWIN AL_ID('X','W','I','N') static ALLEGRO_KEYBOARD_DRIVER keydrv_xwin = { KEYDRV_XWIN, "", "", "X11 keyboard", xkeybd_init_keyboard, xkeybd_exit_keyboard, xkeybd_get_keyboard, xkeybd_set_keyboard_leds, xkeybd_keycode_to_name, xkeybd_get_keyboard_state }; ALLEGRO_KEYBOARD_DRIVER *_al_xwin_keyboard_driver(void) { return &keydrv_xwin; } /* xkeybd_init_keyboard: * Initialise the driver. */ static bool xkeybd_init_keyboard(void) { if (x_keyboard_init() != 0) return false; memset(&the_keyboard, 0, sizeof the_keyboard); _al_event_source_init(&the_keyboard.parent.es); //_xwin_keydrv_set_leds(_key_shifts); /* Get the pid, which we use for the three finger salute */ main_pid = getpid(); return true; } /* xkeybd_exit_keyboard: * Shut down the keyboard driver. */ static void xkeybd_exit_keyboard(void) { x_keyboard_exit(); _al_event_source_free(&the_keyboard.parent.es); } /* xkeybd_get_keyboard: * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. */ static ALLEGRO_KEYBOARD *xkeybd_get_keyboard(void) { return (ALLEGRO_KEYBOARD *)&the_keyboard; } /* xkeybd_set_keyboard_leds: * Updates the LED state. */ static bool xkeybd_set_keyboard_leds(int leds) { x_set_leds(leds); return true; } /* xkeybd_keycode_to_name: * Converts the given keycode to a description of the key. */ static const char *xkeybd_keycode_to_name(int keycode) { return x_scancode_to_name(keycode); } /* xkeybd_get_keyboard_state: * Copy the current keyboard state into RET_STATE, with any necessary locking. */ static void xkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { _al_event_source_lock(&the_keyboard.parent.es); { *ret_state = the_keyboard.state; } _al_event_source_unlock(&the_keyboard.parent.es); } /* handle_key_press: [bgman thread] * Hook for the X event dispatcher to handle key presses. * The caller must lock the X-display. */ static int last_press_code = -1; static void handle_key_press(int mycode, int unichar, int filtered, unsigned int modifiers, ALLEGRO_DISPLAY *display) { bool is_repeat; is_repeat = (last_press_code == mycode); if (mycode > 0) last_press_code = mycode; _al_event_source_lock(&the_keyboard.parent.es); { /* Update the key_down array. */ _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode); /* Generate the events if necessary. */ if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) { ALLEGRO_EVENT event; event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; event.keyboard.timestamp = al_get_time(); event.keyboard.display = display; event.keyboard.keycode = last_press_code; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; event.keyboard.repeat = false; /* Don't send KEY_DOWN for non-physical key events. */ if (mycode > 0 && !is_repeat) { _al_event_source_emit_event(&the_keyboard.parent.es, &event); } /* Don't send KEY_CHAR for events filtered by an input method, * nor modifier keys. */ if (!filtered && mycode < ALLEGRO_KEY_MODIFIERS) { event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; event.keyboard.unichar = unichar; event.keyboard.modifiers = modifiers; event.keyboard.repeat = is_repeat; _al_event_source_emit_event(&the_keyboard.parent.es, &event); } } } _al_event_source_unlock(&the_keyboard.parent.es); /* Toggle mouse grab key. The system driver should not be locked here. */ if (last_press_code && !is_repeat) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); if (system->toggle_mouse_grab_keycode == mycode && (modifiers & system->toggle_mouse_grab_modifiers) == system->toggle_mouse_grab_modifiers) { if (system->mouse_grab_display == display) al_ungrab_mouse(); else al_grab_mouse(display); } } /* Exit by Ctrl-Alt-End. */ if ((_al_three_finger_flag) && ((mycode == ALLEGRO_KEY_DELETE) || (mycode == ALLEGRO_KEY_END)) && (modifiers & ALLEGRO_KEYMOD_CTRL) && (modifiers & (ALLEGRO_KEYMOD_ALT | ALLEGRO_KEYMOD_ALTGR))) { ALLEGRO_WARN("Three finger combo detected. SIGTERMing " "pid %d\n", main_pid); kill(main_pid, SIGTERM); } } /* handle_key_release: [bgman thread] * Hook for the X event dispatcher to handle key releases. * The caller must lock the X-display. */ static void handle_key_release(int mycode, ALLEGRO_DISPLAY *display) { if (last_press_code == mycode) last_press_code = -1; _al_event_source_lock(&the_keyboard.parent.es); { /* Update the key_down array. */ _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode); /* Generate the release event if necessary. */ if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) { ALLEGRO_EVENT event; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = display; event.keyboard.keycode = mycode; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_emit_event(&the_keyboard.parent.es, &event); } } _al_event_source_unlock(&the_keyboard.parent.es); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/xwindow.c0000644000175000001440000000754512104442100015306 0ustar tjadenusers#include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xsystem.h" #include "allegro5/internal/aintern_xwindow.h" ALLEGRO_DEBUG_CHANNEL("xwindow") void _al_xwin_set_size_hints(ALLEGRO_DISPLAY *d, int x_off, int y_off) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (void *)d; XSizeHints *hints = XAllocSizeHints(); hints->flags = 0; /* Do not force the size of the window on resizeable or fullscreen windows */ /* on fullscreen windows, it confuses most X Window Managers */ if (!(d->flags & ALLEGRO_RESIZABLE) && !(d->flags & ALLEGRO_FULLSCREEN)) { hints->flags |= PMinSize | PMaxSize | PBaseSize; hints->min_width = hints->max_width = hints->base_width = d->w; hints->min_height = hints->max_height = hints->base_height = d->h; } // Tell WMs to respect our chosen position, otherwise the x_off/y_off // positions passed to XCreateWindow will be ignored by most WMs. if (x_off != INT_MAX && y_off != INT_MAX) { ALLEGRO_DEBUG("Force window position to %d, %d.\n", x_off, y_off); hints->flags |= PPosition; hints->x = x_off; hints->y = y_off; } if (d->flags & ALLEGRO_FULLSCREEN) { /* kwin will improperly layer a panel over our window on a second display without this. * some other Size flags may cause glitches with various WMs, but this seems to be ok * with metacity and kwin. As noted in xdpy_create_display, compiz is just broken. */ hints->flags |= PBaseSize; hints->base_width = d->w; hints->base_height = d->h; } XSetWMNormalHints(system->x11display, glx->window, hints); XFree(hints); } void _al_xwin_reset_size_hints(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (void *)d; XSizeHints *hints = XAllocSizeHints(); hints->flags = PMinSize | PMaxSize; hints->min_width = 0; hints->min_height = 0; // FIXME: Is there a way to remove/reset max dimensions? hints->max_width = 32768; hints->max_height = 32768; XSetWMNormalHints(system->x11display, glx->window, hints); XFree(hints); } #define X11_ATOM(x) XInternAtom(x11, #x, False); /* Note: The system mutex must be locked (exactly once) before * calling this as we call _al_display_xglx_await_resize. */ void _al_xwin_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Display *x11 = system->x11display; #ifndef ALLEGRO_RASPBERRYPI int old_resize_count = glx->resize_count; #endif ALLEGRO_DEBUG("Toggling _NET_WM_STATE_FULLSCREEN hint: %d\n", value); XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); xev.xclient.window = glx->window; xev.xclient.format = 32; // Note: It seems 0 is not reliable except when mapping a window - // 2 is all we need though. xev.xclient.data.l[0] = value; /* 0 = off, 1 = on, 2 = toggle */ xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_FULLSCREEN); xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 1; XSendEvent( x11, #ifndef ALLEGRO_RASPBERRYPI RootWindowOfScreen(ScreenOfDisplay(x11, glx->xscreen)), #else RootWindowOfScreen(ScreenOfDisplay(x11, DefaultScreen(x11))), #endif False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); #ifndef ALLEGRO_RASPBERRYPI if (value == 2) { /* Only wait for a resize if toggling. */ _al_display_xglx_await_resize(display, old_resize_count, true); } #endif } allegro-5.0.10/src/x/xfullscreen.c0000644000175000001440000007162212104442100016136 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xfullscreen.h" #include "allegro5/internal/aintern_xsystem.h" ALLEGRO_DEBUG_CHANNEL("display") /* globals - this might be better in ALLEGRO_SYSTEM_XGLX */ _ALLEGRO_XGLX_MMON_INTERFACE _al_xglx_mmon_interface; /* generic multi-head x */ int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) { int i; ALLEGRO_DEBUG("mhead get default adapter\n"); if (ScreenCount(s->x11display) == 1) return 0; _al_mutex_lock(&s->lock); Window focus; int revert_to = 0; XWindowAttributes attr; Screen *focus_screen; if (!XGetInputFocus(s->x11display, &focus, &revert_to)) { ALLEGRO_ERROR("XGetInputFocus failed!"); _al_mutex_unlock(&s->lock); return 0; } if (focus == None) { ALLEGRO_ERROR("XGetInputFocus returned None!\n"); _al_mutex_unlock(&s->lock); return 0; } else if (focus == PointerRoot) { ALLEGRO_DEBUG("XGetInputFocus returned PointerRoot.\n"); /* XXX TEST THIS >:( */ Window root, child; int root_x, root_y; int win_x, win_y; unsigned int mask; if (XQueryPointer(s->x11display, focus, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask) == False) { ALLEGRO_ERROR("XQueryPointer failed :("); _al_mutex_unlock(&s->lock); return 0; } focus = root; } else { ALLEGRO_DEBUG("XGetInputFocus returned %i!\n", (int)focus); } XGetWindowAttributes(s->x11display, focus, &attr); focus_screen = attr.screen; int ret = 0; for (i = 0; i < ScreenCount(s->x11display); i++) { if (ScreenOfDisplay(s->x11display, i) == focus_screen) { _al_mutex_unlock(&s->lock); ret = i; break; } } _al_mutex_unlock(&s->lock); return ret; } /* in pure multi-head mode, allegro's virtual adapters map directly to X Screens. */ int _al_xsys_mheadx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) { (void)s; ALLEGRO_DEBUG("mhead get screen %i\n", adapter); return adapter; } /* Returns the parent window of "window" (i.e. the ancestor of window that is a direct child of the root, or window itself if it is a direct child). If window is the root window, returns window. */ static Window get_toplevel_parent(ALLEGRO_SYSTEM_XGLX *s, Window window) { Window parent; Window root; Window * children; unsigned int num_children; while (1) { /* XXX enlightenment shows some very strange errors here, * for some reason 'window' isn't valid when the mouse happens * to be over the windeco when this is called.. */ if (0 == XQueryTree(s->x11display, window, &root, &parent, &children, &num_children)) { ALLEGRO_ERROR("XQueryTree error\n"); return None; } if (children) { /* must test for NULL */ XFree(children); } if (window == root || parent == root) { return window; } else { window = parent; } } return None; } /* used for xinerama and pure xrandr modes */ void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y) { Window focus; int revert_to = 0; _al_mutex_lock(&s->lock); if (!XGetInputFocus(s->x11display, &focus, &revert_to)) { ALLEGRO_ERROR("XGetInputFocus failed!\n"); _al_mutex_unlock(&s->lock); return; } if (focus == None || focus == PointerRoot) { ALLEGRO_DEBUG("XGetInputFocus returned special window, selecting default root!\n"); focus = DefaultRootWindow(s->x11display); } else { /* this horribleness is due to toolkits like GTK (and probably Qt) creating * a 1x1 window under the window you're looking at that actually accepts * all input, so we need to grab the top level parent window rather than * whatever happens to have focus */ focus = get_toplevel_parent(s, focus); } ALLEGRO_DEBUG("XGetInputFocus returned %i\n", (int)focus); XWindowAttributes attr; if (XGetWindowAttributes(s->x11display, focus, &attr) == 0) { ALLEGRO_ERROR("XGetWindowAttributes failed :(\n"); _al_mutex_unlock(&s->lock); return; } _al_mutex_unlock(&s->lock); /* check the center of the window with focus * might be a bit more useful than just checking the top left */ ALLEGRO_DEBUG("focus geom: %ix%i %ix%i\n", attr.x, attr.y, attr.width, attr.height); *x = (attr.x + (attr.x + attr.width)) / 2; *y = (attr.y + (attr.y + attr.height)) / 2; } /*--------------------------------------------------------------------------- * * Xinerama * */ #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA static void xinerama_init(ALLEGRO_SYSTEM_XGLX *s) { int event_base = 0; int error_base = 0; /* init xinerama info to defaults */ s->xinerama_available = 0; s->xinerama_screen_count = 0; s->xinerama_screen_info = NULL; _al_mutex_lock(&s->lock); if (XineramaQueryExtension(s->x11display, &event_base, &error_base)) { int minor_version = 0, major_version = 0; int status = XineramaQueryVersion(s->x11display, &major_version, &minor_version); ALLEGRO_INFO("Xinerama version: %i.%i\n", major_version, minor_version); if (status && !XineramaIsActive(s->x11display)) { ALLEGRO_WARN("Xinerama is not active\n"); } else { s->xinerama_screen_info = XineramaQueryScreens(s->x11display, &s->xinerama_screen_count); if (!s->xinerama_screen_info) { ALLEGRO_ERROR("Xinerama failed to query screens.\n"); } else { s->xinerama_available = 1; ALLEGRO_INFO("Xinerama is active\n"); } } } if (!s->xinerama_available) { ALLEGRO_WARN("Xinerama extension is not available.\n"); } _al_mutex_unlock(&s->lock); } static void xinerama_exit(ALLEGRO_SYSTEM_XGLX *s) { if (!s->xinerama_available) return; ALLEGRO_DEBUG("xfullscreen: xinerama exit.\n"); if (s->xinerama_screen_info) XFree(s->xinerama_screen_info); s->xinerama_available = 0; s->xinerama_screen_count = 0; s->xinerama_screen_info = NULL; } #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE static void xinerama_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) { ALLEGRO_ASSERT(adapter >= 0 && adapter < s->xinerama_screen_count); *x = s->xinerama_screen_info[adapter].x_org; *y = s->xinerama_screen_info[adapter].y_org; ALLEGRO_DEBUG("xinerama dpy off %ix%i\n", *x, *y); } static bool xinerama_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) { if (adapter < 0 || adapter >= s->xinerama_screen_count) return false; mi->x1 = s->xinerama_screen_info[adapter].x_org; mi->y1 = s->xinerama_screen_info[adapter].y_org; mi->x2 = mi->x1 + s->xinerama_screen_info[adapter].width; mi->y2 = mi->y1 + s->xinerama_screen_info[adapter].height; return true; } static ALLEGRO_DISPLAY_MODE *xinerama_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int i, ALLEGRO_DISPLAY_MODE *mode) { if (adapter < 0 || adapter >= s->xinerama_screen_count) return NULL; if (i != 0) return NULL; mode->width = s->xinerama_screen_info[adapter].width; mode->height = s->xinerama_screen_info[adapter].height; mode->format = 0; mode->refresh_rate = 0; return mode; } static int xinerama_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) { int center_x = 0, center_y = 0; ALLEGRO_DEBUG("xinerama get default adapter\n"); _al_xsys_get_active_window_center(s, ¢er_x, ¢er_y); ALLEGRO_DEBUG("xinerama got active center: %ix%i\n", center_x, center_y); int i; for (i = 0; i < s->xinerama_screen_count; i++) { if (center_x >= s->xinerama_screen_info[i].x_org && center_x <= s->xinerama_screen_info[i].x_org + s->xinerama_screen_info[i].width && center_y >= s->xinerama_screen_info[i].y_org && center_y <= s->xinerama_screen_info[i].y_org + s->xinerama_screen_info[i].height) { ALLEGRO_DEBUG("center is inside (%i) %ix%i %ix%i\n", i, s->xinerama_screen_info[i].x_org, s->xinerama_screen_info[i].y_org, s->xinerama_screen_info[i].width, s->xinerama_screen_info[i].height); return i; } } ALLEGRO_DEBUG("xinerama returning default 0\n"); return 0; } /* similar to multi-head x, but theres only one X Screen, so we return 0 always */ static int xinerama_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) { (void)s; (void)adapter; return 0; } #endif /* ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ #endif /* ALLEGRO_XWINDOWS_WITH_XINERAMA */ /*--------------------------------------------------------------------------- * * XF86VidMode * */ #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE // XXX retest under multi-head! static int xfvm_get_num_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) { #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { if (adapter < 0 || adapter > s->xinerama_screen_count) return 0; /* due to braindeadedness of the NVidia binary driver we can't know what an individual * monitor's modes are, as the NVidia binary driver only reports combined "BigDesktop" * or "TwinView" modes to user-space. There is no way to set modes on individual screens. * As such, we can only do one thing here and report one single mode, * which will end up being the xinerama size for the requested adapter */ return 1; } #endif if (adapter < 0 || adapter > s->xfvm_screen_count) return 0; return s->xfvm_screen[adapter].mode_count; } static ALLEGRO_DISPLAY_MODE *xfvm_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int i, ALLEGRO_DISPLAY_MODE *mode) { int denom; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView gives us one large screen via xfvm, and no way to * properly change modes on individual monitors, so we want to query * xinerama for the lone mode. */ if (s->xinerama_available && s->xfvm_screen_count != s->xinerama_screen_count) { return xinerama_get_mode(s, adapter, i, mode); } #endif if (adapter < 0 || adapter > s->xfvm_screen_count) return NULL; if (i < 0 || i > s->xfvm_screen[adapter].mode_count) return NULL; mode->width = s->xfvm_screen[adapter].modes[i]->hdisplay; mode->height = s->xfvm_screen[adapter].modes[i]->vdisplay; mode->format = 0; denom = s->xfvm_screen[adapter].modes[i]->htotal * s->xfvm_screen[adapter].modes[i]->vtotal; if (denom > 0) mode->refresh_rate = s->xfvm_screen[adapter].modes[i]->dotclock * 1000L / denom; else mode->refresh_rate = 0; return mode; } static bool xfvm_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh_rate) { int mode_idx = -1; int adapter = _al_xglx_get_adapter(s, d, false); #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { /* at least pretend we set a mode if its the current mode */ if (s->xinerama_screen_info[adapter].width != w || s->xinerama_screen_info[adapter].height != h) return false; return true; } #endif mode_idx = _al_xglx_fullscreen_select_mode(s, adapter, w, h, format, refresh_rate); if (mode_idx == -1) return false; if (!XF86VidModeSwitchToMode(s->x11display, adapter, s->xfvm_screen[adapter].modes[mode_idx])) { ALLEGRO_ERROR("xfullscreen: XF86VidModeSwitchToMode failed\n"); return false; } return true; } static void xfvm_store_video_mode(ALLEGRO_SYSTEM_XGLX *s) { int n; ALLEGRO_DEBUG("xfullscreen: xfvm_store_video_mode\n"); #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { return; } #endif // save all original modes int i; for (i = 0; i < s->xfvm_screen_count; i++) { n = xfvm_get_num_modes(s, i); if (n == 0) { /* XXX what to do here? */ continue; } s->xfvm_screen[i].original_mode = s->xfvm_screen[i].modes[0]; int j; for (j = 0; j < s->xfvm_screen[i].mode_count; j++) { ALLEGRO_DEBUG("xfvm: screen[%d] mode[%d] = (%d, %d)\n", i, j, s->xfvm_screen[i].modes[j]->hdisplay, s->xfvm_screen[i].modes[j]->vdisplay); } ALLEGRO_INFO("xfvm: screen[%d] original mode = (%d, %d)\n", i, s->xfvm_screen[i].original_mode->hdisplay, s->xfvm_screen[i].original_mode->vdisplay); } } static void xfvm_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) { Bool ok; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { return; } #endif if (adapter < 0 || adapter > s->xfvm_screen_count) return; ASSERT(s->xfvm_screen[adapter].original_mode); ALLEGRO_DEBUG("xfullscreen: xfvm_restore_video_mode (%d, %d)\n", s->xfvm_screen[adapter].original_mode->hdisplay, s->xfvm_screen[adapter].original_mode->vdisplay); ok = XF86VidModeSwitchToMode(s->x11display, adapter, s->xfvm_screen[adapter].original_mode); if (!ok) { ALLEGRO_ERROR("xfullscreen: XF86VidModeSwitchToMode failed\n"); } if (s->mouse_grab_display) { XUngrabPointer(s->gfxdisplay, CurrentTime); s->mouse_grab_display = NULL; } /* This is needed, at least on my machine, or the program may terminate * before the screen mode is actually reset. --pw */ /* can we move this into shutdown_system? It could speed up mode restores -TF */ XFlush(s->gfxdisplay); } static void xfvm_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) { int tmp_x = 0, tmp_y = 0; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available) { xinerama_get_display_offset(s, adapter, &tmp_x, &tmp_y); } //else #else (void)s; (void)adapter; #endif /* don't set the output params if function fails */ /* XXX I don't think this part makes sense at all. * in multi-head mode, the origin is always 0x0 * in Xinerama, its caught by xinerama, and xfvm is NEVER * used when xrandr is active -TF */ //if (!XF86VidModeGetViewPort(s->x11display, adapter, &tmp_x, &tmp_y)) // return; *x = tmp_x; *y = tmp_y; ALLEGRO_DEBUG("xfvm dpy off %ix%i\n", *x, *y); } static int xfvm_get_num_adapters(ALLEGRO_SYSTEM_XGLX *s) { #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available) { return s->xinerama_screen_count; } #endif return s->xfvm_screen_count; } static bool xfvm_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) { #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available) { return xinerama_get_monitor_info(s, adapter, mi); } #endif if (adapter < 0 || adapter > s->xfvm_screen_count) return false; XWindowAttributes xwa; Window root; _al_mutex_lock(&s->lock); root = RootWindow(s->x11display, adapter); XGetWindowAttributes(s->x11display, root, &xwa); _al_mutex_unlock(&s->lock); /* under plain X, each screen has its own origin, and theres no way to figure out orientation or relative position */ mi->x1 = 0; mi->y1 = 0; mi->x2 = xwa.width; mi->y2 = xwa.height; return true; } static int xfvm_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) { ALLEGRO_DEBUG("xfvm get default adapter\n"); #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available) { return xinerama_get_default_adapter(s); } #endif return _al_xsys_mheadx_get_default_adapter(s); } static int xfvm_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) { ALLEGRO_DEBUG("xfvm get xscreen for adapter %i\n", adapter); #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA if (s->xinerama_available) { return xinerama_get_xscreen(s, adapter); } #endif return _al_xsys_mheadx_get_xscreen(s, adapter); } static void xfvm_post_setup(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d) { int x = 0, y = 0; XWindowAttributes xwa; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { return; } #endif int adapter = _al_xglx_get_adapter(s, d, false); XGetWindowAttributes(s->x11display, d->window, &xwa); xfvm_get_display_offset(s, adapter, &x, &y); /* some window managers like to move our window even if we explicitly tell it not to * so we need to get the correct offset here */ x = xwa.x - x; y = xwa.y - y; ALLEGRO_DEBUG("xfvm set view port: %ix%i\n", x, y); XF86VidModeSetViewPort(s->x11display, adapter, x, y); } static void xfvm_init(ALLEGRO_SYSTEM_XGLX *s) { int event_base = 0; int error_base = 0; /* init xfvm info to defaults */ s->xfvm_available = 0; s->xfvm_screen_count = 0; s->xfvm_screen = NULL; _al_mutex_lock(&s->lock); if (XF86VidModeQueryExtension(s->x11display, &event_base, &error_base)) { int minor_version = 0, major_version = 0; int status = XF86VidModeQueryVersion(s->x11display, &major_version, &minor_version); ALLEGRO_INFO("XF86VidMode version: %i.%i\n", major_version, minor_version); if (!status) { ALLEGRO_WARN("XF86VidMode not available, XF86VidModeQueryVersion failed.\n"); } else { // I don't actually know what versions are required here, just going to assume any is ok for now. ALLEGRO_INFO("XF86VidMode %i.%i is active\n", major_version, minor_version); s->xfvm_available = 1; } } else { ALLEGRO_WARN("XF86VidMode extension is not available.\n"); } if (s->xfvm_available) { int num_screens; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* This is some fun stuff right here, if XRANDR is available, we can't use the xinerama screen count * and we really want the xrandr init in xglx_initialize to come last so it overrides xf86vm if available * and I really don't want to add more XRRQuery* or #ifdefs here. * I don't think XRandR can be disabled once its loaded, * so just seeing if its in the extension list should be fine. */ /* interesting thing to note is if XRandR is available, that means we have TwinView, * and not multi-head Xinerama mode, as True Xinerama disables XRandR on my NVidia. * which means all of those xfvm_screen_count != xinerama_screen_count tests * only apply to TwinView. As this code below sets xfvm_screen_count to xinerama_screen_count * making all those compares fail, and make us fall back to the normal xfvm multi-head code. */ /* second note, if FakeXinerama is disabled on TwinView setups, we will end up using * XRandR, as there is no other way to detect TwinView outside of libNVCtrl */ int ext_op, ext_evt, ext_err; Bool ext_ret = XQueryExtension(s->x11display, "RANDR", &ext_op, &ext_evt, &ext_err); if (s->xinerama_available && ext_ret == False) { num_screens = s->xinerama_screen_count; } else #endif { num_screens = ScreenCount(s->x11display); } ALLEGRO_DEBUG("XF86VidMode Got %d screens.\n", num_screens); s->xfvm_screen_count = num_screens; s->xfvm_screen = al_calloc(num_screens, sizeof(*s->xfvm_screen)); if (!s->xfvm_screen) { ALLEGRO_ERROR("XF86VidMode: failed to allocate screen array.\n"); s->xfvm_available = 0; } else { int i; for (i = 0; i < num_screens; i++) { ALLEGRO_DEBUG("XF86VidMode GetAllModeLines on screen %d.\n", i); if (!XF86VidModeGetAllModeLines(s->x11display, i, &(s->xfvm_screen[i].mode_count), &(s->xfvm_screen[i].modes))) { /* XXX what to do here? */ } } _al_xglx_mmon_interface.get_num_display_modes = xfvm_get_num_modes; _al_xglx_mmon_interface.get_display_mode = xfvm_get_mode; _al_xglx_mmon_interface.set_mode = xfvm_set_mode; _al_xglx_mmon_interface.store_mode = xfvm_store_video_mode; _al_xglx_mmon_interface.restore_mode = xfvm_restore_video_mode; _al_xglx_mmon_interface.get_display_offset = xfvm_get_display_offset; _al_xglx_mmon_interface.get_num_adapters = xfvm_get_num_adapters; _al_xglx_mmon_interface.get_monitor_info = xfvm_get_monitor_info; _al_xglx_mmon_interface.get_default_adapter = xfvm_get_default_adapter; _al_xglx_mmon_interface.get_xscreen = xfvm_get_xscreen; _al_xglx_mmon_interface.post_setup = xfvm_post_setup; } } _al_mutex_unlock(&s->lock); } static void xfvm_exit(ALLEGRO_SYSTEM_XGLX *s) { int adapter; ALLEGRO_DEBUG("xfullscreen: XFVM exit\n"); for (adapter = 0; adapter < s->xfvm_screen_count; adapter++) { if (s->xfvm_screen[adapter].mode_count > 0) { int i; for (i = 0; i < s->xfvm_screen[adapter].mode_count; i++) { if (s->xfvm_screen[adapter].modes[i]->privsize > 0) { //XFree(s->xfvm_screen[adapter].modes[i]->private); } } //XFree(s->xfvm_screen[adapter].modes); } s->xfvm_screen[adapter].mode_count = 0; s->xfvm_screen[adapter].modes = NULL; s->xfvm_screen[adapter].original_mode = NULL; ALLEGRO_DEBUG("xfullscreen: XFVM freed adapter %d.\n", adapter); } al_free(s->xfvm_screen); s->xfvm_screen = NULL; } #endif /* ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ /*--------------------------------------------------------------------------- * * Generic multi-monitor interface * */ static bool init_mmon_interface(ALLEGRO_SYSTEM_XGLX *s) { if (s->x11display == NULL) { ALLEGRO_WARN("Not connected to X server.\n"); return false; } if (s->mmon_interface_inited) return true; /* Shouldn't we avoid initing any more of these than we need? */ /* nope, no way to tell which is going to be used on any given system * this way, xrandr always overrides everything else should it succeed. * And when xfvm is chosen, it needs xinerama inited, * incase there are multiple screens. */ #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA xinerama_init(s); #endif #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE xfvm_init(s); #endif #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR _al_xsys_xrandr_init(s); #endif if (_al_xglx_mmon_interface.store_mode) _al_xglx_mmon_interface.store_mode(s); s->mmon_interface_inited = true; return true; } void _al_xsys_mmon_exit(ALLEGRO_SYSTEM_XGLX *s) { if (!s->mmon_interface_inited) return; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA xinerama_exit(s); #endif #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE xfvm_exit(s); #endif #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR _al_xsys_xrandr_exit(s); #endif s->mmon_interface_inited = false; } int _al_xglx_get_num_display_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) { if (!init_mmon_interface(s)) return 0; if (adapter < 0) adapter = _al_xglx_get_default_adapter(s); if (!_al_xglx_mmon_interface.get_num_display_modes) { if (adapter != 0) return 0; return 1; } return _al_xglx_mmon_interface.get_num_display_modes(s, adapter); } ALLEGRO_DISPLAY_MODE *_al_xglx_get_display_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int index, ALLEGRO_DISPLAY_MODE *mode) { if (!init_mmon_interface(s)) return NULL; if (adapter < 0) adapter = _al_xglx_get_default_adapter(s); if (!_al_xglx_mmon_interface.get_display_mode) { mode->width = DisplayWidth(s->x11display, DefaultScreen(s->x11display)); mode->height = DisplayHeight(s->x11display, DefaultScreen(s->x11display)); mode->format = 0; mode->refresh_rate = 0; return NULL; } return _al_xglx_mmon_interface.get_display_mode(s, adapter, index, mode); } int _al_xglx_fullscreen_select_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int w, int h, int format, int refresh_rate) { /* GCC complains about mode being uninitialized without this: */ ALLEGRO_DISPLAY_MODE mode = mode; ALLEGRO_DISPLAY_MODE mode2; int i; int n; if (!init_mmon_interface(s)) return -1; if (adapter < 0) adapter = _al_xglx_get_default_adapter(s); n = _al_xglx_get_num_display_modes(s, adapter); if (!n) return -1; /* Find all modes with correct parameters. */ int possible_modes[n]; int possible_count = 0; for (i = 0; i < n; i++) { if (!_al_xglx_get_display_mode(s, adapter, i, &mode)) { continue; } if (mode.width == w && mode.height == h && (format == 0 || mode.format == format) && (refresh_rate == 0 || mode.refresh_rate == refresh_rate)) { possible_modes[possible_count++] = i; } } if (!possible_count) return -1; /* Choose mode with highest refresh rate. */ int best_mode = possible_modes[0]; _al_xglx_get_display_mode(s, adapter, best_mode, &mode); for (i = 1; i < possible_count; i++) { if (!_al_xglx_get_display_mode(s, adapter, possible_modes[i], &mode2)) { continue; } if (mode2.refresh_rate > mode.refresh_rate) { mode = mode2; best_mode = possible_modes[i]; } } ALLEGRO_INFO("best mode [%d] = (%d, %d)\n", best_mode, mode.width, mode.height); return best_mode; } bool _al_xglx_fullscreen_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh_rate) { if (!init_mmon_interface(s)) return false; if (!_al_xglx_mmon_interface.set_mode) return false; return _al_xglx_mmon_interface.set_mode(s, d, w, h, format, refresh_rate); } void _al_xglx_fullscreen_to_display(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d) { if (!init_mmon_interface(s)) return; if (!_al_xglx_mmon_interface.post_setup) return; _al_xglx_mmon_interface.post_setup(s, d); } void _al_xglx_store_video_mode(ALLEGRO_SYSTEM_XGLX *s) { if (!init_mmon_interface(s)) return; if (!_al_xglx_mmon_interface.store_mode) return; _al_xglx_mmon_interface.store_mode(s); } void _al_xglx_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) { if (!init_mmon_interface(s)) return; if (!_al_xglx_mmon_interface.restore_mode) return; _al_xglx_mmon_interface.restore_mode(s, adapter); } void _al_xglx_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) { if (!init_mmon_interface(s)) return; if (!_al_xglx_mmon_interface.get_display_offset) return; _al_xglx_mmon_interface.get_display_offset(s, adapter, x, y); } bool _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info) { if (!init_mmon_interface(s)) return false; if (!_al_xglx_mmon_interface.get_monitor_info) { _al_mutex_lock(&s->lock); info->x1 = 0; info->y1 = 0; info->x2 = DisplayWidth(s->x11display, DefaultScreen(s->x11display)); info->y2 = DisplayHeight(s->x11display, DefaultScreen(s->x11display)); _al_mutex_unlock(&s->lock); return true; } return _al_xglx_mmon_interface.get_monitor_info(s, adapter, info); } int _al_xglx_get_num_video_adapters(ALLEGRO_SYSTEM_XGLX *s) { if (!init_mmon_interface(s)) return 0; if (!_al_xglx_mmon_interface.get_num_adapters) return 1; return _al_xglx_mmon_interface.get_num_adapters(s); } int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) { ALLEGRO_DEBUG("get default adapter\n"); if (!init_mmon_interface(s)) return 0; if (!_al_xglx_mmon_interface.get_default_adapter) return 0; return _al_xglx_mmon_interface.get_default_adapter(s); } int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) { ALLEGRO_DEBUG("get xscreen\n"); if (!init_mmon_interface(s)) return 0; if (!_al_xglx_mmon_interface.get_xscreen) return 0; return _al_xglx_mmon_interface.get_xscreen(s, adapter); } int _al_xglx_get_adapter(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool recalc) { if (!init_mmon_interface(s)) return 0; if (d->adapter >= 0 && !recalc) return d->adapter; if (!_al_xglx_mmon_interface.get_adapter) return 0; return _al_xglx_mmon_interface.get_adapter(s, d); } void _al_xglx_handle_mmon_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e) { ALLEGRO_DEBUG("got event %i\n", e->type); // if we haven't setup the mmon interface, just bail if (!s->mmon_interface_inited) return; // bail if the current mmon interface doesn't implement the handle_xevent method if (!_al_xglx_mmon_interface.handle_xevent) return; _al_xglx_mmon_interface.handle_xevent(s, d, e); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/x/xdisplay.c0000644000175000001440000011021412104442100015430 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/internal/aintern_x.h" #include "allegro5/internal/aintern_xcursor.h" #include "allegro5/internal/aintern_xdisplay.h" #include "allegro5/internal/aintern_xfullscreen.h" #include "allegro5/internal/aintern_xglx_config.h" #include "allegro5/internal/aintern_xsystem.h" #include "allegro5/internal/aintern_xwindow.h" #include "allegro5/platform/aintxglx.h" ALLEGRO_DEBUG_CHANNEL("display") static ALLEGRO_DISPLAY_INTERFACE xdpy_vt; /* Helper to set a window icon. We use the _NET_WM_ICON property which is * supported by modern window managers. * * The old method is XSetWMHints but the (antiquated) ICCCM talks about 1-bit * pixmaps. For colour icons, perhaps you're supposed use the icon_window, * and draw the window yourself? */ static bool xdpy_set_icon_inner(Display *x11display, Window window, ALLEGRO_BITMAP *bitmap, int prop_mode) { int w, h; int data_size; unsigned long *data; /* Yes, unsigned long, even on 64-bit platforms! */ ALLEGRO_LOCKED_REGION *lr; bool ret; w = al_get_bitmap_width(bitmap); h = al_get_bitmap_height(bitmap); data_size = 2 + w * h; data = al_malloc(data_size * sizeof(data[0])); if (!data) return false; lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, ALLEGRO_LOCK_READONLY); if (lr) { int x, y; ALLEGRO_COLOR c; unsigned char r, g, b, a; Atom _NET_WM_ICON; data[0] = w; data[1] = h; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { c = al_get_pixel(bitmap, x, y); al_unmap_rgba(c, &r, &g, &b, &a); data[2 + y*w + x] = (a << 24) | (r << 16) | (g << 8) | b; } } _NET_WM_ICON = XInternAtom(x11display, "_NET_WM_ICON", False); XChangeProperty(x11display, window, _NET_WM_ICON, XA_CARDINAL, 32, prop_mode, (unsigned char *)data, data_size); al_unlock_bitmap(bitmap); ret = true; } else { ret = false; } al_free(data); return ret; } static void xdpy_set_icons(ALLEGRO_DISPLAY *d, int num_icons, ALLEGRO_BITMAP *bitmaps[]) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; int prop_mode = PropModeReplace; int i; _al_mutex_lock(&system->lock); for (i = 0; i < num_icons; i++) { if (xdpy_set_icon_inner(system->x11display, glx->window, bitmaps[i], prop_mode)) { prop_mode = PropModeAppend; } } _al_mutex_unlock(&system->lock); } static void xdpy_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Window root, parent, child, *children; unsigned int n; _al_mutex_lock(&system->lock); /* To account for the window border, we have to find the parent window which * draws the border. If the parent is the root though, then we should not * translate. */ XQueryTree(system->x11display, glx->window, &root, &parent, &children, &n); if (parent != root) { XTranslateCoordinates(system->x11display, parent, glx->window, x, y, &x, &y, &child); } XMoveWindow(system->x11display, glx->window, x, y); XFlush(system->x11display); /* We have to store these immediately, as we will ignore the XConfigureEvent * that we receive in response. _al_display_xglx_configure() knows why. */ glx->x = x; glx->y = y; _al_mutex_unlock(&system->lock); } static void xdpy_set_frame(ALLEGRO_DISPLAY *display, bool frame_on) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Display *x11 = system->x11display; Atom hints; _al_mutex_lock(&system->lock); #if 1 /* This code is taken from the GDK sources. So it works perfectly in Gnome, * no idea if it will work anywhere else. X11 documentation itself only * describes a way how to make the window completely unmanaged, but that * would also require special care in the event handler. */ hints = XInternAtom(x11, "_MOTIF_WM_HINTS", True); if (hints) { struct { unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status; } motif = {2, 0, frame_on, 0, 0}; XChangeProperty(x11, glx->window, hints, hints, 32, PropModeReplace, (void *)&motif, sizeof motif / 4); if (frame_on) display->flags &= ~ALLEGRO_FRAMELESS; else display->flags |= ALLEGRO_FRAMELESS; } #endif _al_mutex_unlock(&system->lock); } static void xdpy_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); if (onoff == !(display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { _al_mutex_lock(&system->lock); _al_xwin_reset_size_hints(display); _al_xwin_set_fullscreen_window(display, 2); /* XXX Technically, the user may fiddle with the _NET_WM_STATE_FULLSCREEN * property outside of Allegro so this flag may not be in sync with * reality. */ display->flags ^= ALLEGRO_FULLSCREEN_WINDOW; _al_xwin_set_size_hints(display, INT_MAX, INT_MAX); _al_mutex_unlock(&system->lock); } } static bool xdpy_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool flag_onoff) { switch (flag) { case ALLEGRO_FRAMELESS: /* The ALLEGRO_FRAMELESS flag is backwards. */ xdpy_set_frame(display, !flag_onoff); return true; case ALLEGRO_FULLSCREEN_WINDOW: xdpy_set_fullscreen_window(display, flag_onoff); return true; } return false; } static void _al_xglx_use_adapter(ALLEGRO_SYSTEM_XGLX *s, int adapter) { ALLEGRO_DEBUG("use adapter %i\n", adapter); s->adapter_use_count++; s->adapter_map[adapter]++; } static void _al_xglx_unuse_adapter(ALLEGRO_SYSTEM_XGLX *s, int adapter) { ALLEGRO_DEBUG("unuse adapter %i\n", adapter); s->adapter_use_count--; s->adapter_map[adapter]--; } static void xdpy_destroy_display(ALLEGRO_DISPLAY *d); /* Create a new X11 display, which maps directly to a GLX window. */ static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); int adapter = al_get_new_display_adapter(); if (system->x11display == NULL) { ALLEGRO_WARN("Not connected to X server.\n"); return NULL; } if (w <= 0 || h <= 0) { ALLEGRO_ERROR("Invalid window size %dx%d\n", w, h); return NULL; } _al_mutex_lock(&system->lock); ALLEGRO_DISPLAY_XGLX *d = al_calloc(1, sizeof *d); ALLEGRO_DISPLAY *display = (void*)d; ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); display->ogl_extras = ogl; int major, minor; glXQueryVersion(system->x11display, &major, &minor); d->glx_version = major * 100 + minor * 10; ALLEGRO_INFO("GLX %.1f.\n", d->glx_version / 100.f); display->w = w; display->h = h; display->vt = _al_display_xglx_driver(); display->refresh_rate = al_get_new_display_refresh_rate(); display->flags = al_get_new_display_flags(); // FIXME: default? Is this the right place to set this? display->flags |= ALLEGRO_OPENGL; // store our initial virtual adapter, used by fullscreen and positioning code d->adapter = adapter; ALLEGRO_DEBUG("selected adapter %i\n", adapter); if (d->adapter < 0) { d->adapter = _al_xglx_get_default_adapter(system); } _al_xglx_use_adapter(system, d->adapter); /* if we're in multi-head X mode, bail if we try to use more than one display * as there are bugs in X/glX that cause us to hang in X if we try to use more than one. */ /* if we're in real xinerama mode, also bail, x makes mouse use evil */ bool true_xinerama_active = false; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA bool xrandr_active = false; #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR xrandr_active = system->xrandr_available; #endif true_xinerama_active = !xrandr_active && system->xinerama_available; #endif if ((true_xinerama_active || ScreenCount(system->x11display) > 1) && system->adapter_use_count) { uint32_t i, adapter_use_count = 0; for (i = 0; i < 32; i++) { if (system->adapter_map[i]) adapter_use_count++; } if (adapter_use_count > 1) { ALLEGRO_ERROR("Use of more than one adapter at once in multi-head X or X with true Xinerama active is not possible.\n"); al_free(d); al_free(ogl); _al_mutex_unlock(&system->lock); return NULL; } } ALLEGRO_DEBUG("xdpy: selected adapter %i\n", d->adapter); // store or initial X Screen, used by window creation, fullscreen, and glx visual code d->xscreen = _al_xglx_get_xscreen(system, d->adapter); ALLEGRO_DEBUG("xdpy: selected xscreen %i\n", d->xscreen); d->is_mapped = false; _al_cond_init(&d->mapped); d->resize_count = 0; d->programmatic_resize = false; _al_xglx_config_select_visual(d); if (!d->xvinfo) { ALLEGRO_ERROR("FIXME: Need better visual selection.\n"); ALLEGRO_ERROR("No matching visual found.\n"); al_free(d); al_free(ogl); _al_mutex_unlock(&system->lock); return NULL; } ALLEGRO_INFO("Selected X11 visual %lu.\n", d->xvinfo->visualid); /* Add ourself to the list of displays. */ ALLEGRO_DISPLAY_XGLX **add; add = _al_vector_alloc_back(&system->system.displays); *add = d; /* Each display is an event source. */ _al_event_source_init(&display->es); /* Create a colormap. */ Colormap cmap = XCreateColormap(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), d->xvinfo->visual, AllocNone); /* Create an X11 window */ XSetWindowAttributes swa; int mask = CWBorderPixel | CWColormap | CWEventMask; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | PropertyChangeMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; /* For a non-compositing window manager, a black background can look * less broken if the application doesn't react to expose events fast * enough. However in some cases like resizing, the black background * causes horrible flicker. */ if (!(display->flags & ALLEGRO_RESIZABLE)) { mask |= CWBackPixel; swa.background_pixel = BlackPixel(system->x11display, d->xvinfo->screen); } int x_off = INT_MAX, y_off = INT_MAX; if (display->flags & ALLEGRO_FULLSCREEN) { _al_xglx_get_display_offset(system, d->adapter, &x_off, &y_off); } else { /* we want new_display_adapter's offset to add to the new_window_position */ int xscr_x = 0, xscr_y = 0; al_get_new_window_position(&x_off, &y_off); if (adapter >= 0) { /* non default adapter. I'm assuming this means the user wants the window to be placed on the adapter offset by new display pos */ _al_xglx_get_display_offset(system, d->adapter, &xscr_x, &xscr_y); if (x_off != INT_MAX) x_off += xscr_x; if (y_off != INT_MAX) y_off += xscr_y; } } d->window = XCreateWindow(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), x_off != INT_MAX ? x_off : 0, y_off != INT_MAX ? y_off : 0, w, h, 0, d->xvinfo->depth, InputOutput, d->xvinfo->visual, mask, &swa); // Try to set full screen mode if requested, fail if we can't if (display->flags & ALLEGRO_FULLSCREEN) { /* According to the spec, the window manager is supposed to disable * window decorations when _NET_WM_STATE_FULLSCREEN is in effect. * However, some WMs may not be fully compliant, e.g. Fluxbox. */ xdpy_set_frame(display, false); _al_xglx_set_above(display, 1); if (!_al_xglx_fullscreen_set_mode(system, d, w, h, 0, display->refresh_rate)) { ALLEGRO_DEBUG("xdpy: failed to set fullscreen mode.\n"); xdpy_destroy_display(display); _al_mutex_unlock(&system->lock); return NULL; } //XSync(system->x11display, False); } if (display->flags & ALLEGRO_FRAMELESS) { xdpy_set_frame(display, false); } ALLEGRO_DEBUG("X11 window created.\n"); _al_xwin_set_size_hints(display, x_off, y_off); XLockDisplay(system->x11display); d->wm_delete_window_atom = XInternAtom(system->x11display, "WM_DELETE_WINDOW", False); XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1); XMapWindow(system->x11display, d->window); ALLEGRO_DEBUG("X11 window mapped.\n"); XUnlockDisplay(system->x11display); /* Send the pending request to the X server. */ XSync(system->x11display, False); /* To avoid race conditions where some X11 functions fail before the window * is mapped, we wait here until it is mapped. Note that the thread is * locked, so the event could not possibly have been processed yet in the * events thread. So as long as no other map events occur, the condition * should only be signalled when our window gets mapped. */ while (!d->is_mapped) { _al_cond_wait(&d->mapped, &system->lock); } /* We can do this at any time, but if we already have a mapped * window when switching to fullscreen it will use the same * monitor (with the MetaCity version I'm using here right now). */ if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { ALLEGRO_INFO("Toggling fullscreen flag for %d x %d window.\n", display->w, display->h); _al_xwin_reset_size_hints(display); _al_xwin_set_fullscreen_window(display, 2); _al_xwin_set_size_hints(display, INT_MAX, INT_MAX); XWindowAttributes xwa; XGetWindowAttributes(system->x11display, d->window, &xwa); display->w = xwa.width; display->h = xwa.height; ALLEGRO_INFO("Using ALLEGRO_FULLSCREEN_WINDOW of %d x %d\n", display->w, display->h); } if (display->flags & ALLEGRO_FULLSCREEN) { /* kwin wants these here */ /* metacity wants these here too */ /* XXX compiz is quiky, can't seem to find a combination of hints that * make sure we are layerd over panels, and are positioned properly */ //_al_xwin_set_fullscreen_window(display, 1); _al_xglx_set_above(display, 1); _al_xglx_fullscreen_to_display(system, d); /* Grab mouse if we only have one display, ungrab it if we have more than * one. */ if (_al_vector_size(&system->system.displays) == 1) { al_grab_mouse(display); } else if (_al_vector_size(&system->system.displays) > 1) { al_ungrab_mouse(); } } if (!_al_xglx_config_create_context(d)) { xdpy_destroy_display(display); _al_mutex_unlock(&system->lock); return NULL; } /* Make our GLX context current for reading and writing in the current * thread. */ if (d->fbc) { if (!glXMakeContextCurrent(system->gfxdisplay, d->glxwindow, d->glxwindow, d->context)) { ALLEGRO_ERROR("glXMakeContextCurrent failed\n"); } } else { if (!glXMakeCurrent(system->gfxdisplay, d->glxwindow, d->context)) { ALLEGRO_ERROR("glXMakeCurrent failed\n"); } } _al_ogl_manage_extensions(display); _al_ogl_set_extensions(ogl->extension_api); /* Print out OpenGL version info */ ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION)); ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR)); ALLEGRO_INFO("Renderer: %s\n", (const char*)glGetString(GL_RENDERER)); if (display->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings(); if (eds->required & (1<lock); return NULL; } display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; } #if 0 // Apparently, you can get a OpenGL 3.0 context without specifically creating // it with glXCreateContextAttribsARB, and not every OpenGL 3.0 is evil, but we // can't tell the difference at this stage. else if (display->ogl_extras->ogl_info.version > _ALLEGRO_OPENGL_VERSION_2_1) { /* We don't have OpenGL3 a driver. */ display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; } #endif if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) _al_ogl_setup_gl(display); /* vsync */ /* Fill in the user setting. */ display->extra_settings.settings[ALLEGRO_VSYNC] = _al_get_new_display_settings()->settings[ALLEGRO_VSYNC]; /* We set the swap interval to 0 if vsync is forced off, and to 1 * if it is forced on. * http://www.opengl.org/registry/specs/SGI/swap_control.txt * If the option is set to 0, we simply use the system default. The * above extension specifies vsync on as default though, so in the * end with GLX we can't force vsync on, just off. */ ALLEGRO_DEBUG("requested vsync=%d.\n", display->extra_settings.settings[ALLEGRO_VSYNC]); if (display->extra_settings.settings[ALLEGRO_VSYNC]) { if (display->ogl_extras->extension_list->ALLEGRO_GLX_SGI_swap_control) { int x = 1; if (display->extra_settings.settings[ALLEGRO_VSYNC] == 2) x = 0; if (glXSwapIntervalSGI(x)) { ALLEGRO_WARN("glXSwapIntervalSGI(%d) failed.\n", x); } } else { ALLEGRO_WARN("no vsync, GLX_SGI_swap_control missing.\n"); /* According to the specification that means it's on, but * the driver might have disabled it. So we do not know. */ display->extra_settings.settings[ALLEGRO_VSYNC] = 0; } } d->invisible_cursor = None; /* Will be created on demand. */ d->current_cursor = None; /* Initially, we use the root cursor. */ d->cursor_hidden = false; d->icon = None; d->icon_mask = None; _al_mutex_unlock(&system->lock); return display; } static void xdpy_destroy_display(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (void *)d; ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; ALLEGRO_DEBUG("destroy display.\n"); /* If we're the last display, convert all bitmpas to display independent * (memory) bitmaps. */ if (s->system.displays._size == 1) { while (d->bitmaps._size > 0) { ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); ALLEGRO_BITMAP *b = *bptr; _al_convert_to_memory_bitmap(b); } } else { /* Pass all bitmaps to any other living display. (We assume all displays * are compatible.) */ size_t i; ALLEGRO_DISPLAY **living = NULL; ASSERT(s->system.displays._size > 1); for (i = 0; i < s->system.displays._size; i++) { living = _al_vector_ref(&s->system.displays, i); if (*living != d) break; } for (i = 0; i < d->bitmaps._size; i++) { ALLEGRO_BITMAP **add = _al_vector_alloc_back(&(*living)->bitmaps); ALLEGRO_BITMAP **ref = _al_vector_ref(&d->bitmaps, i); *add = *ref; (*add)->display = *living; } } _al_xglx_unuse_adapter(s, glx->adapter); _al_ogl_unmanage_extensions(d); ALLEGRO_DEBUG("unmanaged extensions.\n"); _al_mutex_lock(&s->lock); _al_vector_find_and_delete(&s->system.displays, &d); XDestroyWindow(s->x11display, glx->window); if (s->mouse_grab_display == d) { s->mouse_grab_display = NULL; } ALLEGRO_DEBUG("destroy window.\n"); if (d->flags & ALLEGRO_FULLSCREEN) { size_t i; ALLEGRO_DISPLAY **living = NULL; bool last_fullscreen = true; /* If any other fullscreen display is still active on the same adapter, * we must not touch the video mode. */ for (i = 0; i < s->system.displays._size; i++) { living = _al_vector_ref(&s->system.displays, i); ALLEGRO_DISPLAY_XGLX *living_glx = (void*)*living; if (*living == d) continue; /* check for fullscreen displays on the same adapter */ if (living_glx->adapter == glx->adapter && al_get_display_flags(*living) & ALLEGRO_FULLSCREEN) { last_fullscreen = false; } } if (last_fullscreen) { ALLEGRO_DEBUG("restore modes.\n"); _al_xglx_restore_video_mode(s, glx->adapter); } else { ALLEGRO_DEBUG("*not* restoring modes.\n"); } } if (ogl->backbuffer) { _al_ogl_destroy_backbuffer(ogl->backbuffer); ogl->backbuffer = NULL; ALLEGRO_DEBUG("destroy backbuffer.\n"); } if (glx->context) { glXDestroyContext(s->gfxdisplay, glx->context); glx->context = NULL; ALLEGRO_DEBUG("destroy context.\n"); } /* XXX quick pre-release hack */ /* In multi-window programs these result in a double-free bugs. */ #if 0 if (glx->fbc) { al_free(glx->fbc); glx->fbc = NULL; XFree(glx->xvinfo); glx->xvinfo = NULL; } else if (glx->xvinfo) { al_free(glx->xvinfo); glx->xvinfo = NULL; } #endif _al_cond_destroy(&glx->mapped); _al_vector_free(&d->bitmaps); _al_event_source_free(&d->es); al_free(d->ogl_extras); al_free(d->vertex_cache); al_free(d); _al_mutex_unlock(&s->lock); ALLEGRO_DEBUG("destroy display finished.\n"); } static bool xdpy_set_current_display(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; /* Make our GLX context current for reading and writing in the current * thread. */ if (glx->fbc) { if (!glXMakeContextCurrent(system->gfxdisplay, glx->glxwindow, glx->glxwindow, glx->context)) return false; } else { if (!glXMakeCurrent(system->gfxdisplay, glx->glxwindow, glx->context)) return false; } _al_ogl_set_extensions(ogl->extension_api); return true; } static void xdpy_unset_current_display(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); (void)d; glXMakeContextCurrent(system->gfxdisplay, None, None, NULL); } /* Dummy implementation of flip. */ static void xdpy_flip_display(ALLEGRO_DISPLAY *d) { int e = glGetError(); if (e) { ALLEGRO_ERROR("OpenGL error was not 0: %d\n", e); } ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; if (d->extra_settings.settings[ALLEGRO_SINGLE_BUFFER]) glFlush(); else glXSwapBuffers(system->gfxdisplay, glx->glxwindow); } static void xdpy_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, int w, int h) { (void)x; (void)y; (void)w; (void)h; xdpy_flip_display(d); } static bool xdpy_acknowledge_resize(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; XWindowAttributes xwa; unsigned int w, h; _al_mutex_lock(&system->lock); /* glXQueryDrawable is GLX 1.3+. */ /* glXQueryDrawable(system->x11display, glx->glxwindow, GLX_WIDTH, &w); glXQueryDrawable(system->x11display, glx->glxwindow, GLX_HEIGHT, &h); */ XGetWindowAttributes(system->x11display, glx->window, &xwa); w = xwa.width; h = xwa.height; if ((int)w != d->w || (int)h != d->h) { d->w = w; d->h = h; ALLEGRO_DEBUG("xdpy: acknowledge_resize (%d, %d)\n", d->w, d->h); /* No context yet means this is a stray call happening during * initialization. */ if (glx->context) { _al_ogl_setup_gl(d); } } _al_mutex_unlock(&system->lock); return true; } /* Note: The system mutex must be locked (exactly once) so when we * wait for the condition variable it gets auto-unlocked. For a * nested lock that would not be the case. */ void _al_display_xglx_await_resize(ALLEGRO_DISPLAY *d, int old_resize_count, bool delay_hack) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; ALLEGRO_TIMEOUT timeout; ALLEGRO_DEBUG("Awaiting resize event\n"); XSync(system->x11display, False); /* Wait until we are actually resized. * Don't wait forever if an event never comes. */ al_init_timeout(&timeout, 1.0); while (old_resize_count == glx->resize_count) { if (_al_cond_timedwait(&system->resized, &system->lock, &timeout) == -1) { ALLEGRO_ERROR("Timeout while waiting for resize event.\n"); return; } } /* XXX: This hack helps when toggling between fullscreen windows and not, * on various window managers. */ if (delay_hack) { al_rest(0.2); } xdpy_acknowledge_resize(d); } static bool xdpy_resize_display(ALLEGRO_DISPLAY *d, int w, int h) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; XWindowAttributes xwa; int attempts; bool ret = false; /* A fullscreen-window can't be resized. */ if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) return false; _al_mutex_lock(&system->lock); /* It seems some X servers will treat the resize as a no-op if the window is * already the right size, so check for it to avoid a deadlock later. */ XGetWindowAttributes(system->x11display, glx->window, &xwa); if (xwa.width == w && xwa.height == h) { _al_mutex_unlock(&system->lock); return false; } if (d->flags & ALLEGRO_FULLSCREEN) { _al_xwin_set_fullscreen_window(d, 0); if (!_al_xglx_fullscreen_set_mode(system, glx, w, h, 0, 0)) { ret = false; goto skip_resize; } attempts = 3; } else { attempts = 1; } /* Hack: try multiple times to resize the window, with delays. KDE reacts * slowly to the video mode change, and won't resize our window until a * while after. It would be better to wait for some sort of event rather * than just waiting some amount of time, but I didn't manage to find that * event. --pw */ for (; attempts >= 0; attempts--) { const int old_resize_count = glx->resize_count; ALLEGRO_DEBUG("calling XResizeWindow, attempts=%d\n", attempts); _al_xwin_reset_size_hints(d); glx->programmatic_resize = true; XResizeWindow(system->x11display, glx->window, w, h); _al_display_xglx_await_resize(d, old_resize_count, (d->flags & ALLEGRO_FULLSCREEN)); glx->programmatic_resize = false; _al_xwin_set_size_hints(d, INT_MAX, INT_MAX); if (d->w == w && d->h == h) { ret = true; break; } /* Wait before trying again. */ al_rest(0.333); } if (attempts == 0) { ALLEGRO_ERROR("XResizeWindow didn't work; giving up\n"); } skip_resize: if (d->flags & ALLEGRO_FULLSCREEN) { _al_xwin_set_fullscreen_window(d, 1); _al_xglx_set_above(d, 1); _al_xglx_fullscreen_to_display(system, glx); ALLEGRO_DEBUG("xdpy: resize fullscreen?\n"); } _al_mutex_unlock(&system->lock); return ret; } void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y, int width, int height, bool setglxy) { ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; ALLEGRO_EVENT_SOURCE *es = &glx->display.es; _al_event_source_lock(es); /* Generate a resize event if the size has changed non-programmtically. * We cannot asynchronously change the display size here yet, since the user * will only know about a changed size after receiving the resize event. * Here we merely add the event to the queue. */ if (!glx->programmatic_resize && (d->w != width || d->h != height)) { if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.timestamp = al_get_time(); event.display.x = x; event.display.y = y; event.display.width = width; event.display.height = height; _al_event_source_emit_event(es, &event); } } /* We receive two configure events when toggling the window frame. * We ignore the first one as it has bogus coordinates. * The only way to tell them apart seems to be the send_event field. * Unfortunately, we also end up ignoring the only event we receive in * response to a XMoveWindow request so we have to compensate for that. */ if (setglxy) { glx->x = x; glx->y = y; } ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX*)al_get_system_driver(); ALLEGRO_MONITOR_INFO mi; int center_x = (glx->x + (glx->x + width)) / 2; int center_y = (glx->y + (glx->y + height)) / 2; _al_xglx_get_monitor_info(system, glx->adapter, &mi); ALLEGRO_DEBUG("xconfigure event! %ix%i\n", x, y); /* check if we're no longer inside the stored adapter */ if ((center_x < mi.x1 && center_x > mi.x2) || (center_y < mi.y1 && center_y > mi.x2)) { int new_adapter = _al_xglx_get_adapter(system, glx, true); if (new_adapter != glx->adapter) { ALLEGRO_DEBUG("xdpy: adapter change!\n"); _al_xglx_unuse_adapter(system, glx->adapter); if (d->flags & ALLEGRO_FULLSCREEN) _al_xglx_restore_video_mode(system, glx->adapter); glx->adapter = new_adapter; _al_xglx_use_adapter(system, glx->adapter); } } _al_event_source_unlock(es); } /* Handle an X11 configure event. [X11 thread] * Only called from the event handler with the system locked. */ void _al_xglx_display_configure_event(ALLEGRO_DISPLAY *d, XEvent *xevent) { /* We receive two configure events when toggling the window frame. * We ignore the first one as it has bogus coordinates. * The only way to tell them apart seems to be the send_event field. * Unfortunately, we also end up ignoring the only event we receive in * response to a XMoveWindow request so we have to compensate for that. */ bool setglxy = (xevent->xconfigure.send_event); _al_xglx_display_configure(d, xevent->xconfigure.x, xevent->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure.height, setglxy); } /* Handle X11 switch event. [X11 thread] */ void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *display, XFocusChangeEvent *xevent) { /* Anything but NotifyNormal seem to indicate the switch is not "real". * TODO: Find out details? */ if (xevent->mode != NotifyNormal) return; ALLEGRO_EVENT_SOURCE *es = &display->es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; if (xevent->type == FocusOut) event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; else event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; event.display.timestamp = al_get_time(); _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); } void _al_xwin_display_expose(ALLEGRO_DISPLAY *display, XExposeEvent *xevent) { ALLEGRO_EVENT_SOURCE *es = &display->es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; event.display.timestamp = al_get_time(); event.display.x = xevent->x; event.display.y = xevent->y; event.display.width = xevent->width; event.display.height = xevent->height; _al_event_source_emit_event(es, &event); } _al_event_source_unlock(es); } static bool xdpy_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { /* All GLX bitmaps are compatible. */ (void)display; (void)bitmap; return true; } static void xdpy_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) { ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; /* We could also query the X11 server, but it just would take longer, and * would not be synchronized to our events. The latter can be an advantage * or disadvantage. */ *x = glx->x; *y = glx->y; } static void xdpy_set_window_title(ALLEGRO_DISPLAY *display, const char *title) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; _al_mutex_lock(&system->lock); Atom WM_NAME = XInternAtom(system->x11display, "WM_NAME", False); Atom _NET_WM_NAME = XInternAtom(system->x11display, "_NET_WM_NAME", False); char *list[] = {(void *)title}; XTextProperty property; Xutf8TextListToTextProperty(system->x11display, list, 1, XUTF8StringStyle, &property); XSetTextProperty(system->x11display, glx->window, &property, WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, _NET_WM_NAME); XFree(property.value); XClassHint hint; hint.res_name = strdup(title); // Leak? (below too...) hint.res_class = strdup(title); XSetClassHint(system->x11display, glx->window, &hint); _al_mutex_unlock(&system->lock); } static bool xdpy_wait_for_vsync(ALLEGRO_DISPLAY *display) { (void) display; if (al_get_opengl_extension_list()->ALLEGRO_GLX_SGI_video_sync) { unsigned int count; glXGetVideoSyncSGI(&count); glXWaitVideoSyncSGI(2, (count+1) & 1, &count); return true; } return false; } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_display_xglx_driver(void) { if (xdpy_vt.create_display) return &xdpy_vt; xdpy_vt.create_display = xdpy_create_display; xdpy_vt.destroy_display = xdpy_destroy_display; xdpy_vt.set_current_display = xdpy_set_current_display; xdpy_vt.unset_current_display = xdpy_unset_current_display; xdpy_vt.flip_display = xdpy_flip_display; xdpy_vt.update_display_region = xdpy_update_display_region; xdpy_vt.acknowledge_resize = xdpy_acknowledge_resize; xdpy_vt.create_bitmap = _al_ogl_create_bitmap; xdpy_vt.create_sub_bitmap = _al_ogl_create_sub_bitmap; xdpy_vt.get_backbuffer = _al_ogl_get_backbuffer; xdpy_vt.set_target_bitmap = _al_ogl_set_target_bitmap; xdpy_vt.is_compatible_bitmap = xdpy_is_compatible_bitmap; xdpy_vt.resize_display = xdpy_resize_display; xdpy_vt.set_icons = xdpy_set_icons; xdpy_vt.set_window_title = xdpy_set_window_title; xdpy_vt.set_window_position = xdpy_set_window_position; xdpy_vt.get_window_position = xdpy_get_window_position; xdpy_vt.set_display_flag = xdpy_set_display_flag; xdpy_vt.wait_for_vsync = xdpy_wait_for_vsync; _al_xwin_add_cursor_functions(&xdpy_vt); _al_ogl_add_drawing_functions(&xdpy_vt); return &xdpy_vt; } #define X11_ATOM(x) XInternAtom(x11, #x, False); void _al_xglx_set_above(ALLEGRO_DISPLAY *display, int value) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Display *x11 = system->x11display; ALLEGRO_DEBUG("Toggling _NET_WM_STATE_ABOVE hint: %d\n", value); XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); xev.xclient.window = glx->window; xev.xclient.format = 32; // Note: It seems 0 is not reliable except when mapping a window - // 2 is all we need though. xev.xclient.data.l[0] = value; /* 0 = off, 1 = on, 2 = toggle */ xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_ABOVE); xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 1; XSendEvent(x11, DefaultRootWindow(x11), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/src/memblit.c0000644000175000001440000002745112125155766015015 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory bitmap drawing routines * */ #define _AL_NO_BLEND_INLINE_FUNC #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_convert.h" #include "allegro5/internal/aintern_memblit.h" #include "allegro5/internal/aintern_transform.h" #include "allegro5/internal/aintern_tri_soft.h" #include #define MIN _ALLEGRO_MIN #define MAX _ALLEGRO_MAX static void _al_draw_transformed_scaled_bitmap_memory( ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags); static void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap, int sx, int sy, int sw, int sh, int dx, int dy, int flags); /* The CLIPPER macro takes pre-clipped coordinates for both the source * and destination bitmaps and clips them as necessary, taking sub- * bitmaps into consideration. The wr and hr parameters are the ratio of * source width & height to destination width & height _before_ clipping. * * First the left (top) coordinates are moved inward. Then the right * (bottom) coordinates are moved inward. The changes are applied * simultaneously to the complementary bitmap with scaling taken into * consideration. * * The coordinates are modified, and the sub-bitmaps are set to the * parent bitmaps. If nothing needs to be drawn, the macro exits the * function. */ #define CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, wr, hr, flags)\ { \ float cl = dest->cl, cr = dest->cr_excl; \ float ct = dest->ct, cb = dest->cb_excl; \ float sx_ = 0, sy_ = 0, sw_ = 0, sh_ = 0; \ bool hflip = false, vflip = false; \ if (dw < 0) { \ hflip = true; \ dx += dw; \ dw = -dw; \ sx_ = sx; sw_ = sw; \ } \ if (dh < 0) { \ vflip = true; \ dy += dh; \ dh = -dh; \ sy_ = sy; sh_ = sh; \ } \ \ if (dest->parent) { \ dx += dest->xofs; \ dy += dest->yofs; \ \ cl += dest->xofs; \ if (cl >= dest->parent->w) { \ return; \ } \ else if (cl < 0) { \ cl = 0; \ } \ \ ct += dest->yofs; \ if (ct >= dest->parent->h) { \ return; \ } \ else if (ct < 0) { \ ct = 0; \ } \ \ cr = MIN(dest->parent->w, cr + dest->xofs); \ cb = MIN(dest->parent->h, cb + dest->yofs); \ \ dest = dest->parent; \ } \ \ if (dx < cl) { \ const int d = cl - dx; \ dx = cl; \ dw -= d; \ sx += d * wr; \ sw -= d * wr; \ } \ \ if (dx + dw > cr) { \ const int d = dx + dw - cr; \ dw -= d; \ sw -= d * wr; \ } \ \ if (dy < ct) { \ const int d = ct - dy; \ dy = ct; \ dh -= d; \ sy += d * hr; \ sh -= d * hr; \ } \ \ if (dy + dh > cb) { \ const int d = dy + dh - cb; \ dh -= d; \ sh -= d * hr; \ } \ \ if (sh <= 0 || sw <= 0) return; \ \ if (hflip) {dx += dw; dw = -dw; sx = sx_ + sw_ - sw + sx_ - sx; dx--;} \ if (vflip) {dy += dh; dh = -dh; sy = sy_ + sh_ - sh + sy_ - sy; dy--;} \ } void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int flags) { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; float xtrans, ytrans; ASSERT(src->parent == NULL); al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED_TINT_WHITE && _al_transform_is_translation(al_get_current_transform(), &xtrans, &ytrans)) { _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh, dx + xtrans, dy + ytrans, flags); return; } /* We used to have special cases for translation/scaling only, but the * general version received much more optimisation and ended up being * faster. */ _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy, sw, sh, dx, dy, sw, sh, flags); } static void _al_draw_transformed_bitmap_memory(ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dw, int dh, ALLEGRO_TRANSFORM* local_trans, int flags) { float xsf[4], ysf[4]; int tl = 0, tr = 1, bl = 3, br = 2; int tmp; ALLEGRO_VERTEX v[4]; ASSERT(_al_pixel_format_is_real(src->format)); /* Decide what order to take corners in. */ if (flags & ALLEGRO_FLIP_VERTICAL) { tl = 3; tr = 2; bl = 0; br = 1; } else { tl = 0; tr = 1; bl = 3; br = 2; } if (flags & ALLEGRO_FLIP_HORIZONTAL) { tmp = tl; tl = tr; tr = tmp; tmp = bl; bl = br; br = tmp; } xsf[0] = 0; ysf[0] = 0; xsf[1] = dw; ysf[1] = 0; xsf[2] = 0; ysf[2] = dh; al_transform_coordinates(local_trans, &xsf[0], &ysf[0]); al_transform_coordinates(local_trans, &xsf[1], &ysf[1]); al_transform_coordinates(local_trans, &xsf[2], &ysf[2]); v[tl].x = xsf[0]; v[tl].y = ysf[0]; v[tl].z = 0; v[tl].u = sx; v[tl].v = sy; v[tl].color = tint; v[tr].x = xsf[1]; v[tr].y = ysf[1]; v[tr].z = 0; v[tr].u = sx + sw; v[tr].v = sy; v[tr].color = tint; v[br].x = xsf[2] + xsf[1] - xsf[0]; v[br].y = ysf[2] + ysf[1] - ysf[0]; v[br].z = 0; v[br].u = sx + sw; v[br].v = sy + sh; v[br].color = tint; v[bl].x = xsf[2]; v[bl].y = ysf[2]; v[bl].z = 0; v[bl].u = sx; v[bl].v = sy + sh; v[bl].color = tint; al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); _al_triangle_2d(src, &v[tl], &v[tr], &v[br]); _al_triangle_2d(src, &v[tl], &v[br], &v[bl]); al_unlock_bitmap(src); } static void _al_draw_transformed_scaled_bitmap_memory( ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags) { ALLEGRO_TRANSFORM local_trans; al_identity_transform(&local_trans); al_translate_transform(&local_trans, dx, dy); al_compose_transform(&local_trans, al_get_current_transform()); _al_draw_transformed_bitmap_memory(src, tint, sx, sy, sw, sh, dw, dh, &local_trans, flags); } static void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap, int sx, int sy, int sw, int sh, int dx, int dy, int flags) { ALLEGRO_LOCKED_REGION *src_region; ALLEGRO_LOCKED_REGION *dst_region; ALLEGRO_BITMAP *dest = al_get_target_bitmap(); int dw = sw, dh = sh; ASSERT(_al_pixel_format_is_real(bitmap->format)); ASSERT(_al_pixel_format_is_real(dest->format)); ASSERT(bitmap->parent == NULL); /* Currently the only flags are for flipping, which is handled as negative * scaling. */ ASSERT(flags == 0); (void)flags; CLIPPER(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1, 1, flags) if (!(src_region = al_lock_bitmap_region(bitmap, sx, sy, sw, sh, bitmap->format, ALLEGRO_LOCK_READONLY))) { return; } if (!(dst_region = al_lock_bitmap_region(dest, dx, dy, sw, sh, dest->format, ALLEGRO_LOCK_WRITEONLY))) { al_unlock_bitmap(bitmap); return; } /* will detect if no conversion is needed */ _al_convert_bitmap_data( src_region->data, bitmap->format, src_region->pitch, dst_region->data, dest->format, dst_region->pitch, 0, 0, 0, 0, sw, sh); al_unlock_bitmap(bitmap); al_unlock_bitmap(dest); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/misc/0000755000175000001440000000000012157230741014132 5ustar tjadenusersallegro-5.0.10/src/misc/bstrlib.txt0000644000175000001440000045536011375630156016356 0ustar tjadenusersBetter String library --------------------- by Paul Hsieh The bstring library is an attempt to provide improved string processing functionality to the C and C++ language. At the heart of the bstring library (Bstrlib for short) is the management of "bstring"s which are a significant improvement over '\0' terminated char buffers. =============================================================================== Motivation ---------- The standard C string library has serious problems: 1) Its use of '\0' to denote the end of the string means knowing a string's length is O(n) when it could be O(1). 2) It imposes an interpretation for the character value '\0'. 3) gets() always exposes the application to a buffer overflow. 4) strtok() modifies the string its parsing and thus may not be usable in programs which are re-entrant or multithreaded. 5) fgets has the unusual semantic of ignoring '\0's that occur before '\n's are consumed. 6) There is no memory management, and actions performed such as strcpy, strcat and sprintf are common places for buffer overflows. 7) strncpy() doesn't '\0' terminate the destination in some cases. 8) Passing NULL to C library string functions causes an undefined NULL pointer access. 9) Parameter aliasing (overlapping, or self-referencing parameters) within most C library functions has undefined behavior. 10) Many C library string function calls take integer parameters with restricted legal ranges. Parameters passed outside these ranges are not typically detected and cause undefined behavior. So the desire is to create an alternative string library that does not suffer from the above problems and adds in the following functionality: 1) Incorporate string functionality seen from other languages. a) MID$() - from BASIC b) split()/join() - from Python c) string/char x n - from Perl 2) Implement analogs to functions that combine stream IO and char buffers without creating a dependency on stream IO functionality. 3) Implement the basic text editor-style functions insert, delete, find, and replace. 4) Implement reference based sub-string access (as a generalization of pointer arithmetic.) 5) Implement runtime write protection for strings. There is also a desire to avoid "API-bloat". So functionality that can be implemented trivially in other functionality is omitted. So there is no left$() or right$() or reverse() or anything like that as part of the core functionality. Explaining Bstrings ------------------- A bstring is basically a header which wraps a pointer to a char buffer. Lets start with the declaration of a struct tagbstring: struct tagbstring { int mlen; int slen; unsigned char * data; }; This definition is considered exposed, not opaque (though it is neither necessary nor recommended that low level maintenance of bstrings be performed whenever the abstract interfaces are sufficient). The mlen field (usually) describes a lower bound for the memory allocated for the data field. The slen field describes the exact length for the bstring. The data field is a single contiguous buffer of unsigned chars. Note that the existence of a '\0' character in the unsigned char buffer pointed to by the data field does not necessarily denote the end of the bstring. To be a well formed modifiable bstring the mlen field must be at least the length of the slen field, and slen must be non-negative. Furthermore, the data field must point to a valid buffer in which access to the first mlen characters has been acquired. So the minimal check for correctness is: (slen >= 0 && mlen >= slen && data != NULL) bstrings returned by bstring functions can be assumed to be either NULL or satisfy the above property. (When bstrings are only readable, the mlen >= slen restriction is not required; this is discussed later in this section.) A bstring itself is just a pointer to a struct tagbstring: typedef struct tagbstring * bstring; Note that use of the prefix "tag" in struct tagbstring is required to work around the inconsistency between C and C++'s struct namespace usage. This definition is also considered exposed. Bstrlib basically manages bstrings allocated as a header and an associated data-buffer. Since the implementation is exposed, they can also be constructed manually. Functions which mutate bstrings assume that the header and data buffer have been malloced; the bstring library may perform al_free() or al_realloc() on both the header and data buffer of any bstring parameter. Functions which return bstring's create new bstrings. The string memory is freed by a bdestroy() call (or using the bstrFree macro). The following related typedef is also provided: typedef const struct tagbstring * const_bstring; which is also considered exposed. These are directly bstring compatible (no casting required) but are just used for parameters which are meant to be non-mutable. So in general, bstring parameters which are read as input but not meant to be modified will be declared as const_bstring, and bstring parameters which may be modified will be declared as bstring. This convention is recommended for user written functions as well. Since bstrings maintain interoperability with C library char-buffer style strings, all functions which modify, update or create bstrings also append a '\0' character into the position slen + 1. This trailing '\0' character is not required for bstrings input to the bstring functions; this is provided solely as a convenience for interoperability with standard C char-buffer functionality. Analogs for the ANSI C string library functions have been created when they are necessary, but have also been left out when they are not. In particular there are no functions analogous to fwrite, or puts just for the purposes of bstring. The ->data member of any string is exposed, and therefore can be used just as easily as char buffers for C functions which read strings. For those that wish to hand construct bstrings, the following should be kept in mind: 1) While bstrlib can accept constructed bstrings without terminating '\0' characters, the rest of the C language string library will not function properly on such non-terminated strings. This is obvious but must be kept in mind. 2) If it is intended that a constructed bstring be written to by the bstring library functions then the data portion should be allocated by the malloc function and the slen and mlen fields should be entered properly. The struct tagbstring header is not reallocated, and only freed by bdestroy. 3) Writing arbitrary '\0' characters at various places in the string will not modify its length as perceived by the bstring library functions. In fact, '\0' is a legitimate non-terminating character for a bstring to contain. 4) For read only parameters, bstring functions do not check the mlen. I.e., the minimal correctness requirements are reduced to: (slen >= 0 && data != NULL) Better pointer arithmetic ------------------------- One built-in feature of '\0' terminated char * strings, is that its very easy and fast to obtain a reference to the tail of any string using pointer arithmetic. Bstrlib does one better by providing a way to get a reference to any substring of a bstring (or any other length delimited block of memory.) So rather than just having pointer arithmetic, with bstrlib one essentially has segment arithmetic. This is achieved using the macro blk2tbstr() which builds a reference to a block of memory and the macro bmid2tbstr() which builds a reference to a segment of a bstring. Bstrlib also includes functions for direct consumption of memory blocks into bstrings, namely bcatblk () and blk2bstr (). One scenario where this can be extremely useful is when string contains many substrings which one would like to pass as read-only reference parameters to some string consuming function without the need to allocate entire new containers for the string data. More concretely, imagine parsing a command line string whose parameters are space delimited. This can only be done for tails of the string with '\0' terminated char * strings. Improved NULL semantics and error handling ------------------------------------------ Unless otherwise noted, if a NULL pointer is passed as a bstring or any other detectably illegal parameter, the called function will return with an error indicator (either NULL or BSTR_ERR) rather than simply performing a NULL pointer access, or having undefined behavior. To illustrate the value of this, consider the following example: strcpy (p = malloc (13 * sizeof (char)), "Hello,"); strcat (p, " World"); This is not correct because malloc may return NULL (due to an out of memory condition), and the behaviour of strcpy is undefined if either of its parameters are NULL. However: bstrcat (p = bfromcstr ("Hello,"), q = bfromcstr (" World")); bdestroy (q); is well defined, because if either p or q are assigned NULL (indicating a failure to allocate memory) both bstrcat and bdestroy will recognize it and perform no detrimental action. Note that it is not necessary to check any of the members of a returned bstring for internal correctness (in particular the data member does not need to be checked against NULL when the header is non-NULL), since this is assured by the bstring library itself. bStreams -------- In addition to the bgets and bread functions, bstrlib can abstract streams with a high performance read only stream called a bStream. In general, the idea is to open a core stream (with something like fopen) then pass its handle as well as a bNread function pointer (like fread) to the bsopen function which will return a handle to an open bStream. Then the functions bsread, bsreadln or bsreadlns can be called to read portions of the stream. Finally, the bsclose function is called to close the bStream -- it will return a handle to the original (core) stream. So bStreams, essentially, wrap other streams. The bStreams have two main advantages over the bgets and bread (as well as fgets/ungetc) paradigms: 1) Improved functionality via the bunread function which allows a stream to unread characters, giving the bStream stack-like functionality if so desired. 2) A very high performance bsreadln function. The C library function fgets() (and the bgets function) can typically be written as a loop on top of fgetc(), thus paying all of the overhead costs of calling fgetc on a per character basis. bsreadln will read blocks at a time, thus amortizing the overhead of fread calls over many characters at once. However, clearly bStreams are suboptimal or unusable for certain kinds of streams (stdin) or certain usage patterns (a few spotty, or non-sequential reads from a slow stream.) For those situations, using bgets will be more appropriate. The semantics of bStreams allows practical construction of layerable data streams. What this means is that by writing a bNread compatible function on top of a bStream, one can construct a new bStream on top of it. This can be useful for writing multi-pass parsers that don't actually read the entire input more than once and don't require the use of intermediate storage. Aliasing -------- Aliasing occurs when a function is given two parameters which point to data structures which overlap in the memory they occupy. While this does not disturb read only functions, for many libraries this can make functions that write to these memory locations malfunction. This is a common problem of the C standard library and especially the string functions in the C standard library. The C standard string library is entirely char by char oriented (as is bstring) which makes conforming implementations alias safe for some scenarios. However no actual detection of aliasing is typically performed, so it is easy to find cases where the aliasing will cause anomolous or undesirable behaviour (consider: strcat (p, p).) The C99 standard includes the "restrict" pointer modifier which allows the compiler to document and assume a no-alias condition on usage. However, only the most trivial cases can be caught (if at all) by the compiler at compile time, and thus there is no actual enforcement of non-aliasing. Bstrlib, by contrast, permits aliasing and is completely aliasing safe, in the C99 sense of aliasing. That is to say, under the assumption that pointers of incompatible types from distinct objects can never alias, bstrlib is completely aliasing safe. (In practice this means that the data buffer portion of any bstring and header of any bstring are assumed to never alias.) With the exception of the reference building macros, the library behaves as if all read-only parameters are first copied and replaced by temporary non-aliased parameters before any writing to any output bstring is performed (though actual copying is extremely rarely ever done.) Besides being a useful safety feature, bstring searching/comparison functions can improve to O(1) execution when aliasing is detected. Note that aliasing detection and handling code in Bstrlib is generally extremely cheap. There is almost never any appreciable performance penalty for using aliased parameters. Reenterancy ----------- Nearly every function in Bstrlib is a leaf function, and is completely reenterable with the exception of writing to common bstrings. The split functions which use a callback mechanism requires only that the source string not be destroyed by the callback function unless the callback function returns with an error status (note that Bstrlib functions which return an error do not modify the string in any way.) The string can in fact be modified by the callback and the behaviour is deterministic. See the documentation of the various split functions for more details. Undefined scenarios ------------------- One of the basic important premises for Bstrlib is to not to increase the propogation of undefined situations from parameters that are otherwise legal in of themselves. In particular, except for extremely marginal cases, usages of bstrings that use the bstring library functions alone cannot lead to any undefined action. But due to C/C++ language and library limitations, there is no way to define a non-trivial library that is completely without undefined operations. All such possible undefined operations are described below: 1) bstrings or struct tagbstrings that are not explicitely initialized cannot be passed as a parameter to any bstring function. 2) The members of the NULL bstring cannot be accessed directly. (Though all APIs and macros detect the NULL bstring.) 3) A bstring whose data member has not been obtained from a malloc or compatible call and which is write accessible passed as a writable parameter will lead to undefined results. (i.e., do not writeAllow any constructed bstrings unless the data portion has been obtained from the heap.) 4) If the headers of two strings alias but are not identical (which can only happen via a defective manual construction), then passing them to a bstring function in which one is writable is not defined. 5) If the mlen member is larger than the actual accessible length of the data member for a writable bstring, or if the slen member is larger than the readable length of the data member for a readable bstring, then the corresponding bstring operations are undefined. 6) Any bstring definition whose header or accessible data portion has been assigned to inaccessible or otherwise illegal memory clearly cannot be acted upon by the bstring library in any way. 7) Destroying the source of an incremental split from within the callback and not returning with a negative value (indicating that it should abort) will lead to undefined behaviour. (Though *modifying* or adjusting the state of the source data, even if those modification fail within the bstrlib API, has well defined behavior.) 8) Modifying a bstring which is write protected by direct access has undefined behavior. While this may seem like a long list, with the exception of invalid uses of the writeAllow macro, and source destruction during an iterative split without an accompanying abort, no usage of the bstring API alone can cause any undefined scenario to occurr. I.e., the policy of restricting usage of bstrings to the bstring API can significantly reduce the risk of runtime errors (in practice it should eliminate them) related to string manipulation due to undefined action. C++ wrapper ----------- A C++ wrapper has been created to enable bstring functionality for C++ in the most natural (for C++ programers) way possible. The mandate for the C++ wrapper is different from the base C bstring library. Since the C++ language has far more abstracting capabilities, the CBString structure is considered fully abstracted -- i.e., hand generated CBStrings are not supported (though conversion from a struct tagbstring is allowed) and all detectable errors are manifest as thrown exceptions. - The C++ class definitions are all under the namespace Bstrlib. bstrwrap.h enables this namespace (with a using namespace Bstrlib; directive at the end) unless the macro BSTRLIB_DONT_ASSUME_NAMESPACE has been defined before it is included. - Erroneous accesses results in an exception being thrown. The exception parameter is of type "struct CBStringException" which is derived from std::exception if STL is used. A verbose description of the error message can be obtained from the what() method. - CBString is a C++ structure derived from a struct tagbstring. An address of a CBString cast to a bstring must not be passed to bdestroy. The bstring C API has been made C++ safe and can be used directly in a C++ project. - It includes constructors which can take a char, '\0' terminated char buffer, tagbstring, (char, repeat-value), a length delimited buffer or a CBStringList to initialize it. - Concatenation is performed with the + and += operators. Comparisons are done with the ==, !=, <, >, <= and >= operators. Note that == and != use the biseq call, while <, >, <= and >= use bstrcmp. - CBString's can be directly cast to const character buffers. - CBString's can be directly cast to double, float, int or unsigned int so long as the CBString are decimal representations of those types (otherwise an exception will be thrown). Converting the other way should be done with the format(a) method(s). - CBString contains the length, character and [] accessor methods. The character and [] accessors are aliases of each other. If the bounds for the string are exceeded, an exception is thrown. To avoid the overhead for this check, first cast the CBString to a (const char *) and use [] to dereference the array as normal. Note that the character and [] accessor methods allows both reading and writing of individual characters. - The methods: format, formata, find, reversefind, findcaseless, reversefindcaseless, midstr, insert, insertchrs, replace, findreplace, findreplacecaseless, remove, findchr, nfindchr, alloc, toupper, tolower, gets, read are analogous to the functions that can be found in the C API. - The caselessEqual and caselessCmp methods are analogous to biseqcaseless and bstricmp functions respectively. - Note that just like the bformat function, the format and formata methods do not automatically cast CBStrings into char * strings for "%s"-type substitutions: CBString w("world"); CBString h("Hello"); CBString hw; /* The casts are necessary */ hw.format ("%s, %s", (const char *)h, (const char *)w); - The methods trunc and repeat have been added instead of using pattern. - ltrim, rtrim and trim methods have been added. These remove characters from a given character string set (defaulting to the whitespace characters) from either the left, right or both ends of the CBString, respectively. - The method setsubstr is also analogous in functionality to bsetstr, except that it cannot be passed NULL. Instead the method fill and the fill-style constructor have been supplied to enable this functionality. - The writeprotect(), writeallow() and iswriteprotected() methods are analogous to the bwriteprotect(), bwriteallow() and biswriteprotected() macros in the C API. Write protection semantics in CBString are stronger than with the C API in that indexed character assignment is checked for write protection. However, unlike with the C API, a write protected CBString can be destroyed by the destructor. - CBStream is a C++ structure which wraps a struct bStream (its not derived from it, since destruction is slightly different). It is constructed by passing in a bNread function pointer and a stream parameter cast to void *. This structure includes methods for detecting eof, setting the buffer length, reading the whole stream or reading entries line by line or block by block, an unread function, and a peek function. - If STL is available, the CBStringList structure is derived from a vector of CBString with various split methods. The split method has been overloaded to accept either a character or CBString as the second parameter (when the split parameter is a CBString any character in that CBString is used as a seperator). The splitstr method takes a CBString as a substring seperator. Joins can be performed via a CBString constructor which takes a CBStringList as a parameter, or just using the CBString::join() method. - If there is proper support for std::iostreams, then the >> and << operators and the getline() function have been added (with semantics the same as those for std::string). Multithreading -------------- A mutable bstring is kind of analogous to a small (two entry) linked list allocated by malloc, with all aliasing completely under programmer control. I.e., manipulation of one bstring will never affect any other distinct bstring unless explicitely constructed to do so by the programmer via hand construction or via building a reference. Bstrlib also does not use any static or global storage, so there are no hidden unremovable race conditions. Bstrings are also clearly not inherently thread local. So just like char *'s, bstrings can be passed around from thread to thread and shared and so on, so long as modifications to a bstring correspond to some kind of exclusive access lock as should be expected (or if the bstring is read-only, which can be enforced by bstring write protection) for any sort of shared object in a multithreaded environment. Bsafe module ------------ For convenience, a bsafe module has been included. The idea is that if this module is included, inadvertant usage of the most dangerous C functions will be overridden and lead to an immediate run time abort. Of course, it should be emphasized that usage of this module is completely optional. The intention is essentially to provide an option for creating project safety rules which can be enforced mechanically rather than socially. This is useful for larger, or open development projects where its more difficult to enforce social rules or "coding conventions". Problems not solved ------------------- Bstrlib is written for the C and C++ languages, which have inherent weaknesses that cannot be easily solved: 1. Memory leaks: Forgetting to call bdestroy on a bstring that is about to be unreferenced, just as forgetting to call free on a heap buffer that is about to be dereferenced. Though bstrlib itself is leak free. 2. Read before write usage: In C, declaring an auto bstring does not automatically fill it with legal/valid contents. This problem has been somewhat mitigated in C++. (The bstrDeclare and bstrFree macros from bstraux can be used to help mitigate this problem.) Other problems not addressed: 3. Built-in mutex usage to automatically avoid all bstring internal race conditions in multitasking environments: The problem with trying to implement such things at this low a level is that it is typically more efficient to use locks in higher level primitives. There is also no platform independent way to implement locks or mutexes. 4. Unicode/widecharacter support. Note that except for spotty support of wide characters, the default C standard library does not address any of these problems either. Configurable compilation options -------------------------------- All configuration options are meant solely for the purpose of compiler compatibility. Configuration options are not meant to change the semantics or capabilities of the library, except where it is unavoidable. Since some C++ compilers don't include the Standard Template Library and some have the options of disabling exception handling, a number of macros can be used to conditionally compile support for each of this: BSTRLIB_CAN_USE_STL - defining this will enable the used of the Standard Template Library. Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. BSTRLIB_CANNOT_USE_STL - defining this will disable the use of the Standard Template Library. Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. BSTRLIB_CAN_USE_IOSTREAM - defining this will enable the used of streams from class std. Defining BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. BSTRLIB_CANNOT_USE_IOSTREAM - defining this will disable the use of streams from class std. Defining BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. BSTRLIB_THROWS_EXCEPTIONS - defining this will enable the exception handling within bstring. Defining BSTRLIB_THROWS_EXCEPTIONS overrides the BSTRLIB_DOESNT_THROWS_EXCEPTIONS macro. BSTRLIB_DOESNT_THROW_EXCEPTIONS - defining this will disable the exception handling within bstring. Defining BSTRLIB_THROWS_EXCEPTIONS overrides the BSTRLIB_DOESNT_THROW_EXCEPTIONS macro. Note that these macros must be defined consistently throughout all modules that use CBStrings including bstrwrap.cpp. Some older C compilers do not support functions such as vsnprintf. This is handled by the following macro variables: BSTRLIB_NOVSNP - defining this indicates that the compiler does not support vsnprintf. This will cause bformat and bformata to not be declared. Note that for some compilers, such as Turbo C, this is set automatically. Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. BSTRLIB_VSNP_OK - defining this will disable the autodetection of compilers the do not support of compilers that do not support vsnprintf. Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. Semantic compilation options ---------------------------- Bstrlib comes with very few compilation options for changing the semantics of of the library. These are described below. BSTRLIB_DONT_ASSUME_NAMESPACE - Defining this before including bstrwrap.h will disable the automatic enabling of the Bstrlib namespace for the C++ declarations. BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR - Defining this will make the CBString destructor non-virtual. BSTRLIB_MEMORY_DEBUG - Defining this will cause the bstrlib modules bstrlib.c and bstrwrap.cpp to invoke a #include "memdbg.h". memdbg.h has to be supplied by the user. Note that these macros must be defined consistently throughout all modules that use bstrings or CBStrings including bstrlib.c, bstraux.c and bstrwrap.cpp. =============================================================================== Files ----- bstrlib.c - C implementaion of bstring functions. bstrlib.h - C header file for bstring functions. bstraux.c - C example that implements trivial additional functions. bstraux.h - C header for bstraux.c bstest.c - C unit/regression test for bstrlib.c bstrwrap.cpp - C++ implementation of CBString. bstrwrap.h - C++ header file for CBString. test.cpp - C++ unit/regression test for bstrwrap.cpp bsafe.c - C runtime stubs to abort usage of unsafe C functions. bsafe.h - C header file for bsafe.c functions. C projects need only include bstrlib.h and compile/link bstrlib.c to use the bstring library. C++ projects need to additionally include bstrwrap.h and compile/link bstrwrap.cpp. For both, there may be a need to make choices about feature configuration as described in the "Configurable compilation options" in the section above. Other files that are included in this archive are: license.txt - The BSD license for Bstrlib gpl.txt - The GPL version 2 security.txt - A security statement useful for auditting Bstrlib porting.txt - A guide to porting Bstrlib bstrlib.txt - This file =============================================================================== The functions ------------- extern bstring bfromcstr (const char * str); Take a standard C library style '\0' terminated char buffer and generate a bstring with the same contents as the char buffer. If an error occurs NULL is returned. So for example: bstring b = bfromcstr ("Hello"); if (!b) { fprintf (stderr, "Out of memory"); } else { puts ((char *) b->data); } .......................................................................... extern bstring bfromcstralloc (int mlen, const char * str); Create a bstring which contains the contents of the '\0' terminated char * buffer str. The memory buffer backing the bstring is at least mlen characters in length. If an error occurs NULL is returned. So for example: bstring b = bfromcstralloc (64, someCstr); if (b) b->data[63] = 'x'; The idea is that this will set the 64th character of b to 'x' if it is at least 64 characters long otherwise do nothing. And we know this is well defined so long as b was successfully created, since it will have been allocated with at least 64 characters. .......................................................................... extern bstring blk2bstr (const void * blk, int len); Create a bstring whose contents are described by the contiguous buffer pointing to by blk with a length of len bytes. Note that this function creates a copy of the data in blk, rather than simply referencing it. Compare with the blk2tbstr macro. If an error occurs NULL is returned. .......................................................................... extern char * bstr2cstr (const_bstring s, char z); Create a '\0' terminated char buffer which contains the contents of the bstring s, except that any contained '\0' characters are converted to the character in z. This returned value should be freed with bcstrfree(), by the caller. If an error occurs NULL is returned. .......................................................................... extern int bcstrfree (char * s); Frees a C-string generated by bstr2cstr (). This is normally unnecessary since it just wraps a call to free (), however, if malloc () and free () have been redefined as a macros within the bstrlib module (via macros in the memdbg.h backdoor) with some difference in behaviour from the std library functions, then this allows a correct way of freeing the memory that allows higher level code to be independent from these macro redefinitions. .......................................................................... extern bstring bstrcpy (const_bstring b1); Make a copy of the passed in bstring. The copied bstring is returned if there is no error, otherwise NULL is returned. .......................................................................... extern int bassign (bstring a, const_bstring b); Overwrite the bstring a with the contents of bstring b. Note that the bstring a must be a well defined and writable bstring. If an error occurs BSTR_ERR is returned and a is not overwritten. .......................................................................... int bassigncstr (bstring a, const char * str); Overwrite the string a with the contents of char * string str. Note that the bstring a must be a well defined and writable bstring. If an error occurs BSTR_ERR is returned and a may be partially overwritten. .......................................................................... int bassignblk (bstring a, const void * s, int len); Overwrite the string a with the contents of the block (s, len). Note that the bstring a must be a well defined and writable bstring. If an error occurs BSTR_ERR is returned and a is not overwritten. .......................................................................... extern int bassignmidstr (bstring a, const_bstring b, int left, int len); Overwrite the bstring a with the middle of contents of bstring b starting from position left and running for a length len. left and len are clamped to the ends of b as with the function bmidstr. Note that the bstring a must be a well defined and writable bstring. If an error occurs BSTR_ERR is returned and a is not overwritten. .......................................................................... extern bstring bmidstr (const_bstring b, int left, int len); Create a bstring which is the substring of b starting from position left and running for a length len (clamped by the end of the bstring b.) If there was no error, the value of this constructed bstring is returned otherwise NULL is returned. .......................................................................... extern int bdelete (bstring s1, int pos, int len); Removes characters from pos to pos+len-1 and shifts the tail of the bstring starting from pos+len to pos. len must be positive for this call to have any effect. The section of the bstring described by (pos, len) is clamped to boundaries of the bstring b. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int bconcat (bstring b0, const_bstring b1); Concatenate the bstring b1 to the end of bstring b0. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int bconchar (bstring b, char c); Concatenate the character c to the end of bstring b. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int bcatcstr (bstring b, const char * s); Concatenate the char * string s to the end of bstring b. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int bcatblk (bstring b, const void * s, int len); Concatenate a fixed length buffer (s, len) to the end of bstring b. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int biseq (const_bstring b0, const_bstring b1); Compare the bstring b0 and b1 for equality. If the bstrings differ, 0 is returned, if the bstrings are the same, 1 is returned, if there is an error, -1 is returned. If the length of the bstrings are different, this function has O(1) complexity. Contained '\0' characters are not treated as a termination character. Note that the semantics of biseq are not completely compatible with bstrcmp because of its different treatment of the '\0' character. .......................................................................... extern int bisstemeqblk (const_bstring b, const void * blk, int len); Compare beginning of bstring b0 with a block of memory of length len for equality. If the beginning of b0 differs from the memory block (or if b0 is too short), 0 is returned, if the bstrings are the same, 1 is returned, if there is an error, -1 is returned. .......................................................................... extern int biseqcaseless (const_bstring b0, const_bstring b1); Compare two bstrings for equality without differentiating between case. If the bstrings differ other than in case, 0 is returned, if the bstrings are the same, 1 is returned, if there is an error, -1 is returned. If the length of the bstrings are different, this function is O(1). '\0' termination characters are not treated in any special way. .......................................................................... extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); Compare beginning of bstring b0 with a block of memory of length len without differentiating between case for equality. If the beginning of b0 differs from the memory block other than in case (or if b0 is too short), 0 is returned, if the bstrings are the same, 1 is returned, if there is an error, -1 is returned. .......................................................................... extern int biseqcstr (const_bstring b, const char *s); Compare the bstring b and char * bstring s. The C string s must be '\0' terminated at exactly the length of the bstring b, and the contents between the two must be identical with the bstring b with no '\0' characters for the two contents to be considered equal. This is equivalent to the condition that their current contents will be always be equal when comparing them in the same format after converting one or the other. If they are equal 1 is returned, if they are unequal 0 is returned and if there is a detectable error BSTR_ERR is returned. .......................................................................... extern int biseqcstrcaseless (const_bstring b, const char *s); Compare the bstring b and char * string s. The C string s must be '\0' terminated at exactly the length of the bstring b, and the contents between the two must be identical except for case with the bstring b with no '\0' characters for the two contents to be considered equal. This is equivalent to the condition that their current contents will be always be equal ignoring case when comparing them in the same format after converting one or the other. If they are equal, except for case, 1 is returned, if they are unequal regardless of case 0 is returned and if there is a detectable error BSTR_ERR is returned. .......................................................................... extern int bstrcmp (const_bstring b0, const_bstring b1); Compare the bstrings b0 and b1 for ordering. If there is an error, SHRT_MIN is returned, otherwise a value less than or greater than zero, indicating that the bstring pointed to by b0 is lexicographically less than or greater than the bstring pointed to by b1 is returned. If the bstring lengths are unequal but the characters up until the length of the shorter are equal then a value less than, or greater than zero, indicating that the bstring pointed to by b0 is shorter or longer than the bstring pointed to by b1 is returned. 0 is returned if and only if the two bstrings are the same. If the length of the bstrings are different, this function is O(n). Like its standard C library counter part, the comparison does not proceed past any '\0' termination characters encountered. The seemingly odd error return value, merely provides slightly more granularity than the undefined situation given in the C library function strcmp. The function otherwise behaves very much like strcmp(). Note that the semantics of bstrcmp are not completely compatible with biseq because of its different treatment of the '\0' termination character. .......................................................................... extern int bstrncmp (const_bstring b0, const_bstring b1, int n); Compare the bstrings b0 and b1 for ordering for at most n characters. If there is an error, SHRT_MIN is returned, otherwise a value is returned as if b0 and b1 were first truncated to at most n characters then bstrcmp was called with these new bstrings are paremeters. If the length of the bstrings are different, this function is O(n). Like its standard C library counter part, the comparison does not proceed past any '\0' termination characters encountered. The seemingly odd error return value, merely provides slightly more granularity than the undefined situation given in the C library function strncmp. The function otherwise behaves very much like strncmp(). .......................................................................... extern int bstricmp (const_bstring b0, const_bstring b1); Compare two bstrings without differentiating between case. The return value is the difference of the values of the characters where the two bstrings first differ, otherwise 0 is returned indicating that the bstrings are equal. If the lengths are different, then a difference from 0 is given, but if the first extra character is '\0', then it is taken to be the value UCHAR_MAX+1. .......................................................................... extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); Compare two bstrings without differentiating between case for at most n characters. If the position where the two bstrings first differ is before the nth position, the return value is the difference of the values of the characters, otherwise 0 is returned. If the lengths are different and less than n characters, then a difference from 0 is given, but if the first extra character is '\0', then it is taken to be the value UCHAR_MAX+1. .......................................................................... extern int bdestroy (bstring b); Deallocate the bstring passed. Passing NULL in as a parameter will have no effect. Note that both the header and the data portion of the bstring will be freed. No other bstring function which modifies one of its parameters will free or reallocate the header. Because of this, in general, bdestroy cannot be called on any declared struct tagbstring even if it is not write protected. A bstring which is write protected cannot be destroyed via the bdestroy call. Any attempt to do so will result in no action taken, and BSTR_ERR will be returned. Note to C++ users: Passing in a CBString cast to a bstring will lead to undefined behavior (free will be called on the header, rather than the CBString destructor.) Instead just use the ordinary C++ language facilities to dealloc a CBString. .......................................................................... extern int binstr (const_bstring s1, int pos, const_bstring s2); Search for the bstring s2 in s1 starting at position pos and looking in a forward (increasing) direction. If it is found then it returns with the first position after pos where it is found, otherwise it returns BSTR_ERR. The algorithm used is brute force; O(m*n). .......................................................................... extern int binstrr (const_bstring s1, int pos, const_bstring s2); Search for the bstring s2 in s1 starting at position pos and looking in a backward (decreasing) direction. If it is found then it returns with the first position after pos where it is found, otherwise return BSTR_ERR. Note that the current position at pos is tested as well -- so to be disjoint from a previous forward search it is recommended that the position be backed up (decremented) by one position. The algorithm used is brute force; O(m*n). .......................................................................... extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); Search for the bstring s2 in s1 starting at position pos and looking in a forward (increasing) direction but without regard to case. If it is found then it returns with the first position after pos where it is found, otherwise it returns BSTR_ERR. The algorithm used is brute force; O(m*n). .......................................................................... extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); Search for the bstring s2 in s1 starting at position pos and looking in a backward (decreasing) direction but without regard to case. If it is found then it returns with the first position after pos where it is found, otherwise return BSTR_ERR. Note that the current position at pos is tested as well -- so to be disjoint from a previous forward search it is recommended that the position be backed up (decremented) by one position. The algorithm used is brute force; O(m*n). .......................................................................... extern int binchr (const_bstring b0, int pos, const_bstring b1); Search for the first position in b0 starting from pos or after, in which one of the characters in b1 is found. This function has an execution time of O(b0->slen + b1->slen). If such a position does not exist in b0, then BSTR_ERR is returned. .......................................................................... extern int binchrr (const_bstring b0, int pos, const_bstring b1); Search for the last position in b0 no greater than pos, in which one of the characters in b1 is found. This function has an execution time of O(b0->slen + b1->slen). If such a position does not exist in b0, then BSTR_ERR is returned. .......................................................................... extern int bninchr (const_bstring b0, int pos, const_bstring b1); Search for the first position in b0 starting from pos or after, in which none of the characters in b1 is found and return it. This function has an execution time of O(b0->slen + b1->slen). If such a position does not exist in b0, then BSTR_ERR is returned. .......................................................................... extern int bninchrr (const_bstring b0, int pos, const_bstring b1); Search for the last position in b0 no greater than pos, in which none of the characters in b1 is found and return it. This function has an execution time of O(b0->slen + b1->slen). If such a position does not exist in b0, then BSTR_ERR is returned. .......................................................................... extern int bstrchr (const_bstring b, int c); Search for the character c in the bstring b forwards from the start of the bstring. Returns the position of the found character or BSTR_ERR if it is not found. NOTE: This has been implemented as a macro on top of bstrchrp (). .......................................................................... extern int bstrrchr (const_bstring b, int c); Search for the character c in the bstring b backwards from the end of the bstring. Returns the position of the found character or BSTR_ERR if it is not found. NOTE: This has been implemented as a macro on top of bstrrchrp (). .......................................................................... extern int bstrchrp (const_bstring b, int c, int pos); Search for the character c in b forwards from the position pos (inclusive). Returns the position of the found character or BSTR_ERR if it is not found. .......................................................................... extern int bstrrchrp (const_bstring b, int c, int pos); Search for the character c in b backwards from the position pos in bstring (inclusive). Returns the position of the found character or BSTR_ERR if it is not found. .......................................................................... extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); Overwrite the bstring b0 starting at position pos with the bstring b1. If the position pos is past the end of b0, then the character "fill" is appended as necessary to make up the gap between the end of b0 and pos. If b1 is NULL, it behaves as if it were a 0-length bstring. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); Inserts the bstring s2 into s1 at position pos. If the position pos is past the end of s1, then the character "fill" is appended as necessary to make up the gap between the end of s1 and pos. The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int binsertch (bstring s1, int pos, int len, unsigned char fill); Inserts the character fill repeatedly into s1 at position pos for a length len. If the position pos is past the end of s1, then the character "fill" is appended as necessary to make up the gap between the end of s1 and the position pos + len (exclusive). The value BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is returned. .......................................................................... extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill); Replace a section of a bstring from pos for a length len with the bstring b2. If the position pos is past the end of b1 then the character "fill" is appended as necessary to make up the gap between the end of b1 and pos. .......................................................................... extern int bfindreplace (bstring b, const_bstring find, const_bstring replace, int position); Replace all occurrences of the find substring with a replace bstring after a given position in the bstring b. The find bstring must have a length > 0 otherwise BSTR_ERR is returned. This function does not perform recursive per character replacement; that is to say successive searches resume at the position after the last replace. So for example: bfindreplace (a0 = bfromcstr("aabaAb"), a1 = bfromcstr("a"), a2 = bfromcstr("aa"), 0); Should result in changing a0 to "aaaabaaAb". This function performs exactly (b->slen - position) bstring comparisons, and data movement is bounded above by character volume equivalent to size of the output bstring. .......................................................................... extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring replace, int position); Replace all occurrences of the find substring, ignoring case, with a replace bstring after a given position in the bstring b. The find bstring must have a length > 0 otherwise BSTR_ERR is returned. This function does not perform recursive per character replacement; that is to say successive searches resume at the position after the last replace. So for example: bfindreplacecaseless (a0 = bfromcstr("AAbaAb"), a1 = bfromcstr("a"), a2 = bfromcstr("aa"), 0); Should result in changing a0 to "aaaabaaaab". This function performs exactly (b->slen - position) bstring comparisons, and data movement is bounded above by character volume equivalent to size of the output bstring. .......................................................................... extern int balloc (bstring b, int length); Increase the allocated memory backing the data buffer for the bstring b to a length of at least length. If the memory backing the bstring b is already large enough, not action is performed. This has no effect on the bstring b that is visible to the bstring API. Usually this function will only be used when a minimum buffer size is required coupled with a direct access to the ->data member of the bstring structure. Be warned that like any other bstring function, the bstring must be well defined upon entry to this function. I.e., doing something like: b->slen *= 2; /* ?? Most likely incorrect */ balloc (b, b->slen); is invalid, and should be implemented as: int t; if (BSTR_OK == balloc (b, t = (b->slen * 2))) b->slen = t; This function will return with BSTR_ERR if b is not detected as a valid bstring or length is not greater than 0, otherwise BSTR_OK is returned. .......................................................................... extern int ballocmin (bstring b, int length); Change the amount of memory backing the bstring b to at least length. This operation will never truncate the bstring data including the extra terminating '\0' and thus will not decrease the length to less than b->slen + 1. Note that repeated use of this function may cause performance problems (realloc may be called on the bstring more than the O(log(INT_MAX)) times). This function will return with BSTR_ERR if b is not detected as a valid bstring or length is not greater than 0, otherwise BSTR_OK is returned. So for example: if (BSTR_OK == ballocmin (b, 64)) b->data[63] = 'x'; The idea is that this will set the 64th character of b to 'x' if it is at least 64 characters long otherwise do nothing. And we know this is well defined so long as the ballocmin call was successfully, since it will ensure that b has been allocated with at least 64 characters. .......................................................................... int btrunc (bstring b, int n); Truncate the bstring to at most n characters. This function will return with BSTR_ERR if b is not detected as a valid bstring or n is less than 0, otherwise BSTR_OK is returned. .......................................................................... extern int bpattern (bstring b, int len); Replicate the starting bstring, b, end to end repeatedly until it surpasses len characters, then chop the result to exactly len characters. This function operates in-place. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int btoupper (bstring b); Convert contents of bstring to upper case. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int btolower (bstring b); Convert contents of bstring to lower case. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int bltrimws (bstring b); Delete whitespace contiguous from the left end of the bstring. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int brtrimws (bstring b); Delete whitespace contiguous from the right end of the bstring. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int btrimws (bstring b); Delete whitespace contiguous from both ends of the bstring. This function will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. .......................................................................... extern int bstrListCreate (void); Create an empty struct bstrList. The struct bstrList output structure is declared as follows: struct bstrList { int qty, mlen; bstring * entry; }; The entry field actually is an array with qty number entries. The mlen record counts the maximum number of bstring's for which there is memory in the entry record. The Bstrlib API does *NOT* include a comprehensive set of functions for full management of struct bstrList in an abstracted way. The reason for this is because aliasing semantics of the list are best left to the user of this function, and performance varies wildly depending on the assumptions made. For a complete list of bstring data type it is recommended that the C++ public std::vector be used, since its semantics are usage are more standard. .......................................................................... extern int bstrListDestroy (struct bstrList * sl); Destroy a struct bstrList structure that was returned by the bsplit function. Note that this will destroy each bstring in the ->entry array as well. See bstrListCreate() above for structure of struct bstrList. .......................................................................... extern int bstrListAlloc (struct bstrList * sl, int msz); Ensure that there is memory for at least msz number of entries for the list. .......................................................................... extern int bstrListAllocMin (struct bstrList * sl, int msz); Try to allocate the minimum amount of memory for the list to include at least msz entries or sl->qty whichever is greater. .......................................................................... extern struct bstrList * bsplit (bstring str, unsigned char splitChar); Create an array of sequential substrings from str divided by the character splitChar. Successive occurrences of the splitChar will be divided by empty bstring entries, following the semantics from the Python programming language. To reclaim the memory from this output structure, bstrListDestroy () should be called. See bstrListCreate() above for structure of struct bstrList. .......................................................................... extern struct bstrList * bsplits (bstring str, const_bstring splitStr); Create an array of sequential substrings from str divided by any character contained in splitStr. An empty splitStr causes a single entry bstrList containing a copy of str to be returned. See bstrListCreate() above for structure of struct bstrList. .......................................................................... extern struct bstrList * bsplitstr (bstring str, const_bstring splitStr); Create an array of sequential substrings from str divided by the entire substring splitStr. An empty splitStr causes a single entry bstrList containing a copy of str to be returned. See bstrListCreate() above for structure of struct bstrList. .......................................................................... extern bstring bjoin (const struct bstrList * bl, const_bstring sep); Join the entries of a bstrList into one bstring by sequentially concatenating them with the sep bstring in between. If sep is NULL, it is treated as if it were the empty bstring. Note that: bjoin (l = bsplit (b, s->data[0]), s); should result in a copy of b, if s->slen is 1. If there is an error NULL is returned, otherwise a bstring with the correct result is returned. See bstrListCreate() above for structure of struct bstrList. .......................................................................... extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); Iterate the set of disjoint sequential substrings over str starting at position pos divided by the character splitChar. The parm passed to bsplitcb is passed on to cb. If the function cb returns a value < 0, then further iterating is halted and this value is returned by bsplitcb. Note: Non-destructive modification of str from within the cb function while performing this split is not undefined. bsplitcb behaves in sequential lock step with calls to cb. I.e., after returning from a cb that return a non-negative integer, bsplitcb continues from the position 1 character after the last detected split character and it will halt immediately if the length of str falls below this point. However, if the cb function destroys str, then it *must* return with a negative value, otherwise bsplitcb will continue in an undefined manner. This function is provided as an incremental alternative to bsplit that is abortable and which does not impose additional memory allocation. .......................................................................... extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); Iterate the set of disjoint sequential substrings over str starting at position pos divided by any of the characters in splitStr. An empty splitStr causes the whole str to be iterated once. The parm passed to bsplitcb is passed on to cb. If the function cb returns a value < 0, then further iterating is halted and this value is returned by bsplitcb. Note: Non-destructive modification of str from within the cb function while performing this split is not undefined. bsplitscb behaves in sequential lock step with calls to cb. I.e., after returning from a cb that return a non-negative integer, bsplitscb continues from the position 1 character after the last detected split character and it will halt immediately if the length of str falls below this point. However, if the cb function destroys str, then it *must* return with a negative value, otherwise bsplitscb will continue in an undefined manner. This function is provided as an incremental alternative to bsplits that is abortable and which does not impose additional memory allocation. .......................................................................... extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); Iterate the set of disjoint sequential substrings over str starting at position pos divided by the entire substring splitStr. An empty splitStr causes each character of str to be iterated. The parm passed to bsplitcb is passed on to cb. If the function cb returns a value < 0, then further iterating is halted and this value is returned by bsplitcb. Note: Non-destructive modification of str from within the cb function while performing this split is not undefined. bsplitstrcb behaves in sequential lock step with calls to cb. I.e., after returning from a cb that return a non-negative integer, bsplitstrcb continues from the position 1 character after the last detected split character and it will halt immediately if the length of str falls below this point. However, if the cb function destroys str, then it *must* return with a negative value, otherwise bsplitscb will continue in an undefined manner. This function is provided as an incremental alternative to bsplitstr that is abortable and which does not impose additional memory allocation. .......................................................................... extern bstring bformat (const char * fmt, ...); Takes the same parameters as printf (), but rather than outputting results to stdio, it forms a bstring which contains what would have been output. Note that if there is an early generation of a '\0' character, the bstring will be truncated to this end point. Note that %s format tokens correspond to '\0' terminated char * buffers, not bstrings. To print a bstring, first dereference data element of the the bstring: /* b1->data needs to be '\0' terminated, so tagbstrings generated by blk2tbstr () might not be suitable. */ b0 = bformat ("Hello, %s", b1->data); Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been compiled the bformat function is not present. .......................................................................... extern int bformata (bstring b, const char * fmt, ...); In addition to the initial output buffer b, bformata takes the same parameters as printf (), but rather than outputting results to stdio, it appends the results to the initial bstring parameter. Note that if there is an early generation of a '\0' character, the bstring will be truncated to this end point. Note that %s format tokens correspond to '\0' terminated char * buffers, not bstrings. To print a bstring, first dereference data element of the the bstring: /* b1->data needs to be '\0' terminated, so tagbstrings generated by blk2tbstr () might not be suitable. */ bformata (b0 = bfromcstr ("Hello"), ", %s", b1->data); Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been compiled the bformata function is not present. .......................................................................... extern int bassignformat (bstring b, const char * fmt, ...); After the first parameter, it takes the same parameters as printf (), but rather than outputting results to stdio, it outputs the results to the bstring parameter b. Note that if there is an early generation of a '\0' character, the bstring will be truncated to this end point. Note that %s format tokens correspond to '\0' terminated char * buffers, not bstrings. To print a bstring, first dereference data element of the the bstring: /* b1->data needs to be '\0' terminated, so tagbstrings generated by blk2tbstr () might not be suitable. */ bassignformat (b0 = bfromcstr ("Hello"), ", %s", b1->data); Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been compiled the bassignformat function is not present. .......................................................................... extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); The bvcformata function formats data under control of the format control string fmt and attempts to append the result to b. The fmt parameter is the same as that of the printf function. The variable argument list is replaced with arglist, which has been initialized by the va_start macro. The size of the output is upper bounded by count. If the required output exceeds count, the string b is not augmented with any contents and a value below BSTR_ERR is returned. If a value below -count is returned then it is recommended that the negative of this value be used as an update to the count in a subsequent pass. On other errors, such as running out of memory, parameter errors or numeric wrap around BSTR_ERR is returned. BSTR_OK is returned when the output is successfully generated and appended to b. Note: There is no sanity checking of arglist, and this function is destructive of the contents of b from the b->slen point onward. If there is an early generation of a '\0' character, the bstring will be truncated to this end point. Although this function is part of the external API for Bstrlib, the interface and semantics (length limitations, and unusual return codes) are fairly atypical. The real purpose for this function is to provide an engine for the bvformata macro. Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been compiled the bvcformata function is not present. .......................................................................... extern bstring bread (bNread readPtr, void * parm); typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm); Read an entire stream into a bstring, verbatum. The readPtr function pointer is compatible with fread sematics, except that it need not obtain the stream data from a file. The intention is that parm would contain the stream data context/state required (similar to the role of the FILE* I/O stream parameter of fread.) Abstracting the block read function allows for block devices other than file streams to be read if desired. Note that there is an ANSI compatibility issue if "fread" is used directly; see the ANSI issues section below. .......................................................................... extern int breada (bstring b, bNread readPtr, void * parm); Read an entire stream and append it to a bstring, verbatum. Behaves like bread, except that it appends it results to the bstring b. BSTR_ERR is returned on error, otherwise 0 is returned. .......................................................................... extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); typedef int (* bNgetc) (void * parm); Read a bstring from a stream. As many bytes as is necessary are read until the terminator is consumed or no more characters are available from the stream. If read from the stream, the terminator character will be appended to the end of the returned bstring. The getcPtr function must have the same semantics as the fgetc C library function (i.e., returning an integer whose value is negative when there are no more characters available, otherwise the value of the next available unsigned character from the stream.) The intention is that parm would contain the stream data context/state required (similar to the role of the FILE* I/O stream parameter of fgets.) If no characters are read, or there is some other detectable error, NULL is returned. bgets will never call the getcPtr function more often than necessary to construct its output (including a single call, if required, to determine that the stream contains no more characters.) Abstracting the character stream function and terminator character allows for different stream devices and string formats other than '\n' terminated lines in a file if desired (consider \032 terminated email messages, in a UNIX mailbox for example.) For files, this function can be used analogously as fgets as follows: fp = fopen ( ... ); if (fp) b = bgets ((bNgetc) fgetc, fp, '\n'); (Note that only one terminator character can be used, and that '\0' is not assumed to terminate the stream in addition to the terminator character. This is consistent with the semantics of fgets.) .......................................................................... extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); Read from a stream and concatenate to a bstring. Behaves like bgets, except that it appends it results to the bstring b. The value 1 is returned if no characters are read before a negative result is returned from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned in other normal cases. .......................................................................... extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); Read from a stream and concatenate to a bstring. Behaves like bgets, except that it assigns the results to the bstring b. The value 1 is returned if no characters are read before a negative result is returned from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned in other normal cases. .......................................................................... extern struct bStream * bsopen (bNread readPtr, void * parm); Wrap a given open stream (described by a fread compatible function pointer and stream handle) into an open bStream suitable for the bstring library streaming functions. .......................................................................... extern void * bsclose (struct bStream * s); Close the bStream, and return the handle to the stream that was originally used to open the given stream. If s is NULL or detectably invalid, NULL will be returned. .......................................................................... extern int bsbufflength (struct bStream * s, int sz); Set the length of the buffer used by the bStream. If sz is the macro BSTR_BS_BUFF_LENGTH_GET (which is 0), the length is not set. If s is NULL or sz is negative, the function will return with BSTR_ERR, otherwise this function returns with the previous length. .......................................................................... extern int bsreadln (bstring r, struct bStream * s, char terminator); Read a bstring terminated by the terminator character or the end of the stream from the bStream (s) and return it into the parameter r. The matched terminator, if found, appears at the end of the line read. If the stream has been exhausted of all available data, before any can be read, BSTR_ERR is returned. This function may read additional characters into the stream buffer from the core stream that are not returned, but will be retained for subsequent read operations. When reading from high speed streams, this function can perform significantly faster than bgets. .......................................................................... extern int bsreadlna (bstring r, struct bStream * s, char terminator); Read a bstring terminated by the terminator character or the end of the stream from the bStream (s) and concatenate it to the parameter r. The matched terminator, if found, appears at the end of the line read. If the stream has been exhausted of all available data, before any can be read, BSTR_ERR is returned. This function may read additional characters into the stream buffer from the core stream that are not returned, but will be retained for subsequent read operations. When reading from high speed streams, this function can perform significantly faster than bgets. .......................................................................... extern int bsreadlns (bstring r, struct bStream * s, bstring terminators); Read a bstring terminated by any character in the terminators bstring or the end of the stream from the bStream (s) and return it into the parameter r. This function may read additional characters from the core stream that are not returned, but will be retained for subsequent read operations. .......................................................................... extern int bsreadlnsa (bstring r, struct bStream * s, bstring terminators); Read a bstring terminated by any character in the terminators bstring or the end of the stream from the bStream (s) and concatenate it to the parameter r. If the stream has been exhausted of all available data, before any can be read, BSTR_ERR is returned. This function may read additional characters from the core stream that are not returned, but will be retained for subsequent read operations. .......................................................................... extern int bsread (bstring r, struct bStream * s, int n); Read a bstring of length n (or, if it is fewer, as many bytes as is remaining) from the bStream. This function will read the minimum required number of additional characters from the core stream. When the stream is at the end of the file BSTR_ERR is returned, otherwise BSTR_OK is returned. .......................................................................... extern int bsreada (bstring r, struct bStream * s, int n); Read a bstring of length n (or, if it is fewer, as many bytes as is remaining) from the bStream and concatenate it to the parameter r. This function will read the minimum required number of additional characters from the core stream. When the stream is at the end of the file BSTR_ERR is returned, otherwise BSTR_OK is returned. .......................................................................... extern int bsunread (struct bStream * s, const_bstring b); Insert a bstring into the bStream at the current position. These characters will be read prior to those that actually come from the core stream. .......................................................................... extern int bspeek (bstring r, const struct bStream * s); Return the number of currently buffered characters from the bStream that will be read prior to reads from the core stream, and append it to the the parameter r. .......................................................................... extern int bssplitscb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); Iterate the set of disjoint sequential substrings over the stream s divided by any character from the bstring splitStr. The parm passed to bssplitscb is passed on to cb. If the function cb returns a value < 0, then further iterating is halted and this return value is returned by bssplitscb. Note: At the point of calling the cb function, the bStream pointer is pointed exactly at the position right after having read the split character. The cb function can act on the stream by causing the bStream pointer to move, and bssplitscb will continue by starting the next split at the position of the pointer after the return from cb. However, if the cb causes the bStream s to be destroyed then the cb must return with a negative value, otherwise bssplitscb will continue in an undefined manner. This function is provided as way to incrementally parse through a file or other generic stream that in total size may otherwise exceed the practical or desired memory available. As with the other split callback based functions this is abortable and does not impose additional memory allocation. .......................................................................... extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); Iterate the set of disjoint sequential substrings over the stream s divided by the entire substring splitStr. The parm passed to bssplitstrcb is passed on to cb. If the function cb returns a value < 0, then further iterating is halted and this return value is returned by bssplitstrcb. Note: At the point of calling the cb function, the bStream pointer is pointed exactly at the position right after having read the split character. The cb function can act on the stream by causing the bStream pointer to move, and bssplitstrcb will continue by starting the next split at the position of the pointer after the return from cb. However, if the cb causes the bStream s to be destroyed then the cb must return with a negative value, otherwise bssplitscb will continue in an undefined manner. This function is provided as way to incrementally parse through a file or other generic stream that in total size may otherwise exceed the practical or desired memory available. As with the other split callback based functions this is abortable and does not impose additional memory allocation. .......................................................................... extern int bseof (const struct bStream * s); Return the defacto "EOF" (end of file) state of a stream (1 if the bStream is in an EOF state, 0 if not, and BSTR_ERR if stream is closed or detectably erroneous.) When the readPtr callback returns a value <= 0 the stream reaches its "EOF" state. Note that bunread with non-empty content will essentially turn off this state, and the stream will not be in its "EOF" state so long as its possible to read more data out of it. Also note that the semantics of bseof() are slightly different from something like feof(). I.e., reaching the end of the stream does not necessarily guarantee that bseof() will return with a value indicating that this has happened. bseof() will only return indicating that it has reached the "EOF" and an attempt has been made to read past the end of the bStream. The macros ---------- The macros described below are shown in a prototype form indicating their intended usage. Note that the parameters passed to these macros will be referenced multiple times. As with all macros, programmer care is required to guard against unintended side effects. int blengthe (const_bstring b, int err); Returns the length of the bstring. If the bstring is NULL err is returned. .......................................................................... int blength (const_bstring b); Returns the length of the bstring. If the bstring is NULL, the length returned is 0. .......................................................................... int bchare (const_bstring b, int p, int c); Returns the p'th character of the bstring b. If the position p refers to a position that does not exist in the bstring or the bstring is NULL, then c is returned. .......................................................................... char bchar (const_bstring b, int p); Returns the p'th character of the bstring b. If the position p refers to a position that does not exist in the bstring or the bstring is NULL, then '\0' is returned. .......................................................................... char * bdatae (bstring b, char * err); Returns the char * data portion of the bstring b. If b is NULL, err is returned. .......................................................................... char * bdata (bstring b); Returns the char * data portion of the bstring b. If b is NULL, NULL is returned. .......................................................................... char * bdataofse (bstring b, int ofs, char * err); Returns the char * data portion of the bstring b offset by ofs. If b is NULL, err is returned. .......................................................................... char * bdataofs (bstring b, int ofs); Returns the char * data portion of the bstring b offset by ofs. If b is NULL, NULL is returned. .......................................................................... struct tagbstring var = bsStatic ("..."); The bsStatic macro allows for static declarations of literal string constants as struct tagbstring structures. The resulting tagbstring does not need to be freed or destroyed. Note that this macro is only well defined for string literal arguments. For more general string pointers, use the btfromcstr macro. The resulting struct tagbstring is permanently write protected. Attempts to write to this struct tagbstring from any bstrlib function will lead to BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct tagbstring has no effect. .......................................................................... <- bsStaticBlkParms ("...") The bsStaticBlkParms macro emits a pair of comma seperated parameters corresponding to the block parameters for the block functions in Bstrlib (i.e., blk2bstr, bcatblk, blk2tbstr, bisstemeqblk, bisstemeqcaselessblk.) Note that this macro is only well defined for string literal arguments. Examples: bstring b = blk2bstr (bsStaticBlkParms ("Fast init. ")); bcatblk (b, bsStaticBlkParms ("No frills fast concatenation.")); These are faster than using bfromcstr() and bcatcstr() respectively because the length of the inline string is known as a compile time constant. Also note that seperate struct tagbstring declarations for holding the output of a bsStatic() macro are not required. .......................................................................... void btfromcstr (struct tagbstring& t, const char * s); Fill in the tagbstring t with the '\0' terminated char buffer s. This action is purely reference oriented; no memory management is done. The data member is just assigned s, and slen is assigned the strlen of s. The s parameter is accessed exactly once in this macro. The resulting struct tagbstring is initially write protected. Attempts to write to this struct tagbstring in a write protected state from any bstrlib function will lead to BSTR_ERR being returned. Invoke the bwriteallow on this struct tagbstring to make it writeable (though this requires that s be obtained from a function compatible with malloc.) .......................................................................... void btfromblk (struct tagbstring& t, void * s, int len); Fill in the tagbstring t with the data buffer s with length len. This action is purely reference oriented; no memory management is done. The data member of t is just assigned s, and slen is assigned len. Note that the buffer is not appended with a '\0' character. The s and len parameters are accessed exactly once each in this macro. The resulting struct tagbstring is initially write protected. Attempts to write to this struct tagbstring in a write protected state from any bstrlib function will lead to BSTR_ERR being returned. Invoke the bwriteallow on this struct tagbstring to make it writeable (though this requires that s be obtained from a function compatible with malloc.) .......................................................................... void btfromblkltrimws (struct tagbstring& t, void * s, int len); Fill in the tagbstring t with the data buffer s with length len after it has been left trimmed. This action is purely reference oriented; no memory management is done. The data member of t is just assigned to a pointer inside the buffer s. Note that the buffer is not appended with a '\0' character. The s and len parameters are accessed exactly once each in this macro. The resulting struct tagbstring is permanently write protected. Attempts to write to this struct tagbstring from any bstrlib function will lead to BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct tagbstring has no effect. .......................................................................... void btfromblkrtrimws (struct tagbstring& t, void * s, int len); Fill in the tagbstring t with the data buffer s with length len after it has been right trimmed. This action is purely reference oriented; no memory management is done. The data member of t is just assigned to a pointer inside the buffer s. Note that the buffer is not appended with a '\0' character. The s and len parameters are accessed exactly once each in this macro. The resulting struct tagbstring is permanently write protected. Attempts to write to this struct tagbstring from any bstrlib function will lead to BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct tagbstring has no effect. .......................................................................... void btfromblktrimws (struct tagbstring& t, void * s, int len); Fill in the tagbstring t with the data buffer s with length len after it has been left and right trimmed. This action is purely reference oriented; no memory management is done. The data member of t is just assigned to a pointer inside the buffer s. Note that the buffer is not appended with a '\0' character. The s and len parameters are accessed exactly once each in this macro. The resulting struct tagbstring is permanently write protected. Attempts to write to this struct tagbstring from any bstrlib function will lead to BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct tagbstring has no effect. .......................................................................... void bmid2tbstr (struct tagbstring& t, bstring b, int pos, int len); Fill the tagbstring t with the substring from b, starting from position pos with a length len. The segment is clamped by the boundaries of the bstring b. This action is purely reference oriented; no memory management is done. Note that the buffer is not appended with a '\0' character. Note that the t parameter to this macro may be accessed multiple times. Note that the contents of t will become undefined if the contents of b change or are destroyed. The resulting struct tagbstring is permanently write protected. Attempts to write to this struct tagbstring in a write protected state from any bstrlib function will lead to BSTR_ERR being returned. Invoking the bwriteallow macro on this struct tagbstring will have no effect. .......................................................................... void bvformata (int& ret, bstring b, const char * format, lastarg); Append the bstring b with printf like formatting with the format control string, and the arguments taken from the ... list of arguments after lastarg passed to the containing function. If the containing function does not have ... parameters or lastarg is not the last named parameter before the ... then the results are undefined. If successful, the results are appended to b and BSTR_OK is assigned to ret. Otherwise BSTR_ERR is assigned to ret. Example: void dbgerror (FILE * fp, const char * fmt, ...) { int ret; bstring b; bvformata (ret, b = bfromcstr ("DBG: "), fmt, fmt); if (BSTR_OK == ret) fputs ((char *) bdata (b), fp); bdestroy (b); } Note that if the BSTRLIB_NOVSNP macro was set when bstrlib had been compiled the bvformata macro will not link properly. If the BSTRLIB_NOVSNP macro has been set, the bvformata macro will not be available. .......................................................................... void bwriteprotect (struct tagbstring& t); Disallow bstring from being written to via the bstrlib API. Attempts to write to the resulting tagbstring from any bstrlib function will lead to BSTR_ERR being returned. Note: bstrings which are write protected cannot be destroyed via bdestroy. Note to C++ users: Setting a CBString as write protected will not prevent it from being destroyed by the destructor. .......................................................................... void bwriteallow (struct tagbstring& t); Allow bstring to be written to via the bstrlib API. Note that such an action makes the bstring both writable and destroyable. If the bstring is not legitimately writable (as is the case for struct tagbstrings initialized with a bsStatic value), the results of this are undefined. Note that invoking the bwriteallow macro may increase the number of reallocs by one more than necessary for every call to bwriteallow interleaved with any bstring API which writes to this bstring. .......................................................................... int biswriteprotected (struct tagbstring& t); Returns 1 if the bstring is write protected, otherwise 0 is returned. =============================================================================== The bstest module ----------------- The bstest module is just a unit test for the bstrlib module. For correct implementations of bstrlib, it should execute with 0 failures being reported. This test should be utilized if modifications/customizations to bstrlib have been performed. It tests each core bstrlib function with bstrings of every mode (read-only, NULL, static and mutable) and ensures that the expected semantics are observed (including results that should indicate an error). It also tests for aliasing support. Passing bstest is a necessary but not a sufficient condition for ensuring the correctness of the bstrlib module. The test module --------------- The test module is just a unit test for the bstrwrap module. For correct implementations of bstrwrap, it should execute with 0 failures being reported. This test should be utilized if modifications/customizations to bstrwrap have been performed. It tests each core bstrwrap function with CBStrings write protected or not and ensures that the expected semantics are observed (including expected exceptions.) Note that exceptions cannot be disabled to run this test. Passing test is a necessary but not a sufficient condition for ensuring the correctness of the bstrwrap module. =============================================================================== Using Bstring and CBString as an alternative to the C library ------------------------------------------------------------- First let us give a table of C library functions and the alternative bstring functions and CBString methods that should be used instead of them. C-library Bstring alternative CBString alternative --------- ------------------- -------------------- gets bgets ::gets strcpy bassign = operator strncpy bassignmidstr ::midstr strcat bconcat += operator strncat bconcat + btrunc += operator + ::trunc strtok bsplit, bsplits ::split sprintf b(assign)format ::format snprintf b(assign)format + btrunc ::format + ::trunc vsprintf bvformata bvformata vsnprintf bvformata + btrunc bvformata + btrunc vfprintf bvformata + fputs use bvformata + fputs strcmp biseq, bstrcmp comparison operators. strncmp bstrncmp, memcmp bstrncmp, memcmp strlen ->slen, blength ::length strdup bstrcpy constructor strset bpattern ::fill strstr binstr ::find strpbrk binchr ::findchr stricmp bstricmp cast & use bstricmp strlwr btolower cast & use btolower strupr btoupper cast & use btoupper strrev bReverse (aux module) cast & use bReverse strchr bstrchr cast & use bstrchr strspnp use strspn use strspn ungetc bsunread bsunread The top 9 C functions listed here are troublesome in that they impose memory management in the calling function. The Bstring and CBstring interfaces have built-in memory management, so there is far less code with far less potential for buffer overrun problems. strtok can only be reliably called as a "leaf" calculation, since it (quite bizarrely) maintains hidden internal state. And gets is well known to be broken no matter what. The Bstrlib alternatives do not suffer from those sorts of problems. The substitute for strncat can be performed with higher performance by using the blk2tbstr macro to create a presized second operand for bconcat. C-library Bstring alternative CBString alternative --------- ------------------- -------------------- strspn strspn acceptable strspn acceptable strcspn strcspn acceptable strcspn acceptable strnset strnset acceptable strnset acceptable printf printf acceptable printf acceptable puts puts acceptable puts acceptable fprintf fprintf acceptable fprintf acceptable fputs fputs acceptable fputs acceptable memcmp memcmp acceptable memcmp acceptable Remember that Bstring (and CBstring) functions will automatically append the '\0' character to the character data buffer. So by simply accessing the data buffer directly, ordinary C string library functions can be called directly on them. Note that bstrcmp is not the same as memcmp in exactly the same way that strcmp is not the same as memcmp. C-library Bstring alternative CBString alternative --------- ------------------- -------------------- fread balloc + fread ::alloc + fread fgets balloc + fgets ::alloc + fgets These are odd ones because of the exact sizing of the buffer required. The Bstring and CBString alternatives requires that the buffers are forced to hold at least the prescribed length, then just use fread or fgets directly. However, typically the automatic memory management of Bstring and CBstring will make the typical use of fgets and fread to read specifically sized strings unnecessary. Implementation Choices ---------------------- Overhead: ......... The bstring library has more overhead versus straight char buffers for most functions. This overhead is essentially just the memory management and string header allocation. This overhead usually only shows up for small string manipulations. The performance loss has to be considered in light of the following: 1) What would be the performance loss of trying to write this management code in one's own application? 2) Since the bstring library source code is given, a sufficiently powerful modern inlining globally optimizing compiler can remove function call overhead. Since the data type is exposed, a developer can replace any unsatisfactory function with their own inline implementation. And that is besides the main point of what the better string library is mainly meant to provide. Any overhead lost has to be compared against the value of the safe abstraction for coupling memory management and string functionality. Performance of the C interface: ............................... The algorithms used have performance advantages versus the analogous C library functions. For example: 1. bfromcstr/blk2str/bstrcpy versus strcpy/strdup. By using memmove instead of strcpy, the break condition of the copy loop is based on an independent counter (that should be allocated in a register) rather than having to check the results of the load. Modern out-of-order executing CPUs can parallelize the final branch mis-predict penality with the loading of the source string. Some CPUs will also tend to have better built-in hardware support for counted memory moves than load-compare-store. (This is a minor, but non-zero gain.) 2. biseq versus strcmp. If the strings are unequal in length, bsiseq will return in O(1) time. If the strings are aliased, or have aliased data buffers, biseq will return in O(1) time. strcmp will always be O(k), where k is the length of the common prefix or the whole string if they are identical. 3. ->slen versus strlen. ->slen is obviously always O(1), while strlen is always O(n) where n is the length of the string. 4. bconcat versus strcat. Both rely on precomputing the length of the destination string argument, which will favor the bstring library. On iterated concatenations the performance difference can be enormous. 5. bsreadln versus fgets. The bsreadln function reads large blocks at a time from the given stream, then parses out lines from the buffers directly. Some C libraries will implement fgets as a loop over single fgetc calls. Testing indicates that the bsreadln approach can be several times faster for fast stream devices (such as a file that has been entirely cached.) 6. bsplits/bsplitscb versus strspn. Accelerators for the set of match characters are generated only once. Practical testing indicates that in general Bstrlib is never signifcantly slower than the C library for common operations, while very often having a performance advantage that ranges from significant to massive. Even for functions like b(n)inchr versus str(c)spn() (where, in theory, there is no advantage for the Bstrlib architecture) the performance of Bstrlib is vastly superior to most tested C library implementations. Some of Bstrlib's extra functionality also lead to inevitable performance advantages over typical C solutions. For example, using the blk2tbstr macro, one can (in O(1) time) generate an internal substring by reference while not disturbing the original string. If disturbing the original string is not an option, typically, a comparable C solution would have to make a copy of the substring to provide similar functionality. Another example is reverse character set scanning -- the str(c)spn functions only scan in a forward direction which can complicate some parsing algorithms. Where high performance char * based algorithms are available, Bstrlib can still leverage them by accessing the ->data field on bstrings. So realistically Bstrlib can never be significantly slower than any standard '\0' terminated char * based solutions. Performance of the C++ interface: ................................. The C++ interface has been designed with an emphasis on abstraction and safety first. However, since it is substantially a wrapper for the C bstring functions, for longer strings the performance comments described in the "Performance of the C interface" section above still apply. Note that the (CBString *) type can be directly cast to a (bstring) type, and passed as parameters to the C functions (though a CBString must never be passed to bdestroy.) Probably the most controversial choice is performing full bounds checking on the [] operator. This decision was made because 1) the fast alternative of not bounds checking is still available by first casting the CBString to a (const char *) buffer or to a (struct tagbstring) then derefencing .data and 2) because the lack of bounds checking is seen as one of the main weaknesses of C/C++ versus other languages. This check being done on every access leads to individual character extraction being actually slower than other languages in this one respect (other language's compilers will normally dedicate more resources on hoisting or removing bounds checking as necessary) but otherwise bring C++ up to the level of other languages in terms of functionality. It is common for other C++ libraries to leverage the abstractions provided by C++ to use reference counting and "copy on write" policies. While these techniques can speed up some scenarios, they impose a problem with respect to thread safety. bstrings and CBStrings can be properly protected with "per-object" mutexes, meaning that two bstrlib calls can be made and execute simultaneously, so long as the bstrings and CBstrings are distinct. With a reference count and alias before copy on write policy, global mutexes are required that prevent multiple calls to the strings library to execute simultaneously regardless of whether or not the strings represent the same string. One interesting trade off in CBString is that the default constructor is not trivial. I.e., it always prepares a ready to use memory buffer. The purpose is to ensure that there is a uniform internal composition for any functioning CBString that is compatible with bstrings. It also means that the other methods in the class are not forced to perform "late initialization" checks. In the end it means that construction of CBStrings are slower than other comparable C++ string classes. Initial testing, however, indicates that CBString outperforms std::string and MFC's CString, for example, in all other operations. So to work around this weakness it is recommended that CBString declarations be pushed outside of inner loops. Practical testing indicates that with the exception of the caveats given above (constructors and safe index character manipulations) the C++ API for Bstrlib generally outperforms popular standard C++ string classes. Amongst the standard libraries and compilers, the quality of concatenation operations varies wildly and very little care has gone into search functions. Bstrlib dominates those performance benchmarks. Memory management: .................. The bstring functions which write and modify bstrings will automatically reallocate the backing memory for the char buffer whenever it is required to grow. The algorithm for resizing chosen is to snap up to sizes that are a power of two which are sufficient to hold the intended new size. Memory reallocation is not performed when the required size of the buffer is decreased. This behavior can be relied on, and is necessary to make the behaviour of balloc deterministic. This trades off additional memory usage for decreasing the frequency for required reallocations: 1. For any bstring whose size never exceeds n, its buffer is not ever reallocated more than log_2(n) times for its lifetime. 2. For any bstring whose size never exceeds n, its buffer is never more than 2*(n+1) in length. (The extra characters beyond 2*n are to allow for the implicit '\0' which is always added by the bstring modifying functions.) Decreasing the buffer size when the string decreases in size would violate 1) above and in real world case lead to pathological heap thrashing. Similarly, allocating more tightly than "least power of 2 greater than necessary" would lead to a violation of 1) and have the same potential for heap thrashing. Property 2) needs emphasizing. Although the memory allocated is always a power of 2, for a bstring that grows linearly in size, its buffer memory also grows linearly, not exponentially. The reason is that the amount of extra space increases with each reallocation, which decreases the frequency of future reallocations. Obviously, given that bstring writing functions may reallocate the data buffer backing the target bstring, one should not attempt to cache the data buffer address and use it after such bstring functions have been called. This includes making reference struct tagbstrings which alias to a writable bstring. balloc or bfromcstralloc can be used to preallocate the minimum amount of space used for a given bstring. This will reduce even further the number of times the data portion is reallocated. If the length of the string is never more than one less than the memory length then there will be no further reallocations. Note that invoking the bwriteallow macro may increase the number of reallocs by one more than necessary for every call to bwriteallow interleaved with any bstring API which writes to this bstring. The library does not use any mechanism for automatic clean up for the C API. Thus explicit clean up via calls to bdestroy() are required to avoid memory leaks. Constant and static tagbstrings: ................................ A struct tagbstring can be write protected from any bstrlib function using the bwriteprotect macro. A write protected struct tagbstring can then be reset to being writable via the bwriteallow macro. There is, of course, no protection from attempts to directly access the bstring members. Modifying a bstring which is write protected by direct access has undefined behavior. static struct tagbstrings can be declared via the bsStatic macro. They are considered permanently unwritable. Such struct tagbstrings's are declared such that attempts to write to it are not well defined. Invoking either bwriteallow or bwriteprotect on static struct tagbstrings has no effect. struct tagbstring's initialized via btfromcstr or blk2tbstr are protected by default but can be made writeable via the bwriteallow macro. If bwriteallow is called on such struct tagbstring's, it is the programmer's responsibility to ensure that: 1) the buffer supplied was allocated from the heap. 2) bdestroy is not called on this tagbstring (unless the header itself has also been allocated from the heap.) 3) free is called on the buffer to reclaim its memory. bwriteallow and bwriteprotect can be invoked on ordinary bstrings (they have to be dereferenced with the (*) operator to get the levels of indirection correct) to give them write protection. Buffer declaration: ................... The memory buffer is actually declared "unsigned char *" instead of "char *". The reason for this is to trigger compiler warnings whenever uncasted char buffers are assigned to the data portion of a bstring. This will draw more diligent programmers into taking a second look at the code where they have carelessly left off the typically required cast. (Research from AT&T/Lucent indicates that additional programmer eyeballs is one of the most effective mechanisms at ferreting out bugs.) Function pointers: .................. The bgets, bread and bStream functions use function pointers to obtain strings from data streams. The function pointer declarations have been specifically chosen to be compatible with the fgetc and fread functions. While this may seem to be a convoluted way of implementing fgets and fread style functionality, it has been specifically designed this way to ensure that there is no dependency on a single narrowly defined set of device interfaces, such as just stream I/O. In the embedded world, its quite possible to have environments where such interfaces may not exist in the standard C library form. Furthermore, the generalization that this opens up allows for more sophisticated uses for these functions (performing an fgets like function on a socket, for example.) By using function pointers, it also allows such abstract stream interfaces to be created using the bstring library itself while not creating a circular dependency. Use of int's for sizes: ....................... This is just a recognition that 16bit platforms with requirements for strings that are larger than 64K and 32bit+ platforms with requirements for strings that are larger than 4GB are pretty marginal. The main focus is for 32bit platforms, and emerging 64bit platforms with reasonable < 4GB string requirements. Using ints allows for negative values which has meaning internally to bstrlib. Semantic consideration: ....................... Certain care needs to be taken when copying and aliasing bstrings. A bstring is essentially a pointer type which points to a multipart abstract data structure. Thus usage, and lifetime of bstrings have semantics that follow these considerations. For example: bstring a, b; struct tagbstring t; a = bfromcstr("Hello"); /* Create new bstring and copy "Hello" into it. */ b = a; /* Alias b to the contents of a. */ t = *a; /* Create a current instance pseudo-alias of a. */ bconcat (a, b); /* Double a and b, t is now undefined. */ bdestroy (a); /* Destroy the contents of both a and b. */ Variables of type bstring are really just references that point to real bstring objects. The equal operator (=) creates aliases, and the asterisk dereference operator (*) creates a kind of alias to the current instance (which is generally not useful for any purpose.) Using bstrcpy() is the correct way of creating duplicate instances. The ampersand operator (&) is useful for creating aliases to struct tagbstrings (remembering that constructed struct tagbstrings are not writable by default.) CBStrings use complete copy semantics for the equal operator (=), and thus do not have these sorts of issues. Debugging: .......... Bstrings have a simple, exposed definition and construction, and the library itself is open source. So most debugging is going to be fairly straight- forward. But the memory for bstrings come from the heap, which can often be corrupted indirectly, and it might not be obvious what has happened even from direct examination of the contents in a debugger or a core dump. There are some tools such as Purify, Insure++ and Electric Fence which can help solve such problems, however another common approach is to directly instrument the calls to malloc, realloc, calloc, free, memcpy, memmove and/or other calls by overriding them with macro definitions. Although the user could hack on the Bstrlib sources directly as necessary to perform such an instrumentation, Bstrlib comes with a built-in mechanism for doing this. By defining the macro BSTRLIB_MEMORY_DEBUG and providing an include file named memdbg.h this will force the core Bstrlib modules to attempt to include this file. In such a file, macros could be defined which overrides Bstrlib's useage of the C standard library. Rather than calling malloc, realloc, free, memcpy or memmove directly, Bstrlib emits the macros bstr__alloc, bstr__realloc, bstr__free, bstr__memcpy and bstr__memmove in their place respectively. By default these macros are simply assigned to be equivalent to their corresponding C standard library function call. However, if they are given earlier macro definitions (via the back door include file) they will not be given their default definition. In this way Bstrlib's interface to the standard library can be changed but without having to directly redefine or link standard library symbols (both of which are not strictly ANSI C compliant.) An example definition might include: #define bstr__alloc(sz) X_malloc ((sz), __LINE__, __FILE__) which might help contextualize heap entries in a debugging environment. The NULL parameter and sanity checking of bstrings is part of the Bstrlib API, and thus Bstrlib itself does not present any different modes which would correspond to "Debug" or "Release" modes. Bstrlib always contains mechanisms which one might think of as debugging features, but retains the performance and small memory footprint one would normally associate with release mode code. Integration Microsoft's Visual Studio debugger: ............................................... Microsoft's Visual Studio debugger has a capability of customizable mouse float over data type descriptions. This is accomplished by editting the AUTOEXP.DAT file to include the following: ; new for CBString tagbstring =slen= mlen= Bstrlib::CBStringList =count= In Visual C++ 6.0 this file is located in the directory: C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin and in Visual Studio .NET 2003 its located here: C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger This will improve the ability of debugging with Bstrlib under Visual Studio. Security -------- Bstrlib does not come with explicit security features outside of its fairly comprehensive error detection, coupled with its strict semantic support. That is to say that certain common security problems, such as buffer overrun, constant overwrite, arbitrary truncation etc, are far less likely to happen inadvertently. Where it does help, Bstrlib maximizes its advantage by providing developers a simple adoption path that lets them leave less secure string mechanisms behind. The library will not leave developers wanting, so they will be less likely to add new code using a less secure string library to add functionality that might be missing from Bstrlib. That said there are a number of security ideas not addressed by Bstrlib: 1. Race condition exploitation (i.e., verifying a string's contents, then raising the privilege level and execute it as a shell command as two non-atomic steps) is well beyond the scope of what Bstrlib can provide. It should be noted that MFC's built-in string mutex actually does not solve this problem either -- it just removes immediate data corruption as a possible outcome of such exploit attempts (it can be argued that this is worse, since it will leave no trace of the exploitation). In general race conditions have to be dealt with by careful design and implementation; it cannot be assisted by a string library. 2. Any kind of access control or security attributes to prevent usage in dangerous interfaces such as system(). Perl includes a "trust" attribute which can be endowed upon strings that are intended to be passed to such dangerous interfaces. However, Perl's solution reflects its own limitations -- notably that it is not a strongly typed language. In the example code for Bstrlib, there is a module called taint.cpp. It demonstrates how to write a simple wrapper class for managing "untainted" or trusted strings using the type system to prevent questionable mixing of ordinary untrusted strings with untainted ones then passing them to dangerous interfaces. In this way the security correctness of the code reduces to auditing the direct usages of dangerous interfaces or promotions of tainted strings to untainted ones. 3. Encryption of string contents is way beyond the scope of Bstrlib. Maintaining encrypted string contents in the futile hopes of thwarting things like using system-level debuggers to examine sensitive string data is likely to be a wasted effort (imagine a debugger that runs at a higher level than a virtual processor where the application runs). For more standard encryption usages, since the bstring contents are simply binary blocks of data, this should pose no problem for usage with other standard encryption libraries. Compatibility ------------- The Better String Library is known to compile and function correctly with the following compilers: - Microsoft Visual C++ - Watcom C/C++ - Intel's C/C++ compiler (Windows) - The GNU C/C++ compiler (cygwin and Linux on PPC64) - Borland C - Turbo C Setting of configuration options should be unnecessary for these compilers (unless exceptions are being disabled or STLport has been added to WATCOM C/C++). Bstrlib has been developed with an emphasis on portability. As such porting it to other compilers should be straight forward. This package includes a porting guide (called porting.txt) which explains what issues may exist for porting Bstrlib to different compilers and environments. ANSI issues ----------- 1. The function pointer types bNgetc and bNread have prototypes which are very similar to, but not exactly the same as fgetc and fread respectively. Basically the FILE * parameter is replaced by void *. The purpose of this was to allow one to create other functions with fgetc and fread like semantics without being tied to ANSI C's file streaming mechanism. I.e., one could very easily adapt it to sockets, or simply reading a block of memory, or procedurally generated strings (for fractal generation, for example.) The problem is that invoking the functions (bNgetc)fgetc and (bNread)fread is not technically legal in ANSI C. The reason being that the compiler is only able to coerce the function pointers themselves into the target type, however are unable to perform any cast (implicit or otherwise) on the parameters passed once invoked. I.e., if internally void * and FILE * need some kind of mechanical coercion, the compiler will not properly perform this conversion and thus lead to undefined behavior. Apparently a platform from Data General called "Eclipse" and another from Tandem called "NonStop" have a different representation for pointers to bytes and pointers to words, for example, where coercion via casting is necessary. (Actual confirmation of the existence of such machines is hard to come by, so it is prudent to be skeptical about this information.) However, this is not an issue for any known contemporary platforms. One may conclude that such platforms are effectively apocryphal even if they do exist. To correctly work around this problem to the satisfaction of the ANSI limitations, one needs to create wrapper functions for fgets and/or fread with the prototypes of bNgetc and/or bNread respectively which performs no other action other than to explicitely cast the void * parameter to a FILE *, and simply pass the remaining parameters straight to the function pointer call. The wrappers themselves are trivial: size_t freadWrap (void * buff, size_t esz, size_t eqty, void * parm) { return fread (buff, esz, eqty, (FILE *) parm); } int fgetcWrap (void * parm) { return fgetc ((FILE *) parm); } These have not been supplied in bstrlib or bstraux to prevent unnecessary linking with file I/O functions. 2. vsnprintf is not available on all compilers. Because of this, the bformat and bformata functions (and format and formata methods) are not guaranteed to work properly. For those compilers that don't have vsnprintf, the BSTRLIB_NOVSNP macro should be set before compiling bstrlib, and the format functions/method will be disabled. The more recent ANSI C standards have specified the required inclusion of a vsnprintf function. 3. The bstrlib function names are not unique in the first 6 characters. This is only an issue for older C compiler environments which do not store more than 6 characters for function names. 4. The bsafe module defines macros and function names which are part of the C library. This simply overrides the definition as expected on all platforms tested, however it is not sanctioned by the ANSI standard. This module is clearly optional and should be omitted on platforms which disallow its undefined semantics. In practice the real issue is that some compilers in some modes of operation can/will inline these standard library functions on a module by module basis as they appear in each. The linker will thus have no opportunity to override the implementation of these functions for those cases. This can lead to inconsistent behaviour of the bsafe module on different platforms and compilers. =============================================================================== Comparison with Microsoft's CString class ----------------------------------------- Although developed independently, CBStrings have very similar functionality to Microsoft's CString class. However, the bstring library has significant advantages over CString: 1. Bstrlib is a C-library as well as a C++ library (using the C++ wrapper). - Thus it is compatible with more programming environments and available to a wider population of programmers. 2. The internal structure of a bstring is considered exposed. - A single contiguous block of data can be cut into read-only pieces by simply creating headers, without allocating additional memory to create reference copies of each of these sub-strings. - In this way, using bstrings in a totally abstracted way becomes a choice rather than an imposition. Further this choice can be made differently at different layers of applications that use it. 3. Static declaration support precludes the need for constructor invocation. - Allows for static declarations of constant strings that has no additional constructor overhead. 4. Bstrlib is not attached to another library. - Bstrlib is designed to be easily plugged into any other library collection, without dependencies on other libraries or paradigms (such as "MFC".) The bstring library also comes with a few additional functions that are not available in the CString class: - bsetstr - bsplit - bread - breplace (this is different from CString::Replace()) - Writable indexed characters (for example a[i]='x') Interestingly, although Microsoft did implement mid$(), left$() and right$() functional analogues (these are functions from GWBASIC) they seem to have forgotten that mid$() could be also used to write into the middle of a string. This functionality exists in Bstrlib with the bsetstr() and breplace() functions. Among the disadvantages of Bstrlib is that there is no special support for localization or wide characters. Such things are considered beyond the scope of what bstrings are trying to deliver. CString essentially supports the older UCS-2 version of Unicode via widechar_t as an application-wide compile time switch. CString's also use built-in mechanisms for ensuring thread safety under all situations. While this makes writing thread safe code that much easier, this built-in safety feature has a price -- the inner loops of each CString method runs in its own critical section (grabbing and releasing a light weight mutex on every operation.) The usual way to decrease the impact of a critical section performance penalty is to amortize more operations per critical section. But since the implementation of CStrings is fixed as a one critical section per-operation cost, there is no way to leverage this common performance enhancing idea. The search facilities in Bstrlib are comparable to those in MFC's CString class, though it is missing locale specific collation. But because Bstrlib is interoperable with C's char buffers, it will allow programmers to write their own string searching mechanism (such as Boyer-Moore), or be able to choose from a variety of available existing string searching libraries (such as those for regular expressions) without difficulty. Microsoft used a very non-ANSI conforming trick in its implementation to allow printf() to use the "%s" specifier to output a CString correctly. This can be convenient, but it is inherently not portable. CBString requires an explicit cast, while bstring requires the data member to be dereferenced. Microsoft's own documentation recommends casting, instead of relying on this feature. Comparison with C++'s std::string --------------------------------- This is the C++ language's standard STL based string class. 1. There is no C implementation. 2. The [] operator is not bounds checked. 3. Missing a lot of useful functions like printf-like formatting. 4. Some sub-standard std::string implementations (SGI) are necessarily unsafe to use with multithreading. 5. Limited by STL's std::iostream which in turn is limited by ifstream which can only take input from files. (Compare to CBStream's API which can take abstracted input.) 6. Extremely uneven performance across implementations. Comparison with ISO C TR 24731 proposal --------------------------------------- Following the ISO C99 standard, Microsoft has proposed a group of C library extensions which are supposedly "safer and more secure". This proposal is expected to be adopted by the ISO C standard which follows C99. The proposal reveals itself to be very similar to Microsoft's "StrSafe" library. The functions are basically the same as other standard C library string functions except that destination parameters are paired with an additional length parameter of type rsize_t. rsize_t is the same as size_t, however, the range is checked to make sure its between 1 and RSIZE_MAX. Like Bstrlib, the functions perform a "parameter check". Unlike Bstrlib, when a parameter check fails, rather than simply outputing accumulatable error statuses, they call a user settable global error function handler, and upon return of control performs no (additional) detrimental action. The proposal covers basic string functions as well as a few non-reenterable functions (asctime, ctime, and strtok). 1. Still based solely on char * buffers (and therefore strlen() and strcat() is still O(n), and there are no faster streq() comparison functions.) 2. No growable string semantics. 3. Requires manual buffer length synchronization in the source code. 4. No attempt to enhance functionality of the C library. 5. Introduces a new error scenario (strings exceeding RSIZE_MAX length). The hope is that by exposing the buffer length requirements there will be fewer buffer overrun errors. However, the error modes are really just transformed, rather than removed. The real problem of buffer overflows is that they all happen as a result of erroneous programming. So forcing programmers to manually deal with buffer limits, will make them more aware of the problem but doesn't remove the possibility of erroneous programming. So a programmer that erroneously mixes up the rsize_t parameters is no better off from a programmer that introduces potential buffer overflows through other more typical lapses. So at best this may reduce the rate of erroneous programming, rather than making any attempt at removing failure modes. The error handler can discriminate between types of failures, but does not take into account any callsite context. So the problem is that the error is going to be manifest in a piece of code, but there is no pointer to that code. It would seem that passing in the call site __FILE__, __LINE__ as parameters would be very useful, but the API clearly doesn't support such a thing (it would increase code bloat even more than the extra length parameter does, and would require macro tricks to implement). The Bstrlib C API takes the position that error handling needs to be done at the callsite, and just tries to make it as painless as possible. Furthermore, error modes are removed by supporting auto-growing strings and aliasing. For capturing errors in more central code fragments, Bstrlib's C++ API uses exception handling extensively, which is superior to the leaf-only error handler approach. Comparison with Managed String Library CERT proposal ---------------------------------------------------- The main webpage for the managed string library: http://www.cert.org/secure-coding/managedstring.html Robert Seacord at CERT has proposed a C string library that he calls the "Managed String Library" for C. Like Bstrlib, it introduces a new type which is called a managed string. The structure of a managed string (string_m) is like a struct tagbstring but missing the length field. This internal structure is considered opaque. The length is, like the C standard library, always computed on the fly by searching for a terminating NUL on every operation that requires it. So it suffers from every performance problem that the C standard library suffers from. Interoperating with C string APIs (like printf, fopen, or anything else that takes a string parameter) requires copying to additionally allocating buffers that have to be manually freed -- this makes this library probably slower and more cumbersome than any other string library in existence. The library gives a fully populated error status as the return value of every string function. The hope is to be able to diagnose all problems specifically from the return code alone. Comparing this to Bstrlib, which aways returns one consistent error message, might make it seem that Bstrlib would be harder to debug; but this is not true. With Bstrlib, if an error occurs there is always enough information from just knowing there was an error and examining the parameters to deduce exactly what kind of error has happened. The managed string library thus gives up nested function calls while achieving little benefit, while Bstrlib does not. One interesting feature that "managed strings" has is the idea of data sanitization via character set whitelisting. That is to say, a globally definable filter that makes any attempt to put invalid characters into strings lead to an error and not modify the string. The author gives the following example: // create valid char set if (retValue = strcreate_m(&str1, "abc") ) { fprintf( stderr, "Error %d from strcreate_m.\n", retValue ); } if (retValue = setcharset(str1)) { fprintf( stderr, "Error %d from setcharset().\n", retValue ); } if (retValue = strcreate_m(&str1, "aabbccabc")) { fprintf( stderr, "Error %d from strcreate_m.\n", retValue ); } // create string with invalid char set if (retValue = strcreate_m(&str1, "abbccdabc")) { fprintf( stderr, "Error %d from strcreate_m.\n", retValue ); } Which we can compare with a more Bstrlib way of doing things: bstring bCreateWithFilter (const char * cstr, const_bstring filter) { bstring b = bfromcstr (cstr); if (BSTR_ERR != bninchr (b, filter) && NULL != b) { fprintf (stderr, "Filter violation.\n"); bdestroy (b); b = NULL; } return b; } struct tagbstring charFilter = bsStatic ("abc"); bstring str1 = bCreateWithFilter ("aabbccabc", &charFilter); bstring str2 = bCreateWithFilter ("aabbccdabc", &charFilter); The first thing we should notice is that with the Bstrlib approach you can have different filters for different strings if necessary. Furthermore, selecting a charset filter in the Managed String Library is uni-contextual. That is to say, there can only be one such filter active for the entire program, which means its usage is not well defined for intermediate library usage (a library that uses it will interfere with user code that uses it, and vice versa.) It is also likely to be poorly defined in multi-threading environments. There is also a question as to whether the data sanitization filter is checked on every operation, or just on creation operations. Since the charset can be set arbitrarily at run time, it might be set *after* some managed strings have been created. This would seem to imply that all functions should run this additional check every time if there is an attempt to enforce this. This would make things tremendously slow. On the other hand, if it is assumed that only creates and other operations that take char *'s as input need be checked because the charset was only supposed to be called once at and before any other managed string was created, then one can see that its easy to cover Bstrlib with equivalent functionality via a few wrapper calls such as the example given above. And finally we have to question the value of sanitation in the first place. For example, for httpd servers, there is generally a requirement that the URLs parsed have some form that avoids undesirable translation to local file system filenames or resources. The problem is that the way URLs can be encoded, it must be completely parsed and translated to know if it is using certain invalid character combinations. That is to say, merely filtering each character one at a time is not necessarily the right way to ensure that a string has safe contents. In the article that describes this proposal, it is claimed that it fairly closely approximates the existing C API semantics. On this point we should compare this "closeness" with Bstrlib: Bstrlib Managed String Library ------- ---------------------- Pointer arithmetic Segment arithmetic N/A Use in C Std lib ->data, or bdata{e} getstr_m(x,*) ... free(x) String literals bsStatic, bsStaticBlk strcreate_m() Transparency Complete None Its pretty clear that the semantic mapping from C strings to Bstrlib is fairly straightforward, and that in general semantic capabilities are the same or superior in Bstrlib. On the other hand the Managed String Library is either missing semantics or changes things fairly significantly. Comparison with Annexia's c2lib library --------------------------------------- This library is available at: http://www.annexia.org/freeware/c2lib 1. Still based solely on char * buffers (and therefore strlen() and strcat() is still O(n), and there are no faster streq() comparison functions.) Their suggestion that alternatives which wrap the string data type (such as bstring does) imposes a difficulty in interoperating with the C langauge's ordinary C string library is not founded. 2. Introduction of memory (and vector?) abstractions imposes a learning curve, and some kind of memory usage policy that is outside of the strings themselves (and therefore must be maintained by the developer.) 3. The API is massive, and filled with all sorts of trivial (pjoin) and controvertial (pmatch -- regular expression are not sufficiently standardized, and there is a very large difference in performance between compiled and non-compiled, REs) functions. Bstrlib takes a decidely minimal approach -- none of the functionality in c2lib is difficult or challenging to implement on top of Bstrlib (except the regex stuff, which is going to be difficult, and controvertial no matter what.) 4. Understanding why c2lib is the way it is pretty much requires a working knowledge of Perl. bstrlib requires only knowledge of the C string library while providing just a very select few worthwhile extras. 5. It is attached to a lot of cruft like a matrix math library (that doesn't include any functions for getting the determinant, eigenvectors, eigenvalues, the matrix inverse, test for singularity, test for orthogonality, a grahm schmit orthogonlization, LU decomposition ... I mean why bother?) Convincing a development house to use c2lib is likely quite difficult. It introduces too much, while not being part of any kind of standards body. The code must therefore be trusted, or maintained by those that use it. While bstring offers nothing more on this front, since its so much smaller, covers far less in terms of scope, and will typically improve string performance, the barrier to usage should be much smaller. Comparison with stralloc/qmail ------------------------------ More information about this library can be found here: http://www.canonical.org/~kragen/stralloc.html or here: http://cr.yp.to/lib/stralloc.html 1. Library is very very minimal. A little too minimal. 2. Untargetted source parameters are not declared const. 3. Slightly different expected emphasis (like _cats function which takes an ordinary C string char buffer as a parameter.) Its clear that the remainder of the C string library is still required to perform more useful string operations. The struct declaration for their string header is essentially the same as that for bstring. But its clear that this was a quickly written hack whose goals are clearly a subset of what Bstrlib supplies. For anyone who is served by stralloc, Bstrlib is complete substitute that just adds more functionality. stralloc actually uses the interesting policy that a NULL data pointer indicates an empty string. In this way, non-static empty strings can be declared without construction. This advantage is minimal, since static empty bstrings can be declared inline without construction, and if the string needs to be written to it should be constructed from an empty string (or its first initializer) in any event. wxString class -------------- This is the string class used in the wxWindows project. A description of wxString can be found here: http://www.wxwindows.org/manuals/2.4.2/wx368.htm#wxstring This C++ library is similar to CBString. However, it is littered with trivial functions (IsAscii, UpperCase, RemoveLast etc.) 1. There is no C implementation. 2. The memory management strategy is to allocate a bounded fixed amount of additional space on each resize, meaning that it does not have the log_2(n) property that Bstrlib has (it will thrash very easily, cause massive fragmentation in common heap implementations, and can easily be a common source of performance problems). 3. The library uses a "copy on write" strategy, meaning that it has to deal with multithreading problems. Vstr ---- This is a highly orthogonal C string library with an emphasis on networking/realtime programming. It can be found here: http://www.and.org/vstr/ 1. The convoluted internal structure does not contain a '\0' char * compatible buffer, so interoperability with the C library a non-starter. 2. The API and implementation is very large (owing to its orthogonality) and can lead to difficulty in understanding its exact functionality. 3. An obvious dependency on gnu tools (confusing make configure step) 4. Uses a reference counting system, meaning that it is not likely to be thread safe. The implementation has an extreme emphasis on performance for nontrivial actions (adds, inserts and deletes are all constant or roughly O(#operations) time) following the "zero copy" principle. This trades off performance of trivial functions (character access, char buffer access/coersion, alias detection) which becomes significantly slower, as well as incremental accumulative costs for its searching/parsing functions. Whether or not Vstr wins any particular performance benchmark will depend a lot on the benchmark, but it should handily win on some, while losing dreadfully on others. The learning curve for Vstr is very steep, and it doesn't come with any obvious way to build for Windows or other platforms without gnu tools. At least one mechanism (the iterator) introduces a new undefined scenario (writing to a Vstr while iterating through it.) Vstr has a very large footprint, and is very ambitious in its total functionality. Vstr has no C++ API. Vstr usage requires context initialization via vstr_init() which must be run in a thread-local context. Given the totally reference based architecture this means that sharing Vstrings across threads is not well defined, or at least not safe from race conditions. This API is clearly geared to the older standard of fork() style multitasking in UNIX, and is not safely transportable to modern shared memory multithreading available in Linux and Windows. There is no portable external solution making the library thread safe (since it requires a mutex around each Vstr context -- not each string.) In the documentation for this library, a big deal is made of its self hosted s(n)printf-like function. This is an issue for older compilers that don't include vsnprintf(), but also an issue because Vstr has a slow conversion to '\0' terminated char * mechanism. That is to say, using "%s" to format data that originates from Vstr would be slow without some sort of native function to do so. Bstrlib sidesteps the issue by relying on what snprintf-like functionality does exist and having a high performance conversion to a char * compatible string so that "%s" can be used directly. Str Library ----------- This is a fairly extensive string library, that includes full unicode support and targetted at the goal of out performing MFC and STL. The architecture, similarly to MFC's CStrings, is a copy on write reference counting mechanism. http://www.utilitycode.com/str/default.aspx 1. Commercial. 2. C++ only. This library, like Vstr, uses a ref counting system. There is only so deeply I can analyze it, since I don't have a license for it. However, performance improvements over MFC's and STL, doesn't seem like a sufficient reason to move your source base to it. For example, in the future, Microsoft may improve the performance CString. It should be pointed out that performance testing of Bstrlib has indicated that its relative performance advantage versus MFC's CString and STL's std::string is at least as high as that for the Str library. libmib astrings --------------- A handful of functional extensions to the C library that add dynamic string functionality. http://www.mibsoftware.com/libmib/astring/ This package basically references strings through char ** pointers and assumes they are pointing to the top of an allocated heap entry (or NULL, in which case memory will be newly allocated from the heap.) So its still up to user to mix and match the older C string functions with these functions whenever pointer arithmetic is used (i.e., there is no leveraging of the type system to assert semantic differences between references and base strings as Bstrlib does since no new types are introduced.) Unlike Bstrlib, exact string length meta data is not stored, thus requiring a strlen() call on *every* string writing operation. The library is very small, covering only a handful of C's functions. While this is better than nothing, it is clearly slower than even the standard C library, less safe and less functional than Bstrlib. To explain the advantage of using libmib, their website shows an example of how dangerous C code: char buf[256]; char *pszExtraPath = ";/usr/local/bin"; strcpy(buf,getenv("PATH")); /* oops! could overrun! */ strcat(buf,pszExtraPath); /* Could overrun as well! */ printf("Checking...%s\n",buf); /* Some printfs overrun too! */ is avoided using libmib: char *pasz = 0; /* Must initialize to 0 */ char *paszOut = 0; char *pszExtraPath = ";/usr/local/bin"; if (!astrcpy(&pasz,getenv("PATH"))) /* malloc error */ exit(-1); if (!astrcat(&pasz,pszExtraPath)) /* malloc error */ exit(-1); /* Finally, a "limitless" printf! we can use */ asprintf(&paszOut,"Checking...%s\n",pasz);fputs(paszOut,stdout); astrfree(&pasz); /* Can use free(pasz) also. */ astrfree(&paszOut); However, compare this to Bstrlib: bstring b, out; bcatcstr (b = bfromcstr (getenv ("PATH")), ";/usr/local/bin"); out = bformat ("Checking...%s\n", bdatae (b, "")); /* if (out && b) */ fputs (bdatae (out, ""), stdout); bdestroy (b); bdestroy (out); Besides being shorter, we can see that error handling can be deferred right to the very end. Also, unlike the above two versions, if getenv() returns with NULL, the Bstrlib version will not exhibit undefined behavior. Initialization starts with the relevant content rather than an extra autoinitialization step. libclc ------ An attempt to add to the standard C library with a number of common useful functions, including additional string functions. http://libclc.sourceforge.net/ 1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass the responsibility to guard against aliasing to the programmer. 2. Adds no safety or memory management whatsoever. 3. Most of the supplied string functions are completely trivial. The goals of libclc and Bstrlib are clearly quite different. fireString ---------- http://firestuff.org/ 1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass the responsibility to guard against aliasing to the programmer. 2. Mixes char * and length wrapped buffers (estr) functions, doubling the API size, with safety limited to only half of the functions. Firestring was originally just a wrapper of char * functionality with extra length parameters. However, it has been augmented with the inclusion of the estr type which has similar functionality to stralloc. But firestring does not nearly cover the functional scope of Bstrlib. Safe C String Library --------------------- A library written for the purpose of increasing safety and power to C's string handling capabilities. http://www.zork.org/safestr/safestr.html 1. While the safestr_* functions are safe in of themselves, interoperating with char * string has dangerous unsafe modes of operation. 2. The architecture of safestr's causes the base pointer to change. Thus, its not practical/safe to store a safestr in multiple locations if any single instance can be manipulated. 3. Dependent on an additional error handling library. 4. Uses reference counting, meaning that it is either not thread safe or slow and not portable. I think the idea of reallocating (and hence potentially changing) the base pointer is a serious design flaw that is fatal to this architecture. True safety is obtained by having automatic handling of all common scenarios without creating implicit constraints on the user. Because of its automatic temporary clean up system, it cannot use "const" semantics on input arguments. Interesting anomolies such as: safestr_t s, t; s = safestr_replace (t = SAFESTR_TEMP ("This is a test"), SAFESTR_TEMP (" "), SAFESTR_TEMP (".")); /* t is now undefined. */ are possible. If one defines a function which takes a safestr_t as a parameter, then the function would not know whether or not the safestr_t is defined after it passes it to a safestr library function. The author recommended method for working around this problem is to examine the attributes of the safestr_t within the function which is to modify any of its parameters and play games with its reference count. I think, therefore, that the whole SAFESTR_TEMP idea is also fatally broken. The library implements immutability, optional non-resizability, and a "trust" flag. This trust flag is interesting, and suggests that applying any arbitrary sequence of safestr_* function calls on any set of trusted strings will result in a trusted string. It seems to me, however, that if one wanted to implement a trusted string semantic, one might do so by actually creating a different *type* and only implement the subset of string functions that are deemed safe (i.e., user input would be excluded, for example.) This, in essence, would allow the compiler to enforce trust propogation at compile time rather than run time. Non-resizability is also interesting, however, it seems marginal (i.e., to want a string that cannot be resized, yet can be modified and yet where a fixed sized buffer is undesirable.) =============================================================================== Examples -------- Dumping a line numbered file: FILE * fp; int i, ret; struct bstrList * lines; struct tagbstring prefix = bsStatic ("-> "); if (NULL != (fp = fopen ("bstrlib.txt", "rb"))) { bstring b = bread ((bNread) fread, fp); fclose (fp); if (NULL != (lines = bsplit (b, '\n'))) { for (i=0; i < lines->qty; i++) { binsert (lines->entry[i], 0, &prefix, '?'); printf ("%04d: %s\n", i, bdatae (lines->entry[i], "NULL")); } bstrListDestroy (lines); } bdestroy (b); } For numerous other examples, see bstraux.c, bstraux.h and the example archive. =============================================================================== License ------- The Better String Library is available under either the BSD license (see the accompanying license.txt) or the Gnu Public License version 2 (see the accompanying gpl.txt) at the option of the user. =============================================================================== Acknowledgements ---------------- The following individuals have made significant contributions to the design and testing of the Better String Library: Bjorn Augestad Clint Olsen Darryl Bleau Fabian Cenedese Graham Wideman Ignacio Burgueno International Business Machines Corporation Ira Mica John Kortink Manuel Woelker Marcel van Kervinck Michael Hsieh Richard A. Smith Simon Ekstrom Wayne Scott =============================================================================== allegro-5.0.10/src/misc/vector.c0000644000175000001440000002120311721435174015601 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Vectors, aka growing arrays. * * By Peter Wang. * * See readme.txt for copyright information. * * * This is a simple growing array to hold objects of various sizes, * growing by powers of two as needed. At the moment the vector never * shrinks, except when it is freed. Usually the vector would hold * pointers to objects, not the objects themselves, as the vector is * allowed to move the objects around. * * This module is NOT thread-safe. */ /* Internal Title: Vectors */ #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_vector.h" /* return the given item's starting address in the vector */ #define ITEM_START(vec, idx) (vec->_items + ((idx) * vec->_itemsize)) /* Internal function: _al_vector_init * * Initialise a vector. ITEMSIZE is the number of bytes to allocate for * each item in the vector. * * Alternatively, you can statically initialise a vector using * _AL_VECTOR vec = _AL_VECTOR_INITIALIZER(itemtype); */ void _al_vector_init(_AL_VECTOR *vec, size_t itemsize) { ASSERT(vec); ASSERT(itemsize > 0); vec->_itemsize = itemsize; vec->_items = NULL; vec->_size = 0; vec->_unused = 0; } /* * Simple inline functions: * * size_t _al_vector_size(const _AL_VECTOR *vec); * bool _al_vector_is_empty(const _AL_VECTOR*); */ /* Internal function: _al_vector_ref * * Return a pointer to the SLOT in the vector given by INDEX. The returned * address should only be used while the vector is not modified; after that * it is invalid. * * Tip: If you are storing pointers in the vector, you need to dereference * the returned value! */ void *_al_vector_ref(const _AL_VECTOR *vec, unsigned int idx) { ASSERT(vec); ASSERT(idx < vec->_size); return ITEM_START(vec, idx); } /* Internal function: _al_vector_ref_front * Convenience function. */ void* _al_vector_ref_front(const _AL_VECTOR *vec) { return _al_vector_ref(vec, 0); } /* Internal function: _al_vector_ref_back * Convenience function. */ void* _al_vector_ref_back(const _AL_VECTOR *vec) { ASSERT(vec); return _al_vector_ref(vec, vec->_size-1); } /* Internal function: _al_vector_append_array * Append `num` elements from `arr` array to _AL_VECTOR `vec` */ bool _al_vector_append_array(_AL_VECTOR *vec, unsigned int num, const void *arr) { ASSERT(vec); ASSERT(arr); ASSERT(num); if (vec->_items == NULL) { ASSERT(vec->_size == 0); ASSERT(vec->_unused == 0); vec->_items = al_malloc(vec->_itemsize * num); ASSERT(vec->_items); if (!vec->_items) return false; vec->_unused = num; } else if (vec->_unused < num) { char *new_items; new_items = al_realloc(vec->_items, (vec->_size + num) * vec->_itemsize); ASSERT(new_items); if (!new_items) return false; vec->_items = new_items; vec->_unused = num; } memcpy(vec->_items + (vec->_size * vec->_itemsize), arr, vec->_itemsize * num); vec->_size += num; vec->_unused -= num; return true; } /* Internal function: _al_vector_alloc_back * * Allocate a block of memory at the back of the vector of the vector's item * size (see _AL_VECTOR_INITIALIZER and _al_vector_init). Returns a pointer * to the start of this block. This address should only be used while the * vector is not modified; after that it is invalid. You may fill the block * with whatever you want. * * Example: * _AL_VECTOR vec = _AL_VECTOR_INITIALIZER(struct boo); * struct boo *thing = _al_vector_alloc_back(&vec); * thing->aaa = 100; * thing->bbb = "a string"; */ void* _al_vector_alloc_back(_AL_VECTOR *vec) { ASSERT(vec); ASSERT(vec->_itemsize > 0); { if (vec->_items == NULL) { ASSERT(vec->_size == 0); ASSERT(vec->_unused == 0); vec->_items = al_malloc(vec->_itemsize); ASSERT(vec->_items); if (!vec->_items) return NULL; vec->_unused = 1; } else if (vec->_unused == 0) { char *new_items = al_realloc(vec->_items, 2 * vec->_size * vec->_itemsize); ASSERT(new_items); if (!new_items) return NULL; vec->_items = new_items; vec->_unused = vec->_size; } vec->_size++; vec->_unused--; return ITEM_START(vec, vec->_size-1); } } /* Internal function: _al_vector_alloc_mid * * Allocate a block of memory in the middle of the vector of the vector's * item * size (see _AL_VECTOR_INITIALIZER and _al_vector_init). Returns a pointer * to the start of this block. This address should only be used while the * vector is not modified; after that it is invalid. You may fill the block * with whatever you want. */ void* _al_vector_alloc_mid(_AL_VECTOR *vec, unsigned int index) { ASSERT(vec); ASSERT(vec->_itemsize > 0); { if (vec->_items == NULL) { ASSERT(index == 0); return _al_vector_alloc_back(vec); } if (vec->_unused == 0) { char *new_items = al_realloc(vec->_items, 2 * vec->_size * vec->_itemsize); ASSERT(new_items); if (!new_items) return NULL; vec->_items = new_items; vec->_unused = vec->_size; } memmove(ITEM_START(vec, index + 1), ITEM_START(vec, index), vec->_itemsize * (vec->_size - index)); vec->_size++; vec->_unused--; return ITEM_START(vec, index); } } /* Internal function: _al_vector_find * * Find the slot in the vector where the contents of the slot * match whatever PTR_ITEM points to, bit-for-bit. If no such * slot is found, a negative number is returned (currently -1). */ int _al_vector_find(const _AL_VECTOR *vec, const void *ptr_item) { ASSERT(vec); ASSERT(ptr_item); if (vec->_itemsize == sizeof(void *)) { /* fast path for pointers */ void **items = (void **)vec->_items; unsigned int i; for (i = 0; i < vec->_size; i++) if (items[i] == *(void **)ptr_item) return i; } else { /* slow path */ unsigned int i; for (i = 0; i < vec->_size; i++) if (memcmp(ITEM_START(vec, i), ptr_item, vec->_itemsize) == 0) return i; } return -1; } /* Internal function: _al_vector_contains * A simple wrapper over _al_vector_find. */ bool _al_vector_contains(const _AL_VECTOR *vec, const void *ptr_item) { return _al_vector_find(vec, ptr_item) >= 0; } /* Internal function: _al_vector_delete_at * * Delete the slot given by index. Deleting from the start or middle of the * vector requires moving the rest of the vector towards the front, so it is * better to delete from the tail of the vector. * * Example: * while (!_al_vector_is_empty(&v)) * _al_vector_delete_at(&v, _al_vector_size(&v)-1); */ void _al_vector_delete_at(_AL_VECTOR *vec, unsigned int idx) { ASSERT(vec); ASSERT(idx < vec->_size); { int to_move = vec->_size - idx - 1; if (to_move > 0) memmove(ITEM_START(vec, idx), ITEM_START(vec, idx+1), to_move * vec->_itemsize); vec->_size--; vec->_unused++; memset(ITEM_START(vec, vec->_size), 0, vec->_itemsize); } } /* Internal function: _al_vector_find_and_delete * * Similar to _al_vector_delete_at(_al_vector_find(vec, ptr_item)) but is * lenient if the item is not found. Returns true if the item was found and * deleted. */ bool _al_vector_find_and_delete(_AL_VECTOR *vec, const void *ptr_item) { int idx = _al_vector_find(vec, ptr_item); if (idx >= 0) { _al_vector_delete_at(vec, idx); return true; } else return false; } /* Internal function: _al_vector_free * * Free the space used by the vector. You really must do this at some * stage. It is not enough to delete all the items in the vector (which you * should usually do also). */ void _al_vector_free(_AL_VECTOR *vec) { ASSERT(vec); if (vec->_items != NULL) { al_free(vec->_items); vec->_items = NULL; } vec->_size = 0; vec->_unused = 0; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/src/misc/list.c0000644000175000001440000003577011522502044015256 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Double linked list. * * By Michał Cichoń. * * See readme.txt for copyright information. * * * This is a simple general purpose double linked list. * * This module is NOT thread-safe. */ #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_list.h" ALLEGRO_DEBUG_CHANNEL("list") /* Definition of list, holds root and size. */ struct _AL_LIST { /* Root of the list. It is an element, but * not visible one. Using it end and the * beginning can be easily identified. */ _AL_LIST_ITEM* root; size_t size; size_t capacity; size_t item_size; size_t item_size_with_extra; _AL_LIST_ITEM* next_free; void* user_data; _AL_LIST_DTOR dtor; }; /* List item, holds user data and destructor. */ struct _AL_LIST_ITEM { _AL_LIST* list; _AL_LIST_ITEM* next; _AL_LIST_ITEM* prev; void* data; _AL_LIST_ITEM_DTOR dtor; }; /* List of the internal functions. */ static _AL_LIST* list_do_create(size_t capacity, size_t item_extra_size); static bool list_is_static(_AL_LIST* list); static _AL_LIST_ITEM* list_get_free_item(_AL_LIST* list); static _AL_LIST_ITEM* list_create_item(_AL_LIST* list); static void list_destroy_item(_AL_LIST* list, _AL_LIST_ITEM* item); /* * Create an instance of double linked list. * * Parameters: * capacity [in] * Maximum number of elements list can hold. If it is zero, list is * created as fully dynamic linked list with unlimited item count. * For any other positive number static linked list is created, * memory for all elements is allocated once and then used. * * extra_item_size [in] * Number of extra bytes which should be left after each list item. * It is currently not used, so default value is zero. * * Returns: * Pointer to new instance of double linked list. * * Remarks: * There are two kind of double linked list supported: dynamic and static. * For dynamic linked list each item is allocated while adding and freed * while removing. This kind of list does not have capacity limit but * suffer from memory allocation delay. * Static linked list use one memory allocation and are hold as solid * piece of memory. This kind of list have capacity, but adding and * removing elements is very cheap operation. */ static _AL_LIST* list_do_create(size_t capacity, size_t extra_item_size) { size_t i; size_t memory_size; uint8_t* memory_ptr; _AL_LIST* list = NULL; _AL_LIST_ITEM* item = NULL; _AL_LIST_ITEM* prev = NULL; /* Calculate amount of memory needed for the list. * Always at least one element is allocated together with list, * which is intended to be a root. */ memory_size = sizeof(_AL_LIST) + (capacity + 1) * (sizeof(_AL_LIST_ITEM) + extra_item_size); memory_ptr = (uint8_t*)al_malloc(memory_size); if (NULL == memory_ptr) { ALLEGRO_ERROR("Out of memory."); return NULL; } list = (_AL_LIST*)memory_ptr; memory_ptr += sizeof(_AL_LIST); list->size = 0; list->capacity = capacity; list->item_size = sizeof(_AL_LIST_ITEM); list->item_size_with_extra = sizeof(_AL_LIST_ITEM) + extra_item_size; list->next_free = (_AL_LIST_ITEM*)memory_ptr; list->user_data = NULL; list->dtor = NULL; /* Initialize free item list. */ prev = NULL; item = list->next_free; for (i = 0; i <= list->capacity; ++i) { memory_ptr += list->item_size_with_extra; item->list = list; item->next = (_AL_LIST_ITEM*)memory_ptr; prev = item; item = item->next; } /* Set proper free list tail value. */ prev->next = NULL; /* Initialize root. */ list->root = list_get_free_item(list); list->root->dtor = NULL; list->root->next = list->root; list->root->prev = list->root; return list; } /* * Returns true if 'list' point to static double linked list. */ static bool list_is_static(_AL_LIST* list) { return 0 != list->capacity; } /* * Returns free item from internal list. Call to this function * is valid only for static lists. */ static _AL_LIST_ITEM* list_get_free_item(_AL_LIST* list) { _AL_LIST_ITEM* item; //thedmd: disabled, root is always static-like element and this method // is called even for dynamic lists //ASSERT(list_is_static(list)); item = list->next_free; if (NULL != item) list->next_free = item->next; return item; } /* * Create an instance of new double linked list item. */ static _AL_LIST_ITEM* list_create_item(_AL_LIST* list) { _AL_LIST_ITEM* item = NULL; if (list_is_static(list)) { /* Items from internal list already are partially initialized. * So we do not have to setup list pointer. */ item = list_get_free_item(list); } else { item = (_AL_LIST_ITEM*)al_malloc(list->item_size_with_extra); item->list = list; } return item; } /* * Destroys double linked list item. Item destructor is called * when necessary. */ static void list_destroy_item(_AL_LIST* list, _AL_LIST_ITEM* item) { ASSERT(list == item->list); if (NULL != item->dtor) item->dtor(item->data, list->user_data); if (list_is_static(list)) { item->next = list->next_free; list->next_free = item; } else al_free(item); } /* * Create new instance of dynamic double linked list. * * See: * list_do_create */ _AL_LIST* _al_list_create(void) { return list_do_create(0, 0); } /* * Create new instance of list item. Maximum number of list items is * limited by capacity. * * See: * list_do_create */ _AL_LIST* _al_list_create_static(size_t capacity) { if (capacity < 1) { ALLEGRO_ERROR("Cannot create static list without any capacity."); return NULL; } return list_do_create(capacity, 0); } /* * Destroys instance of the list. All elements * that list contain are also destroyed. */ void _al_list_destroy(_AL_LIST* list) { if (NULL == list) return; if (list->dtor) list->dtor(list->user_data); _al_list_clear(list); al_free(list); } /* * Sets a destructor for the list. */ void _al_list_set_dtor(_AL_LIST* list, _AL_LIST_DTOR dtor) { list->dtor = dtor; } /* * Returns destructor of the list. */ _AL_LIST_DTOR _al_list_get_dtor(_AL_LIST* list) { return list->dtor; } /* * Create and push new item at the beginning of the list. * * Returns pointer to new item. */ _AL_LIST_ITEM* _al_list_push_front(_AL_LIST* list, void* data) { return _al_list_insert_after(list, list->root, data); } /* * Pretty the same as _al_list_push_front(), but also allow * to provide custom destructor for the item. */ _AL_LIST_ITEM* _al_list_push_front_ex(_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor) { return _al_list_insert_after_ex(list, list->root, data, dtor); } /* * Create and push new item at the end of the list. * * Returns pointer to new item. */ _AL_LIST_ITEM* _al_list_push_back(_AL_LIST* list, void* data) { return _al_list_insert_before(list, list->root, data); } /* * Pretty the same as _al_list_push_back(), but also allow * to provide custom destructor for the item. */ _AL_LIST_ITEM* _al_list_push_back_ex(_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor) { return _al_list_insert_before_ex(list, list->root, data, dtor); } /* * Remove first item in the list. */ void _al_list_pop_front(_AL_LIST* list) { if (list->size > 0) _al_list_erase(list, list->root->next); } /* * Remove last item in the list. */ void _al_list_pop_back(_AL_LIST* list) { if (list->size > 0) _al_list_erase(list, list->root->prev); } /* * Create and insert new item after one specified by 'where'. * * Returns pointer to new item. */ _AL_LIST_ITEM* _al_list_insert_after(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) { return _al_list_insert_after_ex(list, where, data, NULL); } /* * Pretty the same as _al_list_insert_after(), but also allow * to provide custom destructor for the item. */ _AL_LIST_ITEM* _al_list_insert_after_ex(_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor) { _AL_LIST_ITEM* item; ASSERT(list == where->list); item = list_create_item(list); if (NULL == item) return NULL; item->data = data; item->dtor = dtor; item->prev = where; item->next = where->next; where->next->prev = item; where->next = item; list->size++; return item; } /* * Create and insert new item before one specified by 'where'. * * Returns pointer to new item. */ _AL_LIST_ITEM* _al_list_insert_before(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) { return _al_list_insert_before_ex(list, where, data, NULL); } /* * Pretty the same as _al_list_insert_before(), but also allow * to provide custom destructor for the item. */ _AL_LIST_ITEM* _al_list_insert_before_ex(_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor) { _AL_LIST_ITEM* item; ASSERT(list == where->list); item = list_create_item(list); if (NULL == item) return NULL; item->data = data; item->dtor = dtor; item->next = where; item->prev = where->prev; where->prev->next = item; where->prev = item; list->size++; return item; } /* * Remove specified item from the list. */ void _al_list_erase(_AL_LIST* list, _AL_LIST_ITEM* item) { if (NULL == item) return; ASSERT(list == item->list); item->prev->next = item->next; item->next->prev = item->prev; list->size--; list_destroy_item(list, item); } /* * Remove all items from the list. */ void _al_list_clear(_AL_LIST* list) { _AL_LIST_ITEM* item; _AL_LIST_ITEM* next; item = _al_list_front(list); while (NULL != item) { next = _al_list_next(list, item); _al_list_erase(list, item); item = next; } } /* * Remove all occurrences of specified value in the list. */ void _al_list_remove(_AL_LIST* list, void* data) { _AL_LIST_ITEM* item = NULL; _AL_LIST_ITEM* next = NULL; item = _al_list_find_first(list, data); while (NULL != item) { next = _al_list_find_after(list, item, data); _al_list_erase(list, item); item = next; } } /* * Returns true if list is empty. */ bool _al_list_is_empty(_AL_LIST* list) { return 0 == list->size; } /* * Returns true if list contain specified value. */ bool _al_list_contains(_AL_LIST* list, void* data) { return NULL != _al_list_find_first(list, data); } /* * Returns first occurrence of specified value in the list. */ _AL_LIST_ITEM* _al_list_find_first(_AL_LIST* list, void* data) { return _al_list_find_after(list, list->root, data); } /* * Returns last occurrence of specified value in the list. */ _AL_LIST_ITEM* _al_list_find_last(_AL_LIST* list, void* data) { return _al_list_find_before(list, list->root, data); } /* * Return occurrence of specified value in the list after 'where' item. */ _AL_LIST_ITEM* _al_list_find_after(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) { _AL_LIST_ITEM* item; ASSERT(list == where->list); for (item = where->next; item != list->root; item = item->next) if (item->data == data) return item; return NULL; } /* * Return occurrence of specified value in the list before 'where' item. */ _AL_LIST_ITEM* _al_list_find_before(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) { _AL_LIST_ITEM* item; ASSERT(list == where->list); for (item = where->prev; item != list->root; item = item->prev) if (item->data == data) return item; return NULL; } /* * Returns current size of the list. */ size_t _al_list_size(_AL_LIST* list) { return list->size; } /* * Returns item located at specified index. */ _AL_LIST_ITEM* _al_list_at(_AL_LIST* list, size_t index) { if (index >= list->size) return NULL; if (index < list->size / 2) { _AL_LIST_ITEM* item = list->root->next; while (index--) item = item->next; return item; } else { _AL_LIST_ITEM* item = list->root->prev; index = list->size - index; while (index--) item = item->prev; return item; } } /* * Returns first item in the list. */ _AL_LIST_ITEM* _al_list_front(_AL_LIST* list) { if (list->size > 0) return list->root->next; else return NULL; } /* * Returns last item in the list. */ _AL_LIST_ITEM* _al_list_back(_AL_LIST* list) { if (list->size > 0) return list->root->prev; else return NULL; } /* * Returns next element in the list. */ _AL_LIST_ITEM* _al_list_next(_AL_LIST* list, _AL_LIST_ITEM* item) { ASSERT(list == item->list); (void)list; if (item->next != item->list->root) return item->next; else return NULL; } /* * Returns previous element in the list. */ _AL_LIST_ITEM* _al_list_previous(_AL_LIST* list, _AL_LIST_ITEM* item) { ASSERT(list == item->list); (void)list; if (item->prev != item->list->root) return item->prev; else return NULL; } /* * Returns next element in the list. If end of the list is reached, * first element is returned instead of NULL. */ _AL_LIST_ITEM* _al_list_next_circular(_AL_LIST* list, _AL_LIST_ITEM* item) { ASSERT(list == item->list); if (item->next != item->list->root) return item->next; else return list->root->next; } /* * Returns previous element in the list. If beginning of the list is reached, * last element is returned instead of NULL. */ _AL_LIST_ITEM* _al_list_previous_circular(_AL_LIST* list, _AL_LIST_ITEM* item) { ASSERT(list == item->list); if (item->prev != item->list->root) return item->prev; else return list->root->prev; } /* * Returns value associated with specified item. */ void* _al_list_item_data(_AL_LIST_ITEM* item) { return item->data; } /* * Sets item destructor. */ void _al_list_item_set_dtor(_AL_LIST_ITEM* item, _AL_LIST_ITEM_DTOR dtor) { item->dtor = dtor; } /* * Returns item destructor. */ _AL_LIST_ITEM_DTOR _al_list_item_get_dtor(_AL_LIST_ITEM* item) { return item->dtor; } /* * Sets user data for list. This pointer is passed to list destructor. */ void _al_list_set_user_data(_AL_LIST* list, void* user_data) { list->user_data = user_data; } /* * Returns user data for list. */ void* _al_list_get_user_data(_AL_LIST* list) { return list->user_data; } allegro-5.0.10/src/misc/bstrlib.c0000644000175000001440000026547511375630156015767 0ustar tjadenusers/* * This source file has had its exported symbols prefixed with _al_ or _AL_ * for the Allegro project. */ /* * This source file is part of the _al_bstring string library. This code was * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source * license and the GPL. Refer to the accompanying documentation for details * on usage and license. */ /* * bstrlib.c * * This file is the core module for implementing the _al_bstring functions. */ #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/internal/bstrlib.h" #define bstr__alloc(x) al_malloc(x) #define bstr__free(p) al_free(p) #define bstr__realloc(p, x) al_realloc((p), (x)) /* Optionally include a mechanism for debugging memory */ #if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG) #include "memdbg.h" #endif #ifndef bstr__alloc #define bstr__alloc(x) malloc (x) #endif #ifndef bstr__free #define bstr__free(p) free (p) #endif #ifndef bstr__realloc #define bstr__realloc(p,x) realloc ((p), (x)) #endif #ifndef bstr__memcpy #define bstr__memcpy(d,s,l) memcpy ((d), (s), (l)) #endif #ifndef bstr__memmove #define bstr__memmove(d,s,l) memmove ((d), (s), (l)) #endif #ifndef bstr__memset #define bstr__memset(d,c,l) memset ((d), (c), (l)) #endif #ifndef bstr__memcmp #define bstr__memcmp(d,c,l) memcmp ((d), (c), (l)) #endif #ifndef bstr__memchr #define bstr__memchr(s,c,l) memchr ((s), (c), (l)) #endif /* Just a length safe wrapper for memmove. */ #define bBlockCopy(D,S,L) { if ((L) > 0) bstr__memmove ((D),(S),(L)); } /* Compute the snapped size for a given requested size. By snapping to powers of 2 like this, repeated reallocations are avoided. */ static int snapUpSize (int i) { if (i < 8) { i = 8; } else { unsigned int j; j = (unsigned int) i; j |= (j >> 1); j |= (j >> 2); j |= (j >> 4); j |= (j >> 8); /* Ok, since int >= 16 bits */ #if (UINT_MAX != 0xffff) j |= (j >> 16); /* For 32 bit int systems */ #if (UINT_MAX > 0xffffffffUL) j |= (j >> 32); /* For 64 bit int systems */ #endif #endif /* Least power of two greater than i */ j++; if ((int) j >= i) i = (int) j; } return i; } /* int _al_balloc (_al_bstring b, int len) * * Increase the size of the memory backing the _al_bstring b to at least len. */ int _al_balloc (_al_bstring b, int olen) { int len; if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen || olen <= 0) { return _AL_BSTR_ERR; } if (olen >= b->mlen) { unsigned char * x; if ((len = snapUpSize (olen)) <= b->mlen) return _AL_BSTR_OK; /* Assume probability of a non-moving realloc is 0.125 */ if (7 * b->mlen < 8 * b->slen) { /* If slen is close to mlen in size then use realloc to reduce the memory defragmentation */ reallocStrategy:; x = (unsigned char *) bstr__realloc (b->data, (size_t) len); if (x == NULL) { /* Since we failed, try allocating the tighest possible allocation */ if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) { return _AL_BSTR_ERR; } } } else { /* If slen is not close to mlen then avoid the penalty of copying the extra bytes that are allocated, but not considered part of the string */ if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) { /* Perhaps there is no available memory for the two allocations to be in memory at once */ goto reallocStrategy; } else { if (b->slen) bstr__memcpy ((char *) x, (char *) b->data, (size_t) b->slen); bstr__free (b->data); } } b->data = x; b->mlen = len; b->data[b->slen] = (unsigned char) '\0'; } return _AL_BSTR_OK; } /* int _al_ballocmin (_al_bstring b, int len) * * Set the size of the memory backing the _al_bstring b to len or b->slen+1, * whichever is larger. Note that repeated use of this function can degrade * performance. */ int _al_ballocmin (_al_bstring b, int len) { unsigned char * s; if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || b->mlen < b->slen || len <= 0) { return _AL_BSTR_ERR; } if (len < b->slen + 1) len = b->slen + 1; if (len != b->mlen) { s = (unsigned char *) bstr__realloc (b->data, (size_t) len); if (NULL == s) return _AL_BSTR_ERR; s[b->slen] = (unsigned char) '\0'; b->data = s; b->mlen = len; } return _AL_BSTR_OK; } /* _al_bstring _al_bfromcstr (const char * str) * * Create a _al_bstring which contains the contents of the '\0' terminated char * * buffer str. */ _al_bstring _al_bfromcstr (const char * str) { _al_bstring b; int i; size_t j; if (str == NULL) return NULL; j = (strlen) (str); i = snapUpSize ((int) (j + (2 - (j != 0)))); if (i <= (int) j) return NULL; b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); if (NULL == b) return NULL; b->slen = (int) j; if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { bstr__free (b); return NULL; } bstr__memcpy (b->data, str, j+1); return b; } /* _al_bstring _al_bfromcstralloc (int mlen, const char * str) * * Create a _al_bstring which contains the contents of the '\0' terminated char * * buffer str. The memory buffer backing the string is at least len * characters in length. */ _al_bstring _al_bfromcstralloc (int mlen, const char * str) { _al_bstring b; int i; size_t j; if (str == NULL) return NULL; j = (strlen) (str); i = snapUpSize ((int) (j + (2 - (j != 0)))); if (i <= (int) j) return NULL; b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); if (b == NULL) return NULL; b->slen = (int) j; if (i < mlen) i = mlen; if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { bstr__free (b); return NULL; } bstr__memcpy (b->data, str, j+1); return b; } /* _al_bstring _al_blk2bstr (const void * blk, int len) * * Create a _al_bstring which contains the content of the block blk of length * len. */ _al_bstring _al_blk2bstr (const void * blk, int len) { _al_bstring b; int i; if (blk == NULL || len < 0) return NULL; b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); if (b == NULL) return NULL; b->slen = len; i = len + (2 - (len != 0)); i = snapUpSize (i); b->mlen = i; b->data = (unsigned char *) bstr__alloc ((size_t) b->mlen); if (b->data == NULL) { bstr__free (b); return NULL; } if (len > 0) bstr__memcpy (b->data, blk, (size_t) len); b->data[len] = (unsigned char) '\0'; return b; } /* char * _al_bstr2cstr (_al_const_bstring s, char z) * * Create a '\0' terminated char * buffer which is equal to the contents of * the _al_bstring s, except that any contained '\0' characters are converted * to the character in z. This returned value should be freed with a * _al_bcstrfree () call, by the calling application. */ char * _al_bstr2cstr (_al_const_bstring b, char z) { int i, l; char * r; if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; l = b->slen; r = (char *) bstr__alloc ((size_t) (l + 1)); if (r == NULL) return r; for (i=0; i < l; i ++) { r[i] = (char) ((b->data[i] == '\0') ? z : (char) (b->data[i])); } r[l] = (unsigned char) '\0'; return r; } /* int _al_bcstrfree (char * s) * * Frees a C-string generated by _al_bstr2cstr (). This is normally unnecessary * since it just wraps a call to bstr__free (), however, if bstr__alloc () * and bstr__free () have been redefined as a macros within the bstrlib * module (via defining them in memdbg.h after defining * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std * library functions, then this allows a correct way of freeing the memory * that allows higher level code to be independent from these macro * redefinitions. */ int _al_bcstrfree (char * s) { if (s) { bstr__free (s); return _AL_BSTR_OK; } return _AL_BSTR_ERR; } /* int _al_bconcat (_al_bstring b0, _al_const_bstring b1) * * Concatenate the _al_bstring b1 to the _al_bstring b0. */ int _al_bconcat (_al_bstring b0, _al_const_bstring b1) { int len, d; _al_bstring aux = (_al_bstring) b1; if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL) return _AL_BSTR_ERR; d = b0->slen; len = b1->slen; if ((d | (b0->mlen - d) | len | (d + len)) < 0) return _AL_BSTR_ERR; if (b0->mlen <= d + len + 1) { ptrdiff_t pd = b1->data - b0->data; if (0 <= pd && pd < b0->mlen) { if (NULL == (aux = _al_bstrcpy (b1))) return _AL_BSTR_ERR; } if (_al_balloc (b0, d + len + 1) != _AL_BSTR_OK) { if (aux != b1) _al_bdestroy (aux); return _AL_BSTR_ERR; } } bBlockCopy (&b0->data[d], &aux->data[0], (size_t) len); b0->data[d + len] = (unsigned char) '\0'; b0->slen = d + len; if (aux != b1) _al_bdestroy (aux); return _AL_BSTR_OK; } /* int _al_bconchar (_al_bstring b, char c) / * * Concatenate the single character c to the _al_bstring b. */ int _al_bconchar (_al_bstring b, char c) { int d; if (b == NULL) return _AL_BSTR_ERR; d = b->slen; if ((d | (b->mlen - d)) < 0 || _al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; b->data[d] = (unsigned char) c; b->data[d + 1] = (unsigned char) '\0'; b->slen++; return _AL_BSTR_OK; } /* int _al_bcatcstr (_al_bstring b, const char * s) * * Concatenate a char * string to a _al_bstring. */ int _al_bcatcstr (_al_bstring b, const char * s) { char * d; int i, l; if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || s == NULL) return _AL_BSTR_ERR; /* Optimistically concatenate directly */ l = b->mlen - b->slen; d = (char *) &b->data[b->slen]; for (i=0; i < l; i++) { if ((*d++ = *s++) == '\0') { b->slen += i; return _AL_BSTR_OK; } } b->slen += i; /* Need to explicitely resize and concatenate tail */ return _al_bcatblk (b, (const void *) s, (int) strlen (s)); } /* int _al_bcatblk (_al_bstring b, const void * s, int len) * * Concatenate a fixed length buffer to a _al_bstring. */ int _al_bcatblk (_al_bstring b, const void * s, int len) { int nl; if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || s == NULL || len < 0) return _AL_BSTR_ERR; if (0 > (nl = b->slen + len)) return _AL_BSTR_ERR; /* Overflow? */ if (b->mlen <= nl && 0 > _al_balloc (b, nl + 1)) return _AL_BSTR_ERR; bBlockCopy (&b->data[b->slen], s, (size_t) len); b->slen = nl; b->data[nl] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* _al_bstring _al_bstrcpy (_al_const_bstring b) * * Create a copy of the _al_bstring b. */ _al_bstring _al_bstrcpy (_al_const_bstring b) { _al_bstring b0; int i,j; /* Attempted to copy an invalid string? */ if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; b0 = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); if (b0 == NULL) { /* Unable to allocate memory for string header */ return NULL; } i = b->slen; j = snapUpSize (i + 1); b0->data = (unsigned char *) bstr__alloc (j); if (b0->data == NULL) { j = i + 1; b0->data = (unsigned char *) bstr__alloc (j); if (b0->data == NULL) { /* Unable to allocate memory for string data */ bstr__free (b0); return NULL; } } b0->mlen = j; b0->slen = i; if (i) bstr__memcpy ((char *) b0->data, (char *) b->data, i); b0->data[b0->slen] = (unsigned char) '\0'; return b0; } /* int _al_bassign (_al_bstring a, _al_const_bstring b) * * Overwrite the string a with the contents of string b. */ int _al_bassign (_al_bstring a, _al_const_bstring b) { if (b == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; if (b->slen != 0) { if (_al_balloc (a, b->slen) != _AL_BSTR_OK) return _AL_BSTR_ERR; bstr__memmove (a->data, b->data, b->slen); } else { if (a == NULL || a->data == NULL || a->mlen < a->slen || a->slen < 0 || a->mlen == 0) return _AL_BSTR_ERR; } a->data[b->slen] = (unsigned char) '\0'; a->slen = b->slen; return _AL_BSTR_OK; } /* int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len) * * Overwrite the string a with the middle of contents of string b * starting from position left and running for a length len. left and * len are clamped to the ends of b as with the function _al_bmidstr. */ int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len) { if (b == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; if (left < 0) { len += left; left = 0; } if (len > b->slen - left) len = b->slen - left; if (a == NULL || a->data == NULL || a->mlen < a->slen || a->slen < 0 || a->mlen == 0) return _AL_BSTR_ERR; if (len > 0) { if (_al_balloc (a, len) != _AL_BSTR_OK) return _AL_BSTR_ERR; bstr__memmove (a->data, b->data + left, len); a->slen = len; } else { a->slen = 0; } a->data[a->slen] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* int _al_bassigncstr (_al_bstring a, const char * str) * * Overwrite the string a with the contents of char * string str. Note that * the _al_bstring a must be a well defined and writable _al_bstring. If an error * occurs _AL_BSTR_ERR is returned however a may be partially overwritten. */ int _al_bassigncstr (_al_bstring a, const char * str) { int i; size_t len; if (a == NULL || a->data == NULL || a->mlen < a->slen || a->slen < 0 || a->mlen == 0 || NULL == str) return _AL_BSTR_ERR; for (i=0; i < a->mlen; i++) { if ('\0' == (a->data[i] = str[i])) { a->slen = i; return _AL_BSTR_OK; } } a->slen = i; len = strlen (str + i); if (len > INT_MAX || i + len + 1 > INT_MAX || 0 > _al_balloc (a, (int) (i + len + 1))) return _AL_BSTR_ERR; bBlockCopy (a->data + i, str + i, (size_t) len + 1); a->slen += (int) len; return _AL_BSTR_OK; } /* int _al_bassignblk (_al_bstring a, const void * s, int len) * * Overwrite the string a with the contents of the block (s, len). Note that * the _al_bstring a must be a well defined and writable _al_bstring. If an error * occurs _AL_BSTR_ERR is returned and a is not overwritten. */ int _al_bassignblk (_al_bstring a, const void * s, int len) { if (a == NULL || a->data == NULL || a->mlen < a->slen || a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) return _AL_BSTR_ERR; if (len + 1 > a->mlen && 0 > _al_balloc (a, len + 1)) return _AL_BSTR_ERR; bBlockCopy (a->data, s, (size_t) len); a->data[len] = (unsigned char) '\0'; a->slen = len; return _AL_BSTR_OK; } /* int _al_btrunc (_al_bstring b, int n) * * Truncate the _al_bstring to at most n characters. */ int _al_btrunc (_al_bstring b, int n) { if (n < 0 || b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; if (b->slen > n) { b->slen = n; b->data[n] = (unsigned char) '\0'; } return _AL_BSTR_OK; } #define upcase(c) (toupper ((unsigned char) c)) #define downcase(c) (tolower ((unsigned char) c)) #define wspace(c) (isspace ((unsigned char) c)) /* int _al_btoupper (_al_bstring b) * * Convert contents of _al_bstring to upper case. */ int _al_btoupper (_al_bstring b) { int i, len; if (b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; for (i=0, len = b->slen; i < len; i++) { b->data[i] = (unsigned char) upcase (b->data[i]); } return _AL_BSTR_OK; } /* int _al_btolower (_al_bstring b) * * Convert contents of _al_bstring to lower case. */ int _al_btolower (_al_bstring b) { int i, len; if (b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; for (i=0, len = b->slen; i < len; i++) { b->data[i] = (unsigned char) downcase (b->data[i]); } return _AL_BSTR_OK; } /* int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1) * * Compare two strings without differentiating between case. The return * value is the difference of the values of the characters where the two * strings first differ after lower case transformation, otherwise 0 is * returned indicating that the strings are equal. If the lengths are * different, then a difference from 0 is given, but if the first extra * character is '\0', then it is taken to be the value UCHAR_MAX+1. */ int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1) { int i, v, n; if (_al_bdata (b0) == NULL || b0->slen < 0 || _al_bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN; if ((n = b0->slen) > b1->slen) n = b1->slen; else if (b0->slen == b1->slen && b0->data == b1->data) return _AL_BSTR_OK; for (i = 0; i < n; i ++) { v = (char) downcase (b0->data[i]) - (char) downcase (b1->data[i]); if (0 != v) return v; } if (b0->slen > n) { v = (char) downcase (b0->data[n]); if (v) return v; return UCHAR_MAX + 1; } if (b1->slen > n) { v = - (char) downcase (b1->data[n]); if (v) return v; return - (int) (UCHAR_MAX + 1); } return _AL_BSTR_OK; } /* int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n) * * Compare two strings without differentiating between case for at most n * characters. If the position where the two strings first differ is * before the nth position, the return value is the difference of the values * of the characters, otherwise 0 is returned. If the lengths are different * and less than n characters, then a difference from 0 is given, but if the * first extra character is '\0', then it is taken to be the value * UCHAR_MAX+1. */ int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n) { int i, v, m; if (_al_bdata (b0) == NULL || b0->slen < 0 || _al_bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN; m = n; if (m > b0->slen) m = b0->slen; if (m > b1->slen) m = b1->slen; if (b0->data != b1->data) { for (i = 0; i < m; i ++) { v = (char) downcase (b0->data[i]); v -= (char) downcase (b1->data[i]); if (v != 0) return b0->data[i] - b1->data[i]; } } if (n == m || b0->slen == b1->slen) return _AL_BSTR_OK; if (b0->slen > m) { v = (char) downcase (b0->data[m]); if (v) return v; return UCHAR_MAX + 1; } v = - (char) downcase (b1->data[m]); if (v) return v; return - (int) (UCHAR_MAX + 1); } /* int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1) * * Compare two strings for equality without differentiating between case. * If the strings differ other than in case, 0 is returned, if the strings * are the same, 1 is returned, if there is an error, -1 is returned. If * the length of the strings are different, this function is O(1). '\0' * termination characters are not treated in any special way. */ int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1) { int i, n; if (_al_bdata (b0) == NULL || b0->slen < 0 || _al_bdata (b1) == NULL || b1->slen < 0) return _AL_BSTR_ERR; if (b0->slen != b1->slen) return _AL_BSTR_OK; if (b0->data == b1->data || b0->slen == 0) return 1; for (i=0, n=b0->slen; i < n; i++) { if (b0->data[i] != b1->data[i]) { unsigned char c = (unsigned char) downcase (b0->data[i]); if (c != (unsigned char) downcase (b1->data[i])) return 0; } } return 1; } /* int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len) * * Compare beginning of string b0 with a block of memory of length len * without differentiating between case for equality. If the beginning of b0 * differs from the memory block other than in case (or if b0 is too short), * 0 is returned, if the strings are the same, 1 is returned, if there is an * error, -1 is returned. '\0' characters are not treated in any special * way. */ int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len) { int i; if (_al_bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) return _AL_BSTR_ERR; if (b0->slen < len) return _AL_BSTR_OK; if (b0->data == (const unsigned char *) blk || len == 0) return 1; for (i = 0; i < len; i ++) { if (b0->data[i] != ((const unsigned char *) blk)[i]) { if (downcase (b0->data[i]) != downcase (((const unsigned char *) blk)[i])) return 0; } } return 1; } /* * int _al_bltrimws (_al_bstring b) * * Delete whitespace contiguous from the left end of the string. */ int _al_bltrimws (_al_bstring b) { int i, len; if (b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; for (len = b->slen, i = 0; i < len; i++) { if (!wspace (b->data[i])) { return _al_bdelete (b, 0, i); } } b->data[0] = (unsigned char) '\0'; b->slen = 0; return _AL_BSTR_OK; } /* * int _al_brtrimws (_al_bstring b) * * Delete whitespace contiguous from the right end of the string. */ int _al_brtrimws (_al_bstring b) { int i; if (b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; for (i = b->slen - 1; i >= 0; i--) { if (!wspace (b->data[i])) { if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; b->slen = i + 1; return _AL_BSTR_OK; } } b->data[0] = (unsigned char) '\0'; b->slen = 0; return _AL_BSTR_OK; } /* * int _al_btrimws (_al_bstring b) * * Delete whitespace contiguous from both ends of the string. */ int _al_btrimws (_al_bstring b) { int i, j; if (b == NULL || b->data == NULL || b->mlen < b->slen || b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; for (i = b->slen - 1; i >= 0; i--) { if (!wspace (b->data[i])) { if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; b->slen = i + 1; for (j = 0; wspace (b->data[j]); j++) {} return _al_bdelete (b, 0, j); } } b->data[0] = (unsigned char) '\0'; b->slen = 0; return _AL_BSTR_OK; } /* int _al_biseq (_al_const_bstring b0, _al_const_bstring b1) * * Compare the string b0 and b1. If the strings differ, 0 is returned, if * the strings are the same, 1 is returned, if there is an error, -1 is * returned. If the length of the strings are different, this function is * O(1). '\0' termination characters are not treated in any special way. */ int _al_biseq (_al_const_bstring b0, _al_const_bstring b1) { if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || b0->slen < 0 || b1->slen < 0) return _AL_BSTR_ERR; if (b0->slen != b1->slen) return _AL_BSTR_OK; if (b0->data == b1->data || b0->slen == 0) return 1; return !bstr__memcmp (b0->data, b1->data, b0->slen); } /* int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len) * * Compare beginning of string b0 with a block of memory of length len for * equality. If the beginning of b0 differs from the memory block (or if b0 * is too short), 0 is returned, if the strings are the same, 1 is returned, * if there is an error, -1 is returned. '\0' characters are not treated in * any special way. */ int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len) { int i; if (_al_bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) return _AL_BSTR_ERR; if (b0->slen < len) return _AL_BSTR_OK; if (b0->data == (const unsigned char *) blk || len == 0) return 1; for (i = 0; i < len; i ++) { if (b0->data[i] != ((const unsigned char *) blk)[i]) return _AL_BSTR_OK; } return 1; } /* int _al_biseqcstr (_al_const_bstring b, const char *s) * * Compare the _al_bstring b and char * string s. The C string s must be '\0' * terminated at exactly the length of the _al_bstring b, and the contents * between the two must be identical with the _al_bstring b with no '\0' * characters for the two contents to be considered equal. This is * equivalent to the condition that their current contents will be always be * equal when comparing them in the same format after converting one or the * other. If the strings are equal 1 is returned, if they are unequal 0 is * returned and if there is a detectable error _AL_BSTR_ERR is returned. */ int _al_biseqcstr (_al_const_bstring b, const char * s) { int i; if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; for (i=0; i < b->slen; i++) { if (s[i] == '\0' || b->data[i] != (unsigned char) s[i]) return _AL_BSTR_OK; } return s[i] == '\0'; } /* int _al_biseqcstrcaseless (_al_const_bstring b, const char *s) * * Compare the _al_bstring b and char * string s. The C string s must be '\0' * terminated at exactly the length of the _al_bstring b, and the contents * between the two must be identical except for case with the _al_bstring b with * no '\0' characters for the two contents to be considered equal. This is * equivalent to the condition that their current contents will be always be * equal ignoring case when comparing them in the same format after * converting one or the other. If the strings are equal, except for case, * 1 is returned, if they are unequal regardless of case 0 is returned and * if there is a detectable error _AL_BSTR_ERR is returned. */ int _al_biseqcstrcaseless (_al_const_bstring b, const char * s) { int i; if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; for (i=0; i < b->slen; i++) { if (s[i] == '\0' || (b->data[i] != (unsigned char) s[i] && downcase (b->data[i]) != (unsigned char) downcase (s[i]))) return _AL_BSTR_OK; } return s[i] == '\0'; } /* int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1) * * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned, * otherwise a value less than or greater than zero, indicating that the * string pointed to by b0 is lexicographically less than or greater than * the string pointed to by b1 is returned. If the the string lengths are * unequal but the characters up until the length of the shorter are equal * then a value less than, or greater than zero, indicating that the string * pointed to by b0 is shorter or longer than the string pointed to by b1 is * returned. 0 is returned if and only if the two strings are the same. If * the length of the strings are different, this function is O(n). Like its * standard C library counter part strcmp, the comparison does not proceed * past any '\0' termination characters encountered. */ int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1) { int i, v, n; if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || b0->slen < 0 || b1->slen < 0) return SHRT_MIN; n = b0->slen; if (n > b1->slen) n = b1->slen; if (b0->slen == b1->slen && (b0->data == b1->data || b0->slen == 0)) return _AL_BSTR_OK; for (i = 0; i < n; i ++) { v = ((char) b0->data[i]) - ((char) b1->data[i]); if (v != 0) return v; if (b0->data[i] == (unsigned char) '\0') return _AL_BSTR_OK; } if (b0->slen > n) return 1; if (b1->slen > n) return -1; return _AL_BSTR_OK; } /* int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n) * * Compare the string b0 and b1 for at most n characters. If there is an * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and * b1 were first truncated to at most n characters then _al_bstrcmp was called * with these new strings are paremeters. If the length of the strings are * different, this function is O(n). Like its standard C library counter * part strcmp, the comparison does not proceed past any '\0' termination * characters encountered. */ int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n) { int i, v, m; if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || b0->slen < 0 || b1->slen < 0) return SHRT_MIN; m = n; if (m > b0->slen) m = b0->slen; if (m > b1->slen) m = b1->slen; if (b0->data != b1->data) { for (i = 0; i < m; i ++) { v = ((char) b0->data[i]) - ((char) b1->data[i]); if (v != 0) return v; if (b0->data[i] == (unsigned char) '\0') return _AL_BSTR_OK; } } if (n == m || b0->slen == b1->slen) return _AL_BSTR_OK; if (b0->slen > m) return 1; return -1; } /* _al_bstring _al_bmidstr (_al_const_bstring b, int left, int len) * * Create a _al_bstring which is the substring of b starting from position left * and running for a length len (clamped by the end of the _al_bstring b.) If * b is detectably invalid, then NULL is returned. The section described * by (left, len) is clamped to the boundaries of b. */ _al_bstring _al_bmidstr (_al_const_bstring b, int left, int len) { if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; if (left < 0) { len += left; left = 0; } if (len > b->slen - left) len = b->slen - left; if (len <= 0) return _al_bfromcstr (""); return _al_blk2bstr (b->data + left, len); } /* int _al_bdelete (_al_bstring b, int pos, int len) * * Removes characters from pos to pos+len-1 inclusive and shifts the tail of * the _al_bstring starting from pos+len to pos. len must be positive for this * call to have any effect. The section of the string described by (pos, * len) is clamped to boundaries of the _al_bstring b. */ int _al_bdelete (_al_bstring b, int pos, int len) { /* Clamp to left side of _al_bstring */ if (pos < 0) { len += pos; pos = 0; } if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0) return _AL_BSTR_ERR; if (len > 0 && pos < b->slen) { if (pos + len >= b->slen) { b->slen = pos; } else { bBlockCopy ((char *) (b->data + pos), (char *) (b->data + pos + len), b->slen - (pos+len)); b->slen -= len; } b->data[b->slen] = (unsigned char) '\0'; } return _AL_BSTR_OK; } /* int _al_bdestroy (_al_bstring b) * * Free up the _al_bstring. Note that if b is detectably invalid or not writable * then no action is performed and _AL_BSTR_ERR is returned. Like a freed memory * allocation, dereferences, writes or any other action on b after it has * been bdestroyed is undefined. */ int _al_bdestroy (_al_bstring b) { if (b == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen || b->data == NULL) return _AL_BSTR_ERR; bstr__free (b->data); /* In case there is any stale usage, there is one more chance to notice this error. */ b->slen = -1; b->mlen = -__LINE__; b->data = NULL; bstr__free (b); return _AL_BSTR_OK; } /* int _al_binstr (_al_const_bstring b1, int pos, _al_const_bstring b2) * * Search for the _al_bstring b2 in b1 starting from position pos, and searching * forward. If it is found then return with the first position where it is * found, otherwise return _AL_BSTR_ERR. Note that this is just a brute force * string searcher that does not attempt clever things like the Boyer-Moore * search algorithm. Because of this there are many degenerate cases where * this can take much longer than it needs to. */ int _al_binstr (_al_const_bstring b1, int pos, _al_const_bstring b2) { int j, ii, ll, lf; unsigned char * d0; unsigned char c0; register unsigned char * d1; register unsigned char c1; register int i; if (b1 == NULL || b1->data == NULL || b1->slen < 0 || b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; if (b1->slen == pos) return (b2->slen == 0)?pos:_AL_BSTR_ERR; if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; if (b2->slen == 0) return pos; /* No space to find such a string? */ if ((lf = b1->slen - b2->slen + 1) <= pos) return _AL_BSTR_ERR; /* An obvious alias case */ if (b1->data == b2->data && pos == 0) return 0; i = pos; d0 = b2->data; d1 = b1->data; ll = b2->slen; /* Peel off the b2->slen == 1 case */ c0 = d0[0]; if (1 == ll) { for (;i < lf; i++) if (c0 == d1[i]) return i; return _AL_BSTR_ERR; } c1 = c0; j = 0; lf = b1->slen - 1; ii = -1; if (i < lf) do { /* Unrolled current character test */ if (c1 != d1[i]) { if (c1 != d1[1+i]) { i += 2; continue; } i++; } /* Take note if this is the start of a potential match */ if (0 == j) ii = i; /* Shift the test character down by one */ j++; i++; /* If this isn't past the last character continue */ if (j < ll) { c1 = d0[j]; continue; } N0:; /* If no characters mismatched, then we matched */ if (i == ii+j) return ii; /* Shift back to the beginning */ i -= j; j = 0; c1 = c0; } while (i < lf); /* Deal with last case if unrolling caused a misalignment */ if (i == lf && ll == j+1 && c1 == d1[i]) goto N0; return _AL_BSTR_ERR; } /* int _al_binstrr (_al_const_bstring b1, int pos, _al_const_bstring b2) * * Search for the _al_bstring b2 in b1 starting from position pos, and searching * backward. If it is found then return with the first position where it is * found, otherwise return _AL_BSTR_ERR. Note that this is just a brute force * string searcher that does not attempt clever things like the Boyer-Moore * search algorithm. Because of this there are many degenerate cases where * this can take much longer than it needs to. */ int _al_binstrr (_al_const_bstring b1, int pos, _al_const_bstring b2) { int j, i, l; unsigned char * d0, * d1; if (b1 == NULL || b1->data == NULL || b1->slen < 0 || b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; if (b1->slen == pos && b2->slen == 0) return pos; if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; if (b2->slen == 0) return pos; /* Obvious alias case */ if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return 0; i = pos; if ((l = b1->slen - b2->slen) < 0) return _AL_BSTR_ERR; /* If no space to find such a string then snap back */ if (l + 1 <= i) i = l; j = 0; d0 = b2->data; d1 = b1->data; l = b2->slen; for (;;) { if (d0[j] == d1[i + j]) { j ++; if (j >= l) return i; } else { i --; if (i < 0) break; j=0; } } return _AL_BSTR_ERR; } /* int _al_binstrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) * * Search for the _al_bstring b2 in b1 starting from position pos, and searching * forward but without regard to case. If it is found then return with the * first position where it is found, otherwise return _AL_BSTR_ERR. Note that * this is just a brute force string searcher that does not attempt clever * things like the Boyer-Moore search algorithm. Because of this there are * many degenerate cases where this can take much longer than it needs to. */ int _al_binstrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) { int j, i, l, ll; unsigned char * d0, * d1; if (b1 == NULL || b1->data == NULL || b1->slen < 0 || b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; if (b1->slen == pos) return (b2->slen == 0)?pos:_AL_BSTR_ERR; if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; if (b2->slen == 0) return pos; l = b1->slen - b2->slen + 1; /* No space to find such a string? */ if (l <= pos) return _AL_BSTR_ERR; /* An obvious alias case */ if (b1->data == b2->data && pos == 0) return _AL_BSTR_OK; i = pos; j = 0; d0 = b2->data; d1 = b1->data; ll = b2->slen; for (;;) { if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { j ++; if (j >= ll) return i; } else { i ++; if (i >= l) break; j=0; } } return _AL_BSTR_ERR; } /* int _al_binstrrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) * * Search for the _al_bstring b2 in b1 starting from position pos, and searching * backward but without regard to case. If it is found then return with the * first position where it is found, otherwise return _AL_BSTR_ERR. Note that * this is just a brute force string searcher that does not attempt clever * things like the Boyer-Moore search algorithm. Because of this there are * many degenerate cases where this can take much longer than it needs to. */ int _al_binstrrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) { int j, i, l; unsigned char * d0, * d1; if (b1 == NULL || b1->data == NULL || b1->slen < 0 || b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; if (b1->slen == pos && b2->slen == 0) return pos; if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; if (b2->slen == 0) return pos; /* Obvious alias case */ if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return _AL_BSTR_OK; i = pos; if ((l = b1->slen - b2->slen) < 0) return _AL_BSTR_ERR; /* If no space to find such a string then snap back */ if (l + 1 <= i) i = l; j = 0; d0 = b2->data; d1 = b1->data; l = b2->slen; for (;;) { if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { j ++; if (j >= l) return i; } else { i --; if (i < 0) break; j=0; } } return _AL_BSTR_ERR; } /* int _al_bstrchrp (_al_const_bstring b, int c, int pos) * * Search for the character c in b forwards from the position pos * (inclusive). */ int _al_bstrchrp (_al_const_bstring b, int c, int pos) { unsigned char * p; if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return _AL_BSTR_ERR; p = (unsigned char *) bstr__memchr ((b->data + pos), (unsigned char) c, (b->slen - pos)); if (p) return (int) (p - b->data); return _AL_BSTR_ERR; } /* int _al_bstrrchrp (_al_const_bstring b, int c, int pos) * * Search for the character c in b backwards from the position pos in string * (inclusive). */ int _al_bstrrchrp (_al_const_bstring b, int c, int pos) { int i; if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return _AL_BSTR_ERR; for (i=pos; i >= 0; i--) { if (b->data[i] == (unsigned char) c) return i; } return _AL_BSTR_ERR; } #if !defined (BSTRLIB_AGGRESSIVE_MEMORY_FOR_SPEED_TRADEOFF) #define LONG_LOG_BITS_QTY (3) #define LONG_BITS_QTY (1 << LONG_LOG_BITS_QTY) #define LONG_TYPE unsigned char #define CFCLEN ((1 << CHAR_BIT) / LONG_BITS_QTY) struct charField { LONG_TYPE content[CFCLEN]; }; #define testInCharField(cf,c) ((cf)->content[(c) >> LONG_LOG_BITS_QTY] & (((long)1) << ((c) & (LONG_BITS_QTY-1)))) #define setInCharField(cf,idx) { \ unsigned int c = (unsigned int) (idx); \ (cf)->content[c >> LONG_LOG_BITS_QTY] |= (LONG_TYPE) (1ul << (c & (LONG_BITS_QTY-1))); \ } #else #define CFCLEN (1 << CHAR_BIT) struct charField { unsigned char content[CFCLEN]; }; #define testInCharField(cf,c) ((cf)->content[(unsigned char) (c)]) #define setInCharField(cf,idx) (cf)->content[(unsigned int) (idx)] = ~0 #endif /* Convert a _al_bstring to charField */ static int buildCharField (struct charField * cf, _al_const_bstring b) { int i; if (b == NULL || b->data == NULL || b->slen <= 0) return _AL_BSTR_ERR; memset ((void *) cf->content, 0, sizeof (struct charField)); for (i=0; i < b->slen; i++) { setInCharField (cf, b->data[i]); } return _AL_BSTR_OK; } static void invertCharField (struct charField * cf) { int i; for (i=0; i < CFCLEN; i++) cf->content[i] = ~cf->content[i]; } /* Inner engine for _al_binchr */ static int binchrCF (const unsigned char * data, int len, int pos, const struct charField * cf) { int i; for (i=pos; i < len; i++) { unsigned char c = (unsigned char) data[i]; if (testInCharField (cf, c)) return i; } return _AL_BSTR_ERR; } /* int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1); * * Search for the first position in b0 starting from pos or after, in which * one of the characters in b1 is found and return it. If such a position * does not exist in b0, then _AL_BSTR_ERR is returned. */ int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1) { struct charField chrs; if (pos < 0 || b0 == NULL || b0->data == NULL || b0->slen <= pos) return _AL_BSTR_ERR; if (1 == b1->slen) return _al_bstrchrp (b0, b1->data[0], pos); if (0 > buildCharField (&chrs, b1)) return _AL_BSTR_ERR; return binchrCF (b0->data, b0->slen, pos, &chrs); } /* Inner engine for _al_binchrr */ static int binchrrCF (const unsigned char * data, int pos, const struct charField * cf) { int i; for (i=pos; i >= 0; i--) { unsigned int c = (unsigned int) data[i]; if (testInCharField (cf, c)) return i; } return _AL_BSTR_ERR; } /* int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); * * Search for the last position in b0 no greater than pos, in which one of * the characters in b1 is found and return it. If such a position does not * exist in b0, then _AL_BSTR_ERR is returned. */ int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1) { struct charField chrs; if (pos < 0 || b0 == NULL || b0->data == NULL || b1 == NULL || b0->slen < pos) return _AL_BSTR_ERR; if (pos == b0->slen) pos--; if (1 == b1->slen) return _al_bstrrchrp (b0, b1->data[0], pos); if (0 > buildCharField (&chrs, b1)) return _AL_BSTR_ERR; return binchrrCF (b0->data, pos, &chrs); } /* int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1); * * Search for the first position in b0 starting from pos or after, in which * none of the characters in b1 is found and return it. If such a position * does not exist in b0, then _AL_BSTR_ERR is returned. */ int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1) { struct charField chrs; if (pos < 0 || b0 == NULL || b0->data == NULL || b0->slen <= pos) return _AL_BSTR_ERR; if (buildCharField (&chrs, b1) < 0) return _AL_BSTR_ERR; invertCharField (&chrs); return binchrCF (b0->data, b0->slen, pos, &chrs); } /* int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); * * Search for the last position in b0 no greater than pos, in which none of * the characters in b1 is found and return it. If such a position does not * exist in b0, then _AL_BSTR_ERR is returned. */ int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1) { struct charField chrs; if (pos < 0 || b0 == NULL || b0->data == NULL || b0->slen < pos) return _AL_BSTR_ERR; if (pos == b0->slen) pos--; if (buildCharField (&chrs, b1) < 0) return _AL_BSTR_ERR; invertCharField (&chrs); return binchrrCF (b0->data, pos, &chrs); } /* int _al_bsetstr (_al_bstring b0, int pos, _al_bstring b1, unsigned char fill) * * Overwrite the string b0 starting at position pos with the string b1. If * the position pos is past the end of b0, then the character "fill" is * appended as necessary to make up the gap between the end of b0 and pos. * If b1 is NULL, it behaves as if it were a 0-length string. */ int _al_bsetstr (_al_bstring b0, int pos, _al_const_bstring b1, unsigned char fill) { int d, newlen; ptrdiff_t pd; _al_bstring aux = (_al_bstring) b1; if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || b0->mlen < b0->slen || b0->mlen <= 0) return _AL_BSTR_ERR; if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return _AL_BSTR_ERR; d = pos; /* Aliasing case */ if (NULL != aux) { if ((pd = (ptrdiff_t) (b1->data - b0->data)) >= 0 && pd < (ptrdiff_t) b0->mlen) { if (NULL == (aux = _al_bstrcpy (b1))) return _AL_BSTR_ERR; } d += aux->slen; } /* Increase memory size if necessary */ if (_al_balloc (b0, d + 1) != _AL_BSTR_OK) { if (aux != b1) _al_bdestroy (aux); return _AL_BSTR_ERR; } newlen = b0->slen; /* Fill in "fill" character as necessary */ if (pos > newlen) { bstr__memset (b0->data + b0->slen, (int) fill, (size_t) (pos - b0->slen)); newlen = pos; } /* Copy b1 to position pos in b0. */ if (aux != NULL) { bBlockCopy ((char *) (b0->data + pos), (char *) aux->data, aux->slen); if (aux != b1) _al_bdestroy (aux); } /* Indicate the potentially increased size of b0 */ if (d > newlen) newlen = d; b0->slen = newlen; b0->data[newlen] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* int _al_binsert (_al_bstring b1, int pos, _al_bstring b2, unsigned char fill) * * Inserts the string b2 into b1 at position pos. If the position pos is * past the end of b1, then the character "fill" is appended as necessary to * make up the gap between the end of b1 and pos. Unlike _al_bsetstr, _al_binsert * does not allow b2 to be NULL. */ int _al_binsert (_al_bstring b1, int pos, _al_const_bstring b2, unsigned char fill) { int d, l; ptrdiff_t pd; _al_bstring aux = (_al_bstring) b2; if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return _AL_BSTR_ERR; /* Aliasing case */ if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->mlen) { if (NULL == (aux = _al_bstrcpy (b2))) return _AL_BSTR_ERR; } /* Compute the two possible end pointers */ d = b1->slen + aux->slen; l = pos + aux->slen; if ((d|l) < 0) return _AL_BSTR_ERR; if (l > d) { /* Inserting past the end of the string */ if (_al_balloc (b1, l + 1) != _AL_BSTR_OK) { if (aux != b2) _al_bdestroy (aux); return _AL_BSTR_ERR; } bstr__memset (b1->data + b1->slen, (int) fill, (size_t) (pos - b1->slen)); b1->slen = l; } else { /* Inserting in the middle of the string */ if (_al_balloc (b1, d + 1) != _AL_BSTR_OK) { if (aux != b2) _al_bdestroy (aux); return _AL_BSTR_ERR; } bBlockCopy (b1->data + l, b1->data + pos, d - l); b1->slen = d; } bBlockCopy (b1->data + pos, aux->data, aux->slen); b1->data[b1->slen] = (unsigned char) '\0'; if (aux != b2) _al_bdestroy (aux); return _AL_BSTR_OK; } /* int _al_breplace (_al_bstring b1, int pos, int len, _al_bstring b2, * unsigned char fill) * * Replace a section of a string from pos for a length len with the string b2. * fill is used is pos > b1->slen. */ int _al_breplace (_al_bstring b1, int pos, int len, _al_const_bstring b2, unsigned char fill) { int pl, ret; ptrdiff_t pd; _al_bstring aux = (_al_bstring) b2; if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || b2 == NULL || b1->data == NULL || b2->data == NULL || b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return _AL_BSTR_ERR; /* Straddles the end? */ if (pl >= b1->slen) { if ((ret = _al_bsetstr (b1, pos, b2, fill)) < 0) return ret; if (pos + b2->slen < b1->slen) { b1->slen = pos + b2->slen; b1->data[b1->slen] = (unsigned char) '\0'; } return ret; } /* Aliasing case */ if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->slen) { if (NULL == (aux = _al_bstrcpy (b2))) return _AL_BSTR_ERR; } if (aux->slen > len) { if (_al_balloc (b1, b1->slen + aux->slen - len) != _AL_BSTR_OK) { if (aux != b2) _al_bdestroy (aux); return _AL_BSTR_ERR; } } if (aux->slen != len) bstr__memmove (b1->data + pos + aux->slen, b1->data + pos + len, b1->slen - (pos + len)); bstr__memcpy (b1->data + pos, aux->data, aux->slen); b1->slen += aux->slen - len; b1->data[b1->slen] = (unsigned char) '\0'; if (aux != b2) _al_bdestroy (aux); return _AL_BSTR_OK; } /* int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, * int pos) * * Replace all occurrences of a find string with a replace string after a * given point in a _al_bstring. */ typedef int (*instr_fnptr) (_al_const_bstring s1, int pos, _al_const_bstring s2); static int findreplaceengine (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos, instr_fnptr instr) { int i, ret, slen, mlen, delta, acc; int * d; int static_d[32]; ptrdiff_t pd; _al_bstring auxf = (_al_bstring) find; _al_bstring auxr = (_al_bstring) repl; if (b == NULL || b->data == NULL || find == NULL || find->data == NULL || repl == NULL || repl->data == NULL || pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return _AL_BSTR_ERR; if (pos > b->slen - find->slen) return _AL_BSTR_OK; /* Alias with find string */ pd = (ptrdiff_t) (find->data - b->data); if ((ptrdiff_t) (pos - find->slen) < pd && pd < (ptrdiff_t) b->slen) { if (NULL == (auxf = _al_bstrcpy (find))) return _AL_BSTR_ERR; } /* Alias with repl string */ pd = (ptrdiff_t) (repl->data - b->data); if ((ptrdiff_t) (pos - repl->slen) < pd && pd < (ptrdiff_t) b->slen) { if (NULL == (auxr = _al_bstrcpy (repl))) { if (auxf != find) _al_bdestroy (auxf); return _AL_BSTR_ERR; } } delta = auxf->slen - auxr->slen; /* in-place replacement since find and replace strings are of equal length */ if (delta == 0) { while ((pos = instr (b, pos, auxf)) >= 0) { bstr__memcpy (b->data + pos, auxr->data, auxr->slen); pos += auxf->slen; } if (auxf != find) _al_bdestroy (auxf); if (auxr != repl) _al_bdestroy (auxr); return _AL_BSTR_OK; } /* shrinking replacement since auxf->slen > auxr->slen */ if (delta > 0) { acc = 0; while ((i = instr (b, pos, auxf)) >= 0) { if (acc && i > pos) bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); if (auxr->slen) bstr__memcpy (b->data + i - acc, auxr->data, auxr->slen); acc += delta; pos = i + auxf->slen; } if (acc) { i = b->slen; if (i > pos) bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); b->slen -= acc; b->data[b->slen] = (unsigned char) '\0'; } if (auxf != find) _al_bdestroy (auxf); if (auxr != repl) _al_bdestroy (auxr); return _AL_BSTR_OK; } /* expanding replacement since find->slen < repl->slen. Its a lot more complicated. */ mlen = 32; d = (int *) static_d; /* Avoid malloc for trivial cases */ acc = slen = 0; while ((pos = instr (b, pos, auxf)) >= 0) { if (slen + 1 >= mlen) { int sl; int * t; mlen += mlen; sl = sizeof (int *) * mlen; if (static_d == d) d = NULL; if (sl < mlen || NULL == (t = (int *) bstr__realloc (d, sl))) { ret = _AL_BSTR_ERR; goto done; } if (NULL == d) bstr__memcpy (t, static_d, sizeof (static_d)); d = t; } d[slen] = pos; slen++; acc -= delta; pos += auxf->slen; if (pos < 0 || acc < 0) { ret = _AL_BSTR_ERR; goto done; } } d[slen] = b->slen; if (_AL_BSTR_OK == (ret = _al_balloc (b, b->slen + acc + 1))) { b->slen += acc; for (i = slen-1; i >= 0; i--) { int s, l; s = d[i] + auxf->slen; l = d[i+1] - s; if (l) { bstr__memmove (b->data + s + acc, b->data + s, l); } if (auxr->slen) { bstr__memmove (b->data + s + acc - auxr->slen, auxr->data, auxr->slen); } acc += delta; } b->data[b->slen] = (unsigned char) '\0'; } done:; if (static_d == d) d = NULL; bstr__free (d); if (auxf != find) _al_bdestroy (auxf); if (auxr != repl) _al_bdestroy (auxr); return ret; } /* int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, * int pos) * * Replace all occurrences of a find string with a replace string after a * given point in a _al_bstring. */ int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos) { return findreplaceengine (b, find, repl, pos, _al_binstr); } /* int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, * int pos) * * Replace all occurrences of a find string, ignoring case, with a replace * string after a given point in a _al_bstring. */ int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos) { return findreplaceengine (b, find, repl, pos, _al_binstrcaseless); } /* int _al_binsertch (_al_bstring b, int pos, int len, unsigned char fill) * * Inserts the character fill repeatedly into b at position pos for a * length len. If the position pos is past the end of b, then the * character "fill" is appended as necessary to make up the gap between the * end of b and the position pos + len. */ int _al_binsertch (_al_bstring b, int pos, int len, unsigned char fill) { int d, l, i; if (pos < 0 || b == NULL || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || len < 0) return _AL_BSTR_ERR; /* Compute the two possible end pointers */ d = b->slen + len; l = pos + len; if ((d|l) < 0) return _AL_BSTR_ERR; if (l > d) { /* Inserting past the end of the string */ if (_al_balloc (b, l + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; pos = b->slen; b->slen = l; } else { /* Inserting in the middle of the string */ if (_al_balloc (b, d + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; for (i = d - 1; i >= l; i--) { b->data[i] = b->data[i - len]; } b->slen = d; } for (i=pos; i < l; i++) b->data[i] = fill; b->data[b->slen] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* int _al_bpattern (_al_bstring b, int len) * * Replicate the _al_bstring, b in place, end to end repeatedly until it * surpasses len characters, then chop the result to exactly len characters. * This function operates in-place. The function will return with _AL_BSTR_ERR * if b is NULL or of length 0, otherwise _AL_BSTR_OK is returned. */ int _al_bpattern (_al_bstring b, int len) { int i, d; d = _al_blength (b); if (d <= 0 || len < 0 || _al_balloc (b, len + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; if (len > 0) { if (d == 1) return _al_bsetstr (b, len, NULL, b->data[0]); for (i = d; i < len; i++) b->data[i] = b->data[i - d]; } b->data[len] = (unsigned char) '\0'; b->slen = len; return _AL_BSTR_OK; } #define BS_BUFF_SZ (1024) /* int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm) * * Use a finite buffer fread-like function readPtr to concatenate to the * _al_bstring b the entire contents of file-like source data in a roughly * efficient way. */ int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm) { int i, l, n; if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || readPtr == NULL) return _AL_BSTR_ERR; i = b->slen; for (n=i+16; ; n += ((n < BS_BUFF_SZ) ? n : BS_BUFF_SZ)) { if (_AL_BSTR_OK != _al_balloc (b, n + 1)) return _AL_BSTR_ERR; l = (int) readPtr ((void *) (b->data + i), 1, n - i, parm); i += l; b->slen = i; if (i < n) break; } b->data[i] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* _al_bstring _al_bread (_al_bNread readPtr, void * parm) * * Use a finite buffer fread-like function readPtr to create a _al_bstring * filled with the entire contents of file-like source data in a roughly * efficient way. */ _al_bstring _al_bread (_al_bNread readPtr, void * parm) { _al_bstring buff; if (0 > _al_breada (buff = _al_bfromcstr (""), readPtr, parm)) { _al_bdestroy (buff); return NULL; } return buff; } /* int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) * * Use an fgetc-like single character stream reading function (getcPtr) to * obtain a sequence of characters which are concatenated to the end of the * _al_bstring b. The stream read is terminated by the passed in terminator * parameter. * * If getcPtr returns with a negative number, or the terminator character * (which is appended) is read, then the stream reading is halted and the * function returns with a partial result in b. If there is an empty partial * result, 1 is returned. If no characters are read, or there is some other * detectable error, _AL_BSTR_ERR is returned. */ int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) { int c, d, e; if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || getcPtr == NULL) return _AL_BSTR_ERR; d = 0; e = b->mlen - 2; while ((c = getcPtr (parm)) >= 0) { if (d > e) { b->slen = d; if (_al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; e = b->mlen - 2; } b->data[d] = (unsigned char) c; d++; if (c == terminator) break; } b->data[d] = (unsigned char) '\0'; b->slen = d; return d == 0 && c < 0; } /* int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) * * Use an fgetc-like single character stream reading function (getcPtr) to * obtain a sequence of characters which are concatenated to the end of the * _al_bstring b. The stream read is terminated by the passed in terminator * parameter. * * If getcPtr returns with a negative number, or the terminator character * (which is appended) is read, then the stream reading is halted and the * function returns with a partial result concatentated to b. If there is * an empty partial result, 1 is returned. If no characters are read, or * there is some other detectable error, _AL_BSTR_ERR is returned. */ int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) { int c, d, e; if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || b->mlen <= 0 || getcPtr == NULL) return _AL_BSTR_ERR; d = b->slen; e = b->mlen - 2; while ((c = getcPtr (parm)) >= 0) { if (d > e) { b->slen = d; if (_al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; e = b->mlen - 2; } b->data[d] = (unsigned char) c; d++; if (c == terminator) break; } b->data[d] = (unsigned char) '\0'; b->slen = d; return d == 0 && c < 0; } /* _al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator) * * Use an fgetc-like single character stream reading function (getcPtr) to * obtain a sequence of characters which are concatenated into a _al_bstring. * The stream read is terminated by the passed in terminator function. * * If getcPtr returns with a negative number, or the terminator character * (which is appended) is read, then the stream reading is halted and the * result obtained thus far is returned. If no characters are read, or * there is some other detectable error, NULL is returned. */ _al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator) { _al_bstring buff; if (0 > _al_bgetsa (buff = _al_bfromcstr (""), getcPtr, parm, terminator) || 0 >= buff->slen) { _al_bdestroy (buff); buff = NULL; } return buff; } struct _al_bStream { _al_bstring buff; /* Buffer for over-reads */ void * parm; /* The stream handle for core stream */ _al_bNread readFnPtr; /* fread compatible fnptr for core stream */ int isEOF; /* track file's EOF state */ int maxBuffSz; }; /* struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm) * * Wrap a given open stream (described by a fread compatible function * pointer and stream handle) into an open _al_bStream suitable for the _al_bstring * library streaming functions. */ struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm) { struct _al_bStream * s; if (readPtr == NULL) return NULL; s = (struct _al_bStream *) bstr__alloc (sizeof (struct _al_bStream)); if (s == NULL) return NULL; s->parm = parm; s->buff = _al_bfromcstr (""); s->readFnPtr = readPtr; s->maxBuffSz = BS_BUFF_SZ; s->isEOF = 0; return s; } /* int _al_bsbufflength (struct _al_bStream * s, int sz) * * Set the length of the buffer used by the _al_bStream. If sz is zero, the * length is not set. This function returns with the previous length. */ int _al_bsbufflength (struct _al_bStream * s, int sz) { int oldSz; if (s == NULL || sz < 0) return _AL_BSTR_ERR; oldSz = s->maxBuffSz; if (sz > 0) s->maxBuffSz = sz; return oldSz; } int _al_bseof (const struct _al_bStream * s) { if (s == NULL || s->readFnPtr == NULL) return _AL_BSTR_ERR; return s->isEOF && (s->buff->slen == 0); } /* void * _al_bsclose (struct _al_bStream * s) * * Close the _al_bStream, and return the handle to the stream that was originally * used to open the given stream. */ void * _al_bsclose (struct _al_bStream * s) { void * parm; if (s == NULL) return NULL; s->readFnPtr = NULL; if (s->buff) _al_bdestroy (s->buff); s->buff = NULL; parm = s->parm; s->parm = NULL; s->isEOF = 1; bstr__free (s); return parm; } /* int _al_bsreadlna (_al_bstring r, struct _al_bStream * s, char terminator) * * Read a _al_bstring terminated by the terminator character or the end of the * stream from the _al_bStream (s) and return it into the parameter r. This * function may read additional characters from the core stream that are not * returned, but will be retained for subsequent read operations. */ int _al_bsreadlna (_al_bstring r, struct _al_bStream * s, char terminator) { int i, l, ret, rlo; char * b; struct _al_tagbstring x; if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 || r->slen < 0 || r->mlen < r->slen) return _AL_BSTR_ERR; l = s->buff->slen; if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; b = (char *) s->buff->data; x.data = (unsigned char *) b; /* First check if the current buffer holds the terminator */ b[l] = terminator; /* Set sentinel */ for (i=0; b[i] != terminator; i++) ; if (i < l) { x.slen = i + 1; ret = _al_bconcat (r, &x); s->buff->slen = l; if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, i + 1); return _AL_BSTR_OK; } rlo = r->slen; /* If not then just concatenate the entire buffer to the output */ x.slen = l; if (_AL_BSTR_OK != _al_bconcat (r, &x)) return _AL_BSTR_ERR; /* Perform direct in-place reads into the destination to allow for the minimum of data-copies */ for (;;) { if (_AL_BSTR_OK != _al_balloc (r, r->slen + s->maxBuffSz + 1)) return _AL_BSTR_ERR; b = (char *) (r->data + r->slen); l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); if (l <= 0) { r->data[r->slen] = (unsigned char) '\0'; s->buff->slen = 0; s->isEOF = 1; /* If nothing was read return with an error message */ return _AL_BSTR_ERR & -(r->slen == rlo); } b[l] = terminator; /* Set sentinel */ for (i=0; b[i] != terminator; i++) ; if (i < l) break; r->slen += l; } /* Terminator found, push over-read back to buffer */ i++; r->slen += i; s->buff->slen = l - i; bstr__memcpy (s->buff->data, b + i, l - i); r->data[r->slen] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_bstring term) * * Read a _al_bstring terminated by any character in the term string or the end * of the stream from the _al_bStream (s) and return it into the parameter r. * This function may read additional characters from the core stream that * are not returned, but will be retained for subsequent read operations. */ int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_const_bstring term) { int i, l, ret, rlo; unsigned char * b; struct _al_tagbstring x; struct charField cf; if (s == NULL || s->buff == NULL || r == NULL || term == NULL || term->data == NULL || r->mlen <= 0 || r->slen < 0 || r->mlen < r->slen) return _AL_BSTR_ERR; if (term->slen == 1) return _al_bsreadlna (r, s, term->data[0]); if (term->slen < 1 || buildCharField (&cf, term)) return _AL_BSTR_ERR; l = s->buff->slen; if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; b = (unsigned char *) s->buff->data; x.data = b; /* First check if the current buffer holds the terminator */ b[l] = term->data[0]; /* Set sentinel */ for (i=0; !testInCharField (&cf, b[i]); i++) ; if (i < l) { x.slen = i + 1; ret = _al_bconcat (r, &x); s->buff->slen = l; if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, i + 1); return _AL_BSTR_OK; } rlo = r->slen; /* If not then just concatenate the entire buffer to the output */ x.slen = l; if (_AL_BSTR_OK != _al_bconcat (r, &x)) return _AL_BSTR_ERR; /* Perform direct in-place reads into the destination to allow for the minimum of data-copies */ for (;;) { if (_AL_BSTR_OK != _al_balloc (r, r->slen + s->maxBuffSz + 1)) return _AL_BSTR_ERR; b = (unsigned char *) (r->data + r->slen); l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); if (l <= 0) { r->data[r->slen] = (unsigned char) '\0'; s->buff->slen = 0; s->isEOF = 1; /* If nothing was read return with an error message */ return _AL_BSTR_ERR & -(r->slen == rlo); } b[l] = term->data[0]; /* Set sentinel */ for (i=0; !testInCharField (&cf, b[i]); i++) ; if (i < l) break; r->slen += l; } /* Terminator found, push over-read back to buffer */ i++; r->slen += i; s->buff->slen = l - i; bstr__memcpy (s->buff->data, b + i, l - i); r->data[r->slen] = (unsigned char) '\0'; return _AL_BSTR_OK; } /* int _al_bsreada (_al_bstring r, struct _al_bStream * s, int n) * * Read a _al_bstring of length n (or, if it is fewer, as many bytes as is * remaining) from the _al_bStream. This function may read additional * characters from the core stream that are not returned, but will be * retained for subsequent read operations. This function will not read * additional characters from the core stream beyond virtual stream pointer. */ int _al_bsreada (_al_bstring r, struct _al_bStream * s, int n) { int l, ret, orslen; char * b; struct _al_tagbstring x; if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 || r->slen < 0 || r->mlen < r->slen || n <= 0) return _AL_BSTR_ERR; n += r->slen; if (n <= 0) return _AL_BSTR_ERR; l = s->buff->slen; orslen = r->slen; if (0 == l) { if (s->isEOF) return _AL_BSTR_ERR; if (r->mlen > n) { l = (int) s->readFnPtr (r->data + r->slen, 1, n - r->slen, s->parm); if (0 >= l || l > n - r->slen) { s->isEOF = 1; return _AL_BSTR_ERR; } r->slen += l; r->data[r->slen] = (unsigned char) '\0'; return 0; } } if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; b = (char *) s->buff->data; x.data = (unsigned char *) b; do { if (l + r->slen >= n) { x.slen = n - r->slen; ret = _al_bconcat (r, &x); s->buff->slen = l; if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, x.slen); return _AL_BSTR_ERR & -(r->slen == orslen); } x.slen = l; if (_AL_BSTR_OK != _al_bconcat (r, &x)) break; l = n - r->slen; if (l > s->maxBuffSz) l = s->maxBuffSz; l = (int) s->readFnPtr (b, 1, l, s->parm); } while (l > 0); if (l < 0) l = 0; if (l == 0) s->isEOF = 1; s->buff->slen = l; return _AL_BSTR_ERR & -(r->slen == orslen); } /* int _al_bsreadln (_al_bstring r, struct _al_bStream * s, char terminator) * * Read a _al_bstring terminated by the terminator character or the end of the * stream from the _al_bStream (s) and return it into the parameter r. This * function may read additional characters from the core stream that are not * returned, but will be retained for subsequent read operations. */ int _al_bsreadln (_al_bstring r, struct _al_bStream * s, char terminator) { if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0) return _AL_BSTR_ERR; if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; r->slen = 0; return _al_bsreadlna (r, s, terminator); } /* int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_bstring term) * * Read a _al_bstring terminated by any character in the term string or the end * of the stream from the _al_bStream (s) and return it into the parameter r. * This function may read additional characters from the core stream that * are not returned, but will be retained for subsequent read operations. */ int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_const_bstring term) { if (s == NULL || s->buff == NULL || r == NULL || term == NULL || term->data == NULL || r->mlen <= 0) return _AL_BSTR_ERR; if (term->slen == 1) return _al_bsreadln (r, s, term->data[0]); if (term->slen < 1) return _AL_BSTR_ERR; if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; r->slen = 0; return _al_bsreadlnsa (r, s, term); } /* int _al_bsread (_al_bstring r, struct _al_bStream * s, int n) * * Read a _al_bstring of length n (or, if it is fewer, as many bytes as is * remaining) from the _al_bStream. This function may read additional * characters from the core stream that are not returned, but will be * retained for subsequent read operations. This function will not read * additional characters from the core stream beyond virtual stream pointer. */ int _al_bsread (_al_bstring r, struct _al_bStream * s, int n) { if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 || n <= 0) return _AL_BSTR_ERR; if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; r->slen = 0; return _al_bsreada (r, s, n); } /* int _al_bsunread (struct _al_bStream * s, _al_const_bstring b) * * Insert a _al_bstring into the _al_bStream at the current position. These * characters will be read prior to those that actually come from the core * stream. */ int _al_bsunread (struct _al_bStream * s, _al_const_bstring b) { if (s == NULL || s->buff == NULL) return _AL_BSTR_ERR; return _al_binsert (s->buff, 0, b, (unsigned char) '?'); } /* int _al_bspeek (_al_bstring r, const struct _al_bStream * s) * * Return the currently buffered characters from the _al_bStream that will be * read prior to reads from the core stream. */ int _al_bspeek (_al_bstring r, const struct _al_bStream * s) { if (s == NULL || s->buff == NULL) return _AL_BSTR_ERR; return _al_bassign (r, s->buff); } /* _al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep); * * Join the entries of a _al_bstrList into one _al_bstring by sequentially * concatenating them with the sep string in between. If there is an error * NULL is returned, otherwise a _al_bstring with the correct result is returned. */ _al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep) { _al_bstring b; int i, c, v; if (bl == NULL || bl->qty < 0) return NULL; if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL; for (i = 0, c = 1; i < bl->qty; i++) { v = bl->entry[i]->slen; if (v < 0) return NULL; /* Invalid input */ c += v; if (c < 0) return NULL; /* Wrap around ?? */ } if (sep != NULL) c += (bl->qty - 1) * sep->slen; b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); if (NULL == b) return NULL; /* Out of memory */ b->data = (unsigned char *) bstr__alloc (c); if (b->data == NULL) { bstr__free (b); return NULL; } b->mlen = c; b->slen = c-1; for (i = 0, c = 0; i < bl->qty; i++) { if (i > 0 && sep != NULL) { bstr__memcpy (b->data + c, sep->data, sep->slen); c += sep->slen; } v = bl->entry[i]->slen; bstr__memcpy (b->data + c, bl->entry[i]->data, v); c += v; } b->data[c] = (unsigned char) '\0'; return b; } #define BSSSC_BUFF_LEN (256) /* int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, * int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) * * Iterate the set of disjoint sequential substrings read from a stream * divided by any of the characters in splitStr. An empty splitStr causes * the whole stream to be iterated once. * * Note: At the point of calling the cb function, the _al_bStream pointer is * pointed exactly at the position right after having read the split * character. The cb function can act on the stream by causing the _al_bStream * pointer to move, and _al_bssplitscb will continue by starting the next split * at the position of the pointer after the return from cb. * * However, if the cb causes the _al_bStream s to be destroyed then the cb must * return with a negative value, otherwise _al_bssplitscb will continue in an * undefined manner. */ int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) { struct charField chrs; _al_bstring buff; int i, p, ret; if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; if (NULL == (buff = _al_bfromcstr (""))) return _AL_BSTR_ERR; if (splitStr->slen == 0) { while (_al_bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ; if ((ret = cb (parm, 0, buff)) > 0) ret = 0; } else { buildCharField (&chrs, splitStr); ret = p = i = 0; for (;;) { if (i >= buff->slen) { _al_bsreada (buff, s, BSSSC_BUFF_LEN); if (i >= buff->slen) { if (0 < (ret = cb (parm, p, buff))) ret = 0; break; } } if (testInCharField (&chrs, buff->data[i])) { struct _al_tagbstring t; unsigned char c; _al_blk2tbstr (t, buff->data + i + 1, buff->slen - (i + 1)); if ((ret = _al_bsunread (s, &t)) < 0) break; buff->slen = i; c = buff->data[i]; buff->data[i] = (unsigned char) '\0'; if ((ret = cb (parm, p, buff)) < 0) break; buff->data[i] = c; buff->slen = 0; p += i + 1; i = -1; } i++; } } _al_bdestroy (buff); return ret; } /* int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, * int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) * * Iterate the set of disjoint sequential substrings read from a stream * divided by the entire substring splitStr. An empty splitStr causes * each character of the stream to be iterated. * * Note: At the point of calling the cb function, the _al_bStream pointer is * pointed exactly at the position right after having read the split * character. The cb function can act on the stream by causing the _al_bStream * pointer to move, and _al_bssplitscb will continue by starting the next split * at the position of the pointer after the return from cb. * * However, if the cb causes the _al_bStream s to be destroyed then the cb must * return with a negative value, otherwise _al_bssplitscb will continue in an * undefined manner. */ int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) { _al_bstring buff; int i, p, ret; if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; if (splitStr->slen == 1) return _al_bssplitscb (s, splitStr, cb, parm); if (NULL == (buff = _al_bfromcstr (""))) return _AL_BSTR_ERR; if (splitStr->slen == 0) { for (i=0; _al_bsreada (buff, s, BSSSC_BUFF_LEN) >= 0; i++) { if ((ret = cb (parm, 0, buff)) < 0) { _al_bdestroy (buff); return ret; } buff->slen = 0; } return _AL_BSTR_OK; } else { ret = p = i = 0; for (i=p=0;;) { if ((ret = _al_binstr (buff, 0, splitStr)) >= 0) { struct _al_tagbstring t; _al_blk2tbstr (t, buff->data, ret); i = ret + splitStr->slen; if ((ret = cb (parm, p, &t)) < 0) break; p += i; _al_bdelete (buff, 0, i); } else { _al_bsreada (buff, s, BSSSC_BUFF_LEN); if (_al_bseof (s)) { if ((ret = cb (parm, p, buff)) > 0) ret = 0; break; } } } } _al_bdestroy (buff); return ret; } /* int _al_bstrListCreate (void) * * Create a _al_bstrList. */ struct _al_bstrList * _al_bstrListCreate (void) { struct _al_bstrList * sl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); if (sl) { sl->entry = (_al_bstring *) bstr__alloc (1*sizeof (_al_bstring)); if (!sl->entry) { bstr__free (sl); sl = NULL; } else { sl->qty = 0; sl->mlen = 1; } } return sl; } /* int _al_bstrListDestroy (struct _al_bstrList * sl) * * Destroy a _al_bstrList that has been created by _al_bsplit, _al_bsplits or _al_bstrListCreate. */ int _al_bstrListDestroy (struct _al_bstrList * sl) { int i; if (sl == NULL || sl->qty < 0) return _AL_BSTR_ERR; for (i=0; i < sl->qty; i++) { if (sl->entry[i]) { _al_bdestroy (sl->entry[i]); sl->entry[i] = NULL; } } sl->qty = -1; sl->mlen = -1; bstr__free (sl->entry); sl->entry = NULL; bstr__free (sl); return _AL_BSTR_OK; } /* int _al_bstrListAlloc (struct _al_bstrList * sl, int msz) * * Ensure that there is memory for at least msz number of entries for the * list. */ int _al_bstrListAlloc (struct _al_bstrList * sl, int msz) { _al_bstring * l; int smsz; size_t nsz; if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return _AL_BSTR_ERR; if (sl->mlen >= msz) return _AL_BSTR_OK; smsz = snapUpSize (msz); nsz = ((size_t) smsz) * sizeof (_al_bstring); if (nsz < (size_t) smsz) return _AL_BSTR_ERR; l = (_al_bstring *) bstr__realloc (sl->entry, nsz); if (!l) { smsz = msz; nsz = ((size_t) smsz) * sizeof (_al_bstring); l = (_al_bstring *) bstr__realloc (sl->entry, nsz); if (!l) return _AL_BSTR_ERR; } sl->mlen = smsz; sl->entry = l; return _AL_BSTR_OK; } /* int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz) * * Try to allocate the minimum amount of memory for the list to include at * least msz entries or sl->qty whichever is greater. */ int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz) { _al_bstring * l; size_t nsz; if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return _AL_BSTR_ERR; if (msz < sl->qty) msz = sl->qty; if (sl->mlen == msz) return _AL_BSTR_OK; nsz = ((size_t) msz) * sizeof (_al_bstring); if (nsz < (size_t) msz) return _AL_BSTR_ERR; l = (_al_bstring *) bstr__realloc (sl->entry, nsz); if (!l) return _AL_BSTR_ERR; sl->mlen = msz; sl->entry = l; return _AL_BSTR_OK; } /* int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, * int (* cb) (void * parm, int ofs, int len), void * parm) * * Iterate the set of disjoint sequential substrings over str divided by the * character in splitChar. * * Note: Non-destructive modification of str from within the cb function * while performing this split is not undefined. _al_bsplitcb behaves in * sequential lock step with calls to cb. I.e., after returning from a cb * that return a non-negative integer, _al_bsplitcb continues from the position * 1 character after the last detected split character and it will halt * immediately if the length of str falls below this point. However, if the * cb function destroys str, then it *must* return with a negative value, * otherwise _al_bsplitcb will continue in an undefined manner. */ int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, int (* cb) (void * parm, int ofs, int len), void * parm) { int i, p, ret; if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) return _AL_BSTR_ERR; p = pos; do { for (i=p; i < str->slen; i++) { if (str->data[i] == splitChar) break; } if ((ret = cb (parm, p, i - p)) < 0) return ret; p = i + 1; } while (p <= str->slen); return _AL_BSTR_OK; } /* int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, * int (* cb) (void * parm, int ofs, int len), void * parm) * * Iterate the set of disjoint sequential substrings over str divided by any * of the characters in splitStr. An empty splitStr causes the whole str to * be iterated once. * * Note: Non-destructive modification of str from within the cb function * while performing this split is not undefined. _al_bsplitscb behaves in * sequential lock step with calls to cb. I.e., after returning from a cb * that return a non-negative integer, _al_bsplitscb continues from the position * 1 character after the last detected split character and it will halt * immediately if the length of str falls below this point. However, if the * cb function destroys str, then it *must* return with a negative value, * otherwise _al_bsplitscb will continue in an undefined manner. */ int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm) { struct charField chrs; int i, p, ret; if (cb == NULL || str == NULL || pos < 0 || pos > str->slen || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; if (splitStr->slen == 0) { if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0; return ret; } if (splitStr->slen == 1) return _al_bsplitcb (str, splitStr->data[0], pos, cb, parm); buildCharField (&chrs, splitStr); p = pos; do { for (i=p; i < str->slen; i++) { if (testInCharField (&chrs, str->data[i])) break; } if ((ret = cb (parm, p, i - p)) < 0) return ret; p = i + 1; } while (p <= str->slen); return _AL_BSTR_OK; } /* int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, * int (* cb) (void * parm, int ofs, int len), void * parm) * * Iterate the set of disjoint sequential substrings over str divided by the * substring splitStr. An empty splitStr causes the whole str to be * iterated once. * * Note: Non-destructive modification of str from within the cb function * while performing this split is not undefined. _al_bsplitstrcb behaves in * sequential lock step with calls to cb. I.e., after returning from a cb * that return a non-negative integer, _al_bsplitscb continues from the position * 1 character after the last detected split character and it will halt * immediately if the length of str falls below this point. However, if the * cb function destroys str, then it *must* return with a negative value, * otherwise _al_bsplitscb will continue in an undefined manner. */ int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm) { int i, p, ret; if (cb == NULL || str == NULL || pos < 0 || pos > str->slen || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; if (0 == splitStr->slen) { for (i=pos; i < str->slen; i++) { if ((ret = cb (parm, i, 1)) < 0) return ret; } return _AL_BSTR_OK; } if (splitStr->slen == 1) return _al_bsplitcb (str, splitStr->data[0], pos, cb, parm); for (i=p=pos; i <= str->slen - splitStr->slen; i++) { if (0 == bstr__memcmp (splitStr->data, str->data + i, splitStr->slen)) { if ((ret = cb (parm, p, i - p)) < 0) return ret; i += splitStr->slen; p = i; } } if ((ret = cb (parm, p, str->slen - p)) < 0) return ret; return _AL_BSTR_OK; } struct genBstrList { _al_bstring b; struct _al_bstrList * bl; }; static int bscb (void * parm, int ofs, int len) { struct genBstrList * g = (struct genBstrList *) parm; if (g->bl->qty >= g->bl->mlen) { int mlen = g->bl->mlen * 2; _al_bstring * tbl; while (g->bl->qty >= mlen) { if (mlen < g->bl->mlen) return _AL_BSTR_ERR; mlen += mlen; } tbl = (_al_bstring *) bstr__realloc (g->bl->entry, sizeof (_al_bstring) * mlen); if (tbl == NULL) return _AL_BSTR_ERR; g->bl->entry = tbl; g->bl->mlen = mlen; } g->bl->entry[g->bl->qty] = _al_bmidstr (g->b, ofs, len); g->bl->qty++; return _AL_BSTR_OK; } /* struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar) * * Create an array of sequential substrings from str divided by the character * splitChar. */ struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar) { struct genBstrList g; if (str == NULL || str->data == NULL || str->slen < 0) return NULL; g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); if (g.bl == NULL) return NULL; g.bl->mlen = 4; g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); if (NULL == g.bl->entry) { bstr__free (g.bl); return NULL; } g.b = (_al_bstring) str; g.bl->qty = 0; if (_al_bsplitcb (str, splitChar, 0, bscb, &g) < 0) { _al_bstrListDestroy (g.bl); return NULL; } return g.bl; } /* struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr) * * Create an array of sequential substrings from str divided by the entire * substring splitStr. */ struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr) { struct genBstrList g; if (str == NULL || str->data == NULL || str->slen < 0) return NULL; g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); if (g.bl == NULL) return NULL; g.bl->mlen = 4; g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); if (NULL == g.bl->entry) { bstr__free (g.bl); return NULL; } g.b = (_al_bstring) str; g.bl->qty = 0; if (_al_bsplitstrcb (str, splitStr, 0, bscb, &g) < 0) { _al_bstrListDestroy (g.bl); return NULL; } return g.bl; } /* struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_bstring splitStr) * * Create an array of sequential substrings from str divided by any of the * characters in splitStr. An empty splitStr causes a single entry _al_bstrList * containing a copy of str to be returned. */ struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_const_bstring splitStr) { struct genBstrList g; if ( str == NULL || str->slen < 0 || str->data == NULL || splitStr == NULL || splitStr->slen < 0 || splitStr->data == NULL) return NULL; g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); if (g.bl == NULL) return NULL; g.bl->mlen = 4; g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); if (NULL == g.bl->entry) { bstr__free (g.bl); return NULL; } g.b = (_al_bstring) str; g.bl->qty = 0; if (_al_bsplitscb (str, splitStr, 0, bscb, &g) < 0) { _al_bstrListDestroy (g.bl); return NULL; } return g.bl; } #if defined (__TURBOC__) && !defined (__BORLANDC__) # ifndef BSTRLIB_NOVSNP # define BSTRLIB_NOVSNP # endif #endif /* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ #if defined(__WATCOMC__) || defined(_MSC_VER) #define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} #else #ifdef BSTRLIB_NOVSNP /* This is just a hack. If you are using a system without a vsnprintf, it is not recommended that _al_bformat be used at all. */ #define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} #define START_VSNBUFF (256) #else #ifdef __GNUC__ /* Something is making gcc complain about this prototype not being here, so I've just gone ahead and put it in. */ /* Commented out in Allegro source because vsnprintf seems to be defined as a * macro that calls compiler builtins sometimes, e.g. Mac OS X 10.6. */ /* extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); */ #endif #define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);} #endif #endif #if !defined (BSTRLIB_NOVSNP) #ifndef START_VSNBUFF #define START_VSNBUFF (16) #endif /* On IRIX vsnprintf returns n-1 when the operation would overflow the target buffer, WATCOM and MSVC both return -1, while C99 requires that the returned value be exactly what the length would be if the buffer would be large enough. This leads to the idea that if the return value is larger than n, then changing n to the return value will reduce the number of iterations required. */ /* int _al_bformata (_al_bstring b, const char * fmt, ...) * * After the first parameter, it takes the same parameters as printf (), but * rather than outputting results to stdio, it appends the results to * a _al_bstring which contains what would have been output. Note that if there * is an early generation of a '\0' character, the _al_bstring will be truncated * to this end point. */ int _al_bformata (_al_bstring b, const char * fmt, ...) { va_list arglist; _al_bstring buff; int n, r; if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; /* Since the length is not determinable beforehand, a search is performed using the truncating "vsnprintf" call (to avoid buffer overflows) on increasing potential sizes for the output result. */ if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { n = 1; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return _AL_BSTR_ERR; } for (;;) { va_start (arglist, fmt); exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); va_end (arglist); buff->data[n] = (unsigned char) '\0'; buff->slen = (int) (strlen) ((char *) buff->data); if (buff->slen < n) break; if (r > n) n = r; else n += n; if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { _al_bdestroy (buff); return _AL_BSTR_ERR; } } r = _al_bconcat (b, buff); _al_bdestroy (buff); return r; } /* int _al_bassignformat (_al_bstring b, const char * fmt, ...) * * After the first parameter, it takes the same parameters as printf (), but * rather than outputting results to stdio, it outputs the results to * the _al_bstring parameter b. Note that if there is an early generation of a * '\0' character, the _al_bstring will be truncated to this end point. */ int _al_bassignformat (_al_bstring b, const char * fmt, ...) { va_list arglist; _al_bstring buff; int n, r; if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; /* Since the length is not determinable beforehand, a search is performed using the truncating "vsnprintf" call (to avoid buffer overflows) on increasing potential sizes for the output result. */ if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { n = 1; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return _AL_BSTR_ERR; } for (;;) { va_start (arglist, fmt); exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); va_end (arglist); buff->data[n] = (unsigned char) '\0'; buff->slen = (int) (strlen) ((char *) buff->data); if (buff->slen < n) break; if (r > n) n = r; else n += n; if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { _al_bdestroy (buff); return _AL_BSTR_ERR; } } r = _al_bassign (b, buff); _al_bdestroy (buff); return r; } /* _al_bstring _al_bformat (const char * fmt, ...) * * Takes the same parameters as printf (), but rather than outputting results * to stdio, it forms a _al_bstring which contains what would have been output. * Note that if there is an early generation of a '\0' character, the * _al_bstring will be truncated to this end point. */ _al_bstring _al_bformat (const char * fmt, ...) { va_list arglist; _al_bstring buff; int n, r; if (fmt == NULL) return NULL; /* Since the length is not determinable beforehand, a search is performed using the truncating "vsnprintf" call (to avoid buffer overflows) on increasing potential sizes for the output result. */ if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { n = 1; if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return NULL; } for (;;) { va_start (arglist, fmt); exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); va_end (arglist); buff->data[n] = (unsigned char) '\0'; buff->slen = (int) (strlen) ((char *) buff->data); if (buff->slen < n) break; if (r > n) n = r; else n += n; if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { _al_bdestroy (buff); return NULL; } } return buff; } /* int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arglist) * * The _al_bvcformata function formats data under control of the format control * string fmt and attempts to append the result to b. The fmt parameter is * the same as that of the printf function. The variable argument list is * replaced with arglist, which has been initialized by the va_start macro. * The size of the output is upper bounded by count. If the required output * exceeds count, the string b is not augmented with any contents and a value * below _AL_BSTR_ERR is returned. If a value below -count is returned then it * is recommended that the negative of this value be used as an update to the * count in a subsequent pass. On other errors, such as running out of * memory, parameter errors or numeric wrap around _AL_BSTR_ERR is returned. * _AL_BSTR_OK is returned when the output is successfully generated and * appended to b. * * Note: There is no sanity checking of arglist, and this function is * destructive of the contents of b from the b->slen point onward. If there * is an early generation of a '\0' character, the _al_bstring will be truncated * to this end point. */ int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arg) { int n, r, l; if (b == NULL || fmt == NULL || count <= 0 || b->data == NULL || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; if (count > (n = b->slen + count) + 2) return _AL_BSTR_ERR; if (_AL_BSTR_OK != _al_balloc (b, n + 2)) return _AL_BSTR_ERR; exvsnprintf (r, (char *) b->data + b->slen, count + 2, fmt, arg); /* Did the operation complete successfully within bounds? */ if (n >= (l = b->slen + (int) (strlen) ((const char *) b->data + b->slen))) { b->slen = l; return _AL_BSTR_OK; } /* Abort, since the buffer was not large enough. The return value tries to help set what the retry length should be. */ b->data[b->slen] = '\0'; if (r > count+1) l = r; else { l = count+count; if (count > l) l = INT_MAX; } n = -l; if (n > _AL_BSTR_ERR-1) n = _AL_BSTR_ERR-1; return n; } #endif allegro-5.0.10/src/misc/aatree.c0000644000175000001440000001012512043106630015527 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * AA tree, a type of self-balancing search tree. * * By Peter Wang. */ /* prettier */ #define _AL_AATREE Aatree #include "allegro5/allegro.h" #include "allegro5/internal/aintern_aatree.h" struct DelInfo { const void *key; _al_cmp_t compare; Aatree *last; Aatree *deleted; }; static Aatree nil = { 0, &nil, &nil, NULL, NULL }; static Aatree *skew(Aatree *T) { if (T == &nil) return T; if (T->left->level == T->level) { Aatree *L = T->left; T->left = L->right; L->right = T; return L; } return T; } static Aatree *split(Aatree *T) { if (T == &nil) return T; if (T->level == T->right->right->level) { Aatree *R = T->right; T->right = R->left; R->left = T; R->level = R->level + 1; return R; } return T; } static Aatree *singleton(const void *key, void *value) { Aatree *T = al_malloc(sizeof(Aatree)); T->level = 1; T->left = &nil; T->right = &nil; T->key = key; T->value = value; return T; } static Aatree *doinsert(Aatree *T, const void *key, void *value, _al_cmp_t compare) { int cmp; if (T == &nil) { return singleton(key, value); } cmp = compare(key, T->key); if (cmp < 0) { T->left = doinsert(T->left, key, value, compare); } else if (cmp > 0) { T->right = doinsert(T->right, key, value, compare); } else { /* Already exists. We don't yet return any indication of this. */ return T; } T = skew(T); T = split(T); return T; } Aatree *_al_aa_insert(Aatree *T, const void *key, void *value, _al_cmp_t compare) { if (T == NULL) T = &nil; return doinsert(T, key, value, compare); } void *_al_aa_search(const Aatree *T, const void *key, _al_cmp_t compare) { if (T == NULL) return NULL; while (T != &nil) { int cmp = compare(key, T->key); if (cmp == 0) return T->value; T = (cmp < 0) ? T->left : T->right; } return NULL; } static Aatree *dodelete(struct DelInfo *info, Aatree *T, void **ret_value) { if (T == &nil) return T; /* Search down the tree and set pointers last and deleted. */ info->last = T; if (info->compare(info->key, T->key) < 0) { T->left = dodelete(info, T->left, ret_value); } else { info->deleted = T; T->right = dodelete(info, T->right, ret_value); } /* At the bottom of the tree we remove the element if it is present. */ if (T == info->last && info->deleted != &nil && info->compare(info->key, info->deleted->key) == 0) { Aatree *right = T->right; *ret_value = info->deleted->value; info->deleted->key = T->key; info->deleted->value = T->value; info->deleted = &nil; al_free(T); return right; } /* On the way back, we rebalance. */ if (T->left->level < T->level - 1 || T->right->level < T->level - 1) { T->level--; if (T->right->level > T->level) { T->right->level = T->level; } T = skew(T); T->right = skew(T->right); T->right->right = skew(T->right->right); T = split(T); T->right = split(T->right); } return T; } Aatree *_al_aa_delete(Aatree *T, const void *key, _al_cmp_t compare, void **ret_value) { struct DelInfo info; info.key = key; info.compare = compare; info.last = &nil; info.deleted = &nil; if (T) { T = dodelete(&info, T, ret_value); if (T == &nil) T = NULL; } return T; } void _al_aa_free(Aatree *T) { if (T && T != &nil) { _al_aa_free(T->left); _al_aa_free(T->right); al_free(T); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/pixels.c0000644000175000001440000002010412124554576014655 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Pixel formats. * * By Trent Gamblin. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_pixels.h" ALLEGRO_DEBUG_CHANNEL("pixels") /* lookup table for scaling 8 bit integers up to floats [0.0, 1.0] */ float _al_u8_to_float[256]; int _al_rgb_scale_1[2]; int _al_rgb_scale_4[16]; int _al_rgb_scale_5[32]; int _al_rgb_scale_6[64]; static int pixel_sizes[] = { 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ 0, 0, 2, 2, 2, 3, 4, 4, 4, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ 4, 2, 3, 2, 2, 2, 2, 4, 4, 3, 2, 2, 4, 4, 16, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ 4, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ 2 /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ }; static int pixel_bits[] = { 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ 0, 0, 15, 16, 16, 24, 32, 32, 32, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ 32, 16, 24, 16, 15, 16, 16, 32, 32, 24, 16, 15, 32, 32, 128, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ 32, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ 16 /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ }; static bool format_alpha_table[ALLEGRO_NUM_PIXEL_FORMATS] = { false, /* neutral (ALLEGRO_PIXEL_FORMAT_ANY) */ false, true, false, false, true, false, false, true, true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ true, true, false, false, false, true, true, true, false, false, false, false, false, false, true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ true /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ }; static char const *pixel_format_names[ALLEGRO_NUM_PIXEL_FORMATS + 1] = { "ANY", "ANY_NO_ALPHA", "ANY_WITH_ALPHA", "ANY_15_NO_ALPHA", "ANY_16_NO_ALPHA", "ANY_16_WITH_ALPHA", "ANY_24_NO_ALPHA", "ANY_32_NO_ALPHA", "ANY_32_WITH_ALPHA", "ARGB_8888", "RGBA_8888", "ARGB_4444", "RGB_888", "RGB_565", "RGB_555", "RGBA_5551", "ARGB_1555", "ABGR_8888", "XBGR_8888", "BGR_888", "BGR_565", "BGR_555", "RGBX_8888", "XRGB_8888", "ABGR_F32", "ABGR_8888_LE", "RGBA_4444", "INVALID" }; static bool format_is_real[ALLEGRO_NUM_PIXEL_FORMATS] = { false, /* ALLEGRO_PIXEL_FORMAT_ANY */ false, false, false, false, false, false, false, false, true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ true /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ }; void _al_init_pixels(void) { int i; for (i = 0; i < 256; i++) _al_u8_to_float[i] = i / 255.0; for (i = 0; i < 2; i++) _al_rgb_scale_1[i] = i * 255 / 1; for (i = 0; i < 16; i++) _al_rgb_scale_4[i] = i * 255 / 15; for (i = 0; i < 32; i++) _al_rgb_scale_5[i] = i * 255 / 31; for (i = 0; i < 64; i++) _al_rgb_scale_6[i] = i * 255 / 63; } /* Function: al_get_pixel_size */ int al_get_pixel_size(int format) { return pixel_sizes[format]; } /* Function: al_get_pixel_format_bits */ int al_get_pixel_format_bits(int format) { return pixel_bits[format]; } bool _al_pixel_format_has_alpha(int format) { return format_alpha_table[format]; } bool _al_pixel_format_is_real(int format) { ASSERT(format >= 0); ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS); return format_is_real[format]; } /* We use al_get_display_format() as a hint for the preferred RGB ordering when * nothing else is specified. */ static bool try_display_format(ALLEGRO_DISPLAY *display, int *format) { int best_format; int bytes; if (!display) { return false; } best_format = al_get_display_format(display); if (!_al_pixel_format_is_real(best_format)) return false; bytes = al_get_pixel_size(*format); if (bytes && bytes != al_get_pixel_size(best_format)) return false; if (_al_pixel_format_has_alpha(*format) && !_al_pixel_format_has_alpha(best_format)) { switch (best_format) { case ALLEGRO_PIXEL_FORMAT_RGBX_8888: *format = ALLEGRO_PIXEL_FORMAT_RGBA_8888; return true; case ALLEGRO_PIXEL_FORMAT_XRGB_8888: *format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; return true; case ALLEGRO_PIXEL_FORMAT_XBGR_8888: *format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; return true; default: return false; } } *format = best_format; return true; } int _al_get_real_pixel_format(ALLEGRO_DISPLAY *display, int format) { /* Pick an appropriate format if the user is vague */ switch (format) { case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; break; case ALLEGRO_PIXEL_FORMAT_ANY: case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; break; case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGB_555; break; case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_RGB_565; break; case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; break; case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGB_888; break; default: /* Already a real format - don't change it. */ break; } ASSERT(_al_pixel_format_is_real(format)); return format; } char const *_al_pixel_format_name(ALLEGRO_PIXEL_FORMAT format) { if (format >= ALLEGRO_NUM_PIXEL_FORMATS) format = ALLEGRO_NUM_PIXEL_FORMATS; return pixel_format_names[format]; } /* Color mapping functions */ /* Function: al_map_rgba */ ALLEGRO_COLOR al_map_rgba( unsigned char r, unsigned char g, unsigned char b, unsigned char a) { ALLEGRO_COLOR color; _AL_MAP_RGBA(color, r, g, b, a); return color; } /* Function: al_map_rgb */ ALLEGRO_COLOR al_map_rgb( unsigned char r, unsigned char g, unsigned char b) { return al_map_rgba(r, g, b, 255); } /* Function: al_map_rgba_f */ ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a) { ALLEGRO_COLOR color; color.r = r; color.g = g; color.b = b; color.a = a; return color; } /* Function: al_map_rgb_f */ ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b) { return al_map_rgba_f(r, g, b, 1.0f); } /* unmapping functions */ /* Function: al_unmap_rgba */ void al_unmap_rgba(ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { *r = color.r * 255.0f; *g = color.g * 255.0f; *b = color.b * 255.0f; *a = color.a * 255.0f; } /* Function: al_unmap_rgb */ void al_unmap_rgb(ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char tmp; al_unmap_rgba(color, r, g, b, &tmp); } /* Function: al_unmap_rgba_f */ void al_unmap_rgba_f(ALLEGRO_COLOR color, float *r, float *g, float *b, float *a) { *r = color.r; *g = color.g; *b = color.b; *a = color.a; } /* Function: al_unmap_rgb_f */ void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b) { float tmp; al_unmap_rgba_f(color, r, g, b, &tmp); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/gp2xwiz/0000755000175000001440000000000012157230741014611 5ustar tjadenusersallegro-5.0.10/src/gp2xwiz/wiz_joystick.c0000644000175000001440000001335511446133765017524 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GP2X Wiz joystick driver * * by Trent Gamblin. * */ #include #include #include #include #include #include #include #include #include "allegro5/allegro.h" #include "allegro5/joystick.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintwiz.h" #include "allegro5/platform/alwiz.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_gp2xwiz.h" static ALLEGRO_JOYSTICK joy; static ALLEGRO_JOYSTICK_STATE joystate; static ALLEGRO_THREAD *wiz_joystick_thread; const int POLLS_PER_SECOND = 60; #define BUTTON(x) (buttons & x) static void joywiz_fill_joystate(ALLEGRO_JOYSTICK_STATE *state) { uint32_t buttons = lc_getbuttons(); /* Left-right axis */ if (BUTTON(BTN_LEFT)) { state->stick[0].axis[0] = -1; } else if (BUTTON(BTN_RIGHT)) { state->stick[0].axis[0] = 1; } else { state->stick[0].axis[0] = 0; } /* Up-down axis */ if (BUTTON(BTN_UP)) { state->stick[0].axis[1] = -1; } else if (BUTTON(BTN_DOWN)) { state->stick[0].axis[1] = 1; } else { state->stick[0].axis[1] = 0; } /* Other buttons */ state->button[0] = BUTTON(BTN_A); state->button[1] = BUTTON(BTN_B); state->button[2] = BUTTON(BTN_X); state->button[3] = BUTTON(BTN_Y); state->button[4] = BUTTON(BTN_L); state->button[5] = BUTTON(BTN_R); state->button[6] = BUTTON(BTN_MENU); state->button[7] = BUTTON(BTN_SELECT); state->button[8] = BUTTON(BTN_VOLUP); state->button[9] = BUTTON(BTN_VOLDOWN); } static void generate_axis_event(ALLEGRO_JOYSTICK *joy, int stick, int axis, float pos) { ALLEGRO_EVENT event; if (!_al_event_source_needs_to_generate_event(&joy->es)) return; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; event.joystick.timestamp = al_get_time(); event.joystick.stick = stick; event.joystick.axis = axis; event.joystick.pos = pos; event.joystick.button = 0; _al_event_source_emit_event(&joy->es, &event); } static void generate_button_event(ALLEGRO_JOYSTICK *joy, int button, ALLEGRO_EVENT_TYPE event_type) { ALLEGRO_EVENT event; if (!_al_event_source_needs_to_generate_event(&joy->es)) return; event.joystick.type = event_type; event.joystick.timestamp = al_get_time(); event.joystick.stick = 0; event.joystick.axis = 0; event.joystick.pos = 0.0; event.joystick.button = button; _al_event_source_emit_event(&joy->es, &event); } static void *joywiz_thread_proc(ALLEGRO_THREAD *thread, void *unused) { ALLEGRO_JOYSTICK_STATE oldstate; memset(&oldstate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); (void)unused; while (!al_get_thread_should_stop(thread)) { joywiz_fill_joystate(&joystate); if (joystate.stick[0].axis[0] != oldstate.stick[0].axis[0]) { generate_axis_event(&joy, 0, 0, joystate.stick[0].axis[0]); } if (joystate.stick[0].axis[1] != oldstate.stick[0].axis[1]) { generate_axis_event(&joy, 0, 1, joystate.stick[0].axis[1]); } int i; for (i = 0; i < 10; i++) { ALLEGRO_EVENT_TYPE type; if (oldstate.button[i] == 0) type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; else type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; if (joystate.button[i] != oldstate.button[i]) { generate_button_event(&joy, i, type); } } oldstate = joystate; al_rest(1.0/POLLS_PER_SECOND); } return NULL; } static void joywiz_fill_joy(void) { joy.info.num_sticks = 1; joy.info.num_buttons = 10; joy.info.stick[0].flags = ALLEGRO_JOYFLAG_DIGITAL; joy.info.stick[0].num_axes = 2; joy.info.stick[0].name = "Wiz D-pad"; joy.info.stick[0].axis[0].name = "Left-right axis"; joy.info.stick[0].axis[1].name = "Up-down axis"; joy.info.button[0].name = "A"; joy.info.button[1].name = "B"; joy.info.button[2].name = "X"; joy.info.button[3].name = "Y"; joy.info.button[4].name = "L"; joy.info.button[5].name = "R"; joy.info.button[6].name = "Menu"; joy.info.button[7].name = "Select"; joy.info.button[8].name = "VolUp"; joy.info.button[9].name = "VolDown"; joy.num = 0; } static bool joywiz_init_joystick(void) { lc_init_joy(); joywiz_fill_joy(); _al_event_source_init(&joy.es); memset(&joystate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); wiz_joystick_thread = al_create_thread(joywiz_thread_proc, NULL); if (!wiz_joystick_thread) { return false; } al_start_thread(wiz_joystick_thread); return true; } static void joywiz_exit_joystick(void) { al_join_thread(wiz_joystick_thread, NULL); al_destroy_thread(wiz_joystick_thread); _al_event_source_free(&joy.es); } static int joywiz_get_num_joysticks(void) { return 1; } static ALLEGRO_JOYSTICK *joywiz_get_joystick(int num) { (void)num; /* Only 1 supported now */ return &joy; } static void joywiz_release_joystick(ALLEGRO_JOYSTICK *joy) { (void)joy; } static void joywiz_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) { _al_event_source_lock(&joy->es); { *ret_state = joystate; } _al_event_source_unlock(&joy->es); } /* the driver vtable */ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_gp2xwiz = { AL_JOY_TYPE_GP2XWIZ, "", "", "GP2X Wiz joystick", joywiz_init_joystick, joywiz_exit_joystick, joywiz_get_num_joysticks, joywiz_get_joystick, joywiz_release_joystick, joywiz_get_joystick_state }; allegro-5.0.10/src/gp2xwiz/wiz_display_fb.c0000644000175000001440000001160012056253610017756 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GP2X Wiz framebuffer display driver * * By Trent Gamblin. * */ #include "allegro5/internal/aintern_gp2xwiz.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_opengl.h" ALLEGRO_DEBUG_CHANNEL("display") static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_vt; static bool set_gfx_mode = false; /* Create a new X11 display, which maps directly to a GLX window. */ static ALLEGRO_DISPLAY *gp2xwiz_create_display_fb(int w, int h) { (void)w; (void)h; /* Only one display allowed at a time */ if (set_gfx_mode) return NULL; lc_init_rest(); ALLEGRO_DISPLAY_GP2XWIZ_FB *d = al_calloc(1, sizeof *d); ALLEGRO_DISPLAY *display = (void *)d; ALLEGRO_SYSTEM_GP2XWIZ *system = (void *)al_get_system_driver(); display->w = 320; display->h = 240; display->vt = _al_display_gp2xwiz_framebuffer_driver(); display->refresh_rate = 60; display->flags = al_get_new_display_flags(); display->flags |= ALLEGRO_FULLSCREEN; /* Add ourself to the list of displays. */ ALLEGRO_DISPLAY_GP2XWIZ_FB **add; add = _al_vector_alloc_back(&system->system.displays); *add = d; /* Each display is an event source. */ _al_event_source_init(&display->es); /* Create a backbuffer and point it to the framebuffer */ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); d->backbuffer = al_create_bitmap(320, 240); d->screen_mem = d->backbuffer->memory; d->backbuffer->memory = (unsigned char *)lc_fb1; set_gfx_mode = true; ALLEGRO_DEBUG("Display created successfully\n"); return display; } static void gp2xwiz_destroy_display_fb(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_GP2XWIZ *s = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_GP2XWIZ_FB *wiz_disp = (void *)d; _al_vector_find_and_delete(&s->system.displays, &d); /* All bitmaps are memory bitmaps, no need to do anything */ _al_vector_free(&d->bitmaps); _al_event_source_free(&d->es); wiz_disp->backbuffer->memory = wiz_disp->screen_mem; al_destroy_bitmap(wiz_disp->backbuffer); al_free(d->vertex_cache); al_free(d); set_gfx_mode = false; } static bool gp2xwiz_set_current_display_fb(ALLEGRO_DISPLAY *d) { (void)d; return true; } static void gp2xwiz_flip_display_fb(ALLEGRO_DISPLAY *d) { (void)d; } static void gp2xwiz_update_display_region_fb(ALLEGRO_DISPLAY *d, int x, int y, int w, int h) { (void)x; (void)y; (void)w; (void)h; gp2xwiz_flip_display_fb(d); } static bool gp2xwiz_acknowledge_resize_fb(ALLEGRO_DISPLAY *d) { (void)d; return false; } static bool gp2xwiz_resize_display_fb(ALLEGRO_DISPLAY *d, int w, int h) { (void)d; (void)w; (void)h; return false; } static bool gp2xwiz_is_compatible_bitmap_fb(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { (void)display; (void)bitmap; return true; } static void gp2xwiz_get_window_position_fb(ALLEGRO_DISPLAY *display, int *x, int *y) { (void)display; *x = 0; *y = 0; } static bool gp2xwiz_wait_for_vsync_fb(ALLEGRO_DISPLAY *display) { (void)display; return false; } static ALLEGRO_BITMAP *gp2xwiz_get_backbuffer_fb(ALLEGRO_DISPLAY *display) { ALLEGRO_DISPLAY_GP2XWIZ_FB *d = (void *)display; return d->backbuffer; } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_framebuffer_driver(void) { if (gp2xwiz_vt) return gp2xwiz_vt; gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); gp2xwiz_vt->create_display = gp2xwiz_create_display_fb; gp2xwiz_vt->destroy_display = gp2xwiz_destroy_display_fb; gp2xwiz_vt->set_current_display = gp2xwiz_set_current_display_fb; gp2xwiz_vt->flip_display = gp2xwiz_flip_display_fb; gp2xwiz_vt->update_display_region = gp2xwiz_update_display_region_fb; gp2xwiz_vt->acknowledge_resize = gp2xwiz_acknowledge_resize_fb; gp2xwiz_vt->create_bitmap = NULL; gp2xwiz_vt->create_sub_bitmap = NULL; gp2xwiz_vt->get_backbuffer = gp2xwiz_get_backbuffer_fb; gp2xwiz_vt->set_target_bitmap = NULL; gp2xwiz_vt->is_compatible_bitmap = gp2xwiz_is_compatible_bitmap_fb; gp2xwiz_vt->resize_display = gp2xwiz_resize_display_fb; gp2xwiz_vt->set_icons = NULL; gp2xwiz_vt->set_window_title = NULL; gp2xwiz_vt->set_window_position = NULL; gp2xwiz_vt->get_window_position = gp2xwiz_get_window_position_fb; gp2xwiz_vt->set_display_flag = NULL; gp2xwiz_vt->wait_for_vsync = gp2xwiz_wait_for_vsync_fb; return gp2xwiz_vt; } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/src/gp2xwiz/wiz_system.c0000644000175000001440000001041711621646427017204 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GP2X Wiz system driver * * By Trent Gamblin. * */ #include #include "allegro5/allegro.h" #include "allegro5/platform/aintunix.h" #include "allegro5/internal/aintern_gp2xwiz.h" #include "allegro5/platform/aintwiz.h" static ALLEGRO_SYSTEM_INTERFACE *gp2xwiz_vt; static ALLEGRO_SYSTEM *gp2xwiz_initialize(int flags) { ALLEGRO_SYSTEM_GP2XWIZ *s; (void)flags; _al_unix_init_time(); s = al_calloc(1, sizeof *s); _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY *)); s->system.vt = gp2xwiz_vt; return &s->system; } static void gp2xwiz_shutdown_system(void) { /* Close all open displays. */ ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_GP2XWIZ *sx = (void *)s; while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); al_free(sx); lc_exit(); } static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_get_display_driver(void) { if (al_get_new_display_flags() & ALLEGRO_OPENGL) return _al_display_gp2xwiz_opengl_driver(); else return _al_display_gp2xwiz_framebuffer_driver(); } static ALLEGRO_KEYBOARD_DRIVER *gp2xwiz_get_keyboard_driver(void) { //return _al_gp2xwiz_keyboard_driver; return NULL; } static ALLEGRO_MOUSE_DRIVER *gp2xwiz_get_mouse_driver(void) { //return _al_gp2xwiz_mouse_driver; return NULL; } static ALLEGRO_JOYSTICK_DRIVER *gp2xwiz_get_joystick_driver(void) { return _al_joystick_driver_list[0].driver; } static int gp2xwiz_get_num_video_adapters(void) { return 1; } static bool gp2xwiz_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { (void)adapter; info->x1 = 0; info->y1 = 0; info->x2 = 320; info->y2 = 240; return true; } // FIXME static bool gp2xwiz_get_cursor_position(int *ret_x, int *ret_y) { *ret_x = 0; *ret_y = 0; return true; } static bool gp2xwiz_inhibit_screensaver(bool inhibit) { (void)inhibit; return false; } static int gp2xwiz_get_num_display_modes(void) { return 1; } static ALLEGRO_DISPLAY_MODE *gp2xwiz_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) { (void)index; ASSERT(index == 0); mode->width = 320; mode->height = 240; mode->format = ALLEGRO_PIXEL_FORMAT_RGB_565; mode->refresh_rate = 60; return mode; } /* Internal function to get a reference to this driver. */ ALLEGRO_SYSTEM_INTERFACE *_al_system_gp2xwiz_driver(void) { if (gp2xwiz_vt) return gp2xwiz_vt; gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); gp2xwiz_vt->initialize = gp2xwiz_initialize; gp2xwiz_vt->get_display_driver = gp2xwiz_get_display_driver; gp2xwiz_vt->get_keyboard_driver = gp2xwiz_get_keyboard_driver; gp2xwiz_vt->get_mouse_driver = gp2xwiz_get_mouse_driver; gp2xwiz_vt->get_joystick_driver = gp2xwiz_get_joystick_driver; gp2xwiz_vt->get_num_display_modes = gp2xwiz_get_num_display_modes; gp2xwiz_vt->get_display_mode = gp2xwiz_get_display_mode; gp2xwiz_vt->shutdown_system = gp2xwiz_shutdown_system; gp2xwiz_vt->get_num_video_adapters = gp2xwiz_get_num_video_adapters; gp2xwiz_vt->get_monitor_info = gp2xwiz_get_monitor_info; gp2xwiz_vt->get_cursor_position = gp2xwiz_get_cursor_position; gp2xwiz_vt->get_path = _al_unix_get_path; gp2xwiz_vt->inhibit_screensaver = gp2xwiz_inhibit_screensaver; gp2xwiz_vt->get_num_display_formats = gp2xwiz_get_num_display_formats; return gp2xwiz_vt; } /* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_gp2xwiz_driver(); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/gp2xwiz/wiz_display_opengl.c0000644000175000001440000001572312056253610020665 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * GP2X Wiz OpenGL display driver * * By Trent Gamblin. * */ #include "allegro5/internal/aintern_gp2xwiz.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_opengl.h" ALLEGRO_DEBUG_CHANNEL("display") static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_vt; static bool set_gfx_mode = false; /* Helper to set up GL state as we want it. */ static void setup_gl(ALLEGRO_DISPLAY *d) { ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; glViewport(0, 0, d->w, d->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, d->w, d->h, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ogl->backbuffer) ogl->backbuffer = _al_ogl_create_backbuffer(d); } /* Create a new X11 display, which maps directly to a GLX window. */ static ALLEGRO_DISPLAY *gp2xwiz_create_display_ogl(int w, int h) { (void)w; (void)h; /* Only one display allowed at a time */ if (set_gfx_mode) return NULL; ALLEGRO_DISPLAY_GP2XWIZ_OGL *d = al_calloc(1, sizeof *d); ALLEGRO_DISPLAY *display = (void*)d; ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); EGLint numConfigs; display->ogl_extras = ogl; ALLEGRO_SYSTEM_GP2XWIZ *system = (void *)al_get_system_driver(); display->w = 320; display->h = 240; display->vt = _al_display_gp2xwiz_opengl_driver(); display->refresh_rate = 60; display->flags = al_get_new_display_flags(); // FIXME: default? Is this the right place to set this? display->flags |= ALLEGRO_OPENGL; display->flags |= ALLEGRO_FULLSCREEN; /* Add ourself to the list of displays. */ ALLEGRO_DISPLAY_GP2XWIZ_OGL **add; add = _al_vector_alloc_back(&system->system.displays); *add = d; /* Each display is an event source. */ _al_event_source_init(&display->es); EGLint attrib_list[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint majorVersion, minorVersion; nanoGL_Init(); d->hNativeWnd = OS_CreateWindow(); d->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(d->egl_display, &majorVersion, &minorVersion); ALLEGRO_DEBUG("EGL Version: %d.%d", majorVersion, minorVersion); eglChooseConfig(d->egl_display, attrib_list, &d->egl_config, 1, &numConfigs); d->egl_surface = eglCreateWindowSurface(d->egl_display, d->egl_config, d->hNativeWnd, NULL); d->egl_context = eglCreateContext(d->egl_display, d->egl_config, EGL_NO_CONTEXT, NULL); eglMakeCurrent(d->egl_display, d->egl_surface, d->egl_surface, d->egl_context); //eglSwapInterval(d->egl_display, EGL_MAX_SWAP_INTERVAL); ALLEGRO_DEBUG("GP2X Wiz window created.\n"); // FIXME: ALLEGRO_DEBUG("Calling _al_ogl_manage_extensions\n"); _al_ogl_manage_extensions(display); ALLEGRO_DEBUG("Calling _al_ogl_set_extensions\n"); _al_ogl_set_extensions(ogl->extension_api); // FIXME // We don't have this extra_settings stuff set up right //if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) setup_gl(display); set_gfx_mode = true; ALLEGRO_DEBUG("Display created successfully\n"); return display; } static void gp2xwiz_destroy_display_ogl(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_GP2XWIZ *s = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (void *)d; while (d->bitmaps._size > 0) { ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); ALLEGRO_BITMAP *b = *bptr; _al_convert_to_memory_bitmap(b); } _al_ogl_unmanage_extensions(d); _al_vector_find_and_delete(&s->system.displays, &d); eglMakeCurrent(wiz_disp->egl_display, 0, 0, wiz_disp->egl_context); eglDestroySurface(wiz_disp->egl_display, wiz_disp->egl_surface); eglDestroyContext(wiz_disp->egl_display, wiz_disp->egl_context); eglTerminate(wiz_disp->egl_display); al_free(wiz_disp->hNativeWnd); nanoGL_Destroy(); _al_vector_free(&d->bitmaps); _al_event_source_free(&d->es); al_free(d->ogl_extras); al_free(d->vertex_cache); al_free(d); set_gfx_mode = false; } static bool gp2xwiz_set_current_display_ogl(ALLEGRO_DISPLAY *d) { (void)d; return true; } static void gp2xwiz_flip_display_ogl(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (ALLEGRO_DISPLAY_GP2XWIZ_OGL *)d; eglSwapBuffers(wiz_disp->egl_display, wiz_disp->egl_surface); } static void gp2xwiz_update_display_region_ogl(ALLEGRO_DISPLAY *d, int x, int y, int w, int h) { (void)x; (void)y; (void)w; (void)h; gp2xwiz_flip_display_ogl(d); } static bool gp2xwiz_acknowledge_resize_ogl(ALLEGRO_DISPLAY *d) { (void)d; return false; } static bool gp2xwiz_resize_display_ogl(ALLEGRO_DISPLAY *d, int w, int h) { (void)d; (void)w; (void)h; return false; } static bool gp2xwiz_is_compatible_bitmap_ogl(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { (void)display; (void)bitmap; return true; } static void gp2xwiz_get_window_position_ogl(ALLEGRO_DISPLAY *display, int *x, int *y) { (void)display; *x = 0; *y = 0; } static bool gp2xwiz_wait_for_vsync_ogl(ALLEGRO_DISPLAY *display) { (void)display; return false; } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_opengl_driver(void) { if (gp2xwiz_vt) return gp2xwiz_vt; gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); gp2xwiz_vt->create_display = gp2xwiz_create_display_ogl; gp2xwiz_vt->destroy_display = gp2xwiz_destroy_display_ogl; gp2xwiz_vt->set_current_display = gp2xwiz_set_current_display_ogl; gp2xwiz_vt->flip_display = gp2xwiz_flip_display_ogl; gp2xwiz_vt->update_display_region = gp2xwiz_update_display_region_ogl; gp2xwiz_vt->acknowledge_resize = gp2xwiz_acknowledge_resize_ogl; gp2xwiz_vt->create_bitmap = _al_ogl_create_bitmap; gp2xwiz_vt->create_sub_bitmap = _al_ogl_create_sub_bitmap; gp2xwiz_vt->get_backbuffer = _al_ogl_get_backbuffer; gp2xwiz_vt->set_target_bitmap = _al_ogl_set_target_bitmap; gp2xwiz_vt->is_compatible_bitmap = gp2xwiz_is_compatible_bitmap_ogl; gp2xwiz_vt->resize_display = gp2xwiz_resize_display_ogl; gp2xwiz_vt->set_icons = NULL; gp2xwiz_vt->set_window_title = NULL; gp2xwiz_vt->set_window_position = NULL; gp2xwiz_vt->get_window_position = gp2xwiz_get_window_position_ogl; gp2xwiz_vt->set_display_flag = NULL; gp2xwiz_vt->wait_for_vsync = gp2xwiz_wait_for_vsync_ogl; _al_ogl_add_drawing_functions(gp2xwiz_vt); return gp2xwiz_vt; } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/src/fullscreen_mode.c0000644000175000001440000000211212057113157016505 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Fullscreen mode queries. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_system.h" /* Function: al_get_num_display_modes */ int al_get_num_display_modes(void) { ALLEGRO_SYSTEM *system = al_get_system_driver(); return system->vt->get_num_display_modes(); } /* Function: al_get_display_mode */ ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) { ALLEGRO_SYSTEM *system = al_get_system_driver(); return system->vt->get_display_mode(index, mode); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/allegro.c0000644000175000001440000000206312132126261014763 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Assorted routines. * * By Shawn Hargreaves and Allegro developers. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/platform/alplatf.h" /* Function: al_get_allegro_version */ uint32_t al_get_allegro_version(void) { return ALLEGRO_VERSION_INT; } /* Function: al_run_main */ int al_run_main(int argc, char **argv, int (*user_main)(int, char **)) { #ifdef ALLEGRO_MACOSX return _al_osx_run_main(argc, argv, user_main); #else return user_main(argc, argv); #endif } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/debug.c0000644000175000001440000001743212125161267014441 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Logging and assertion handlers. * * See LICENSE.txt for copyright information. */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern_debug.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_vector.h" /* tracing */ typedef struct TRACE_INFO { bool trace_virgin; FILE *trace_file; _AL_MUTEX trace_mutex; /* 0: debug, 1: info, 2: warn, 3: error */ int level; /* 1: line number, 2: function name, 4: timestamp */ int flags; /* List of channels to log. NULL to log all channels. */ _AL_VECTOR channels; _AL_VECTOR excluded; /* Whether settings have been read from allegro5.cfg or not. */ bool configured; } TRACE_INFO; static TRACE_INFO trace_info = { true, NULL, _AL_MUTEX_UNINITED, 0, 7, _AL_VECTOR_INITIALIZER(ALLEGRO_USTR *), _AL_VECTOR_INITIALIZER(ALLEGRO_USTR *), false }; /* run-time assertions */ void (*_al_user_assert_handler)(char const *expr, char const *file, int line, char const *func); static void delete_string_list(_AL_VECTOR *v) { while (_al_vector_is_nonempty(v)) { int i = _al_vector_size(v) - 1; ALLEGRO_USTR **iter = _al_vector_ref(v, i); al_ustr_free(*iter); _al_vector_delete_at(v, i); } _al_vector_free(v); } static void configure_logging(void) { ALLEGRO_CONFIG *config; char const *v; bool got_all = false; /* Messages logged before the system driver and allegro5.cfg are * up will always use defaults - but usually nothing is logged * before al_init. */ config = al_get_system_config(); if (!config) return; v = al_get_config_value(config, "trace", "channels"); if (v) { ALLEGRO_USTR_INFO uinfo; const ALLEGRO_USTR *u = al_ref_cstr(&uinfo, v); int pos = 0; while (pos >= 0) { int comma = al_ustr_find_chr(u, pos, ','); int first; ALLEGRO_USTR *u2, **iter; if (comma == -1) u2 = al_ustr_dup_substr(u, pos, al_ustr_length(u)); else u2 = al_ustr_dup_substr(u, pos, comma); al_ustr_trim_ws(u2); first = al_ustr_get(u2, 0); if (first == '-') { al_ustr_remove_chr(u2, 0); iter = _al_vector_alloc_back(&trace_info.excluded); *iter = u2; } else { if (first == '+') al_ustr_remove_chr(u2, 0); iter = _al_vector_alloc_back(&trace_info.channels); *iter = u2; if (!strcmp(al_cstr(u2), "all")) got_all = true; } pos = comma; al_ustr_get_next(u, &pos); } if (got_all) delete_string_list(&trace_info.channels); } v = al_get_config_value(config, "trace", "level"); if (v) { if (!strcmp(v, "error")) trace_info.level = 3; else if (!strcmp(v, "warn")) trace_info.level = 2; else if (!strcmp(v, "info")) trace_info.level = 1; } v = al_get_config_value(config, "trace", "timestamps"); if (!v || strcmp(v, "0")) trace_info.flags |= 4; else trace_info.flags &= ~4; v = al_get_config_value(config, "trace", "functions"); if (!v || strcmp(v, "0")) trace_info.flags |= 2; else trace_info.flags &= ~2; v = al_get_config_value(config, "trace", "lines"); if (!v || strcmp(v, "0")) trace_info.flags |= 1; else trace_info.flags &= ~1; _al_mutex_init(&trace_info.trace_mutex); trace_info.configured = true; } static void open_trace_file(void) { const char *s; if (trace_info.trace_virgin) { s = getenv("ALLEGRO_TRACE"); if (s) trace_info.trace_file = fopen(s, "w"); else #ifdef ALLEGRO_IPHONE // Remember, we have no (accessible) filesystem on (not jailbroken) // iphone. // stderr will be redirected to xcode's debug console though, so // it's as good to use as the NSLog stuff. trace_info.trace_file = stderr; #else trace_info.trace_file = fopen("allegro.log", "w"); #endif trace_info.trace_virgin = false; } } static void do_trace(const char *msg, ...) { va_list ap; if (trace_info.trace_file) { va_start(ap, msg); vfprintf(trace_info.trace_file, msg, ap); va_end(ap); } } /* _al_trace_prefix: * Conditionally write the initial part of a trace message. If we do, return true * and continue to hold the trace_mutex lock. */ bool _al_trace_prefix(char const *channel, int level, char const *file, int line, char const *function) { size_t i; char *name; _AL_VECTOR const *v; /* XXX logging should be reconfigured if the system driver is reinstalled */ if (!trace_info.configured) { configure_logging(); } if (level < trace_info.level) return false; v = &trace_info.channels; if (_al_vector_is_empty(v)) goto channel_included; for (i = 0; i < _al_vector_size(v); i++) { ALLEGRO_USTR **iter = _al_vector_ref(v, i); if (!strcmp(al_cstr(*iter), channel)) goto channel_included; } return false; channel_included: v = &trace_info.excluded; if (_al_vector_is_nonempty(v)) { for (i = 0; i < _al_vector_size(v); i++) { ALLEGRO_USTR **iter = _al_vector_ref(v, i); if (!strcmp(al_cstr(*iter), channel)) return false; } } /* Avoid interleaved output from different threads. */ _al_mutex_lock(&trace_info.trace_mutex); open_trace_file(); do_trace("%-8s ", channel); if (level == 0) do_trace("D "); if (level == 1) do_trace("I "); if (level == 2) do_trace("W "); if (level == 3) do_trace("E "); #ifdef ALLEGRO_MSVC name = strrchr(file, '\\'); #else name = strrchr(file, '/'); #endif if (trace_info.flags & 1) { do_trace("%20s:%-4d ", name ? name + 1 : file, line); } if (trace_info.flags & 2) { do_trace("%-32s ", function); } if (trace_info.flags & 4) { double t = al_get_time(); /* Kludge: * Very high timers (more than a year?) likely mean the timer * subsystem isn't initialized yet, so print 0. */ if (t > 3600 * 24 * 365) t = 0; do_trace("[%10.5f] ", t); } /* Do not unlocked trace_mutex here; that is done by _al_trace_suffix. */ return true; } /* _al_trace_suffix: * Output the final part of a trace message, and release the trace_mutex lock. */ void _al_trace_suffix(const char *msg, ...) { int olderr = errno; va_list ap; if (trace_info.trace_file) { va_start(ap, msg); vfprintf(trace_info.trace_file, msg, ap); va_end(ap); fflush(trace_info.trace_file); } _al_mutex_unlock(&trace_info.trace_mutex); errno = olderr; } void _al_shutdown_logging(void) { if (trace_info.configured) { _al_mutex_destroy(&trace_info.trace_mutex); delete_string_list(&trace_info.channels); delete_string_list(&trace_info.excluded); trace_info.configured = false; } if (trace_info.trace_file && trace_info.trace_file != stderr) { fclose(trace_info.trace_file); } trace_info.trace_file = NULL; trace_info.trace_virgin = true; } /* Function: al_register_assert_handler */ void al_register_assert_handler(void (*handler)(char const *expr, char const *file, int line, char const *func)) { _al_user_assert_handler = handler; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/mousenu.c0000644000175000001440000001372212125160224015034 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New mouse API. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Mouse routines */ #define ALLEGRO_NO_COMPATIBILITY #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/internal/aintern_system.h" /* the active keyboard driver */ static ALLEGRO_MOUSE_DRIVER *new_mouse_driver = NULL; /* Function: al_is_mouse_installed */ bool al_is_mouse_installed(void) { return (new_mouse_driver ? true : false); } /* Function: al_install_mouse */ bool al_install_mouse(void) { if (new_mouse_driver) return true; //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now if (al_get_system_driver()->vt->get_mouse_driver) { new_mouse_driver = al_get_system_driver()->vt->get_mouse_driver(); if (!new_mouse_driver->init_mouse()) { new_mouse_driver = NULL; return false; } _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); return true; } return false; #if 0 if (system_driver && system_driver->mouse_drivers) driver_list = system_driver->mouse_drivers(); else driver_list = _al_mouse_driver_list; ASSERT(driver_list); for (i=0; driver_list[i].driver; i++) { new_mouse_driver = driver_list[i].driver; //name = get_config_text(new_mouse_driver->msedrv_ascii_name); name = new_mouse_driver->msedrv_ascii_name; new_mouse_driver->msedrv_name = name; new_mouse_driver->msedrv_desc = name; if (new_mouse_driver->init_mouse()) { break; } } if (!driver_list[i].driver) { new_mouse_driver = NULL; return false; } _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); return true; #endif } /* Function: al_uninstall_mouse */ void al_uninstall_mouse(void) { if (!new_mouse_driver) return; new_mouse_driver->exit_mouse(); new_mouse_driver = NULL; } /* This was in the public API but its only purpose is now served by * al_get_mouse_event_source(). */ static ALLEGRO_MOUSE *al_get_mouse(void) { ALLEGRO_MOUSE *mse; ASSERT(new_mouse_driver); mse = new_mouse_driver->get_mouse(); ASSERT(mse); return mse; } /* Function: al_get_mouse_num_buttons */ unsigned int al_get_mouse_num_buttons(void) { ASSERT(new_mouse_driver); return new_mouse_driver->get_mouse_num_buttons(); } /* Function: al_get_mouse_num_axes */ unsigned int al_get_mouse_num_axes(void) { ASSERT(new_mouse_driver); return new_mouse_driver->get_mouse_num_axes(); } /* Function: al_set_mouse_xy */ bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) { ASSERT(new_mouse_driver); ASSERT(new_mouse_driver->set_mouse_xy); return new_mouse_driver->set_mouse_xy(display, x, y); } /* Function: al_set_mouse_z */ bool al_set_mouse_z(int z) { ASSERT(new_mouse_driver); ASSERT(new_mouse_driver->set_mouse_axis); return new_mouse_driver->set_mouse_axis(2, z); } /* Function: al_set_mouse_w */ bool al_set_mouse_w(int w) { ASSERT(new_mouse_driver); ASSERT(new_mouse_driver->set_mouse_axis); return new_mouse_driver->set_mouse_axis(3, w); } /* Function: al_set_mouse_axis */ bool al_set_mouse_axis(int which, int value) { ASSERT(new_mouse_driver); ASSERT(new_mouse_driver->set_mouse_axis); ASSERT(which >= 2); ASSERT(which < 4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES); if (which >= 2 && which < 4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES) return new_mouse_driver->set_mouse_axis(which, value); else return false; } /* Function: al_get_mouse_state */ void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) { ASSERT(new_mouse_driver); ASSERT(ret_state); new_mouse_driver->get_mouse_state(ret_state); } /* Function: al_get_mouse_state_axis */ int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis) { ASSERT(state); ASSERT(axis >= 0); ASSERT(axis < (4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES)); switch (axis) { case 0: return state->x; case 1: return state->y; case 2: return state->z; case 3: return state->w; default: return state->more_axes[axis - 4]; } } /* Function: al_mouse_button_down */ bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button) { ASSERT(state); ASSERT(button > 0); return (state->buttons & (1 << (button-1))); } /* Function: al_get_mouse_cursor_position */ bool al_get_mouse_cursor_position(int *ret_x, int *ret_y) { ALLEGRO_SYSTEM *alsys = al_get_system_driver(); ASSERT(ret_x); ASSERT(ret_y); if (alsys->vt->get_cursor_position) { return alsys->vt->get_cursor_position(ret_x, ret_y); } else { *ret_x = 0; *ret_y = 0; return false; } } /* Function: al_grab_mouse */ bool al_grab_mouse(ALLEGRO_DISPLAY *display) { ALLEGRO_SYSTEM *alsys = al_get_system_driver(); if (alsys->vt->grab_mouse) return alsys->vt->grab_mouse(display); return false; } /* Function: al_ungrab_mouse */ bool al_ungrab_mouse(void) { ALLEGRO_SYSTEM *alsys = al_get_system_driver(); if (alsys->vt->ungrab_mouse) return alsys->vt->ungrab_mouse(); return false; } /* Function: al_get_mouse_event_source */ ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void) { ALLEGRO_MOUSE *mouse = al_get_mouse(); return (mouse) ? &mouse->es : NULL; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/config.c0000644000175000001440000003406311771526542014626 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration routines. * * By Trent Gamblin. */ /* Title: Configuration routines */ #include #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_aatree.h" #include "allegro5/internal/aintern_config.h" static int cmp_ustr(void const *a, void const *b) { return al_ustr_compare(a, b); } /* Function: al_create_config */ ALLEGRO_CONFIG *al_create_config(void) { ALLEGRO_CONFIG *config = al_calloc(1, sizeof(ALLEGRO_CONFIG)); ASSERT(config); return config; } static ALLEGRO_CONFIG_SECTION *find_section(const ALLEGRO_CONFIG *config, const ALLEGRO_USTR *section) { return _al_aa_search(config->tree, section, cmp_ustr); } static ALLEGRO_CONFIG_ENTRY *find_entry(const ALLEGRO_CONFIG_SECTION *section, const ALLEGRO_USTR *key) { return _al_aa_search(section->tree, key, cmp_ustr); } static void get_key_and_value(const ALLEGRO_USTR *buf, ALLEGRO_USTR *key, ALLEGRO_USTR *value) { int eq = al_ustr_find_chr(buf, 0, '='); if (eq == -1) { al_ustr_assign(key, buf); al_ustr_assign_cstr(value, ""); } else { al_ustr_assign_substr(key, buf, 0, eq); al_ustr_assign_substr(value, buf, eq + 1, al_ustr_size(buf)); } al_ustr_trim_ws(key); al_ustr_trim_ws(value); } static ALLEGRO_CONFIG_SECTION *config_add_section(ALLEGRO_CONFIG *config, const ALLEGRO_USTR *name) { ALLEGRO_CONFIG_SECTION *sec = config->head; ALLEGRO_CONFIG_SECTION *section; if ((section = find_section(config, name))) return section; section = al_calloc(1, sizeof(ALLEGRO_CONFIG_SECTION)); section->name = al_ustr_dup(name); if (sec == NULL) { config->head = section; config->last = section; } else { ASSERT(config->last->next == NULL); config->last->next = section; config->last = section; } config->tree = _al_aa_insert(config->tree, section->name, section, cmp_ustr); return section; } /* Function: al_add_config_section */ void al_add_config_section(ALLEGRO_CONFIG *config, const char *name) { ALLEGRO_USTR_INFO name_info; const ALLEGRO_USTR *uname; uname = al_ref_cstr(&name_info, name); config_add_section(config, uname); } static void config_set_value(ALLEGRO_CONFIG *config, const ALLEGRO_USTR *section, const ALLEGRO_USTR *key, const ALLEGRO_USTR *value) { ALLEGRO_CONFIG_SECTION *s; ALLEGRO_CONFIG_ENTRY *entry; s = find_section(config, section); if (s) { entry = find_entry(s, key); if (entry) { al_ustr_assign(entry->value, value); al_ustr_trim_ws(entry->value); return; } } entry = al_calloc(1, sizeof(ALLEGRO_CONFIG_ENTRY)); entry->is_comment = false; entry->key = al_ustr_dup(key); entry->value = al_ustr_dup(value); al_ustr_trim_ws(entry->value); if (!s) { s = config_add_section(config, section); } if (s->head == NULL) { s->head = entry; s->last = entry; } else { ASSERT(s->last->next == NULL); s->last->next = entry; s->last = entry; } s->tree = _al_aa_insert(s->tree, entry->key, entry, cmp_ustr); } /* Function: al_set_config_value */ void al_set_config_value(ALLEGRO_CONFIG *config, const char *section, const char *key, const char *value) { ALLEGRO_USTR_INFO section_info; ALLEGRO_USTR_INFO key_info; ALLEGRO_USTR_INFO value_info; const ALLEGRO_USTR *usection; const ALLEGRO_USTR *ukey; const ALLEGRO_USTR *uvalue; if (section == NULL) { section = ""; } ASSERT(key); ASSERT(value); usection = al_ref_cstr(§ion_info, section); ukey = al_ref_cstr(&key_info, key); uvalue = al_ref_cstr(&value_info, value); config_set_value(config, usection, ukey, uvalue); } static void config_add_comment(ALLEGRO_CONFIG *config, const ALLEGRO_USTR *section, const ALLEGRO_USTR *comment) { ALLEGRO_CONFIG_SECTION *s; ALLEGRO_CONFIG_ENTRY *entry; s = find_section(config, section); entry = al_calloc(1, sizeof(ALLEGRO_CONFIG_ENTRY)); entry->is_comment = true; entry->key = al_ustr_dup(comment); /* Replace all newline characters by spaces, otherwise the written comment * file will be corrupted. */ al_ustr_find_replace_cstr(entry->key, 0, "\n", " "); if (!s) { s = config_add_section(config, section); } if (s->head == NULL) { s->head = entry; s->last = entry; } else { ASSERT(s->last->next == NULL); s->last->next = entry; s->last = entry; } } /* Function: al_add_config_comment */ void al_add_config_comment(ALLEGRO_CONFIG *config, const char *section, const char *comment) { ALLEGRO_USTR_INFO section_info; ALLEGRO_USTR_INFO comment_info; const ALLEGRO_USTR *usection; const ALLEGRO_USTR *ucomment; if (section == NULL) { section = ""; } ASSERT(comment); usection = al_ref_cstr(§ion_info, section); ucomment = al_ref_cstr(&comment_info, comment); config_add_comment(config, usection, ucomment); } static bool config_get_value(const ALLEGRO_CONFIG *config, const ALLEGRO_USTR *section, const ALLEGRO_USTR *key, const ALLEGRO_USTR **ret_value) { ALLEGRO_CONFIG_SECTION *s; ALLEGRO_CONFIG_ENTRY *e; s = find_section(config, section); if (!s) return false; e = find_entry(s, key); if (!e) return false; *ret_value = e->value; return true; } /* Function: al_get_config_value */ const char *al_get_config_value(const ALLEGRO_CONFIG *config, const char *section, const char *key) { ALLEGRO_USTR_INFO section_info; ALLEGRO_USTR_INFO key_info; const ALLEGRO_USTR *usection; const ALLEGRO_USTR *ukey; const ALLEGRO_USTR *value; if (section == NULL) { section = ""; } usection = al_ref_cstr(§ion_info, section); ukey = al_ref_cstr(&key_info, key); if (config_get_value(config, usection, ukey, &value)) return al_cstr(value); else return NULL; } static bool readline(ALLEGRO_FILE *file, ALLEGRO_USTR *line) { char buf[128]; if (!al_fgets(file, buf, sizeof(buf))) { return false; } do { al_ustr_append_cstr(line, buf); if (al_ustr_has_suffix_cstr(line, "\n")) break; } while (al_fgets(file, buf, sizeof(buf))); return true; } /* Function: al_load_config_file */ ALLEGRO_CONFIG *al_load_config_file(const char *filename) { ALLEGRO_FILE *file; ALLEGRO_CONFIG *cfg = NULL; file = al_fopen(filename, "r"); if (file) { cfg = al_load_config_file_f(file); al_fclose(file); } return cfg; } /* Function: al_load_config_file_f */ ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file) { ALLEGRO_CONFIG *config; ALLEGRO_CONFIG_SECTION *current_section = NULL; ALLEGRO_USTR *line; ALLEGRO_USTR *section; ALLEGRO_USTR *key; ALLEGRO_USTR *value; ASSERT(file); config = al_create_config(); if (!config) { return NULL; } line = al_ustr_new(""); section = al_ustr_new(""); key = al_ustr_new(""); value = al_ustr_new(""); while (1) { al_ustr_assign_cstr(line, ""); if (!readline(file, line)) break; al_ustr_trim_ws(line); if (al_ustr_has_prefix_cstr(line, "#") || al_ustr_size(line) == 0) { /* Preserve comments and blank lines */ const ALLEGRO_USTR *name; if (current_section) name = current_section->name; else name = al_ustr_empty_string(); config_add_comment(config, name, line); } else if (al_ustr_has_prefix_cstr(line, "[")) { int rbracket = al_ustr_rfind_chr(line, al_ustr_size(line), ']'); if (rbracket == -1) rbracket = al_ustr_size(line); al_ustr_assign_substr(section, line, 1, rbracket); current_section = config_add_section(config, section); } else { get_key_and_value(line, key, value); if (current_section == NULL) config_set_value(config, al_ustr_empty_string(), key, value); else config_set_value(config, current_section->name, key, value); } } al_ustr_free(line); al_ustr_free(section); al_ustr_free(key); al_ustr_free(value); return config; } static bool config_write_section(ALLEGRO_FILE *file, const ALLEGRO_CONFIG_SECTION *s, bool *should_blank) { ALLEGRO_CONFIG_ENTRY *e; if (al_ustr_size(s->name) > 0) { al_fputc(file, '['); al_fputs(file, al_cstr(s->name)); al_fputs(file, "]\n"); *should_blank = false; if (al_ferror(file)) { return false; } } e = s->head; while (e != NULL) { if (e->is_comment) { if (al_ustr_size(e->key) > 0) { if (!al_ustr_has_prefix_cstr(e->key, "#")) { al_fputs(file, "# "); } al_fputs(file, al_cstr(e->key)); } al_fputc(file, '\n'); *should_blank = false; } else { al_fputs(file, al_cstr(e->key)); al_fputc(file, '='); al_fputs(file, al_cstr(e->value)); al_fputc(file, '\n'); *should_blank = true; } if (al_ferror(file)) { return false; } e = e->next; } return true; } /* Function: al_save_config_file */ bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config) { ALLEGRO_FILE *file; bool ret = false; file = al_fopen(filename, "w"); if (file) { ret = al_save_config_file_f(file, config); /* XXX do we delete the incomplete file on error? I suppose not. */ al_fclose(file); } return ret; } /* Function: al_save_config_file_f */ bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config) { ALLEGRO_CONFIG_SECTION *s; bool should_blank = false; /* Save global section */ s = config->head; while (s != NULL) { if (al_ustr_size(s->name) == 0) { if (!config_write_section(file, s, &should_blank)) { return false; } break; } s = s->next; } /* Save other sections */ s = config->head; while (s != NULL) { if (al_ustr_size(s->name) > 0) { if (should_blank) { al_fputs(file, "\n"); } if (!config_write_section(file, s, &should_blank)) { return false; } } s = s->next; } return true; } /* do_config_merge_into: * Helper function for merging. */ static void do_config_merge_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add, bool merge_comments) { ALLEGRO_CONFIG_SECTION *s; ALLEGRO_CONFIG_ENTRY *e; ASSERT(master); if (!add) { return; } /* Save each section */ s = add->head; while (s != NULL) { config_add_section(master, s->name); e = s->head; while (e != NULL) { if (!e->is_comment) { config_set_value(master, s->name, e->key, e->value); } else if (merge_comments) { config_add_comment(master, s->name, e->key); } e = e->next; } s = s->next; } } /* Function: al_merge_config_into */ void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add) { do_config_merge_into(master, add, false); } /* Function: al_merge_config */ ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1, const ALLEGRO_CONFIG *cfg2) { ALLEGRO_CONFIG *config = al_create_config(); do_config_merge_into(config, cfg1, true); do_config_merge_into(config, cfg2, false); return config; } /* Function: al_destroy_config */ void al_destroy_config(ALLEGRO_CONFIG *config) { ALLEGRO_CONFIG_ENTRY *e; ALLEGRO_CONFIG_SECTION *s; if (!config) { return; } s = config->head; while (s) { ALLEGRO_CONFIG_SECTION *tmp = s->next; e = s->head; while (e) { ALLEGRO_CONFIG_ENTRY *tmp = e->next; al_ustr_free(e->key); al_ustr_free(e->value); al_free(e); e = tmp; } al_ustr_free(s->name); _al_aa_free(s->tree); al_free(s); s = tmp; } _al_aa_free(config->tree); al_free(config); } /* Function: al_get_first_config_section */ char const *al_get_first_config_section(ALLEGRO_CONFIG const *config, ALLEGRO_CONFIG_SECTION **iterator) { ALLEGRO_CONFIG_SECTION *s; if (!config) return NULL; s = config->head; if (iterator) *iterator = s; return s ? al_cstr(s->name) : NULL; } /* Function: al_get_next_config_section */ char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator) { ALLEGRO_CONFIG_SECTION *s; if (!iterator) return NULL; s = *iterator; if (s) s = s->next; *iterator = s; return s ? al_cstr(s->name) : NULL; } /* Function: al_get_first_config_entry */ char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config, char const *section, ALLEGRO_CONFIG_ENTRY **iterator) { ALLEGRO_USTR_INFO section_info; const ALLEGRO_USTR *usection; ALLEGRO_CONFIG_SECTION *s; ALLEGRO_CONFIG_ENTRY *e; if (!config) return NULL; if (section == NULL) section = ""; usection = al_ref_cstr(§ion_info, section); s = find_section(config, usection); if (!s) return NULL; e = s->head; while (e && e->is_comment) e = e->next; if (iterator) *iterator = e; return e ? al_cstr(e->key) : NULL; } /* Function: al_get_next_config_entry */ char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator) { ALLEGRO_CONFIG_ENTRY *e; if (!iterator) return NULL; e = *iterator; if (e) e = e->next; while (e && e->is_comment) e = e->next; *iterator = e; return e ? al_cstr(e->key) : NULL; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/system.c0000644000175000001440000002550712125201710014665 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New system driver. * * By Elias Pschernig. * * Modified by Trent Gamblin. */ /* Title: System routines */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include ALLEGRO_INTERNAL_HEADER #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_debug.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_timer.h" #include "allegro5/internal/aintern_tls.h" #include "allegro5/internal/aintern_vector.h" ALLEGRO_DEBUG_CHANNEL("system") static ALLEGRO_SYSTEM *active_sysdrv = NULL; _AL_VECTOR _al_system_interfaces; static _AL_VECTOR _user_system_interfaces = _AL_VECTOR_INITIALIZER(ALLEGRO_SYSTEM_INTERFACE *); _AL_DTOR_LIST *_al_dtor_list = NULL; static bool atexit_virgin = true; static char _al_app_name[256] = ""; static char _al_org_name[256] = ""; static ALLEGRO_SYSTEM *find_system(_AL_VECTOR *vector) { ALLEGRO_SYSTEM_INTERFACE **sptr; ALLEGRO_SYSTEM_INTERFACE *sys_interface; ALLEGRO_SYSTEM *system; unsigned int i; for (i = 0; i < vector->_size; i++) { sptr = _al_vector_ref(vector, i); sys_interface = *sptr; if ((system = sys_interface->initialize(0)) != NULL) return system; } return NULL; } static void shutdown_system_driver(void) { if (active_sysdrv) { ALLEGRO_CONFIG *temp = active_sysdrv->config; if (active_sysdrv->user_exe_path) al_destroy_path(active_sysdrv->user_exe_path); if (active_sysdrv->vt && active_sysdrv->vt->shutdown_system) active_sysdrv->vt->shutdown_system(); active_sysdrv = NULL; /* active_sysdrv is not accessible here so we copied it */ al_destroy_config(temp); while (!_al_vector_is_empty(&_al_system_interfaces)) _al_vector_delete_at(&_al_system_interfaces, _al_vector_size(&_al_system_interfaces)-1); _al_vector_free(&_al_system_interfaces); _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); } } /* al_get_standard_path() does not work before the system driver is * initialised. Before that, we need to call the underlying functions * directly. */ static ALLEGRO_PATH *early_get_exename_path(void) { #if defined(ALLEGRO_WINDOWS) return _al_win_get_path(ALLEGRO_EXENAME_PATH); #elif defined(ALLEGRO_MACOSX) return _al_osx_get_path(ALLEGRO_EXENAME_PATH); #elif defined(ALLEGRO_IPHONE) return _al_iphone_get_path(ALLEGRO_EXENAME_PATH); #elif defined(ALLEGRO_UNIX) return _al_unix_get_path(ALLEGRO_EXENAME_PATH); #else #error early_get_exename_path not implemented #endif } static void read_allegro_cfg(void) { /* We cannot use any logging in this function as it would cause the * logging system to be initialised before all the relevant config files * have been read in. */ /* We assume that the stdio file interface is in effect. */ ALLEGRO_PATH *path; ALLEGRO_CONFIG *temp; active_sysdrv->config = NULL; #if defined(ALLEGRO_UNIX) && !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE) active_sysdrv->config = al_load_config_file("/etc/allegro5rc"); path = _al_unix_get_path(ALLEGRO_USER_HOME_PATH); if (path) { al_set_path_filename(path, "allegro5rc"); temp = al_load_config_file(al_path_cstr(path, '/')); if (temp) { if (active_sysdrv->config) { al_merge_config_into(active_sysdrv->config, temp); al_destroy_config(temp); } else { active_sysdrv->config = temp; } } al_destroy_path(path); } #endif path = early_get_exename_path(); if (path) { al_set_path_filename(path, "allegro5.cfg"); temp = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); if (temp) { if (active_sysdrv->config) { al_merge_config_into(active_sysdrv->config, temp); al_destroy_config(temp); } else { active_sysdrv->config = temp; } } al_destroy_path(path); } /* Always have a configuration available whether or not a config file * exists. */ if (!active_sysdrv->config) active_sysdrv->config = al_create_config(); } /* * Let a = xa.ya.za.* * Let b = xb.yb.zb.* * * When ya is odd, a is compatible with b if xa.ya.za = xb.yb.zb. * When ya is even, a is compatible with b if xa.ya = xb.yb. * * Otherwise a and b are incompatible. */ static bool compatible_versions(int a, int b) { if ((a & 0xffff0000) != (b & 0xffff0000)) { return false; } if (((a & 0x00ff0000) >> 16) & 1) { if ((a & 0x0000ff00) != (b & 0x0000ff00)) { return false; } } return true; } /* Function: al_install_system */ bool al_install_system(int version, int (*atexit_ptr)(void (*)(void))) { ALLEGRO_SYSTEM bootstrap; ALLEGRO_SYSTEM *real_system; int library_version = al_get_allegro_version(); if (active_sysdrv) { return true; } /* Note: We cannot call logging functions yet. * TODO: Maybe we want to do the check after the "bootstrap" system * is available at least? */ if (!compatible_versions(version, library_version)) return false; _al_tls_init_once(); _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); /* We want active_sysdrv->config to be available as soon as * possible - for example what if a system driver need to read * settings out of there. Hence we use a dummy ALLEGRO_SYSTEM * here to load the initial config. */ memset(&bootstrap, 0, sizeof(bootstrap)); active_sysdrv = &bootstrap; read_allegro_cfg(); #ifdef ALLEGRO_BCC32 /* This supresses exceptions on floating point divide by zero */ _control87(MCW_EM, MCW_EM); #endif /* Register builtin system drivers */ _al_register_system_interfaces(); /* Check for a user-defined system driver first */ real_system = find_system(&_user_system_interfaces); /* If a user-defined driver is not found, look for a builtin one */ if (real_system == NULL) { real_system = find_system(&_al_system_interfaces); } if (real_system == NULL) { active_sysdrv = NULL; return false; } active_sysdrv = real_system; active_sysdrv->config = bootstrap.config; ALLEGRO_INFO("Allegro version: %s\n", ALLEGRO_VERSION_STR); if (strcmp(al_get_app_name(), "") == 0) { al_set_app_name(NULL); } _al_add_exit_func(shutdown_system_driver, "shutdown_system_driver"); _al_dtor_list = _al_init_destructors(); _al_init_events(); _al_init_pixels(); _al_init_iio_table(); _al_init_timers(); if (atexit_ptr && atexit_virgin) { atexit_ptr(al_uninstall_system); atexit_virgin = false; } /* Clear errnos set while searching for config files. */ al_set_errno(0); active_sysdrv->installed = true; _al_srand(time(NULL)); return true; } /* Function: al_uninstall_system */ void al_uninstall_system(void) { _al_run_destructors(_al_dtor_list); _al_run_exit_funcs(); _al_shutdown_destructors(_al_dtor_list); _al_dtor_list = NULL; _al_shutdown_logging(); /* shutdown_system_driver is registered as an exit func so we don't need * to do any more here. */ ASSERT(active_sysdrv == NULL); } /* Function: al_is_system_installed */ bool al_is_system_installed(void) { return (active_sysdrv && active_sysdrv->installed) ? true : false; } /* Hidden function: al_get_system_driver * This was exported and documented in 5.0rc1 but probably shouldn't have been * as ALLEGRO_SYSTEM is not documented. */ ALLEGRO_SYSTEM *al_get_system_driver(void) { return active_sysdrv; } /* Function: al_get_system_config */ ALLEGRO_CONFIG *al_get_system_config(void) { return (active_sysdrv) ? active_sysdrv->config : NULL; } /* Function: al_get_standard_path */ ALLEGRO_PATH *al_get_standard_path(int id) { ASSERT(active_sysdrv); ASSERT(active_sysdrv->vt); ASSERT(active_sysdrv->vt->get_path); if (id == ALLEGRO_EXENAME_PATH && active_sysdrv->user_exe_path) return al_clone_path(active_sysdrv->user_exe_path); if (id == ALLEGRO_RESOURCES_PATH && active_sysdrv->user_exe_path) { ALLEGRO_PATH *exe_dir = al_clone_path(active_sysdrv->user_exe_path); al_set_path_filename(exe_dir, NULL); return exe_dir; } if (active_sysdrv->vt->get_path) return active_sysdrv->vt->get_path(id); return NULL; } /* Function: al_set_exe_name */ void al_set_exe_name(char const *path) { ASSERT(active_sysdrv); if (active_sysdrv->user_exe_path) { al_destroy_path(active_sysdrv->user_exe_path); } active_sysdrv->user_exe_path = al_create_path(path); } /* Function: al_set_org_name */ void al_set_org_name(const char *org_name) { if (!org_name) org_name = ""; _al_sane_strncpy(_al_org_name, org_name, sizeof(_al_org_name)); } /* Function: al_set_app_name */ void al_set_app_name(const char *app_name) { if (app_name) { _al_sane_strncpy(_al_app_name, app_name, sizeof(_al_app_name)); } else { ALLEGRO_PATH *path; path = al_get_standard_path(ALLEGRO_EXENAME_PATH); _al_sane_strncpy(_al_app_name, al_get_path_filename(path), sizeof(_al_app_name)); al_destroy_path(path); } } /* Function: al_get_org_name */ const char *al_get_org_name(void) { return _al_org_name; } /* Function: al_get_app_name */ const char *al_get_app_name(void) { return _al_app_name; } /* Function: al_inhibit_screensaver */ bool al_inhibit_screensaver(bool inhibit) { ASSERT(active_sysdrv); if (active_sysdrv->vt->inhibit_screensaver) return active_sysdrv->vt->inhibit_screensaver(inhibit); else return false; } void *_al_open_library(const char *filename) { ASSERT(active_sysdrv); if (active_sysdrv->vt->open_library) return active_sysdrv->vt->open_library(filename); else return NULL; } void *_al_import_symbol(void *library, const char *symbol) { ASSERT(active_sysdrv); if (active_sysdrv->vt->import_symbol) return active_sysdrv->vt->import_symbol(library, symbol); else return NULL; } void _al_close_library(void *library) { ASSERT(active_sysdrv); if (active_sysdrv->vt->close_library) active_sysdrv->vt->close_library(library); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/macosx/0000755000175000001440000000000012157230741014471 5ustar tjadenusersallegro-5.0.10/src/macosx/osx_app_delegate.m0000644000175000001440000002563611771527606020200 0ustar tjadenusers #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintosx.h" #ifdef __LP64__ /* FIXME: the following prototype and enum definition appear to needed in * 64 bit mode on 10.5 (Leopard). Apple's documentation indicates that * "deprecated features" are not available in 64 bit, but * UpdateSystemActivity is not deprecated and the documentation likewise * suggests that all that should be required is to #include CoreServices.h * or Power.h. However, this does not appear to work... for now, this * should work ok. * On 10.6 (Snow Leopard) these defines cause a problem, so they are * disabled. */ extern OSErr UpdateSystemActivity(uint8_t activity); #if 0 enum { OverallAct = 0, /* Delays idle sleep by small amount */ UsrActivity = 1, /* Delays idle sleep and dimming by timeout time */ NetActivity = 2, /* Delays idle sleep and power cycling by small amount */ HDActivity = 3, /* Delays hard drive spindown and idle sleep by small amount */ IdleActivity = 4 /* Delays idle sleep by timeout time */ }; #endif #endif extern NSBundle *_al_osx_bundle; /* For compatibility with the unix code */ static int __crt0_argc; static char **__crt0_argv; static int (*user_main)(int, char **); static char *arg0, *arg1 = NULL; static BOOL in_bundle(void) { /* This comes from the ADC tips & tricks section: how to detect if the app * lives inside a bundle */ FSRef processRef; ProcessSerialNumber psn = { 0, kCurrentProcess }; FSCatalogInfo processInfo; GetProcessBundleLocation(&psn, &processRef); FSGetCatalogInfo(&processRef, kFSCatInfoNodeFlags, &processInfo, NULL, NULL, NULL); if (processInfo.nodeFlags & kFSNodeIsDirectoryMask) return YES; else return NO; } @interface AllegroAppDelegate : NSObject { NSTimer* activity; } - (void) dealloc; - (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename; - (void)applicationDidFinishLaunching: (NSNotification *)aNotification; - (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification; + (void)app_main: (id)arg; - (NSApplicationTerminateReply) applicationShouldTerminate: (id)sender; - (void) updateSystemActivity:(NSTimer*) timer; - (void) setInhibitScreenSaver: (NSNumber*) inhibit; @end @interface AllegroWindowDelegate : NSObject - (BOOL)windowShouldClose: (id)sender; - (void)windowDidDeminiaturize: (NSNotification *)aNotification; @end @implementation AllegroAppDelegate /* setInhibitScreenSaver: * If inhibit is YES, set up an infrequent timer to call * updateSystemActivity: to prevent the screen saver from activating * Must be called from the main thread (osx_inhibit_screensaver ensures * this) * Has no effect if inhibit is YES and the timer is already active * or if inhibit is NO and the timer is not active */ -(void) setInhibitScreenSaver: (NSNumber *) inhibit { if ([inhibit boolValue] == YES) { if (activity == nil) { // Schedule every 30 seconds activity = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(updateSystemActivity:) userInfo:nil repeats:YES]; [activity retain]; } // else already active } else { // OK to send message to nil if timer wasn't set. [activity invalidate]; [activity release]; activity = nil; } } /* updateSystemActivity: * called by a timer to inform the system that there is still activity and * therefore do not dim the screen/start the screensaver */ -(void) updateSystemActivity: (NSTimer*) timer { (void)timer; UpdateSystemActivity(UsrActivity); } -(void) dealloc { [activity invalidate]; [activity release]; [super dealloc]; } - (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename { NSData* data = [filename dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; (void)theApplication; if (data != nil) { unsigned int len = 1 + [data length]; arg1 = al_malloc(len); memset(arg1, 0, len); [data getBytes: arg1]; return YES; } else { return NO; } } /* applicationDidFinishLaunching: * Called when the app is ready to run. */ - (void)applicationDidFinishLaunching: (NSNotification *)aNotification { NSString* exename, *resdir; NSFileManager* fm; BOOL isDir; (void)aNotification; if (in_bundle() == YES) { /* In a bundle, so chdir to the containing directory, * or to the 'magic' resource directory if it exists. * (see the readme.osx file for more info) */ _al_osx_bundle = [NSBundle mainBundle]; exename = [[_al_osx_bundle executablePath] lastPathComponent]; resdir = [[_al_osx_bundle resourcePath] stringByAppendingPathComponent: exename]; fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath: resdir isDirectory: &isDir] && isDir) { /* Yes, it exists inside the bundle */ [fm changeCurrentDirectoryPath: resdir]; } else { /* No, change to the 'standard' OSX resource directory if it exists*/ if ([fm fileExistsAtPath: [_al_osx_bundle resourcePath] isDirectory: &isDir] && isDir) { [fm changeCurrentDirectoryPath: [_al_osx_bundle resourcePath]]; } /* It doesn't exist - this is unusual for a bundle. Don't chdir */ } arg0 = strdup([[_al_osx_bundle bundlePath] fileSystemRepresentation]); if (arg1) { static char *args[2]; args[0] = arg0; args[1] = arg1; __crt0_argv = args; __crt0_argc = 2; } else { __crt0_argv = &arg0; __crt0_argc = 1; } } /* else: not in a bundle so don't chdir */ [NSThread detachNewThreadSelector: @selector(app_main:) toTarget: [AllegroAppDelegate class] withObject: nil]; return; } /* applicationDidChangeScreenParameters: * Invoked when the screen did change resolution/color depth. */ - (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification { /* no-op */ (void)aNotification; } /* Call the user main() */ static void call_user_main(void) { exit(user_main(__crt0_argc, __crt0_argv)); } /* app_main: * Thread dedicated to the user program; real main() gets called here. */ + (void)app_main: (id)arg { (void)arg; call_user_main(); } /* applicationShouldTerminate: * Called upon Command-Q or "Quit" menu item selection. * Post a message but do not quit directly */ - (NSApplicationTerminateReply) applicationShouldTerminate: (id)sender { (void)sender; _al_osx_post_quit(); return NSTerminateCancel; } /* end of AllegroAppDelegate implementation */ @end /* This prevents warnings that 'NSApplication might not * respond to setAppleMenu' on OS X 10.4+ */ @interface NSApplication(AllegroOSX) - (void)setAppleMenu:(NSMenu *)menu; @end /* Helper macro to add entries to the menu */ #define add_menu(name, sel, eq) \ [menu addItem: [[[NSMenuItem allocWithZone: [NSMenu menuZone]] \ initWithTitle: name \ action: @selector(sel) \ keyEquivalent: eq] autorelease]] \ int _al_osx_run_main(int argc, char **argv, int (*real_main)(int, char **)) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; AllegroAppDelegate *app_delegate = [[AllegroAppDelegate alloc] init]; NSMenu *menu; NSMenuItem *temp_item; user_main = real_main; __crt0_argc = argc; __crt0_argv = argv; #ifdef OSX_BOOTSTRAP_DETECTION if (!_al_osx_bootstrap_ok()) /* not safe to use NSApplication */ call_user_main(); #endif [NSApplication sharedApplication]; /* Load the main menu nib if possible */ if ((!in_bundle()) || ([NSBundle loadNibNamed: @"MainMenu" owner: NSApp] == NO)) { /* Didn't load the nib; create a default menu programmatically */ NSString* title = nil; NSDictionary* app_dictionary = [[NSBundle mainBundle] infoDictionary]; if (app_dictionary) { title = [app_dictionary objectForKey: @"CFBundleName"]; } if (title == nil) { title = [[NSProcessInfo processInfo] processName]; } NSMenu* main_menu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle: @""]; [NSApp setMainMenu: main_menu]; /* Add application ("Apple") menu */ menu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle: @"Apple menu"]; temp_item = [[NSMenuItem allocWithZone: [NSMenu menuZone]] initWithTitle: @"" action: NULL keyEquivalent: @""]; [main_menu addItem: temp_item]; [main_menu setSubmenu: menu forItem: temp_item]; [temp_item release]; add_menu([@"Hide " stringByAppendingString: title], hide:, @"h"); add_menu(@"Hide Others", hideOtherApplications:, @""); add_menu(@"Show All", unhideAllApplications:, @""); [menu addItem: [NSMenuItem separatorItem]]; add_menu([@"Quit " stringByAppendingString: title], terminate:, @"q"); [NSApp setAppleMenu: menu]; [menu release]; /* Add "Window" menu */ menu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle: @"Window"]; temp_item = [[NSMenuItem allocWithZone: [NSMenu menuZone]] initWithTitle: @"" action: NULL keyEquivalent: @""]; [main_menu addItem: temp_item]; [main_menu setSubmenu: menu forItem: temp_item]; [temp_item release]; /* Add menu entries */ add_menu(@"Minimize", performMiniaturize:, @"M"); add_menu(@"Bring All to Front", arrangeInFront:, @""); [NSApp setWindowsMenu:menu]; [menu release]; [main_menu release]; } // setDelegate: doesn't retain the delegate here (a Cocoa convention) // therefore we don't release it. [NSApp setDelegate: app_delegate]; [pool drain]; [NSApp run]; /* Can never get here */ [app_delegate release]; return 0; } allegro-5.0.10/src/macosx/qzmouse.m0000644000175000001440000003103012141424516016345 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X mouse driver. * * By Angelo Mottola. * * Modified for 4.9 mouse API by Peter Hull. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintosx.h" #include "./osxgl.h" #ifndef ALLEGRO_MACOSX #error Something is wrong with the makefile #endif ALLEGRO_DEBUG_CHANNEL("MacOSX"); typedef struct ALLEGRO_MOUSE AL_MOUSE; typedef struct ALLEGRO_MOUSE_STATE AL_MOUSE_STATE; static bool osx_init_mouse(void); static unsigned int osx_get_mouse_num_buttons(void); static unsigned int osx_get_mouse_num_axes(void); static bool osx_set_mouse_axis(int axis, int value); static ALLEGRO_MOUSE* osx_get_mouse(void); /* Mouse info - includes extra info for OS X */ static struct { ALLEGRO_MOUSE parent; unsigned int button_count; unsigned int axis_count; int minx, miny, maxx, maxy; ALLEGRO_MOUSE_STATE state; float z_axis, w_axis; BOOL warped; int warped_x, warped_y; NSCursor* cursor; } osx_mouse; void _al_osx_clear_mouse_state(void) { memset(&osx_mouse.state, 0, sizeof(ALLEGRO_MOUSE_STATE)); } /* _al_osx_switch_keyboard_focus: * Handle a focus switch event. */ void _al_osx_switch_mouse_focus(ALLEGRO_DISPLAY *dpy, bool switch_in) { _al_event_source_lock(&osx_mouse.parent.es); if (switch_in) osx_mouse.state.display = dpy; else osx_mouse.state.display = NULL; _al_event_source_unlock(&osx_mouse.parent.es); } /* osx_get_mouse: * Return the Allegro mouse structure */ static ALLEGRO_MOUSE* osx_get_mouse(void) { return (ALLEGRO_MOUSE*) &osx_mouse.parent; } /* _al_osx_mouse_generate_event: * Convert an OS X mouse event to an Allegro event * and push it into a queue. * First check that the event is wanted. */ void _al_osx_mouse_generate_event(NSEvent* evt, ALLEGRO_DISPLAY* dpy) { NSPoint pos; int type, b_change = 0, dx = 0, dy = 0, dz = 0, dw = 0, b = 0; float pressure = 0.0; switch ([evt type]) { case NSMouseMoved: type = ALLEGRO_EVENT_MOUSE_AXES; dx = [evt deltaX]; dy = [evt deltaY]; pressure = [evt pressure]; break; case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: type = ALLEGRO_EVENT_MOUSE_AXES; b = [evt buttonNumber]+1; dx = [evt deltaX]; dy = [evt deltaY]; pressure = [evt pressure]; break; case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; b = [evt buttonNumber]+1; b_change = 1; osx_mouse.state.buttons |= (1 << (b-1)); pressure = [evt pressure]; break; case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; b = [evt buttonNumber]+1; b_change = 1; osx_mouse.state.buttons &= ~(1 << (b-1)); pressure = [evt pressure]; break; case NSScrollWheel: type = ALLEGRO_EVENT_MOUSE_AXES; dx = 0; dy = 0; osx_mouse.w_axis += [evt deltaX]; osx_mouse.z_axis += [evt deltaY]; dw = osx_mouse.w_axis - osx_mouse.state.w; dz = osx_mouse.z_axis - osx_mouse.state.z; break; case NSMouseEntered: type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; b = [evt buttonNumber]+1; dx = [evt deltaX]; dy = [evt deltaY]; break; case NSMouseExited: type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; b = [evt buttonNumber]+1; dx = [evt deltaX]; dy = [evt deltaY]; break; default: return; } pos = [evt locationInWindow]; BOOL within = true; if ([evt window]) { NSRect frm = [[[evt window] contentView] frame]; within = NSMouseInRect(pos, frm, NO); // Y-coordinates in OS X start from the bottom. pos.y = NSHeight(frm) - pos.y; } else { pos.y = [[NSScreen mainScreen] frame].size.height - pos.y; } if (osx_mouse.warped) { dx = -osx_mouse.warped_x; dy = -osx_mouse.warped_y; osx_mouse.warped = FALSE; } _al_event_source_lock(&osx_mouse.parent.es); if ((within || b_change || type == ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY) && _al_event_source_needs_to_generate_event(&osx_mouse.parent.es)) { ALLEGRO_EVENT new_event; ALLEGRO_MOUSE_EVENT* mouse_event = &new_event.mouse; mouse_event->type = type; // Note: we use 'allegro time' rather than the time stamp // from the event mouse_event->timestamp = al_get_time(); mouse_event->display = dpy; mouse_event->button = b; mouse_event->x = pos.x; mouse_event->y = pos.y; mouse_event->z = osx_mouse.z_axis; mouse_event->w = osx_mouse.w_axis; mouse_event->dx = dx; mouse_event->dy = dy; mouse_event->dz = dz; mouse_event->dw = dw; mouse_event->pressure = pressure; _al_event_source_emit_event(&osx_mouse.parent.es, &new_event); } // Record current state osx_mouse.state.x = pos.x; osx_mouse.state.y = pos.y; osx_mouse.state.w = osx_mouse.w_axis; osx_mouse.state.z = osx_mouse.z_axis; osx_mouse.state.pressure = pressure; _al_event_source_unlock(&osx_mouse.parent.es); } /* osx_init_mouse: * Initializes the driver. */ static bool osx_init_mouse(void) { /* NOTE: This function is deprecated, however until we have a better fix * or it is removed, we can used it. The problem without calling this * function is that after synthesizing events (as with al_set_mouse_xy) * there is an unacceptably long delay in receiving new events (mouse * locks up for about 0.5 seconds.) */ CGSetLocalEventsSuppressionInterval(0.0); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; HID_DEVICE_COLLECTION devices={0,0,NULL}; int i = 0, j = 0; int axes = 0, buttons = 0; int max_axes = 0, max_buttons = 0; HID_DEVICE* device = nil; NSString* desc = nil; _al_osx_hid_scan(HID_MOUSE, &devices); ALLEGRO_INFO("Detected %d pointing devices\n", devices.count); for (i=0; imanufacturer ? device->manufacturer : "", device->product ? device->product : ""]; ALLEGRO_INFO("Device %d is a \"%s\"\n", i, [desc UTF8String]); for (j = 0; j < device->num_elements; j++) { switch (device->element[j].type) { case HID_ELEMENT_BUTTON: buttons++; break; case HID_ELEMENT_AXIS: case HID_ELEMENT_AXIS_PRIMARY_X: case HID_ELEMENT_AXIS_PRIMARY_Y: case HID_ELEMENT_STANDALONE_AXIS: axes ++; break; } } ALLEGRO_INFO("Detected %d axes and %d buttons\n", axes, buttons); /* When mouse events reach the application, it is not clear which * device generated them, so effectively the largest number of * buttons and axes reported corresponds to the device that the * application "sees" */ if (axes > max_axes) max_axes = axes; if (buttons > max_buttons) max_buttons = buttons; } _al_osx_hid_free(&devices); ALLEGRO_INFO("Device effectively has %d axes and %d buttons\n", axes, buttons); if (max_buttons <= 0) return false; _al_event_source_init(&osx_mouse.parent.es); osx_mouse.button_count = max_buttons; osx_mouse.axis_count = max_axes; osx_mouse.warped = FALSE; memset(&osx_mouse.state, 0, sizeof(ALLEGRO_MOUSE_STATE)); _al_osx_mouse_was_installed(YES); [pool drain]; return true; } /* osx_exit_mouse: * Shut down the mouse driver */ static void osx_exit_mouse(void) { _al_osx_mouse_was_installed(NO); } /* osx_get_mouse_num_buttons: * Return the number of buttons on the mouse */ static unsigned int osx_get_mouse_num_buttons(void) { return osx_mouse.button_count; } /* osx_get_mouse_num_buttons: * Return the number of buttons on the mouse */ static unsigned int osx_get_mouse_num_axes(void) { return osx_mouse.axis_count; } static void osx_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) { _al_event_source_lock(&osx_mouse.parent.es); memcpy(ret_state, &osx_mouse.state, sizeof(ALLEGRO_MOUSE_STATE)); _al_event_source_unlock(&osx_mouse.parent.es); } /* osx_set_mouse_xy: * Set the current mouse position */ static bool osx_set_mouse_xy(ALLEGRO_DISPLAY *dpy_, int x, int y) { CGPoint pos; CGDirectDisplayID display = 0; ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)dpy_; if ((dpy) && !(dpy->parent.flags & ALLEGRO_FULLSCREEN) && !(dpy->parent.flags & ALLEGRO_FULLSCREEN_WINDOW) && (dpy->win)) { NSWindow *window = dpy->win; NSRect content = [window contentRectForFrameRect: [window frame]]; NSRect frame = [[window screen] frame]; CGRect rect = { { NSMinX(frame), NSMinY(frame) }, { NSWidth(frame), NSHeight(frame) } }; CGDirectDisplayID displays[16]; CGDisplayCount displayCount; if ((CGGetDisplaysWithRect(rect, 16, displays, &displayCount) == 0) && (displayCount >= 1)) display = displays[0]; pos.x = content.origin.x + x; pos.y = rect.size.height - content.origin.y - content.size.height + y; } else { if (dpy) display = dpy->display_id; pos.x = x; pos.y = y; } _al_event_source_lock(&osx_mouse.parent.es); if (_al_event_source_needs_to_generate_event(&osx_mouse.parent.es)) { ALLEGRO_EVENT new_event; ALLEGRO_MOUSE_EVENT* mouse_event = &new_event.mouse; mouse_event->type = ALLEGRO_EVENT_MOUSE_WARPED; // Note: we use 'allegro time' rather than the time stamp // from the event mouse_event->timestamp = al_get_time(); mouse_event->display = (ALLEGRO_DISPLAY *)dpy; mouse_event->button = 0; mouse_event->x = x; mouse_event->y = y; mouse_event->z = osx_mouse.z_axis; mouse_event->dx = x - osx_mouse.state.x; mouse_event->dy = y - osx_mouse.state.y; mouse_event->dz = 0; mouse_event->pressure = 0.0; if (mouse_event->dx || mouse_event->dy) { osx_mouse.warped = TRUE; osx_mouse.warped_x = mouse_event->dx; osx_mouse.warped_y = mouse_event->dy; _al_event_source_emit_event(&osx_mouse.parent.es, &new_event); } } CGDisplayMoveCursorToPoint(display, pos); osx_mouse.state.x = x; osx_mouse.state.y = y; _al_event_source_unlock(&osx_mouse.parent.es); return true; } /* osx_set_mouse_axis: * Set the axis value of the mouse */ static bool osx_set_mouse_axis(int axis, int value) { bool result = false; _al_event_source_lock(&osx_mouse.parent.es); switch (axis) { case 0: case 1: // By design, this doesn't apply to (x, y) break; case 2: osx_mouse.z_axis = value; result = true; break; case 3: osx_mouse.w_axis = value; result = true; break; } /* XXX generate an event if the axis value changed */ _al_event_source_unlock(&osx_mouse.parent.es); return result; } /* Mouse driver */ static ALLEGRO_MOUSE_DRIVER osx_mouse_driver = { 0, //int msedrv_id; "OSXMouse", //const char *msedrv_name; "Driver for Mac OS X",// const char *msedrv_desc; "OSX Mouse", //const char *msedrv_ascii_name; osx_init_mouse, //AL_METHOD(bool, init_mouse, (void)); osx_exit_mouse, //AL_METHOD(void, exit_mouse, (void)); osx_get_mouse, //AL_METHOD(ALLEGRO_MOUSE*, get_mouse, (void)); osx_get_mouse_num_buttons, //AL_METHOD(unsigned int, get_mouse_num_buttons, (void)); osx_get_mouse_num_axes, //AL_METHOD(unsigned int, get_mouse_num_axes, (void)); osx_set_mouse_xy, //AL_METHOD(bool, set_mouse_xy, (int x, int y)); osx_set_mouse_axis, //AL_METHOD(bool, set_mouse_axis, (int which, int value)); osx_get_mouse_state, //AL_METHOD(void, get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); }; ALLEGRO_MOUSE_DRIVER* _al_osx_get_mouse_driver(void) { return &osx_mouse_driver; } /* list the available drivers */ _AL_DRIVER_INFO _al_mouse_driver_list[] = { { 1, &osx_mouse_driver, 1 }, { 0, NULL, 0 } }; /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/src/macosx/osxgl.m0000644000175000001440000021341012146134076016006 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X OpenGL gfx driver * * By Peter Hull. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/platform/aintosx.h" #include "./osxgl.h" #include "allegro5/allegro_osx.h" #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif #import #import ALLEGRO_DEBUG_CHANNEL("MacOSX") /* This constant isn't available on OS X < 10.7, define * it here so the library can be built on < 10.7 (10.6 * tested so far.) */ #if (MAC_OS_X_VERSION_MAX_ALLOWED < 1070 && !defined(NSWindowCollectionBehaviorFullScreenPrimary)) enum { NSWindowCollectionBehaviorFullScreenPrimary = (1 << 7) }; #endif /* Defines */ #define MINIMUM_WIDTH 48 #define MINIMUM_HEIGHT 48 /* Unsigned integer; data type only avaliable for OS X >= 10.5 */ #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 typedef unsigned int NSUInteger; #endif /* Module Variables */ static BOOL _osx_mouse_installed = NO, _osx_keyboard_installed = NO; static NSPoint last_window_pos; static unsigned int next_display_group = 1; /* New window locations are set in threat-local storage by the user with * al_set_new_window_position, however, our window creation routine in * initialiseDisplay (in ALDisplayHelper) calls al_get_new_window_position * from a different threat (the main threat). The "proper" fix for this * situation is to call al_get_new_window position() before invoking * initialiseDisplay and passing these values as parameters. It's a little * tedious to do, however, so we use two global variables instead. This can * lead to a race condition if two windows are created simultaneously from * different threats. Unlikely, but it's possible. * FIXME: do this the proper way! */ static int new_window_pos_x; static int new_window_pos_y; static int new_display_adapter; /* Dictionary to map Allegro's DISPLAY_OPTIONS to OS X * PixelFormatAttributes. * The first column is Allegro's name, the second column is the OS X * PixelFormatAttribute (or 0), the third column indicates whether we * need an extra parameter or not (eg, colour depth). */ static const unsigned int allegro_to_osx_settings[][3] = { { ALLEGRO_RED_SIZE, 0, 0}, // Not supported per component { ALLEGRO_GREEN_SIZE, 0, 0}, // Not supported per component { ALLEGRO_BLUE_SIZE, 0, 0}, // Not supported per component { ALLEGRO_ALPHA_SIZE, NSOpenGLPFAAlphaSize, 1}, { ALLEGRO_RED_SHIFT, 0, 0}, // Not available { ALLEGRO_GREEN_SHIFT, 0, 0}, // Not available { ALLEGRO_BLUE_SHIFT, 0, 0}, // Not available { ALLEGRO_ALPHA_SHIFT, 0, 0}, // Not available { ALLEGRO_ACC_RED_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? { ALLEGRO_ACC_GREEN_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? { ALLEGRO_ACC_BLUE_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? { ALLEGRO_ACC_ALPHA_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? { ALLEGRO_STEREO, NSOpenGLPFAStereo, 0}, { ALLEGRO_AUX_BUFFERS, NSOpenGLPFAAuxBuffers, 1}, { ALLEGRO_COLOR_SIZE, NSOpenGLPFAColorSize, 1}, { ALLEGRO_DEPTH_SIZE, NSOpenGLPFADepthSize, 1}, { ALLEGRO_STENCIL_SIZE, NSOpenGLPFAStencilSize, 1}, { ALLEGRO_SAMPLE_BUFFERS, NSOpenGLPFASampleBuffers, 1}, { ALLEGRO_SAMPLES, NSOpenGLPFASamples, 1}, //{ ALLEGRO_RENDER_METHOD, NSOpenGLPFAAccelerated, 0}, handled separately { ALLEGRO_FLOAT_COLOR, NSOpenGLPFAColorFloat, 0}, { ALLEGRO_FLOAT_DEPTH, 0, 0}, { ALLEGRO_SINGLE_BUFFER , 0, 0}, // Only have inverse of this { ALLEGRO_SWAP_METHOD, 0, 0}, { ALLEGRO_COMPATIBLE_DISPLAY, 0, 0}, { ALLEGRO_DISPLAY_OPTIONS_COUNT, 0, 0} }; static const int number_of_settings = sizeof(allegro_to_osx_settings)/sizeof(*allegro_to_osx_settings); static const char *allegro_pixel_format_names[] = { "ALLEGRO_RED_SIZE", "ALLEGRO_GREEN_SIZE", "ALLEGRO_BLUE_SIZE", "ALLEGRO_ALPHA_SIZE", "ALLEGRO_RED_SHIFT", "ALLEGRO_GREEN_SHIFT", "ALLEGRO_BLUE_SHIFT", "ALLEGRO_ALPHA_SHIFT", "ALLEGRO_ACC_RED_SIZE", "ALLEGRO_ACC_GREEN_SIZE", "ALLEGRO_ACC_BLUE_SIZE", "ALLEGRO_ACC_ALPHA_SIZE", "ALLEGRO_STEREO", "ALLEGRO_AUX_BUFFERS", "ALLEGRO_COLOR_SIZE", "ALLEGRO_DEPTH_SIZE", "ALLEGRO_STENCIL_SIZE", "ALLEGRO_SAMPLE_BUFFERS", "ALLEGRO_SAMPLES", "ALLEGRO_RENDER_METHOD", "ALLEGRO_FLOAT_COLOR", "ALLEGRO_FLOAT_DEPTH", "ALLEGRO_SINGLE_BUFFER", "ALLEGRO_SWAP_METHOD", "ALLEGRO_COMPATIBLE_DISPLAY", "ALLEGRO_DISPLAY_OPTIONS_COUNT" }; /* Module functions */ static NSView* osx_view_from_display(ALLEGRO_DISPLAY* disp); ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver(void); ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void); ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_fs(void); static NSOpenGLContext* osx_create_shareable_context(NSOpenGLPixelFormat* fmt, unsigned int* group); static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff); static NSTrackingArea *create_tracking_area(NSView *view) { NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingActiveAlways; return [[NSTrackingArea alloc] initWithRect:[view bounds] options:options owner:view userInfo:nil]; } /* osx_change_cursor: * Actually change the current cursor. This can be called fom any thread * but ensures that the change is only called from the main thread. */ static void osx_change_cursor(ALLEGRO_DISPLAY_OSX_WIN *dpy, NSCursor* cursor) { NSCursor* old = dpy->cursor; dpy->cursor = [cursor retain]; [old release]; if (dpy->show_cursor) [cursor performSelectorOnMainThread: @selector(set) withObject: nil waitUntilDone: NO]; } /* _al_osx_keyboard_was_installed: * Called by the keyboard driver when the driver is installed or uninstalled. * Set the variable so we can decide to pass events or not. */ void _al_osx_keyboard_was_installed(BOOL install) { _osx_keyboard_installed = install; } /* The main additions to this view are event-handling functions */ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 @interface ALOpenGLView : NSOpenGLView #else @interface ALOpenGLView : NSOpenGLView #endif { /* This is passed onto the event functions so we know where the event came from */ ALLEGRO_DISPLAY* dpy_ptr; } -(void)setAllegroDisplay: (ALLEGRO_DISPLAY*) ptr; -(ALLEGRO_DISPLAY*) allegroDisplay; -(void) reshape; -(BOOL) acceptsFirstResponder; -(void) keyDown:(NSEvent*) event; -(void) keyUp:(NSEvent*) event; -(void) flagsChanged:(NSEvent*) event; -(void) mouseDown: (NSEvent*) evt; -(void) mouseUp: (NSEvent*) evt; -(void) mouseDragged: (NSEvent*) evt; -(void) rightMouseDown: (NSEvent*) evt; -(void) rightMouseUp: (NSEvent*) evt; -(void) rightMouseDragged: (NSEvent*) evt; -(void) otherMouseDown: (NSEvent*) evt; -(void) otherMouseUp: (NSEvent*) evt; -(void) otherMouseDragged: (NSEvent*) evt; -(void) mouseMoved: (NSEvent*) evt; -(void) scrollWheel: (NSEvent*) evt; -(void) viewDidMoveToWindow; -(void) viewWillMoveToWindow: (NSWindow*) newWindow; -(void) mouseEntered: (NSEvent*) evt; -(void) mouseExited: (NSEvent*) evt; -(void) viewDidEndLiveResize; /* Window delegate methods */ -(void) windowDidBecomeMain:(NSNotification*) notification; -(void) windowDidResignMain:(NSNotification*) notification; -(void) windowDidResize:(NSNotification*) notification; -(void) enterFullScreenWindowMode; -(void) exitFullScreenWindowMode; -(void) finishExitingFullScreenWindowMode; @end /* ALWindow: * This class is only here to return YES from canBecomeKeyWindow * to accept events when the window is frameless. */ @interface ALWindow : NSWindow @end @implementation ALWindow -(BOOL) canBecomeKeyWindow { return YES; } @end /* ALSetWindowFrame: * Because we create the window frame on the main thread, we should change * it on the main thread as well, otherwise we will get a warning similar * to "-[NSLock unlock]: lock unlocked from thread which did not lock it" * everytime we change the window frame, which happens when we resize or * move the window. */ @interface ALSetWindowFrame : NSObject +(void) set_frame : (NSValue *)param; @end @implementation ALSetWindowFrame +(void) set_frame : (NSValue *) param { NSArray *array = [param pointerValue]; NSRect *rc = [[array objectAtIndex:0] pointerValue]; NSWindow *win = [[array objectAtIndex:1] pointerValue]; // Couldn't resist animating it! [win setFrame:*rc display:YES animate:YES]; } @end /* _al_osx_mouse_was_installed: * Called by the mouse driver when the driver is installed or uninstalled. * Set the variable so we can decide to pass events or not, and notify all * existing displays that they need to set up their tracking areas. */ void _al_osx_mouse_was_installed(BOOL install) { unsigned int i; if (_osx_mouse_installed == install) { // done it already return; } _osx_mouse_installed = install; _AL_VECTOR* dpys = &al_get_system_driver()->displays; for (i = 0; i < _al_vector_size(dpys); ++i) { ALLEGRO_DISPLAY* dpy = *(ALLEGRO_DISPLAY**) _al_vector_ref(dpys, i); NSView* view = osx_view_from_display(dpy); [[view window] setAcceptsMouseMovedEvents: _osx_mouse_installed]; } } @implementation ALOpenGLView /* setDisplay: * Set the display this view is associated with */ -(void) setAllegroDisplay: (ALLEGRO_DISPLAY*) ptr { dpy_ptr = ptr; } /* display * return the display this view is associated with */ -(ALLEGRO_DISPLAY*) allegroDisplay { return dpy_ptr; } /* reshape * Called when the view changes size */ - (void) reshape { if ([NSOpenGLContext currentContext] != nil) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; NSRect rc = [self bounds]; glViewport(0, 0, NSWidth(rc), NSHeight(rc)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, NSWidth(rc), NSHeight(rc), 0, -1, 1); if (dpy->tracking) { [self removeTrackingArea: dpy->tracking]; dpy->tracking = create_tracking_area(self); [self addTrackingArea: dpy->tracking]; } } } /* acceptsFirstResponder * Overridden to return YES, so that * this view will receive events */ -(BOOL) acceptsFirstResponder { return YES; } /* Keyboard event handler */ -(void) keyDown:(NSEvent*) event { if (_osx_keyboard_installed) _al_osx_keyboard_handler(true, event, dpy_ptr); } -(void) keyUp:(NSEvent*) event { if (_osx_keyboard_installed) _al_osx_keyboard_handler(false, event, dpy_ptr); } -(void) flagsChanged:(NSEvent*) event { if (_osx_keyboard_installed) { _al_osx_keyboard_modifiers([event modifierFlags], dpy_ptr); } } /* Mouse handling */ -(void) mouseDown: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) mouseUp: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) mouseDragged: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) rightMouseDown: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) rightMouseUp: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) rightMouseDragged: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) otherMouseDown: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) otherMouseUp: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) otherMouseDragged: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) mouseMoved: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) scrollWheel: (NSEvent*) evt { if (_osx_mouse_installed) _al_osx_mouse_generate_event(evt, dpy_ptr); } /* Cursor handling */ - (void) viewDidMoveToWindow { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; dpy->tracking = create_tracking_area(self); [self addTrackingArea: dpy->tracking]; } - (void) viewWillMoveToWindow: (NSWindow*) newWindow { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; (void)newWindow; if (([self window] != nil) && (dpy->tracking != 0)) { [self removeTrackingArea:dpy->tracking]; dpy->tracking = 0; } } -(void) mouseEntered: (NSEvent*) evt { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); if (dpy->show_cursor) { [dpy->cursor set]; } else { [NSCursor hide]; } _al_event_source_lock(src); _al_osx_switch_mouse_focus(dpy_ptr, true); _al_event_source_unlock(src); _al_osx_mouse_generate_event(evt, dpy_ptr); } -(void) mouseExited: (NSEvent*) evt { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); if (!dpy->show_cursor) { [NSCursor unhide]; } _al_event_source_lock(src); _al_osx_switch_mouse_focus(dpy_ptr, false); _al_event_source_unlock(src); _al_osx_mouse_generate_event(evt, dpy_ptr); } /* windowShouldClose: * Veto the close and post a message */ - (BOOL)windowShouldClose:(id)sender { (void)sender; ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); _al_event_source_lock(src); ALLEGRO_EVENT evt; evt.type = ALLEGRO_EVENT_DISPLAY_CLOSE; _al_event_source_emit_event(src, &evt); _al_event_source_unlock(src); return NO; } -(void) viewDidEndLiveResize { [super viewDidEndLiveResize]; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; NSWindow *window = dpy->win; NSRect rc = [window frame]; NSRect content = [window contentRectForFrameRect: rc]; ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.timestamp = al_get_time(); event.display.width = NSWidth(content); event.display.height = NSHeight(content); _al_event_source_emit_event(es, &event); ALLEGRO_INFO("Window finished resizing"); } _al_event_source_unlock(es); } /* Window switch in/out */ -(void) windowDidBecomeMain:(NSNotification*) notification { (void)notification; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); _al_event_source_lock(src); ALLEGRO_EVENT evt; evt.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; _al_event_source_emit_event(src, &evt); _al_osx_switch_keyboard_focus(dpy_ptr, true); _al_event_source_unlock(src); osx_change_cursor(dpy, dpy->cursor); } -(void) windowDidResignMain:(NSNotification*) notification { (void)notification; ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); _al_event_source_lock(src); ALLEGRO_EVENT evt; evt.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; _al_event_source_emit_event(src, &evt); _al_osx_switch_keyboard_focus(dpy_ptr, false); _al_event_source_unlock(src); } -(void) windowDidResize:(NSNotification*) notification { (void)notification; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; NSWindow *window = dpy->win; NSRect rc = [window frame]; NSRect content = [window contentRectForFrameRect: rc]; ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; event.display.timestamp = al_get_time(); event.display.width = NSWidth(content); event.display.height = NSHeight(content); _al_event_source_emit_event(es, &event); ALLEGRO_INFO("Window was resized\n"); } _al_event_source_unlock(es); } -(void) enterFullScreenWindowMode { #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; int flags = NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; [dict setObject:[NSNumber numberWithInt: flags] forKey:NSFullScreenModeApplicationPresentationOptions]; [[dpy->win contentView] enterFullScreenMode: [dpy->win screen] withOptions: dict]; [dict release]; #endif } -(void) exitFullScreenWindowMode { ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; /* Going from a fullscreen window to a smaller window, the mouse may end up outside * the window when it was inside before (not possible the other way.) This causes a * crash. To avoid it, remove the tracking area and add it back after exiting fullscreen. * (my theory) */ [dpy->win orderOut:[dpy->win contentView]]; [self exitFullScreenModeWithOptions: nil]; } -(void) finishExitingFullScreenWindowMode { ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; [dpy->win center]; [dpy->win makeKeyAndOrderFront:[dpy->win contentView]]; [[self window] makeFirstResponder: self]; } /* End of ALOpenGLView implementation */ @end /* osx_view_from_display: * given an ALLEGRO_DISPLAY, return the associated Cocoa View or nil * if fullscreen */ static NSView* osx_view_from_display(ALLEGRO_DISPLAY* disp) { NSWindow* window = ((ALLEGRO_DISPLAY_OSX_WIN*) disp)->win; return window == nil ? nil : [window contentView]; } /* set_current_display: * Set the current windowed display to be current. */ bool set_current_display(ALLEGRO_DISPLAY* d) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; if (dpy->ctx != nil) { [dpy->ctx makeCurrentContext]; } _al_ogl_set_extensions(d->ogl_extras->extension_api); return true; } /* Helper to set up GL state as we want it. */ static void setup_gl(ALLEGRO_DISPLAY *d) { glViewport(0, 0, d->w, d->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, d->w, d->h, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; [dpy->ctx update]; } /* Fills the array of NSOpenGLPixelFormatAttributes, which has a specfied * maximum size, with the options appropriate for the display. */ static void osx_set_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy) { int i, n; bool want_double_buffer; NSOpenGLPixelFormatAttribute *a; ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; /* The following combination of flags indicates that multi-sampling is * requested. */ const int sample_flags = (1<attributes, 0, AL_OSX_NUM_PFA*sizeof(*dpy->attributes)); /* We normally want a double buffer */ want_double_buffer = true; /* Begin with the first attribute */ a = dpy->attributes; /* First, check the display flags, so we know if we want a fullscreen * mode or a windowed mode. */ if (dpy->parent.flags & ALLEGRO_FULLSCREEN) { *a = NSOpenGLPFAFullScreen; a++; // Take over the screen. *a = NSOpenGLPFAScreenMask; a++; *a = CGDisplayIDToOpenGLDisplayMask(dpy->display_id); a++; } else { *a = NSOpenGLPFAWindow; a++; } /* Find the requested colour depth */ if (extras) dpy->depth = extras->settings[ALLEGRO_COLOR_SIZE]; if (!dpy->depth) { /* Use default */ NSScreen *screen; int adapter = al_get_new_display_adapter(); if ((adapter >= 0) && (adapter < al_get_num_video_adapters())) { screen = [[NSScreen screens] objectAtIndex: adapter]; } else { screen = [NSScreen mainScreen]; } dpy->depth = NSBitsPerPixelFromDepth([screen depth]); if (dpy->depth == 24) dpy->depth = 32; if (dpy->depth == 15) dpy->depth = 16; ALLEGRO_DEBUG("Using default colour depth %d\n", dpy->depth); } *a = NSOpenGLPFAColorSize; a++; *a = dpy->depth; a++; /* Say we don't need an exact match for the depth of the colour buffer. * FIXME: right now, this is set whenever nothing is required or * something is suggested. Probably need finer control over this... */ if (!extras || !(extras->required) || extras->suggested) { *a = NSOpenGLPFAClosestPolicy; a++; } /* Should we set double buffering? If it's not required we don't care * and go with the default. */ if (extras && (extras->required & (1 << ALLEGRO_SINGLE_BUFFER)) && extras->settings[ALLEGRO_SINGLE_BUFFER]) { want_double_buffer = false; } if (want_double_buffer) { *a = NSOpenGLPFADoubleBuffer; a++; } /* Detect if multi-sampling is requested */ /* Or "NSOpenGLPFASupersample" ? */ if (extras && (extras->required & sample_flags) && (extras->settings[ALLEGRO_SAMPLES]||extras->settings[ALLEGRO_SAMPLE_BUFFERS])) { *a = NSOpenGLPFAMultisample; a++; } /* Now go through all other options, if set */ for (n = 0; n < number_of_settings; n++) { i = allegro_to_osx_settings[n][0]; if (allegro_to_osx_settings[n][1] && extras && ((extras->required & (1 << i)) || (extras->suggested & (1 << i)))) { /* Need to distinguish between boolean attributes and settings that * require a value. */ if (allegro_to_osx_settings[n][2]) { /* Value */ /* We must make sure the value is non-zero because the list are * building is 0-terminated. */ if (extras->settings[i]) { *a = allegro_to_osx_settings[n][1]; a++; *a = extras->settings[i]; a++; ALLEGRO_DEBUG("Passing pixel format attribute %s = %d\n", allegro_pixel_format_names[n], extras->settings[i]); } } else if (extras->settings[i]) { /* Boolean, just turn this on */ *a = allegro_to_osx_settings[n][1]; a++; ALLEGRO_DEBUG("Passing pixel format attribute %s = %d\n", allegro_pixel_format_names[n], extras->settings[i]); } } } /* Accelerated is always preferred, so we only set this for required not * for suggested. */ if (extras->required & ALLEGRO_RENDER_METHOD) { *a++ = NSOpenGLPFAAccelerated; } } /* Set the extra_settings[] array in the display, to report which options * we have selected. */ static void osx_get_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy) { int n; if (!dpy) return; /* Clear list of settings (none selected) */ memset(&dpy->parent.extra_settings, 0, sizeof(dpy->parent.extra_settings)); #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 /* Get the pixel format associated with the OpenGL context. * We use the Carbon API rather than the Cocoa API because that way we * can use the same code in Windowed mode as in fullscreen mode (we * don't have an NSOpenGLView in fullscreen mode). */ CGLContextObj ctx = [dpy->ctx CGLContextObj]; CGLPixelFormatObj pixel_format = CGLGetPixelFormat(ctx); GLint screen_id; CGLGetVirtualScreen(ctx, &screen_id); ALLEGRO_DEBUG("Screen has ID %d\n", (int)screen_id); for (n = 0; n < number_of_settings; n++) { /* Go through the list of options and relist the ones that we have * set to Allegro's option list. */ CGLPixelFormatAttribute attrib = allegro_to_osx_settings[n][1]; /* Skip options that don't exist on OS X */ if (attrib == 0) continue; /* Get value for this attribute */ GLint value; CGLDescribePixelFormat(pixel_format, screen_id, attrib, &value); int al_setting = allegro_to_osx_settings[n][0]; if (allegro_to_osx_settings[n][2] == 0) /* Boolean attribute */ value = 1; dpy->parent.extra_settings.settings[al_setting] = value; ALLEGRO_DEBUG("Pixel format attribute %s set to %d\n", allegro_pixel_format_names[n], value); } #else /* CGLGetPixelFormat does not exist on Tiger, so we need to do something * else. * FIXME: right now, we just return the settings that were chosen by the * user. To be correct, we should query the pixelformat corresponding to * the display, using the NSOpenGLView pixelFormat method and the * NSOpenGLPixelFormat getValues:forAttribute:forVirtualScreen: method, * for which we need to know the logical screen number that the display * is on. That doesn't work for fullscreen modes though... */ NSOpenGLPixelFormatAttribute *attributes = dpy->attributes; for (n = 0; n < number_of_settings; n++) { /* Go through the list of options and relist the ones that we have * set to Allegro's option list. */ NSOpenGLPixelFormatAttribute *a = dpy->attributes; while (*a) { if (*a == allegro_to_osx_settings[n][1]) { int al_setting = allegro_to_osx_settings[n][0]; int value = 1; if (allegro_to_osx_settings[n][2]) value = a[1]; dpy->parent.extra_settings.settings[al_setting] = value; ALLEGRO_DEBUG("Setting pixel format attribute %d to %d\n", al_setting, value); } /* Advance to next option */ if (allegro_to_osx_settings[n][2]) /* Has a parameter in the list */ a++; a++; } } #endif dpy->parent.extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; // Fill in the missing colour format options, as best we can ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = &dpy->parent.extra_settings; if (eds->settings[ALLEGRO_COLOR_SIZE] == 0) { eds->settings[ALLEGRO_COLOR_SIZE] = 32; eds->settings[ALLEGRO_RED_SIZE] = 8; eds->settings[ALLEGRO_GREEN_SIZE] = 8; eds->settings[ALLEGRO_BLUE_SIZE] = 8; eds->settings[ALLEGRO_ALPHA_SIZE] = 8; eds->settings[ALLEGRO_RED_SHIFT] = 0; eds->settings[ALLEGRO_GREEN_SHIFT] = 8; eds->settings[ALLEGRO_BLUE_SHIFT] = 16; eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; } else { int size = eds->settings[ALLEGRO_ALPHA_SIZE]; if (!size) { switch (eds->settings[ALLEGRO_COLOR_SIZE]) { case 32: size = 8; break; case 16: size = 5; break; case 8: size = 8; break; } } if (!eds->settings[ALLEGRO_RED_SIZE]) eds->settings[ALLEGRO_RED_SIZE] = size; if (!eds->settings[ALLEGRO_BLUE_SIZE]) eds->settings[ALLEGRO_BLUE_SIZE] = size; if (!eds->settings[ALLEGRO_GREEN_SIZE]) eds->settings[ALLEGRO_GREEN_SIZE] = size; if (!eds->settings[ALLEGRO_RED_SHIFT]) eds->settings[ALLEGRO_RED_SHIFT] = 0; if (!eds->settings[ALLEGRO_GREEN_SHIFT]) eds->settings[ALLEGRO_GREEN_SHIFT] = eds->settings[ALLEGRO_RED_SIZE]; if (!eds->settings[ALLEGRO_BLUE_SHIFT]) eds->settings[ALLEGRO_BLUE_SHIFT] = eds->settings[ALLEGRO_GREEN_SIZE]+eds->settings[ALLEGRO_GREEN_SHIFT]; if (!eds->settings[ALLEGRO_ALPHA_SHIFT]) eds->settings[ALLEGRO_ALPHA_SHIFT] = eds->settings[ALLEGRO_BLUE_SIZE]+eds->settings[ALLEGRO_BLUE_SHIFT]; } } /* The purpose of this object is to provide a receiver for "perform on main * thread" messages - we can't call C function directly so we do it * like this. * The perform on main thread mechanism is a simple way to avoid threading * issues. */ @interface ALDisplayHelper : NSObject +(void) initialiseDisplay: (NSValue*) display_object; +(void) destroyDisplay: (NSValue*) display_object; +(void) runFullScreenDisplay: (NSValue*) display_object; @end @implementation ALDisplayHelper +(void) initialiseDisplay: (NSValue*) display_object { ALLEGRO_DISPLAY_OSX_WIN* dpy = [display_object pointerValue]; NSRect rc = NSMakeRect(0, 0, dpy->parent.w, dpy->parent.h); NSWindow* win = dpy->win = [ALWindow alloc]; NSScreen *screen; unsigned int mask = (dpy->parent.flags & ALLEGRO_FRAMELESS) ? NSBorderlessWindowMask : (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask); if (dpy->parent.flags & ALLEGRO_RESIZABLE) mask |= NSResizableWindowMask; if (dpy->parent.flags & ALLEGRO_FULLSCREEN) mask |= NSResizableWindowMask; if ((new_display_adapter >= 0) && (new_display_adapter < al_get_num_video_adapters())) { screen = [[NSScreen screens] objectAtIndex: new_display_adapter]; } else { screen = [NSScreen mainScreen]; } [win initWithContentRect: rc styleMask: mask backing: NSBackingStoreBuffered defer: NO screen: screen]; if (dpy->parent.flags & ALLEGRO_RESIZABLE) { if ([win respondsToSelector:NSSelectorFromString(@"setCollectionBehavior:")]) { [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } } NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: dpy->attributes]; ALOpenGLView* view = [[ALOpenGLView alloc] initWithFrame: rc]; dpy->ctx = osx_create_shareable_context(fmt, &dpy->display_group); if (dpy->ctx == nil) { ALLEGRO_DEBUG("Could not create rendering context\n"); [view release]; [fmt release]; return; } [view setOpenGLContext: dpy->ctx]; [view setPixelFormat: fmt]; /* Hook up the view to its display */ [view setAllegroDisplay: &dpy->parent]; /* Realize the window on the main thread */ [win setContentView: view]; [win setDelegate: view]; [win setReleasedWhenClosed: YES]; [win setAcceptsMouseMovedEvents: _osx_mouse_installed]; [win setTitle: @"Allegro"]; /* Set minimum size, otherwise the window can be resized so small we can't * grab the handle any more to make it bigger */ [win setMinSize: NSMakeSize(MINIMUM_WIDTH, MINIMUM_HEIGHT)]; /* Place the window, respecting the location set by the user with * al_set_new_window_position(). * If the user never called al_set_new_window_position, we simply let * the window manager pick a suitable location. * * CAUTION: the window manager under OS X requires that x and y be in * the range -16000 ... 16000 (approximately, probably the range of a * signed 16 bit integer). Should we check for this? */ if ((new_window_pos_x != INT_MAX) && (new_window_pos_y != INT_MAX)) { /* The user gave us window coordinates */ NSRect rc = [win frame]; NSRect sc = [[win screen] frame]; NSPoint origin; /* We need to modify the y coordinate, cf. set_window_position */ origin.x = sc.origin.x + new_window_pos_x; origin.y = sc.origin.y + sc.size.height - rc.size.height - new_window_pos_y; [win setFrameOrigin: origin]; } else { /* Center the window */ NSRect rc = [win frame]; NSRect sc = [[win screen] frame]; NSPoint origin; origin.x = sc.origin.x + sc.size.width/2 - rc.size.width/2; origin.y = sc.origin.y + sc.size.height/2 - rc.size.height/2; [win setFrameOrigin: origin]; } [win makeKeyAndOrderFront:self]; if (!(mask & NSBorderlessWindowMask)) [win makeMainWindow]; [fmt release]; [view release]; } +(void) destroyDisplay: (NSValue*) display_object { ALLEGRO_DISPLAY_OSX_WIN* dpy = [display_object pointerValue]; ALLEGRO_OGL_EXTRAS *ogl = ((ALLEGRO_DISPLAY *)dpy)->ogl_extras; _al_vector_find_and_delete(&al_get_system_driver()->displays, &dpy); if (ogl->backbuffer) { _al_ogl_destroy_backbuffer(ogl->backbuffer); ogl->backbuffer = NULL; ALLEGRO_DEBUG("destroy backbuffer.\n"); } // Disconnect from its view or exit fullscreen mode [dpy->ctx clearDrawable]; // Unlock the screen if (dpy->parent.flags & ALLEGRO_FULLSCREEN) { #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 if (dpy->win) { [[dpy->win contentView] exitFullScreenModeWithOptions: nil]; } #endif CGDisplayRelease(dpy->display_id); dpy->in_fullscreen = false; } if (dpy->win) { // Destroy the containing window if there is one [dpy->win close]; dpy->win = nil; } } /* runFullScreenDisplay: * Capture the display and enter fullscreen mode. Do not leave this function * until full screen is cancelled */ +(void) runFullScreenDisplay: (NSValue*) display_object { ALLEGRO_DISPLAY* display = (ALLEGRO_DISPLAY*) [display_object pointerValue]; ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; while (dpy->in_fullscreen) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // Collect an event NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES]; // Process it as required. switch ([event type]) { case NSKeyDown: _al_osx_keyboard_handler(true,event,display); break; case NSKeyUp: _al_osx_keyboard_handler(false,event,display); break; case NSFlagsChanged: _al_osx_keyboard_modifiers([event modifierFlags],display); break; case NSLeftMouseDown: case NSLeftMouseUp: case NSRightMouseDown: case NSRightMouseUp: case NSOtherMouseDown: case NSOtherMouseUp: case NSMouseMoved: case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: if (_osx_mouse_installed) _al_osx_mouse_generate_event(event, display); break; default: [NSApp sendEvent: event]; break; } [pool release]; } } /* End of ALDisplayHelper implementation */ @end /* osx_create_shareable_context: * * Create an NSOpenGLContext with a given pixel format. If possible, make * the context compatible with one that has already been created and * assigned to a display. If this can't be done, create an unshared one * (which may itself be shared in the future) * Each context is given a group number so that all shared contexts have the * same group number. * * Parameters: * fmt - The pixel format to use * group - Pointer to the assigned group for the new context * * Returns: * The new context or nil if it cannot be created. */ static NSOpenGLContext* osx_create_shareable_context(NSOpenGLPixelFormat* fmt, unsigned int* group) { // Iterate through all existing displays and try and find one that's compatible _AL_VECTOR* dpys = &al_get_system_driver()->displays; unsigned int i; NSOpenGLContext* compat = nil; for (i = 0; i < _al_vector_size(dpys); ++i) { ALLEGRO_DISPLAY_OSX_WIN* other = *(ALLEGRO_DISPLAY_OSX_WIN**) _al_vector_ref(dpys, i); compat = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext: other->ctx]; if (compat != nil) { // OK, we can share with this one *group = other->display_group; ALLEGRO_DEBUG("Sharing display group %d\n", *group); break; } } if (compat == nil) { // Set to a new group *group = next_display_group++; ALLEGRO_DEBUG("Creating new display group %d\n", *group); compat = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext: nil]; } return compat; } /* create_display_fs: * Create a fullscreen display - capture the display */ static ALLEGRO_DISPLAY* create_display_fs(int w, int h) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DEBUG("Switching to fullscreen mode sized %dx%d\n", w, h); if (al_get_new_display_adapter() >= al_get_num_video_adapters()) { [pool drain]; return NULL; } ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); if (dpy == NULL) { [pool drain]; return NULL; } memset(dpy, 0, sizeof(*dpy)); /* Set up the ALLEGRO_DISPLAY part */ dpy->parent.vt = _al_osx_get_display_driver_fs(); dpy->parent.refresh_rate = al_get_new_display_refresh_rate(); dpy->parent.flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_FULLSCREEN; dpy->parent.w = w; dpy->parent.h = h; _al_event_source_init(&dpy->parent.es); dpy->cursor = [[NSCursor arrowCursor] retain]; dpy->display_id = CGMainDisplayID(); /* Get display ID for the requested display */ if (al_get_new_display_adapter() > 0) { int adapter = al_get_new_display_adapter(); NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; NSDictionary *dict = [screen deviceDescription]; NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 dpy->display_id = [display_id intValue]; #else dpy->display_id = [display_id integerValue]; #endif //dpy->display_id = (CGDirectDisplayID)[display_id pointerValue]; } // Set up a pixel format to describe the mode we want. osx_set_opengl_pixelformat_attributes(dpy); NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: dpy->attributes]; if (fmt == nil) { ALLEGRO_DEBUG("Could not set pixel format\n"); [pool drain]; return NULL; } // Create a context which shares with any other contexts with the same format NSOpenGLContext* context = osx_create_shareable_context(fmt, &dpy->display_group); [fmt release]; if (context == nil) { ALLEGRO_DEBUG("Could not create rendering context\n"); [pool drain]; return NULL; } [context makeCurrentContext]; dpy->ctx = context; // Prevent other apps from writing to this display and switch it to our // chosen mode. #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 CGDisplayCapture(dpy->display_id); CFDictionaryRef mode = CGDisplayBestModeForParametersAndRefreshRate(dpy->display_id, dpy->depth, w, h, dpy->parent.refresh_rate, NULL); CGDisplaySwitchToMode(dpy->display_id, mode); #else CGDisplayModeRef mode = NULL; CFArrayRef modes = NULL; CFStringRef pixel_format = NULL; int i; /* Set pixel format string */ if (dpy->depth == 32) pixel_format = CFSTR(IO32BitDirectPixels); if (dpy->depth == 16) pixel_format = CFSTR(IO16BitDirectPixels); if (dpy->depth == 8) pixel_format = CFSTR(IO8BitIndexedPixels); modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); for (i = 0; i < CFArrayGetCount(modes); i++) { CGDisplayModeRef try_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); /* Found mode with matching size/colour depth */ if ( w == (int)CGDisplayModeGetWidth(try_mode) && h == (int)CGDisplayModeGetHeight(try_mode) && CFStringCompare(pixel_encoding, pixel_format, 1) == 0) { mode = try_mode; CFRelease(pixel_encoding); break; } /* Found mode with matching size; colour depth does not match, but * it's the best so far. */ if ( w == (int)CGDisplayModeGetWidth(try_mode) && h == (int)CGDisplayModeGetHeight(try_mode) && mode == NULL) { mode = try_mode; } CFRelease(pixel_encoding); } CFRelease(modes); if (!mode) { /* Trouble! - we can't find a nice mode to set. */ [dpy->ctx clearDrawable]; CGDisplayRelease(dpy->display_id); al_free(dpy); [pool drain]; return NULL; } /* Switch display mode */ CFDictionaryRef options = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL); CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); CFRelease(options); #endif [context setFullScreen]; // Set up the Allegro OpenGL implementation dpy->parent.ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); memset(dpy->parent.ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); _al_ogl_manage_extensions(&dpy->parent); _al_ogl_set_extensions(dpy->parent.ogl_extras->extension_api); dpy->parent.ogl_extras->is_shared = true; /* Retrieve the options that were set */ osx_get_opengl_pixelformat_attributes(dpy); dpy->parent.ogl_extras->backbuffer = _al_ogl_create_backbuffer(&dpy->parent); /* Turn on vsyncing possibly */ if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { GLint swapInterval = 1; [context setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } else { GLint swapInterval = 0; [context setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } /* Set up GL as we want */ setup_gl(&dpy->parent); /* Clear and flush (for double buffering) */ glClear(GL_COLOR_BUFFER_BIT); [context flushBuffer]; glClear(GL_COLOR_BUFFER_BIT); /* Add to the display list */ ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); *add = &dpy->parent; dpy->in_fullscreen = YES; // Begin the 'private' event loop // Necessary because there's no NSResponder (i.e. a view) to collect // events from the window server. [ALDisplayHelper performSelectorOnMainThread: @selector(runFullScreenDisplay:) withObject: [NSValue valueWithPointer:dpy] waitUntilDone: NO]; [pool drain]; return &dpy->parent; } #if 0 /* Alternative, Cocoa-based mode switching. * Works, but I can't get the display to respond to a resize request * properly - EG */ static ALLEGRO_DISPLAY* create_display_fs(int w, int h) { ALLEGRO_DEBUG("Creating full screen mode sized %dx%d\n", w, h); if (al_get_new_display_adapter() >= al_get_num_video_adapters()) return NULL; ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); if (dpy == NULL) { return NULL; } memset(dpy, 0, sizeof(*dpy)); /* Set up the ALLEGRO_DISPLAY part */ dpy->parent.vt = _al_osx_get_display_driver_win(); dpy->parent.refresh_rate = al_get_new_display_refresh_rate(); dpy->parent.flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_FULLSCREEN; dpy->parent.w = w; dpy->parent.h = h; _al_event_source_init(&dpy->parent.es); osx_change_cursor(dpy, [NSCursor arrowCursor]); dpy->show_cursor = YES; // Set up a pixel format to describe the mode we want. osx_set_opengl_pixelformat_attributes(dpy); // Clear last window position to 0 if there are no other open windows if (_al_vector_is_empty(&al_get_system_driver()->displays)) { last_window_pos = NSZeroPoint; } /* OSX specific part - finish the initialisation on the main thread */ [ALDisplayHelper performSelectorOnMainThread: @selector(initialiseDisplay:) withObject: [NSValue valueWithPointer:dpy] waitUntilDone: YES]; [dpy->ctx makeCurrentContext]; [dpy->ctx setFullScreen]; NSScreen *screen = [dpy->win screen]; NSDictionary *dict = [screen deviceDescription]; NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; dpy->display_id = [display_id integerValue]; //dpy->display_id = (CGDirectDisplayID)[display_id pointerValue]; CGDisplayCapture(dpy->display_id); #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 CFDictionaryRef mode = CGDisplayBestModeForParametersAndRefreshRate(dpy->display_id, dpy->depth, w, h, dpy->parent.refresh_rate, NULL); CGDisplaySwitchToMode(dpy->display_id, mode); #else CGDisplayModeRef mode = NULL; CFArrayRef modes = NULL; CFStringRef pixel_format = NULL; int i; /* Set pixel format string */ if (dpy->depth == 32) pixel_format = CFSTR(IO32BitDirectPixels); if (dpy->depth == 16) pixel_format = CFSTR(IO16BitDirectPixels); if (dpy->depth == 8) pixel_format = CFSTR(IO8BitIndexedPixels); modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); for (i = 0; i < CFArrayGetCount(modes); i++) { CGDisplayModeRef try_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); /* Found mode with matching size/colour depth */ if ( w == (int)CGDisplayModeGetWidth(try_mode) && h == (int)CGDisplayModeGetHeight(try_mode) && CFStringCompare(pixel_encoding, pixel_format, 1) == 0) { mode = try_mode; CFRelease(pixel_encoding); break; } /* Found mode with matching size; colour depth does not match, but * it's the best so far. */ if ( w == (int)CGDisplayModeGetWidth(try_mode) && h == (int)CGDisplayModeGetHeight(try_mode) && mode == NULL) { mode = try_mode; } CFRelease(pixel_encoding); } if (!mode) { /* Trouble! - we can't find a nice mode to set. */ [dpy->ctx clearDrawable]; CGDisplayRelease(dpy->display_id); [dpy->win close]; al_free(dpy); return NULL; } /* Switch display mode */ CFDictionaryRef options = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL); CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); CFRelease(options); CFRelease(modes); #endif [[dpy->win contentView] enterFullScreenMode: screen withOptions: nil]; // Set up the Allegro OpenGL implementation dpy->parent.ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); memset(dpy->parent.ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); _al_ogl_manage_extensions(&dpy->parent); _al_ogl_set_extensions(dpy->parent.ogl_extras->extension_api); dpy->parent.ogl_extras->is_shared = true; /* Retrieve the options that were set */ osx_get_opengl_pixelformat_attributes(dpy); dpy->parent.ogl_extras->backbuffer = _al_ogl_create_backbuffer(&dpy->parent); if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { GLint swapInterval = 1; [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } else { GLint swapInterval = 0; [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } /* Set up GL as we want */ setup_gl(&dpy->parent); /* Add to the display list */ ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); *add = &dpy->parent; dpy->in_fullscreen = YES; return &dpy->parent; } #endif /* create_display_win: * Create a windowed display - create the window with an ALOpenGLView * to be its content view */ static ALLEGRO_DISPLAY* create_display_win(int w, int h) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; /* Create a temporary view so that we can check whether a fullscreen * window can be created. */ if (al_get_new_display_flags() & ALLEGRO_FULLSCREEN_WINDOW) { NSRect rc = NSMakeRect(0, 0, w, h); ALOpenGLView* view = [[ALOpenGLView alloc] initWithFrame: rc]; if (![view respondsToSelector: @selector(enterFullScreenMode:withOptions:)]) { ALLEGRO_DEBUG("Cannot create FULLSCREEN_WINDOW"); [view release]; [pool drain]; return NULL; } [view release]; } ALLEGRO_DEBUG("Creating window sized %dx%d\n", w, h); if (al_get_new_display_adapter() >= al_get_num_video_adapters()) { [pool drain]; return NULL; } ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); if (dpy == NULL) { [pool drain]; return NULL; } memset(dpy, 0, sizeof(*dpy)); /* Set up the ALLEGRO_DISPLAY part */ dpy->parent.vt = _al_osx_get_display_driver_win(); dpy->parent.refresh_rate = al_get_new_display_refresh_rate(); dpy->parent.flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_WINDOWED; dpy->parent.w = w; dpy->parent.h = h; _al_event_source_init(&dpy->parent.es); osx_change_cursor(dpy, [NSCursor arrowCursor]); dpy->show_cursor = YES; // Set up a pixel format to describe the mode we want. osx_set_opengl_pixelformat_attributes(dpy); // Clear last window position to 0 if there are no other open windows if (_al_vector_is_empty(&al_get_system_driver()->displays)) { last_window_pos = NSZeroPoint; } /* Get the new window position. This is stored in TLS, so we need to do * this before calling initialiseDisplay, which runs on a different * threat. */ al_get_new_window_position(&new_window_pos_x, &new_window_pos_y); new_display_adapter = al_get_new_display_adapter(); /* OSX specific part - finish the initialisation on the main thread */ [ALDisplayHelper performSelectorOnMainThread: @selector(initialiseDisplay:) withObject: [NSValue valueWithPointer:dpy] waitUntilDone: YES]; if (dpy->parent.flags & ALLEGRO_FULLSCREEN_WINDOW) { NSRect sc = [[dpy->win screen] frame]; dpy->parent.w = sc.size.width; dpy->parent.h = sc.size.height; } [dpy->ctx makeCurrentContext]; /* Print out OpenGL version info */ ALLEGRO_INFO("OpenGL Version: %s\n", glGetString(GL_VERSION)); ALLEGRO_INFO("Vendor: %s\n", glGetString(GL_VENDOR)); ALLEGRO_INFO("Renderer: %s\n", glGetString(GL_RENDERER)); /* Set up a pixel format to describe the mode we want. */ osx_set_opengl_pixelformat_attributes(dpy); /* Retrieve the options that were set */ // Note: This initializes dpy->extra_settings osx_get_opengl_pixelformat_attributes(dpy); // Set up the Allegro OpenGL implementation dpy->parent.ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); memset(dpy->parent.ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); _al_ogl_manage_extensions(&dpy->parent); _al_ogl_set_extensions(dpy->parent.ogl_extras->extension_api); dpy->parent.ogl_extras->is_shared = true; dpy->parent.ogl_extras->backbuffer = _al_ogl_create_backbuffer(&dpy->parent); if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { GLint swapInterval = 1; [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } else { GLint swapInterval = 0; [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; } /* Set up GL as we want */ setup_gl(&dpy->parent); /* Add to the display list */ ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); *add = &dpy->parent; dpy->in_fullscreen = NO; if (dpy->parent.flags & ALLEGRO_FULLSCREEN_WINDOW) { dpy->parent.flags ^= ALLEGRO_FULLSCREEN_WINDOW; /* Not set yet */ set_display_flag(&dpy->parent, ALLEGRO_FULLSCREEN_WINDOW, true); } [pool drain]; return &dpy->parent; } /* destroy_display: * Destroy display, actually close the window or exit fullscreen on the main thread */ static void destroy_display(ALLEGRO_DISPLAY* d) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DISPLAY *old_dpy = al_get_current_display(); ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; ALLEGRO_DISPLAY_OSX_WIN* other = NULL; unsigned int i; // Set the display as the current display; needed because we need to // make the context current. if (old_dpy != d) _al_set_current_display_only(d); /* First of all, save video bitmaps attached to this display. */ // Check for other displays in this display group _AL_VECTOR* dpys = &al_get_system_driver()->displays; for (i = 0; i < _al_vector_size(dpys); ++i) { ALLEGRO_DISPLAY_OSX_WIN* d = *(ALLEGRO_DISPLAY_OSX_WIN**) _al_vector_ref(dpys, i); if (d->display_group == dpy->display_group && (d!=dpy)) { other = d; break; } } if (other != NULL) { // Found another compatible display. Transfer our bitmaps to it. _AL_VECTOR* bmps = &dpy->parent.bitmaps; for (i = 0; i<_al_vector_size(bmps); ++i) { ALLEGRO_BITMAP **add = _al_vector_alloc_back(&other->parent.bitmaps); ALLEGRO_BITMAP **ref = _al_vector_ref(bmps, i); *add = *ref; (*add)->display = &(other->parent); } } else { // This is the last in its group. Convert all its bitmaps to memory bmps while (dpy->parent.bitmaps._size > 0) { ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&dpy->parent.bitmaps); ALLEGRO_BITMAP *bmp = *bptr; _al_convert_to_memory_bitmap(bmp); } } _al_vector_free(&dpy->parent.bitmaps); [ALDisplayHelper performSelectorOnMainThread: @selector(destroyDisplay:) withObject: [NSValue valueWithPointer:dpy] waitUntilDone: YES]; _al_ogl_unmanage_extensions(&dpy->parent); [dpy->ctx release]; [dpy->cursor release]; _al_event_source_free(&d->es); al_free(d->ogl_extras); // Restore original display from before this function was called. // If the display we just destroyed is actually current, set the current // display to NULL. if (old_dpy != d) _al_set_current_display_only(old_dpy); else { // Is this redundant? --pw _al_set_current_display_only(NULL); } al_free(d->vertex_cache); al_free(d); [pool drain]; } /* create_display: * Create a display either fullscreen or windowed depending on flags */ static ALLEGRO_DISPLAY* create_display(int w, int h) { int flags = al_get_new_display_flags(); if (flags & ALLEGRO_FULLSCREEN) { return create_display_fs(w,h); } else { return create_display_win(w,h); } } /* Note: in windowed mode, contexts always behave like single-buffered * though in fact they are composited offscreen */ static void flip_display(ALLEGRO_DISPLAY *disp) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) disp; ALLEGRO_BITMAP *old_target = NULL; if (!disp->ogl_extras->opengl_target->is_backbuffer) { old_target = al_get_target_bitmap(); al_set_target_backbuffer(disp); } if (disp->extra_settings.settings[ALLEGRO_SINGLE_BUFFER]) { glFlush(); } else { [dpy->ctx flushBuffer]; } if (old_target) { al_set_target_bitmap(old_target); } } static void update_display_region(ALLEGRO_DISPLAY *disp, int x, int y, int width, int height) { (void)x; (void)y; (void)width; (void)height; flip_display(disp); } /* _al_osx_create_mouse_cursor: * creates a custom system cursor from the bitmap bmp. * (x_focus, y_focus) indicates the cursor hot-spot. */ ALLEGRO_MOUSE_CURSOR *_al_osx_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_MOUSE_CURSOR_OSX *cursor = NULL; if (!bmp) { [pool drain]; return NULL; } NSImage* cursor_image = NSImageFromAllegroBitmap(bmp); cursor = al_malloc(sizeof *cursor); cursor->cursor = [[NSCursor alloc] initWithImage: cursor_image hotSpot: NSMakePoint(x_focus, y_focus)]; [cursor_image release]; [pool drain]; return (ALLEGRO_MOUSE_CURSOR *)cursor; } /* _al_osx_destroy_mouse_cursor: * destroys a mouse cursor previously created with _al_osx_create_mouse_cursor */ void _al_osx_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *curs) { ALLEGRO_MOUSE_CURSOR_OSX *cursor = (ALLEGRO_MOUSE_CURSOR_OSX *) curs; unsigned i; if (!cursor) return; /* XXX not at all thread safe */ _AL_VECTOR* dpys = &al_get_system_driver()->displays; for (i = 0; i < _al_vector_size(dpys); ++i) { ALLEGRO_DISPLAY* dpy = *(ALLEGRO_DISPLAY**) _al_vector_ref(dpys, i); ALLEGRO_DISPLAY_OSX_WIN *osx_dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy; if (osx_dpy->cursor == cursor->cursor) { osx_change_cursor(osx_dpy, [NSCursor arrowCursor]); } } [cursor->cursor release]; al_free(cursor); } /* osx_set_mouse_cursor: * change the mouse cursor for the active window to the cursor previously * allocated by osx_create_mouse_cursor */ static bool osx_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; ALLEGRO_MOUSE_CURSOR_OSX *osxcursor = (ALLEGRO_MOUSE_CURSOR_OSX *)cursor; osx_change_cursor(dpy, osxcursor->cursor); return true; } /* osx_set_system_mouse_cursor: * change the mouse cursor to one of the system default cursors. * NOTE: Allegro defines four of these, but OS X has no dedicated "busy" or * "question" cursors, so we just set an arrow in those cases. */ static bool osx_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; NSCursor *requested_cursor = NULL; switch (cursor_id) { case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: requested_cursor = [NSCursor arrowCursor]; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: requested_cursor = [NSCursor IBeamCursor]; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: requested_cursor = [NSCursor resizeUpDownCursor]; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: requested_cursor = [NSCursor resizeLeftRightCursor]; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: requested_cursor = [NSCursor crosshairCursor]; break; case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: requested_cursor = [NSCursor pointingHandCursor]; break; default: return false; } osx_change_cursor(dpy, requested_cursor); return true; } /* (show|hide)_cursor: Cursor show or hide. The same function works for both windowed and fullscreen. */ static bool show_cursor(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; dpy->show_cursor = YES; [NSCursor unhide]; return true; } static bool hide_cursor(ALLEGRO_DISPLAY *d) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; dpy->show_cursor = NO; [NSCursor hide]; return true; } static bool acknowledge_resize_display_win(ALLEGRO_DISPLAY *d) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)d; NSWindow* window = dpy->win; NSRect frame = [window frame]; NSRect content = [window contentRectForFrameRect: frame]; d->w = NSWidth(content); d->h = NSHeight(content); _al_ogl_resize_backbuffer(d->ogl_extras->backbuffer, d->w, d->h); setup_gl(d); [pool drain]; return true; } /* resize_display_(win|fs) * Change the size of the display by altering the window size or changing the screen mode */ static bool resize_display_win(ALLEGRO_DISPLAY *d, int w, int h) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; NSWindow* window = dpy->win; NSRect current = [window frame]; w = _ALLEGRO_MAX(w, MINIMUM_WIDTH); h = _ALLEGRO_MAX(h, MINIMUM_HEIGHT); NSRect rc = [window frameRectForContentRect: NSMakeRect(0.0f, 0.0f, (float) w, (float) h)]; rc.origin = current.origin; /* Don't resize a fullscreen window */ if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { [pool drain]; return false; } /* Finalise setting the frame on the main thread. Because this is where * the window's frame was initially set, this is where it should be * modified too. */ NSArray *param = [NSArray arrayWithObjects : [NSValue valueWithPointer:&rc], [NSValue valueWithPointer:window], nil]; [ALSetWindowFrame performSelectorOnMainThread: @selector(set_frame:) withObject: [NSValue valueWithPointer:param] waitUntilDone: YES]; [pool drain]; return acknowledge_resize_display_win(d); } static bool resize_display_fs(ALLEGRO_DISPLAY *d, int w, int h) { ALLEGRO_DEBUG("Resize full screen display to %d x %d\n", w, h); bool success = true; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 CFDictionaryRef current = CGDisplayCurrentMode(dpy->display_id); CFNumberRef bps = (CFNumberRef) CFDictionaryGetValue(current, kCGDisplayBitsPerPixel); int b; CFNumberGetValue(bps, kCFNumberSInt32Type,&b); CFDictionaryRef mode = CGDisplayBestModeForParameters(dpy->display_id, b, w, h, NULL); [dpy->ctx clearDrawable]; CGError err = CGDisplaySwitchToMode(dpy->display_id, mode); success = (err == kCGErrorSuccess); #else CGDisplayModeRef current = CGDisplayCopyDisplayMode(dpy->display_id); CFStringRef bps = CGDisplayModeCopyPixelEncoding(current); CFRelease(current); CGDisplayModeRef mode = NULL; CFArrayRef modes = NULL; int i; modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); for (i = 0; i < CFArrayGetCount(modes); i++) { CGDisplayModeRef try_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); /* Found mode with matching size/colour depth */ if ( w == (int)CGDisplayModeGetWidth(try_mode) && h == (int)CGDisplayModeGetHeight(try_mode) && CFStringCompare(pixel_encoding, bps, 1) == 0) { mode = try_mode; CFRelease(pixel_encoding); break; } CFRelease(pixel_encoding); } CFRelease(bps); CFRelease(modes); if (!mode) { ALLEGRO_DEBUG("Can't resize fullscreen display\n"); return false; } /* Switch display mode */ [dpy->ctx clearDrawable]; CFDictionaryRef options = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL); CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); CFRelease(options); #endif d->w = w; d->h = h; [dpy->ctx setFullScreen]; _al_ogl_resize_backbuffer(d->ogl_extras->backbuffer, d->w, d->h); setup_gl(d); return success; } static bool is_compatible_bitmap(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP* bmp) { return (bmp->display == disp) || (((ALLEGRO_DISPLAY_OSX_WIN*) bmp->display)->display_group == ((ALLEGRO_DISPLAY_OSX_WIN*) disp)->display_group); } /* set_window_position: * Set the position of the window that owns this display * Slightly complicated because Allegro measures from the top down to * the top left corner, OS X from the bottom up to the bottom left corner. */ static void set_window_position(ALLEGRO_DISPLAY* display, int x, int y) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display; NSWindow* window = d->win; NSRect rc = [window frame]; NSRect sc = [[window screen] frame]; rc.origin.x = (float) x; rc.origin.y = sc.size.height - rc.size.height - ((float) y); /* Finalise setting the frame on the main thread. Because this is where * the window's frame was initially set, this is where it should be * modified too. */ NSArray *param = [NSArray arrayWithObjects : [NSValue valueWithPointer:&rc], [NSValue valueWithPointer:window], nil]; [ALSetWindowFrame performSelectorOnMainThread: @selector(set_frame:) withObject: [NSValue valueWithPointer:param] waitUntilDone: YES]; [pool drain]; } /* get_window_position: * Get the position of the window that owns this display. See comment for * set_window_position. */ static void get_window_position(ALLEGRO_DISPLAY* display, int* px, int* py) { ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display; NSWindow* window = d->win; NSRect rc = [window frame]; NSRect sc = [[window screen] frame]; *px = (int) rc.origin.x; *py = (int) (sc.size.height - rc.origin.y - rc.size.height); } /* set_window_title: * Set the title of the window with this display */ static void set_window_title(ALLEGRO_DISPLAY *display, const char *title) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) display; [dpy->win setTitle: [NSString stringWithUTF8String:title]]; [pool drain]; } /* set_icons: * Set the icon - OS X doesn't have per-window icons so * ignore the display parameter */ static void set_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP* bitmaps[]) { /* Multiple icons not yet implemented. */ ALLEGRO_BITMAP *bitmap = bitmaps[num_icons - 1]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSImage *image = NSImageFromAllegroBitmap(bitmap); (void)display; [NSApp setApplicationIconImage: image]; [image release]; [pool drain]; } /* set_display_flag: * Change settings for an already active display */ static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 return false; #else if (!display) return false; ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; NSUInteger mask; NSWindow *win = dpy->win; if (!win) return false; switch (flag) { case ALLEGRO_FRAMELESS: mask = [win styleMask]; if (onoff) mask |= NSBorderlessWindowMask; else mask &= ~NSBorderlessWindowMask; ALLEGRO_DEBUG("Toggle FRAME for display %p to %d\n", dpy, onoff); [win setStyleMask : mask]; return true; case ALLEGRO_RESIZABLE: mask = [win styleMask]; if (onoff) mask |= NSResizableWindowMask; else mask &= ~NSResizableWindowMask; ALLEGRO_DEBUG("Toggle RESIZABLE for display %p to %d\n", dpy, onoff); [win setStyleMask : mask]; return true; case ALLEGRO_FULLSCREEN_WINDOW: { ALOpenGLView *view = (ALOpenGLView *)[win contentView]; if (onoff) { [view performSelectorOnMainThread: @selector(enterFullScreenWindowMode) withObject:nil waitUntilDone:YES]; NSRect sc = [[win screen] frame]; resize_display_win(display, sc.size.width, sc.size.height); display->flags |= ALLEGRO_FULLSCREEN_WINDOW; } else { [view performSelectorOnMainThread: @selector(exitFullScreenWindowMode) withObject:nil waitUntilDone:YES]; NSRect sc = [view frame]; display->flags &= ~ALLEGRO_FULLSCREEN_WINDOW; resize_display_win(display, sc.size.width, sc.size.height); [view performSelectorOnMainThread: @selector(finishExitingFullScreenWindowMode) withObject:nil waitUntilDone:YES]; } return true; } } return false; #endif } ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void) { static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); vt->create_display = create_display_win; vt->destroy_display = destroy_display; vt->set_current_display = set_current_display; vt->flip_display = flip_display; vt->update_display_region = update_display_region; vt->resize_display = resize_display_win; vt->acknowledge_resize = acknowledge_resize_display_win; vt->create_bitmap = _al_ogl_create_bitmap; vt->set_target_bitmap = _al_ogl_set_target_bitmap; vt->get_backbuffer = _al_ogl_get_backbuffer; vt->is_compatible_bitmap = is_compatible_bitmap; vt->create_sub_bitmap = _al_ogl_create_sub_bitmap; vt->show_mouse_cursor = show_cursor; vt->hide_mouse_cursor = hide_cursor; vt->set_mouse_cursor = osx_set_mouse_cursor; vt->set_system_mouse_cursor = osx_set_system_mouse_cursor; vt->get_window_position = get_window_position; vt->set_window_position = set_window_position; vt->set_window_title = set_window_title; vt->set_display_flag = set_display_flag; vt->set_icons = set_icons; _al_ogl_add_drawing_functions(vt); } return vt; } ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_fs(void) { static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); vt->create_display = create_display_fs; vt->destroy_display = destroy_display; vt->set_current_display = set_current_display; vt->flip_display = flip_display; vt->resize_display = resize_display_fs; vt->create_bitmap = _al_ogl_create_bitmap; vt->set_target_bitmap = _al_ogl_set_target_bitmap; vt->show_mouse_cursor = show_cursor; vt->hide_mouse_cursor = hide_cursor; vt->set_mouse_cursor = osx_set_mouse_cursor; vt->set_system_mouse_cursor = osx_set_system_mouse_cursor; vt->get_backbuffer = _al_ogl_get_backbuffer; vt->is_compatible_bitmap = is_compatible_bitmap; vt->create_sub_bitmap = _al_ogl_create_sub_bitmap; _al_ogl_add_drawing_functions(vt); } return vt; } /* Mini VT just for creating displays */ ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver(void) { static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); vt->create_display = create_display; } return vt; } /* Function: al_osx_get_window */ NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display) { if (!display) return NULL; return ((ALLEGRO_DISPLAY_OSX_WIN *)display)->win; } allegro-5.0.10/src/macosx/hidman.m0000644000175000001440000004112211520365435016111 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X HID Manager access routines. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintosx.h" #ifndef ALLEGRO_MACOSX #error Something is wrong with the makefile #endif #define USAGE(p, u) (((p)<<16)+(u)) static void hid_store_element_data(CFTypeRef element, int type, HID_DEVICE *device, int app, int collection, int index); static void hid_scan_physical_collection(CFTypeRef properties, HID_DEVICE *device, int app, int collection); static void hid_scan_application_collection(CFMutableDictionaryRef properties, HID_DEVICE *device); static HID_DEVICE* add_device(HID_DEVICE_COLLECTION*); /* add_element: * Add a new, blank element to a device. * This is later specialized into a button * axis or whatever */ static HID_ELEMENT* add_element(HID_DEVICE* d) { HID_ELEMENT* e; if (d->element==NULL) { d->capacity=8; d->element=al_malloc(d->capacity*sizeof(HID_ELEMENT)); } if (d->num_elements>=d->capacity) { d->capacity*=2; d->element=al_realloc(d->element, d->capacity*sizeof(HID_ELEMENT)); } e=&d->element[d->num_elements++]; memset(e, 0, sizeof(HID_ELEMENT)); return e; } /* i_val: * Helper method - get an integer value from a dictionary * Defaults to 0 if the value is not found; in practice this * should not occur. */ static int i_val(CFTypeRef d, CFStringRef key) { int ans; CFTypeRef num = CFDictionaryGetValue(d, key); if (num) CFNumberGetValue(num, kCFNumberIntType, &ans); else ans = 0; return ans; } /* hid_store_element_data: * Parse this HID element, break it down and store the * relevant data in the device structure */ static void hid_store_element_data(CFTypeRef element, int type, HID_DEVICE *device, int app, int col, int idx) { HID_ELEMENT *hid_element; CFTypeRef type_ref; const char *name; hid_element = add_element(device); hid_element->type = type; hid_element->index = idx; hid_element->col = col; hid_element->app = app; hid_element->cookie = (IOHIDElementCookie) i_val(element, CFSTR(kIOHIDElementCookieKey)); hid_element->min = i_val(element, CFSTR(kIOHIDElementMinKey)); hid_element->max = i_val(element, CFSTR(kIOHIDElementMaxKey)); type_ref = CFDictionaryGetValue(element, CFSTR(kIOHIDElementNameKey)); if ((type_ref) && (name = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) hid_element->name = strdup(name); else hid_element->name = NULL; } /* hid_scan_application: * scan the elements that make up one 'application' * i.e. one unit like a joystick. */ static void hid_scan_application(CFTypeRef properties, HID_DEVICE *device, int app) { CFTypeRef array_ref, element; int type, usage_page, usage; int i; int axis=0; int stick=0; array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { for (i = 0; i < CFArrayGetCount(array_ref); i++) { element = CFArrayGetValueAtIndex(array_ref, i); if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { type = i_val(element, CFSTR(kIOHIDElementTypeKey)); usage = i_val(element, CFSTR(kIOHIDElementUsageKey)); usage_page = i_val(element, CFSTR(kIOHIDElementUsagePageKey)); if (type == kIOHIDElementTypeCollection) { /* It is a collection; recurse into it, if it is part of the * generic desktop (sometimes the whole joystick is wrapped * up inside a collection like this. */ if (usage_page == kHIDPage_GenericDesktop) hid_scan_application(element, device, app); } else { switch (usage_page) { case kHIDPage_GenericDesktop: switch (usage) { case kHIDUsage_GD_Pointer: if (axis!=0) { /* already have some elements in this stick */ ++stick; axis=0; } hid_scan_physical_collection(element, device, app, stick); ++stick; break; case kHIDUsage_GD_X: hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_X, device, app, stick, axis++); break; case kHIDUsage_GD_Y: hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_Y, device, app, stick, axis++); break; case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: hid_store_element_data(element, HID_ELEMENT_AXIS, device,app, stick, axis++); break; case kHIDUsage_GD_Slider: case kHIDUsage_GD_Dial: case kHIDUsage_GD_Wheel: /* If we've already seen some axes on this stick, move to the next one */ if (axis > 0) { ++stick; axis=0; } hid_store_element_data(element, HID_ELEMENT_STANDALONE_AXIS, device, app, stick++, 0); break; case kHIDUsage_GD_Hatswitch: /* If we've already seen some axes on this stick, move to the next one */ if (axis > 0) { ++stick; axis=0; } hid_store_element_data(element, HID_ELEMENT_HAT, device, app, stick++, 0); break; } break; case kHIDPage_Button: hid_store_element_data(element, HID_ELEMENT_BUTTON, device, app, 0, usage-1); break; } } if (axis>=2) { ++stick; axis=0; } } } } } /* hid_scan_physical_collection: * scan the elements that make up one 'stick' */ static void hid_scan_physical_collection(CFTypeRef properties, HID_DEVICE *device, int app, int stick) { CFTypeRef array_ref, element; int type, usage_page, usage; int i; int axis=0; array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { for (i = 0; i < CFArrayGetCount(array_ref); i++) { element = CFArrayGetValueAtIndex(array_ref, i); if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { type = i_val(element, CFSTR(kIOHIDElementTypeKey)); usage = i_val(element, CFSTR(kIOHIDElementUsageKey)); usage_page = i_val(element, CFSTR(kIOHIDElementUsagePageKey)); switch (usage_page) { case kHIDPage_GenericDesktop: switch (usage) { case kHIDUsage_GD_X: hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_X, device, app, stick, axis++); break; case kHIDUsage_GD_Y: hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_Y, device, app, stick, axis++); break; case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: hid_store_element_data(element, HID_ELEMENT_AXIS, device,app, stick, axis++); break; } break; case kHIDPage_Button: hid_store_element_data(element, HID_ELEMENT_BUTTON, device, app, 0, usage-1); break; } } } } } /* hid_scan_application_collection: * Scan the elements array; each element will be an 'application' * i.e. one joystick, gamepad or mouse * */ static void hid_scan_application_collection(CFMutableDictionaryRef properties, HID_DEVICE *device) { CFTypeRef array_ref, element; int usage, usage_page; int i; array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { for (i = 0; i < CFArrayGetCount(array_ref); i++) { element = CFArrayGetValueAtIndex(array_ref, i); if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { usage=i_val(element, CFSTR(kIOHIDElementUsageKey)); usage_page=i_val(element, CFSTR(kIOHIDElementUsagePageKey)); switch (USAGE(usage_page, usage)) { case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick): device->type=HID_JOYSTICK; hid_scan_application(element, device, device->cur_app); device->cur_app++; break; case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad): device->type=HID_GAMEPAD; hid_scan_application(element, device, device->cur_app); device->cur_app++; break; case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse): device->type=HID_MOUSE; hid_scan_application(element, device, device->cur_app); device->cur_app++; break; } } } } } /* get_usb_properties: * Get a property dictionary from the USB plane. */ static CFMutableDictionaryRef get_usb_properties(io_object_t device) { io_registry_entry_t parent, grandparent; CFMutableDictionaryRef usb_properties = NULL; if (IORegistryEntryGetParentEntry(device, kIOServicePlane, &parent) == KERN_SUCCESS) { if (IORegistryEntryGetParentEntry(parent, kIOServicePlane, &grandparent) == KERN_SUCCESS) { IORegistryEntryCreateCFProperties (grandparent, &usb_properties, kCFAllocatorDefault, kNilOptions); IOObjectRelease(grandparent); } IOObjectRelease(parent); } return usb_properties; } #if OSX_HID_PSEUDO_SCAN /* * Pseudo scan - for development purposes, if someone has hardware * that isn't parsed by this code, you can ask them to dump _their_ scan * as a plist, then reload it here in order to debug it. */ HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION* col) { HID_DEVICE* this_device; NSDictionary* properties = nil; NSString* filename; switch (type) { case HID_GAMEPAD: filename = @"gamepad.plist"; break; case HID_JOYSTICK: filename = @"joystick.plist"; break; case HID_MOUSE: filename = @"mouse.plist"; break; default: filename = nil; break; } if (filename != nil) properties = [NSDictionary dictionaryWithContentsOfFile:filename]; if (properties) { this_device = add_device(col); this_device->manufacturer = strdup([((NSString*) [properties objectForKey: @kIOHIDManufacturerKey]) lossyCString]); this_device->product = strdup([((NSString*) [properties objectForKey: @kIOHIDProductKey]) lossyCString]); hid_scan_application_collection((CFDictionaryRef) properties, this_device); [properties release]; } return col; } #else /* _al_osx_hid_scan: * Scan the hid manager for devices of type 'type', * and append to the collection col */ HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION* col) { ASSERT(col); HID_DEVICE *this_device; mach_port_t master_port = 0; io_iterator_t hid_object_iterator = 0; io_object_t hid_device = 0; CFMutableDictionaryRef class_dictionary = NULL; int usage, usage_page; CFTypeRef type_ref; CFNumberRef usage_ref = NULL, usage_page_ref = NULL; CFMutableDictionaryRef properties = NULL, usb_properties = NULL; IOCFPlugInInterface **plugin_interface = NULL; IOReturn result; const char *string; SInt32 score = 0; int error; usage_page = kHIDPage_GenericDesktop; switch (type) { case HID_MOUSE: usage = kHIDUsage_GD_Mouse; break; case HID_JOYSTICK: usage = kHIDUsage_GD_Joystick; break; case HID_GAMEPAD: usage=kHIDUsage_GD_GamePad; break; } result = IOMasterPort(bootstrap_port, &master_port); if (result == kIOReturnSuccess) { class_dictionary = IOServiceMatching(kIOHIDDeviceKey); if (class_dictionary) { /* Add key for device type to refine the matching dictionary. */ usage_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); usage_page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); CFDictionarySetValue(class_dictionary, CFSTR(kIOHIDPrimaryUsageKey), usage_ref); CFDictionarySetValue(class_dictionary, CFSTR(kIOHIDPrimaryUsagePageKey), usage_page_ref); } result = IOServiceGetMatchingServices(master_port, class_dictionary, &hid_object_iterator); if ((result == kIOReturnSuccess) && (hid_object_iterator)) { /* Ok, we have a list of attached HID devices; scan them. */ while ((hid_device = IOIteratorNext(hid_object_iterator))!=0) { if ((IORegistryEntryCreateCFProperties(hid_device, &properties, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) && (properties != NULL)) { error = false; this_device = add_device(col); this_device->type = type; if (col->count==0) { this_device->cur_app=0; } else { this_device->cur_app=col->devices[col->count-1].cur_app; } /* * Mac OS X currently is not mirroring all USB properties * to HID page so need to look at USB device page also. */ usb_properties = get_usb_properties(hid_device); type_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDManufacturerKey)); if (!type_ref) type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Vendor Name")); if ((type_ref) && (string = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) this_device->manufacturer = strdup(string); else this_device->manufacturer = NULL; type_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDProductKey)); if (!type_ref) type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Product Name")); if ((type_ref) && (string = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) this_device->product = strdup(string); else this_device->product = NULL; type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Address")); if ((type == HID_MOUSE) && (!type_ref)) { /* Not an USB mouse. Must be integrated trackpad: we report it as a single button mouse */ add_element(this_device)->type = HID_ELEMENT_BUTTON; } else { /* Scan for device elements */ this_device->num_elements = 0; hid_scan_application_collection(properties, this_device); } this_device->interface = NULL; if ((type == HID_JOYSTICK) || (type == HID_GAMEPAD)) { /* Joystick or gamepad device: create HID interface */ if (IOCreatePlugInInterfaceForService(hid_device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin_interface, &score) != kIOReturnSuccess) error = true; else { if ((*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void *)&(this_device->interface)) != S_OK) error = true; (*plugin_interface)->Release(plugin_interface); if ((*(this_device->interface))->open(this_device->interface, 0) != KERN_SUCCESS) error = true; } } if (error) { if (this_device->manufacturer) al_free(this_device->manufacturer); if (this_device->product) al_free(this_device->product); if (this_device->interface) (*(this_device->interface))->Release(this_device->interface); this_device->interface=NULL; --col->count; } CFRelease(properties); CFRelease(usb_properties); } } IOObjectRelease(hid_object_iterator); } if (usage_ref) CFRelease(usage_ref); if (usage_page_ref) CFRelease(usage_page_ref); mach_port_deallocate(mach_task_self(), master_port); } return col; } #endif /* add_device: * add a new device to a collection */ static HID_DEVICE* add_device(HID_DEVICE_COLLECTION* o) { HID_DEVICE* d; if (o->devices==NULL) { o->count=0; o->capacity=1; o->devices=al_malloc(o->capacity*sizeof(HID_DEVICE)); } if (o->count>=o->capacity) { o->capacity*=2; o->devices=al_realloc(o->devices, o->capacity*sizeof(HID_DEVICE)); } d=&o->devices[o->count]; memset(d, 0, sizeof(HID_DEVICE)); /* Chain onto the preceding app count */ if (o->count>0) d->cur_app = o->devices[o->count-1].cur_app; ++o->count; return d; } /* _al_osx_hid_free: * Release the memory taken up by a collection */ void _al_osx_hid_free(HID_DEVICE_COLLECTION *col) { HID_DEVICE *device; HID_ELEMENT *element; int i, j; for (i = 0; i < col->count; i++) { device = &col->devices[i]; if (device->manufacturer) al_free(device->manufacturer); if (device->product) al_free(device->product); for (j = 0; j < device->num_elements; j++) { element = &device->element[j]; if (element->name) al_free(element->name); } al_free(device->element); if (device->interface) { (*(device->interface))->close(device->interface); (*(device->interface))->Release(device->interface); } } al_free(col->devices); } /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/src/macosx/osxgl.h0000644000175000001440000000166312116357745016015 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/platform/aintosx.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_opengl.h" #include "allegro5/opengl/gl_ext.h" /* Number of pixel format attributes we can set */ #define AL_OSX_NUM_PFA 64 /* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ typedef struct ALLEGRO_DISPLAY_OSX_WIN { ALLEGRO_DISPLAY parent; int depth; NSOpenGLContext* ctx; NSOpenGLPixelFormatAttribute attributes[AL_OSX_NUM_PFA]; NSWindow* win; NSCursor* cursor; CGDirectDisplayID display_id; BOOL show_cursor; NSTrackingArea *tracking; unsigned int display_group; BOOL in_fullscreen; } ALLEGRO_DISPLAY_OSX_WIN; /* This is our version of ALLEGRO_MOUSE_CURSOR */ typedef struct ALLEGRO_MOUSE_CURSOR_OSX { NSCursor *cursor; } ALLEGRO_MOUSE_CURSOR_OSX; allegro-5.0.10/src/macosx/hidjoy-10.4.m0000644000175000001440000004073511476663345016543 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * HID Joystick driver routines for MacOS X. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #include "allegro5/allegro5.h" #include "allegro5/platform/aintosx.h" #import #import #import #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif ALLEGRO_DEBUG_CHANNEL("MacOSX") #define _AL_MAX_JOYSTICKS 8 static bool init_joystick(void); static void exit_joystick(void); static int num_joysticks(void); static ALLEGRO_JOYSTICK* get_joystick(int); static void release_joystick(ALLEGRO_JOYSTICK*); static void get_joystick_state(ALLEGRO_JOYSTICK*, ALLEGRO_JOYSTICK_STATE*); /* ALJoystickHelper: * The joystick events are delivered through the run loop. We need to * attach the callback to the main thread's run loop * (otherwise the events are never delivered) * The class methods are used with performOnMainThread:withObject:waitUntilDone: * to ensure that we access the main thread */ @interface ALJoystickHelper : NSObject { } +(void)startQueues; +(void)stopQueues; @end /* OSX HID Joystick * Maintains an array of links which connect a HID cookie to * an element in the ALLEGRO_JOYSTICK_STATE structure. */ typedef struct { ALLEGRO_JOYSTICK parent; struct { IOHIDElementCookie cookie; int* ppressed; } button_link[_AL_MAX_JOYSTICK_BUTTONS]; struct { IOHIDElementCookie cookie; SInt32 intvalue; float* pvalue; float offset; float multiplier; int stick, axis; } axis_link[_AL_MAX_JOYSTICK_AXES * _AL_MAX_JOYSTICK_STICKS]; int num_axis_links; ALLEGRO_JOYSTICK_STATE state; IOHIDDeviceInterface122** interface; IOHIDQueueInterface** queue; CFRunLoopSourceRef source; } ALLEGRO_JOYSTICK_OSX; static ALLEGRO_JOYSTICK_OSX joysticks[_AL_MAX_JOYSTICKS]; static unsigned int joystick_count; /* create_device_iterator: * Create an iterator which will match all joysticks/ * gamepads on the system. */ static io_iterator_t create_device_iterator(UInt16 usage) { NSMutableDictionary* matching; io_iterator_t iter; matching = (NSMutableDictionary*) IOServiceMatching(kIOHIDDeviceKey); // Add in our criteria: [matching setObject:[NSNumber numberWithShort: usage] forKey: (NSString*) CFSTR(kIOHIDPrimaryUsageKey)]; [matching setObject:[NSNumber numberWithShort: kHIDPage_GenericDesktop] forKey: (NSString*) CFSTR(kIOHIDPrimaryUsagePageKey)]; // Get the iterator IOReturn err = IOServiceGetMatchingServices(kIOMasterPortDefault, (CFDictionaryRef) matching, &iter); return (err == kIOReturnSuccess) ? iter : 0; } /* create_interface: * Create the interface to access this device, via * the intermediate plug-in interface */ static BOOL create_interface(io_object_t device, IOHIDDeviceInterface122*** interface) { io_name_t class_name; IOReturn err = IOObjectGetClass(device,class_name); SInt32 score; IOCFPlugInInterface** plugin; err = IOCreatePlugInInterfaceForService(device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (LPVOID) interface); (*plugin)->Release(plugin); return YES; } /* joystick_callback: * Called when an event occurs on the joystick event queue * target: the joystick * refcon: always null * sender: the queue */ static void joystick_callback(void *target, IOReturn result, void *refcon __attribute__((unused)), void *sender) { ALLEGRO_JOYSTICK_OSX* joy = (ALLEGRO_JOYSTICK_OSX*) target; IOHIDQueueInterface** queue = (IOHIDQueueInterface**) sender; AbsoluteTime past = {0,0}; ALLEGRO_EVENT_SOURCE *src = al_get_joystick_event_source(); if (src == NULL) { return; } _al_event_source_lock(src); while (result == kIOReturnSuccess) { IOHIDEventStruct event; result = (*queue)->getNextEvent(queue, &event, past, 0); if (result == kIOReturnSuccess) { int i; for (i=0; iparent.info.num_buttons; ++i) { if (joy->button_link[i].cookie == event.elementCookie) { int newvalue = event.value; if (*joy->button_link[i].ppressed != newvalue) { *joy->button_link[i].ppressed = newvalue; // emit event ALLEGRO_EVENT evt; if (newvalue) evt.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; else evt.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; evt.joystick.button = i; _al_event_source_emit_event(src, &evt); } } } for (i=0; inum_axis_links; ++i) { if (joy->axis_link[i].cookie == event.elementCookie) { SInt32 newvalue = event.value; if (joy->axis_link[i].intvalue != newvalue) { joy->axis_link[i].intvalue = newvalue; *joy->axis_link[i].pvalue = (joy->axis_link[i].offset + newvalue) * joy->axis_link[i].multiplier; // emit event ALLEGRO_EVENT evt; evt.type = ALLEGRO_EVENT_JOYSTICK_AXIS; evt.joystick.axis = joy->axis_link[i].axis; evt.joystick.pos = *joy->axis_link[i].pvalue; evt.joystick.stick = joy->axis_link[i].stick; _al_event_source_emit_event(src, &evt); } } } } } _al_event_source_unlock(src); } /* add_device: * Create the joystick structure for this device * and add it to the 'joysticks' vector * TODO this only works for simple joysticks and * only allows access to the primary X & Y axes. * In reality there can be more axes than this and * more that one distinct controller handled by the same * interface. * We should iterate through the application collections to * find the joysticks then through the physical collections * therein to identify the individual sticks. */ static void add_device(io_object_t device) { ALLEGRO_JOYSTICK_OSX* joy; NSArray* elements = nil; int num_buttons = 0; BOOL have_x = NO, have_y = NO; IOReturn err; joy = &joysticks[joystick_count++]; memset(joy, 0, sizeof(*joy)); joy->parent.info.num_sticks = 0; joy->parent.info.num_buttons = 0; IOHIDDeviceInterface122** interface; create_interface(device, &interface); // Open the device err = (*interface)->open(interface, 0); // Create an event queue IOHIDQueueInterface** queue = (*interface)->allocQueue(interface); err = (*queue)->create(queue, 0, 8); // Create a source err = (*queue)->createAsyncEventSource(queue, &joy->source); err = (*queue)->setEventCallout(queue, joystick_callback, joy, NULL); joy->queue = queue; (*interface)->copyMatchingElements(interface, NULL, (CFArrayRef*) &elements); NSEnumerator* enumerator = [elements objectEnumerator]; NSDictionary* element; while ((element = (NSDictionary*) [enumerator nextObject])) { short usage = [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementUsageKey)]) shortValue]; short usage_page = [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementUsagePageKey)]) shortValue]; if (usage_page == kHIDPage_Button && num_buttons < _AL_MAX_JOYSTICK_BUTTONS) { joy->button_link[num_buttons].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; joy->button_link[num_buttons].ppressed = &joy->state.button[num_buttons]; // Use the provided name or make one up. NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; if (name == nil) { name = [NSString stringWithFormat:@"Button %d", (num_buttons+1)]; } ALLEGRO_INFO("Found button named \"%s\"\n", [name UTF8String]); // Say that we want events from this button err = (*queue)->addElement(queue, joy->button_link[num_buttons].cookie, 0); if (err != 0) { ALLEGRO_WARN("Button named \"%s\" NOT added to event queue\n", [name UTF8String]); } else { joy->parent.info.button[num_buttons].name = strdup([name UTF8String]); ++num_buttons; } } if (usage_page == kHIDPage_GenericDesktop) { if ((usage == kHIDUsage_GD_X) && (!have_x)) { NSNumber* minValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMinKey)]; NSNumber* maxValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMaxKey)]; joy->axis_link[0].axis = 0; joy->axis_link[0].stick = 0; joy->axis_link[0].offset = - ([minValue floatValue] + [maxValue floatValue]) / 2.0f; joy->axis_link[0].multiplier = 2.0f / ([maxValue floatValue] - [minValue floatValue]); joy->axis_link[0].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; joy->axis_link[0].pvalue = &joy->state.stick[0].axis[0]; NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; if (name == nil) { name = @"X-axis"; } ALLEGRO_INFO("Found X-axis named \"%s\"\n", [name UTF8String]); // Say that we want events from this axis err = (*queue)->addElement(queue, joy->axis_link[0].cookie, 0); if (err != 0) { ALLEGRO_WARN("X-axis named \"%s\" NOT added to event queue\n", [name UTF8String]); } else { have_x = YES; joy->parent.info.stick[0].axis[0].name = strdup([name UTF8String]); } } if ((usage == kHIDUsage_GD_Y) && (!have_y)) { NSNumber* minValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMinKey)]; NSNumber* maxValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMaxKey)]; joy->axis_link[1].axis = 1; joy->axis_link[1].stick = 0; joy->axis_link[1].offset = - ([minValue floatValue] + [maxValue floatValue]) / 2.0f; joy->axis_link[1].multiplier = 2.0f / ([maxValue floatValue] - [minValue floatValue]); joy->axis_link[1].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; joy->axis_link[1].pvalue = &joy->state.stick[0].axis[1]; NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; if (name == nil) { name = @"Y-axis"; } ALLEGRO_INFO("Found Y-axis named \"%s\"\n", [name UTF8String]); // Say that we want events from this axis err = (*queue)->addElement(queue, joy->axis_link[1].cookie, 0); if (err != 0) { ALLEGRO_WARN("Y-axis named \"%s\" NOT added to event queue\n", [name UTF8String]); } else { have_y = YES; joy->parent.info.stick[0].axis[1].name = strdup([name UTF8String]); } } } } joy->parent.info.num_buttons = num_buttons; if (have_x && have_y) { joy->parent.info.stick[0].name = strdup("Primary axis"); joy->parent.info.num_sticks = 1; joy->parent.info.stick[0].num_axes = 2; joy->num_axis_links = 2; } joy->interface = interface; joystick_callback(joy,kIOReturnSuccess,NULL,queue); [elements release]; } // FIXME! static const char *get_joystick_name(ALLEGRO_JOYSTICK *joy_) { (void)joy_; return "Joystick"; } static bool get_joystick_active(ALLEGRO_JOYSTICK *joy_) { (void)joy_; return true; } static bool reconfigure_joysticks(void) { return false; } ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_4(void) { static ALLEGRO_JOYSTICK_DRIVER* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(*vt)); vt->joydrv_ascii_name = "OSX HID Driver"; vt->init_joystick = init_joystick; vt->exit_joystick = exit_joystick; vt->num_joysticks = num_joysticks; vt->get_joystick = get_joystick; vt->release_joystick = release_joystick; vt->get_joystick_state = get_joystick_state; vt->reconfigure_joysticks = reconfigure_joysticks; vt->get_name = get_joystick_name; vt->get_active = get_joystick_active; } return vt; } /* init_joystick: * Initializes the HID joystick driver. */ static bool init_joystick(void) { joystick_count = 0; io_iterator_t iterator; io_object_t device; iterator = create_device_iterator(kHIDUsage_GD_GamePad); if (iterator != 0) { while ((device = IOIteratorNext(iterator))) { add_device(device); } IOObjectRelease(iterator); } iterator = create_device_iterator(kHIDUsage_GD_Joystick); if (iterator != 0) { while ((device = IOIteratorNext(iterator))) { add_device(device); } IOObjectRelease(iterator); } [ALJoystickHelper performSelectorOnMainThread: @selector(startQueues) withObject: nil waitUntilDone: YES]; return true; } /* exit_joystick: * Shuts down the HID joystick driver. */ static void exit_joystick(void) { [ALJoystickHelper performSelectorOnMainThread: @selector(stopQueues) withObject: nil waitUntilDone: YES]; unsigned int i; for (i=0; i< joystick_count; ++i) { ALLEGRO_JOYSTICK_OSX* joy = &joysticks[i]; CFRelease(joy->source); if (joy->queue) { (*joy->queue)->dispose(joy->queue); (*joy->queue)->Release(joy->queue); } if (joy->interface) { (*joy->interface)->close(joy->interface); (*joy->interface)->Release(joy->interface); } int a, b, s; /* Free everything we might have created * (all fields set to NULL initially so this is OK.) */ for (b = 0; b < _AL_MAX_JOYSTICK_BUTTONS; ++ b) { al_free((void*) joy->parent.info.button[b].name); } for (s = 0; s < _AL_MAX_JOYSTICK_STICKS; ++s) { al_free((void*) joy->parent.info.stick[s].name); for (a = 0; a < _AL_MAX_JOYSTICK_AXES; ++a) { al_free((void*) joy->parent.info.stick[s].axis[a].name); } } } } /* num_joysticks: * Return number of active joysticks */ static int num_joysticks(void) { return joystick_count; } /* get_joystick: * Get a pointer to a joystick structure */ static ALLEGRO_JOYSTICK* get_joystick(int index) { ALLEGRO_JOYSTICK* joy = NULL; if (index >= 0 && index < (int) joystick_count) { joy = (ALLEGRO_JOYSTICK *)&joysticks[index]; } return joy; } /* release_joystick: * Release a pointer that has been obtained */ static void release_joystick(ALLEGRO_JOYSTICK* joy __attribute__((unused)) ) { // No-op } /* get_joystick_state: * Get the current status of a joystick */ static void get_joystick_state(ALLEGRO_JOYSTICK* ajoy, ALLEGRO_JOYSTICK_STATE* state) { ALLEGRO_JOYSTICK_OSX* joy = (ALLEGRO_JOYSTICK_OSX*) ajoy; memcpy(state, &joy->state,sizeof(*state)); } @implementation ALJoystickHelper +(void)startQueues { unsigned int i; CFRunLoopRef current = CFRunLoopGetCurrent(); for (i=0; isource,kCFRunLoopDefaultMode); (*joy->queue)->start(joy->queue); } } +(void) stopQueues { unsigned int i; CFRunLoopRef current = CFRunLoopGetCurrent(); for (i=0; iqueue)->stop(joy->queue); CFRunLoopRemoveSource(current,joy->source,kCFRunLoopDefaultMode); } } @end /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/src/macosx/system.m0000644000175000001440000005160211771527644016213 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X system driver. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/platform/aintosx.h" #include #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif #import #include #include #include ALLEGRO_DEBUG_CHANNEL("MacOSX") /* These are used to warn the dock about the application */ struct CPSProcessSerNum { UInt32 lo; UInt32 hi; }; extern OSErr CPSGetCurrentProcess(struct CPSProcessSerNum *psn); extern OSErr CPSEnableForegroundOperation(struct CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); extern OSErr CPSSetFrontProcess(struct CPSProcessSerNum *psn); typedef struct THREAD_AND_POOL { ALLEGRO_THREAD *thread; } THREAD_AND_POOL; static ALLEGRO_SYSTEM* osx_sys_init(int flags); ALLEGRO_SYSTEM_INTERFACE *_al_system_osx_driver(void); static void osx_sys_exit(void); /* Global variables */ NSBundle *_al_osx_bundle = NULL; static _AL_VECTOR osx_display_modes; static ALLEGRO_SYSTEM osx_system; _AL_VECTOR _osx_threads = _AL_VECTOR_INITIALIZER(THREAD_AND_POOL *); /* osx_tell_dock: * Tell the dock about us; the origins of this hack are unknown, but it's * currently the only way to make a Cocoa app to work when started from a * console. * For the future, (10.3 and above) investigate TranformProcessType in the * HIServices framework. */ static void osx_tell_dock(void) { struct CPSProcessSerNum psn; if ((!CPSGetCurrentProcess(&psn)) && (!CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103)) && (!CPSSetFrontProcess(&psn))) [NSApplication sharedApplication]; } /* _al_osx_bootstrap_ok: * Check if the current bootstrap context is privilege. If it's not, we can't * use NSApplication, and instead have to go directly to main. * Returns 1 if ok, 0 if not. */ #ifdef OSX_BOOTSTRAP_DETECTION int _al_osx_bootstrap_ok(void) { static int _ok = -1; mach_port_t bp; kern_return_t ret; CFMachPortRef cfport; /* If have tested once, just return that answer */ if (_ok >= 0) return _ok; cfport = CFMachPortCreate(NULL, NULL, NULL, NULL); task_get_bootstrap_port(mach_task_self(), &bp); ret = bootstrap_register(bp, "bootstrap-ok-test", CFMachPortGetPort(cfport)); CFRelease(cfport); _ok = (ret == KERN_SUCCESS) ? 1 : 0; return _ok; } #endif /* osx_sys_init: * Initalizes the MacOS X system driver. */ static ALLEGRO_SYSTEM* osx_sys_init(int flags) { (void)flags; #ifdef OSX_BOOTSTRAP_DETECTION /* If we're in the 'dead bootstrap' environment, the Mac driver won't work. */ if (!_al_osx_bootstrap_ok()) { return NULL; } #endif /* Initialise the vt and display list */ osx_system.vt = _al_system_osx_driver(); _al_vector_init(&osx_system.displays, sizeof(ALLEGRO_DISPLAY*)); if (_al_osx_bundle == NULL) { /* If in a bundle, the dock will recognise us automatically */ osx_tell_dock(); } /* Mark the beginning of time. */ _al_unix_init_time(); _al_vector_init(&osx_display_modes, sizeof(ALLEGRO_DISPLAY_MODE)); ALLEGRO_DEBUG("system driver initialised.\n"); return &osx_system; } /* osx_sys_exit: * Shuts down the system driver. */ static void osx_sys_exit(void) { _al_vector_free(&osx_display_modes); ALLEGRO_DEBUG("system driver shutdown.\n"); } /* * _al_osx_get_num_display_modes: * Gets the number of available display modes */ static int _al_osx_get_num_display_modes(void) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras = _al_get_new_display_settings(); ALLEGRO_EXTRA_DISPLAY_SETTINGS temp; int refresh_rate = al_get_new_display_refresh_rate(); int adapter = al_get_new_display_adapter(); int depth = 0; CGDirectDisplayID display; CFArrayRef modes; CFIndex i; if (extras) depth = extras->settings[ALLEGRO_COLOR_SIZE]; memset(&temp, 0, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); display = CGMainDisplayID(); /* Get display ID for the requested display */ if (adapter > 0) { NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; NSDictionary *dict = [screen deviceDescription]; NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; /* FIXME (how?): in 64 bit-mode, this generates a warning, because * CGDirectDisplayID is apparently 32 bit whereas a pointer is 64 * bit. Considering that a CGDirectDisplayID is supposed to be a * pointer as well (according to the documentation available on-line) * it is not quite clear what the correct way to do this would be. */ display = (CGDirectDisplayID) [display_id pointerValue]; } _al_vector_free(&osx_display_modes); #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 /* Note: modes is owned by OSX and must not be released */ modes = CGDisplayAvailableModes(display); ALLEGRO_INFO("detected %d display modes.\n", (int)CFArrayGetCount(modes)); for (i = 0; i < CFArrayGetCount(modes); i++) { ALLEGRO_DISPLAY_MODE *mode; CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(modes, i); CFNumberRef number; int value, samples; number = CFDictionaryGetValue(dict, kCGDisplayBitsPerPixel); CFNumberGetValue(number, kCFNumberIntType, &value); ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, value); if (depth && value != depth) { ALLEGRO_WARN("Skipping mode %d (requested colour depth %d).\n", (int)i, depth); continue; } number = CFDictionaryGetValue(dict, kCGDisplayRefreshRate); CFNumberGetValue(number, kCFNumberIntType, &value); ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, value); if (refresh_rate && value != refresh_rate) { ALLEGRO_WARN("Skipping mode %d (requested refresh rate %d).\n", (int)i, refresh_rate); continue; } mode = (ALLEGRO_DISPLAY_MODE *)_al_vector_alloc_back(&osx_display_modes); number = CFDictionaryGetValue(dict, kCGDisplayWidth); CFNumberGetValue(number, kCFNumberIntType, &mode->width); number = CFDictionaryGetValue(dict, kCGDisplayHeight); CFNumberGetValue(number, kCFNumberIntType, &mode->height); number = CFDictionaryGetValue(dict, kCGDisplayRefreshRate); CFNumberGetValue(number, kCFNumberIntType, &mode->refresh_rate); ALLEGRO_INFO("Mode %d is %dx%d@%dHz\n", (int)i, mode->width, mode->height, mode->refresh_rate); number = CFDictionaryGetValue(dict, kCGDisplayBitsPerPixel); CFNumberGetValue(number, kCFNumberIntType, &temp.settings[ALLEGRO_COLOR_SIZE]); number = CFDictionaryGetValue(dict, kCGDisplaySamplesPerPixel); CFNumberGetValue(number, kCFNumberIntType, &samples); number = CFDictionaryGetValue(dict, kCGDisplayBitsPerSample); CFNumberGetValue(number, kCFNumberIntType, &value); ALLEGRO_INFO("Mode %d has %d bits per pixel, %d samples per pixel and %d bits per sample\n", (int)i, temp.settings[ALLEGRO_COLOR_SIZE], samples, value); if (samples >= 3) { temp.settings[ALLEGRO_RED_SIZE] = value; temp.settings[ALLEGRO_GREEN_SIZE] = value; temp.settings[ALLEGRO_BLUE_SIZE] = value; if (samples == 4) temp.settings[ALLEGRO_ALPHA_SIZE] = value; } _al_fill_display_settings(&temp); mode->format = _al_deduce_color_format(&temp); } #else modes = CGDisplayCopyAllDisplayModes(display, NULL); ALLEGRO_INFO("detected %d display modes.\n", (int)CFArrayGetCount(modes)); for (i = 0; i < CFArrayGetCount(modes); i++) { ALLEGRO_DISPLAY_MODE *amode; CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(mode); int bpp = 0, mode_refresh_rate, samples = 0, value = 0; /* Determine pixel format. Whever thought this was a better idea than * having query functions for each of these properties should be * spoken to very harshly in a very severe voice. */ if (CFStringCompare(pixel_encoding, CFSTR(kIO16BitFloatPixels), 1) == 0) { bpp = 64; samples = 3; value = 16; } if (CFStringCompare(pixel_encoding, CFSTR(kIO32BitFloatPixels), 1) == 0) { bpp = 128; samples = 3; value = 32; } if (CFStringCompare(pixel_encoding, CFSTR(kIO64BitDirectPixels), 1) == 0) { bpp = 64; samples = 3; value = 16; } if (CFStringCompare(pixel_encoding, CFSTR(kIO30BitDirectPixels), 1) == 0) { bpp = 32; samples = 3; value = 10; } if (CFStringCompare(pixel_encoding, CFSTR(IO32BitDirectPixels), 1) == 0) { bpp = 32; samples = 3; value = 8; } if (CFStringCompare(pixel_encoding, CFSTR(IO16BitDirectPixels), 1) == 0) { bpp = 16; samples = 3; value = 5; } if (CFStringCompare(pixel_encoding, CFSTR(IO8BitIndexedPixels), 1) == 0) { bpp = 8; samples = 1; value = 8; } CFRelease(pixel_encoding); /* Check if this mode is ok in terms of depth and refresh rate */ ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, bpp); if (depth && bpp != depth) { ALLEGRO_WARN("Skipping mode %d (requested colour depth %d).\n", (int)i, depth); continue; } mode_refresh_rate = CGDisplayModeGetRefreshRate(mode); ALLEGRO_INFO("Mode %d has a refresh rate of %d.\n", (int)i, mode_refresh_rate); if (refresh_rate && mode_refresh_rate != refresh_rate) { ALLEGRO_WARN("Skipping mode %d (requested refresh rate %d).\n", (int)i, refresh_rate); continue; } /* Yes, it's fine */ amode = (ALLEGRO_DISPLAY_MODE *)_al_vector_alloc_back(&osx_display_modes); amode->width = CGDisplayModeGetWidth(mode); amode->height = CGDisplayModeGetHeight(mode); amode->refresh_rate = mode_refresh_rate; ALLEGRO_INFO("Mode %d is %dx%d@%dHz\n", (int)i, amode->width, amode->height, amode->refresh_rate); temp.settings[ALLEGRO_COLOR_SIZE] = bpp; ALLEGRO_INFO("Mode %d has %d bits per pixel, %d samples per pixel and %d bits per sample\n", (int)i, temp.settings[ALLEGRO_COLOR_SIZE], samples, value); if (samples >= 3) { temp.settings[ALLEGRO_RED_SIZE] = value; temp.settings[ALLEGRO_GREEN_SIZE] = value; temp.settings[ALLEGRO_BLUE_SIZE] = value; if (samples == 4) temp.settings[ALLEGRO_ALPHA_SIZE] = value; } _al_fill_display_settings(&temp); amode->format = _al_deduce_color_format(&temp); } CFRelease(modes); #endif return _al_vector_size(&osx_display_modes); } /* * _al_osx_get_num_display_modes: * Gets the number of available display modes */ static ALLEGRO_DISPLAY_MODE *_al_osx_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) { if ((unsigned)index >= _al_vector_size(&osx_display_modes)) return NULL; memcpy(mode, _al_vector_ref(&osx_display_modes, index), sizeof(ALLEGRO_DISPLAY_MODE)); return mode; } /* osx_get_num_video_adapters: * Return the number of video adapters i.e displays */ static int osx_get_num_video_adapters(void) { NSArray *screen_list; int num = 0; screen_list = [NSScreen screens]; if (screen_list) num = [screen_list count]; ALLEGRO_INFO("Detected %d displays\n", num); return num; } /* osx_get_monitor_info: * Return the details of one monitor */ static bool osx_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO* info) { /* int count = osx_get_num_video_adapters(); if (adapter < count) { NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; NSRect rc = [screen frame]; info->x1 = (int) rc.origin.x; info->x2 = (int) (rc.origin.x + rc.size.width); info->y1 = (int) rc.origin.y; info->y2 = (int) (rc.origin.y + rc.size.height); } */ CGDisplayCount count; // Assume no more than 16 monitors connected static const int max_displays = 16; CGDirectDisplayID displays[max_displays]; CGError err = CGGetActiveDisplayList(max_displays, displays, &count); if (err == kCGErrorSuccess && adapter >= 0 && adapter < (int) count) { CGRect rc = CGDisplayBounds(displays[adapter]); info->x1 = (int) rc.origin.x; info->x2 = (int) (rc.origin.x + rc.size.width); info->y1 = (int) rc.origin.y; info->y2 = (int) (rc.origin.y + rc.size.height); ALLEGRO_INFO("Display %d has coordinates (%d, %d) - (%d, %d)\n", adapter, info->x1, info->y1, info->x2, info->y2); return true; } else { return false; } } /* osx_inhibit_screensaver: * Stops the screen dimming/screen saver activation if inhibit is true * otherwise re-enable normal behaviour. The last call takes force (i.e * it does not count the calls to inhibit/uninhibit. * Always returns true */ static bool osx_inhibit_screensaver(bool inhibit) { // Send a message to the App's delegate always on the main thread [[NSApp delegate] performSelectorOnMainThread: @selector(setInhibitScreenSaver:) withObject: [NSNumber numberWithBool:inhibit ? YES : NO] waitUntilDone: NO]; ALLEGRO_INFO("Stop screensaver\n"); return true; } /* NSImageFromAllegroBitmap: * Create an NSImage from an Allegro bitmap * This could definitely be speeded up if necessary. */ NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp) { int w = al_get_bitmap_width(bmp); int h = al_get_bitmap_height(bmp); NSImage* img = [[NSImage alloc] initWithSize: NSMakeSize((float) w, (float) h)]; NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL // Allocate memory yourself pixelsWide:w pixelsHigh:h bitsPerSample: 8 samplesPerPixel: 4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow: 0 // Calculate yourself bitsPerPixel:0 ];// Calculate yourself al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); int x, y; for (y = 0; y 1 */ static bool osx_get_cursor_position(int *x, int *y) { NSPoint p = [NSEvent mouseLocation]; NSRect r = [[NSScreen mainScreen] frame]; *x = p.x; *y = r.size.height - p.y; return true; } static void osx_thread_init(ALLEGRO_THREAD *thread) { THREAD_AND_POOL *tap = al_malloc(sizeof(THREAD_AND_POOL)); tap->thread = thread; THREAD_AND_POOL **ptr = _al_vector_alloc_back(&_osx_threads); *ptr = tap; } static void osx_thread_exit(ALLEGRO_THREAD *thread) { unsigned int i; THREAD_AND_POOL *tap; for (i = 0; i < _osx_threads._size; i++) { tap = _al_vector_ref(&_osx_threads, i); if (tap->thread == thread) { _al_vector_delete_at(&_osx_threads, i); al_free(tap); return; } } } /* Internal function to get a reference to this driver. */ ALLEGRO_SYSTEM_INTERFACE *_al_system_osx_driver(void) { static ALLEGRO_SYSTEM_INTERFACE* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(*vt)); vt->initialize = osx_sys_init; vt->get_display_driver = _al_osx_get_display_driver; vt->get_keyboard_driver = _al_osx_get_keyboard_driver; vt->get_mouse_driver = _al_osx_get_mouse_driver; vt->get_joystick_driver = _al_osx_get_joystick_driver; vt->get_num_display_modes = _al_osx_get_num_display_modes; vt->get_display_mode = _al_osx_get_display_mode; vt->shutdown_system = osx_sys_exit; vt->get_num_video_adapters = osx_get_num_video_adapters; vt->get_monitor_info = osx_get_monitor_info; vt->create_mouse_cursor = _al_osx_create_mouse_cursor; vt->destroy_mouse_cursor = _al_osx_destroy_mouse_cursor; vt->get_cursor_position = osx_get_cursor_position; vt->get_path = _al_osx_get_path; vt->inhibit_screensaver = osx_inhibit_screensaver; vt->thread_init = osx_thread_init; vt->thread_exit = osx_thread_exit; }; return vt; } /* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces() { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_osx_driver(); } /* Implementation of get_path */ ALLEGRO_PATH *_al_osx_get_path(int id) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString* ans = nil; NSArray* paths = nil; NSString *org_name = [[NSString alloc] initWithUTF8String: al_get_org_name()]; NSString *app_name = [[NSString alloc] initWithUTF8String: al_get_app_name()]; ALLEGRO_PATH *path = NULL; switch (id) { case ALLEGRO_RESOURCES_PATH: if (_al_osx_bundle) { ans = [_al_osx_bundle resourcePath]; path = al_create_path_for_directory([ans UTF8String]); } else { /* Otherwise, return the executable pathname */ path = _al_osx_get_path(ALLEGRO_EXENAME_PATH); al_set_path_filename(path, NULL); } break; case ALLEGRO_TEMP_PATH: ans = NSTemporaryDirectory(); path = al_create_path_for_directory([ans UTF8String]); break; case ALLEGRO_USER_DATA_PATH: paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); if ([paths count] > 0) ans = [paths objectAtIndex: 0]; if (ans != nil) { /* Append program name */ ans = [[ans stringByAppendingPathComponent: org_name] stringByAppendingPathComponent: app_name]; } path = al_create_path_for_directory([ans UTF8String]); break; case ALLEGRO_USER_HOME_PATH: ans = NSHomeDirectory(); path = al_create_path_for_directory([ans UTF8String]); break; case ALLEGRO_USER_DOCUMENTS_PATH: paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); if ([paths count] > 0) ans = [paths objectAtIndex: 0]; path = al_create_path_for_directory([ans UTF8String]); break; case ALLEGRO_EXENAME_PATH: { char exepath[PATH_MAX]; uint32_t size = sizeof(exepath); if (_NSGetExecutablePath(exepath, &size) == 0) ans = [NSString stringWithUTF8String: exepath]; path = al_create_path([ans UTF8String]); break; } case ALLEGRO_USER_SETTINGS_PATH: paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); if ([paths count] > 0) ans = [paths objectAtIndex: 0]; if (ans != nil) { /* Append program name */ ans = [[ans stringByAppendingPathComponent: org_name] stringByAppendingPathComponent: app_name]; } path = al_create_path_for_directory([ans UTF8String]); break; default: break; } [org_name release]; [app_name release]; [pool drain]; return path; } /* _al_osx_post_quit * called when the user clicks the quit menu or cmd-Q. * Currently just sends a window close event to all windows. * This is a bit unsatisfactory */ void _al_osx_post_quit(void) { unsigned int i; _AL_VECTOR* dpys = &al_get_system_driver()->displays; // Iterate through all existing displays for (i = 0; i < _al_vector_size(dpys); ++i) { ALLEGRO_DISPLAY* dpy = *(ALLEGRO_DISPLAY**) _al_vector_ref(dpys, i); ALLEGRO_EVENT_SOURCE* src = &(dpy->es); _al_event_source_lock(src); ALLEGRO_EVENT evt; evt.type = ALLEGRO_EVENT_DISPLAY_CLOSE; // Send event _al_event_source_emit_event(src, &evt); _al_event_source_unlock(src); } } /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/src/macosx/hidjoy.m0000644000175000001440000004646411655352247016163 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * HID Joystick driver routines for MacOS X. * * By Angelo Mottola. * New API (Leopard) support and hotplugging by Trent Gamblin. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/platform/aintosx.h" #import #import #ifndef ALLEGRO_MACOSX #error something is wrong with the makefile #endif #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 #import /* State transitions: * unused -> born * born -> alive * born -> dying * active -> dying * dying -> unused */ typedef enum { JOY_STATE_UNUSED, JOY_STATE_BORN, JOY_STATE_ALIVE, JOY_STATE_DYING } CONFIG_STATE; // These values can be found in the USB HID Usage Tables: // http://www.usb.org/developers/hidpage #define GENERIC_DESKTOP_USAGE_PAGE 0x01 #define JOYSTICK_USAGE_NUMBER 0x04 #define GAMEPAD_USAGE_NUMBER 0x05 typedef struct { ALLEGRO_JOYSTICK parent; int num_buttons; int num_x_axes; int num_y_axes; int num_z_axes; IOHIDElementRef buttons[_AL_MAX_JOYSTICK_BUTTONS]; IOHIDElementRef axes[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; long min[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; long max[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; CONFIG_STATE cfg_state; ALLEGRO_JOYSTICK_STATE state; IOHIDDeviceRef ident; } ALLEGRO_JOYSTICK_OSX; static IOHIDManagerRef hidManagerRef; static _AL_VECTOR joysticks; static CONFIG_STATE new_joystick_state = JOY_STATE_ALIVE; static bool initialized = false; static ALLEGRO_MUTEX *add_mutex; ALLEGRO_DEBUG_CHANNEL("MacOSX") // function to create matching dictionary (for devices) static CFMutableDictionaryRef CreateDeviceMatchingDictionary( UInt32 inUsagePage, UInt32 inUsage ) { // create a dictionary to add usage page/usages to CFMutableDictionaryRef result = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if (result) { // Add key for device type to refine the matching dictionary. CFNumberRef pageCFNumberRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &inUsagePage ); if (pageCFNumberRef) { CFStringRef usage_page = CFSTR(kIOHIDDeviceUsagePageKey); CFDictionarySetValue( result, usage_page, pageCFNumberRef ); CFRelease(pageCFNumberRef); // note: the usage is only valid if the usage page is also defined CFNumberRef usageCFNumberRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &inUsage ); if (usageCFNumberRef) { CFStringRef usage_key = CFSTR(kIOHIDDeviceUsageKey); CFDictionarySetValue( result, usage_key, usageCFNumberRef ); CFRelease(usageCFNumberRef); } } } return result; } static ALLEGRO_JOYSTICK_OSX *find_joystick(IOHIDDeviceRef ident) { int i; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); if (ident == joy->ident) { return joy; } } return NULL; } static const char *get_element_name(IOHIDElementRef elem, const char *default_name) { CFStringRef name = IOHIDElementGetName(elem); if (name) { return CFStringGetCStringPtr(name, kCFStringEncodingUTF8); } else return default_name; } static void joy_null(ALLEGRO_JOYSTICK_OSX *joy) { int i, j; // NULL the parent for (i = 0; i < _AL_MAX_JOYSTICK_BUTTONS; i++) { joy->parent.info.button[i].name = NULL; } for (i = 0; i < _AL_MAX_JOYSTICK_STICKS; i++) { joy->parent.info.stick[i].name = NULL; for (j = 0; j < _AL_MAX_JOYSTICK_AXES; j++) { joy->parent.info.stick[i].axis[j].name = NULL; } } } static void add_elements(CFArrayRef elements, ALLEGRO_JOYSTICK_OSX *joy) { int i; char default_name[100]; joy_null(joy); for (i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef elem = (IOHIDElementRef)CFArrayGetValueAtIndex( elements, i ); int usage = IOHIDElementGetUsage(elem); if (IOHIDElementGetType(elem) == kIOHIDElementTypeInput_Button) { if (usage >= 0 && usage < _AL_MAX_JOYSTICK_BUTTONS && !joy->buttons[usage-1]) { joy->buttons[usage-1] = elem; sprintf(default_name, "Button %d", usage-1); const char *name = get_element_name(elem, default_name); char *str = al_malloc(strlen(name)+1); strcpy(str, name); joy->parent.info.button[usage-1].name = str; joy->num_buttons++; } } else if ( IOHIDElementGetType(elem) == kIOHIDElementTypeInput_Misc) { long min = IOHIDElementGetLogicalMin(elem); long max = IOHIDElementGetLogicalMax(elem); if ((usage == kHIDUsage_GD_X || usage == kHIDUsage_GD_Rx) && joy->num_x_axes < _AL_MAX_JOYSTICK_STICKS) { joy->min[joy->num_x_axes][0] = min; joy->max[joy->num_x_axes][0] = max; sprintf(default_name, "Axis 0"); const char *name = get_element_name(elem, default_name); char *str = al_malloc(strlen(name)+1); strcpy(str, name); joy->parent.info.stick[joy->num_x_axes].axis[0].name = str; joy->axes[joy->num_x_axes++][0] = elem; } else if ((usage == kHIDUsage_GD_Y || usage == kHIDUsage_GD_Ry) && joy->num_x_axes < _AL_MAX_JOYSTICK_STICKS) { joy->min[joy->num_y_axes][1] = min; joy->max[joy->num_y_axes][1] = max; sprintf(default_name, "Axis 1"); const char *name = get_element_name(elem, default_name); char *str = al_malloc(strlen(name)+1); strcpy(str, name); joy->parent.info.stick[joy->num_y_axes].axis[1].name = str; joy->axes[joy->num_y_axes++][1] = elem; } else if ((usage == kHIDUsage_GD_Z || usage == kHIDUsage_GD_Rz) && joy->num_z_axes < _AL_MAX_JOYSTICK_STICKS) { joy->min[joy->num_z_axes][2] = min; joy->max[joy->num_z_axes][2] = max; sprintf(default_name, "Axis 2"); const char *name = get_element_name(elem, default_name); char *str = al_malloc(strlen(name)+1); strcpy(str, name); joy->parent.info.stick[joy->num_z_axes].axis[2].name = str; joy->axes[joy->num_z_axes++][2] = elem; } } } } static void osx_joy_generate_configure_event(void) { if (!initialized) return; ALLEGRO_EVENT event; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; event.joystick.timestamp = al_current_time(); _al_generate_joystick_event(&event); } static void device_add_callback( void *context, IOReturn result, void *sender, IOHIDDeviceRef ref ) { int i; (void)context; (void)result; (void)sender; al_lock_mutex(add_mutex); ALLEGRO_JOYSTICK_OSX *joy = find_joystick(ref); if (joy == NULL) { joy = al_calloc(1, sizeof(ALLEGRO_JOYSTICK_OSX)); joy->ident = ref; ALLEGRO_JOYSTICK_OSX **back = _al_vector_alloc_back(&joysticks); *back = joy; } joy->cfg_state = new_joystick_state; CFArrayRef elements = IOHIDDeviceCopyMatchingElements( ref, NULL, kIOHIDOptionsTypeNone ); add_elements(elements, joy); CFRelease(elements); // Fill in ALLEGRO_JOYSTICK properties joy->parent.info.num_sticks = joy->num_x_axes; joy->parent.info.num_buttons = joy->num_buttons; for (i = 0; i < joy->num_x_axes; i++) { int axes = 1; if (joy->num_y_axes >= i) axes++; if (joy->num_z_axes >= i) axes++; joy->parent.info.stick[i].num_axes = axes; char *buf = al_malloc(20); sprintf(buf, "Stick %d", i); joy->parent.info.stick[i].name = buf; } al_unlock_mutex(add_mutex); osx_joy_generate_configure_event(); ALLEGRO_INFO("Found joystick (%d buttons, %d %d %d axes)\n", joy->num_buttons, joy->num_x_axes, joy->num_y_axes, joy->num_z_axes); } static void device_remove_callback( void *context, IOReturn result, void *sender, IOHIDDeviceRef ref ) { (void)context; (void)result; (void)sender; int i; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); if (joy->ident == ref) { joy->cfg_state = JOY_STATE_DYING; osx_joy_generate_configure_event(); return; } } } static void osx_joy_generate_axis_event(ALLEGRO_JOYSTICK_OSX *joy, int stick, int axis, float pos) { joy->state.stick[stick].axis[axis] = pos; ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; event.joystick.timestamp = al_current_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = stick; event.joystick.axis = axis; event.joystick.pos = pos; event.joystick.button = 0; _al_event_source_emit_event(es, &event); } static void osx_joy_generate_button_event(ALLEGRO_JOYSTICK_OSX *joy, int button, ALLEGRO_EVENT_TYPE event_type) { joy->state.button[button] = event_type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP ? 0 : 1;; ALLEGRO_EVENT event; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); if (!_al_event_source_needs_to_generate_event(es)) return; event.joystick.type = event_type; event.joystick.timestamp = al_current_time(); event.joystick.id = (ALLEGRO_JOYSTICK *)joy; event.joystick.stick = 0; event.joystick.axis = 0; event.joystick.pos = 0.0; event.joystick.button = button; _al_event_source_emit_event(es, &event); } static void value_callback( void *context, IOReturn result, void *sender, IOHIDValueRef value ) { if (!initialized) return; (void)context; (void)result; (void)sender; IOHIDElementRef elem = IOHIDValueGetElement(value); IOHIDDeviceRef ref = IOHIDElementGetDevice(elem); ALLEGRO_JOYSTICK_OSX *joy = find_joystick(ref); if (!joy) return; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); int i; for (i = 0; i < joy->num_buttons; i++) { if (joy->buttons[i] == elem) { ALLEGRO_EVENT_TYPE type; if (IOHIDValueGetIntegerValue(value) == 0) type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; else type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; osx_joy_generate_button_event(joy, i, type); goto done; } } int int_value = IOHIDValueGetIntegerValue(value); int stick = -1; int axis = -1; for (i = 0; i < joy->num_x_axes; i++) { if (joy->axes[i][0] == elem) { stick = i; axis = 0; goto gen_axis_event; } } for (i = 0; i < joy->num_y_axes; i++) { if (joy->axes[i][1] == elem) { stick = i; axis = 1; goto gen_axis_event; } } for (i = 0; i < joy->num_z_axes; i++) { if (joy->axes[i][2] == elem) { stick = i; axis = 2; goto gen_axis_event; } } // Unknown event goto done; gen_axis_event: { float pos; long min = joy->min[stick][axis]; long max = joy->max[stick][axis]; if (min < 0) { if (int_value < 0) pos = -(float)int_value/min; else pos = (float)int_value/max; } else { pos = ((float)int_value/max*2) - 1; } osx_joy_generate_axis_event(joy, stick, axis, pos); } done: _al_event_source_unlock(es); } /* init_joystick: * Initializes the HID joystick driver. */ static bool init_joystick(void) { add_mutex = al_create_mutex(); hidManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone ); if (CFGetTypeID(hidManagerRef) != IOHIDManagerGetTypeID()) { ALLEGRO_ERROR("Unable to create HID Manager\n"); return false; } // Set which devices we want to match CFMutableDictionaryRef criteria0 = CreateDeviceMatchingDictionary( GENERIC_DESKTOP_USAGE_PAGE, JOYSTICK_USAGE_NUMBER ); CFMutableDictionaryRef criteria1 = CreateDeviceMatchingDictionary( GENERIC_DESKTOP_USAGE_PAGE, GAMEPAD_USAGE_NUMBER ); CFMutableDictionaryRef criteria_list[] = { criteria0, criteria1 }; CFArrayRef criteria = CFArrayCreate( kCFAllocatorDefault, (const void **)criteria_list, 2, NULL ); IOHIDManagerSetDeviceMatchingMultiple( hidManagerRef, criteria ); CFRelease(criteria0); CFRelease(criteria1); CFRelease(criteria); /* Register for plug/unplug notifications */ IOHIDManagerRegisterDeviceMatchingCallback( hidManagerRef, device_add_callback, NULL ); IOHIDManagerRegisterDeviceRemovalCallback( hidManagerRef, device_remove_callback, NULL ); // Register for value changes IOHIDManagerRegisterInputValueCallback( hidManagerRef, value_callback, NULL ); IOHIDManagerScheduleWithRunLoop( hidManagerRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode ); _al_vector_init(&joysticks, sizeof(ALLEGRO_JOYSTICK_OSX *)); al_lock_mutex(add_mutex); IOReturn ret = IOHIDManagerOpen( hidManagerRef, kIOHIDOptionsTypeSeizeDevice ); al_unlock_mutex(add_mutex); if (ret != kIOReturnSuccess) { return false; } // Wait for the devices to be enumerated int count; int size; do { al_rest(0.001); CFSetRef devices = IOHIDManagerCopyDevices(hidManagerRef); if (devices == nil) { break; } count = CFSetGetCount(devices); CFRelease(devices); al_lock_mutex(add_mutex); size = _al_vector_size(&joysticks); al_unlock_mutex(add_mutex); } while (size < count); new_joystick_state = JOY_STATE_BORN; initialized = true; return true; } /* exit_joystick: * Shuts down the HID joystick driver. */ static void exit_joystick(void) { al_destroy_mutex(add_mutex); IOHIDManagerUnscheduleFromRunLoop( hidManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode ); // Unregister from value changes IOHIDManagerRegisterInputValueCallback( hidManagerRef, NULL, NULL ); IOHIDManagerClose( hidManagerRef, kIOHIDOptionsTypeNone ); CFRelease(hidManagerRef); _al_vector_free(&joysticks); } /* num_joysticks: * Return number of active joysticks */ static int num_joysticks(void) { int i; int count = 0; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); if (joy->cfg_state == JOY_STATE_ALIVE) { count++; } } return count; } /* get_joystick: * Get a pointer to a joystick structure */ static ALLEGRO_JOYSTICK* get_joystick(int index) { ASSERT(index >= 0 && index < (int)_al_vector_size(&joysticks)); int i; int count = 0; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); if (joy->cfg_state == JOY_STATE_ALIVE || joy->cfg_state == JOY_STATE_DYING) { if (count == index) { return (ALLEGRO_JOYSTICK *)joy; } count++; } } return NULL; } /* release_joystick: * Release a pointer that has been obtained */ static void release_joystick(ALLEGRO_JOYSTICK* joy __attribute__((unused)) ) { // No-op } /* get_joystick_state: * Get the current status of a joystick */ static void get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_OSX *joy = (ALLEGRO_JOYSTICK_OSX *) joy_; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); { *ret_state = joy->state; } _al_event_source_unlock(es); } static bool reconfigure_joysticks(void) { int i; bool ret = false; for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); if (joy->cfg_state == JOY_STATE_DYING) { joy->cfg_state = JOY_STATE_UNUSED; for (i = 0; i < _AL_MAX_JOYSTICK_BUTTONS; i++) { al_free((char *)joy->parent.info.button[i].name); } for (i = 0; i < _AL_MAX_JOYSTICK_STICKS; i++) { int j; al_free(joy->parent.info.stick[i].name); for (j = 0; j < _AL_MAX_JOYSTICK_AXES; j++) { al_free(joy->parent.info.stick[i].axis[j].name); } } joy_null(joy); joy->num_buttons = joy->num_x_axes = joy->num_y_axes = joy->num_z_axes = 0; memset(joy->buttons, 0, _AL_MAX_JOYSTICK_BUTTONS*sizeof(IOHIDElementRef)); memset(&joy->state, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); } else if (joy->cfg_state == JOY_STATE_BORN) joy->cfg_state = JOY_STATE_ALIVE; else continue; ret = true; } return ret; } // FIXME! static const char *get_joystick_name(ALLEGRO_JOYSTICK *joy_) { (void)joy_; return "Joystick"; } static bool get_joystick_active(ALLEGRO_JOYSTICK *joy_) { ALLEGRO_JOYSTICK_OSX *joy = (ALLEGRO_JOYSTICK_OSX *)joy_; return joy->cfg_state == JOY_STATE_ALIVE || joy->cfg_state == JOY_STATE_DYING; } ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_5(void) { static ALLEGRO_JOYSTICK_DRIVER* vt = NULL; if (vt == NULL) { vt = al_malloc(sizeof(*vt)); memset(vt, 0, sizeof(*vt)); vt->joydrv_ascii_name = "OSX HID Driver"; vt->init_joystick = init_joystick; vt->exit_joystick = exit_joystick; vt->reconfigure_joysticks = reconfigure_joysticks; vt->num_joysticks = num_joysticks; vt->get_joystick = get_joystick; vt->release_joystick = release_joystick; vt->get_joystick_state = get_joystick_state; vt->get_name = get_joystick_name; vt->get_active = get_joystick_active; } return vt; } #endif // Leopard+ ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_4(void); ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_5(void); ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver(void) { SInt32 major, minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); if (major >= 10 && minor >= 5) { return _al_osx_get_joystick_driver_10_5(); } else { return _al_osx_get_joystick_driver_10_4(); } } /* Local variables: */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/src/macosx/keybd.m0000644000175000001440000002715312125426002015745 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X keyboard module. * * By Angelo Mottola. * * Based on Unix/X11 version by Michael Bukin. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/platform/aintosx.h" #ifndef ALLEGRO_MACOSX #error Something is wrong with the makefile #endif /* Dictionary to translate OS X modifier codes to Allegro modifier codes * and key codes. */ static unsigned const int mod_info[5][3] = { { NSAlphaShiftKeyMask, ALLEGRO_KEYMOD_CAPSLOCK, ALLEGRO_KEY_CAPSLOCK }, { NSShiftKeyMask, ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEY_LSHIFT }, { NSControlKeyMask, ALLEGRO_KEYMOD_CTRL, ALLEGRO_KEY_LCTRL }, { NSAlternateKeyMask, ALLEGRO_KEYMOD_ALT, ALLEGRO_KEY_ALT }, { NSCommandKeyMask, ALLEGRO_KEYMOD_COMMAND, ALLEGRO_KEY_COMMAND } }; static bool osx_keyboard_init(void); static void osx_keyboard_exit(void); static ALLEGRO_KEYBOARD* osx_get_keyboard(void); static ALLEGRO_KEYBOARD keyboard; static ALLEGRO_KEYBOARD_STATE kbdstate; /* translate_modifier_flags: * Translate a bitmask of OS X modifier flags to Allegro's modifier flags */ static int translate_modifier_flags(int osx_mods) { int allegro_mods = 0; int i; for (i = 0; i < 5; i++) { if (osx_mods & mod_info[i][0]) allegro_mods |= mod_info[i][1]; } return allegro_mods; } /* _al_osx_switch_keyboard_focus: * Handle a focus switch event. */ void _al_osx_switch_keyboard_focus(ALLEGRO_DISPLAY *dpy, bool switch_in) { _al_event_source_lock(&keyboard.es); if (switch_in) kbdstate.display = dpy; else kbdstate.display = NULL; _al_event_source_unlock(&keyboard.es); } static void _handle_key_press(ALLEGRO_DISPLAY* dpy, int unicode, int scancode, int modifiers, bool is_repeat) { _al_event_source_lock(&keyboard.es); { /* Generate the press event if necessary. */ if (_al_event_source_needs_to_generate_event(&keyboard.es)) { ALLEGRO_EVENT event; event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; event.keyboard.timestamp = al_get_time(); event.keyboard.display = dpy; event.keyboard.keycode = scancode; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; event.keyboard.repeat = false; if (!is_repeat) { _al_event_source_emit_event(&keyboard.es, &event); } if (unicode > 0) { /* Apple maps function, arrow, and other keys to Unicode points. */ /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CORPCHAR.TXT */ if (unicode >= 0xF700 && unicode <= 0xF747) { unicode = 0; } event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; event.keyboard.unichar = unicode; event.keyboard.modifiers = modifiers; event.keyboard.repeat = is_repeat; _al_event_source_emit_event(&keyboard.es, &event); } } } /* Maintain the kbdstate array. */ _AL_KEYBOARD_STATE_SET_KEY_DOWN(kbdstate, scancode); _al_event_source_unlock(&keyboard.es); } static void _handle_key_release(ALLEGRO_DISPLAY* dpy, int scancode) { _al_event_source_lock(&keyboard.es); { /* Generate the release event if necessary. */ if (_al_event_source_needs_to_generate_event(&keyboard.es)) { ALLEGRO_EVENT event; event.keyboard.type = ALLEGRO_EVENT_KEY_UP; event.keyboard.timestamp = al_get_time(); event.keyboard.display = dpy; event.keyboard.keycode = scancode; event.keyboard.unichar = 0; event.keyboard.modifiers = 0; _al_event_source_emit_event(&keyboard.es, &event); } } /* Maintain the kbdstate array. */ _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(kbdstate, scancode); _al_event_source_unlock(&keyboard.es); } /* Mac keycode to Allegro scancode conversion table */ static const int mac_to_scancode[128] = { /* 0x00 */ ALLEGRO_KEY_A, ALLEGRO_KEY_S, ALLEGRO_KEY_D, ALLEGRO_KEY_F, /* 0x04 */ ALLEGRO_KEY_H, ALLEGRO_KEY_G, ALLEGRO_KEY_Z, ALLEGRO_KEY_X, /* 0x08 */ ALLEGRO_KEY_C, ALLEGRO_KEY_V, 0, ALLEGRO_KEY_B, /* 0x0c */ ALLEGRO_KEY_Q, ALLEGRO_KEY_W, ALLEGRO_KEY_E, ALLEGRO_KEY_R, /* 0x10 */ ALLEGRO_KEY_Y, ALLEGRO_KEY_T, ALLEGRO_KEY_1, ALLEGRO_KEY_2, /* 0x14 */ ALLEGRO_KEY_3, ALLEGRO_KEY_4, ALLEGRO_KEY_6, ALLEGRO_KEY_5, /* 0x18 */ ALLEGRO_KEY_EQUALS, ALLEGRO_KEY_9, ALLEGRO_KEY_7, ALLEGRO_KEY_MINUS, /* 0x1c */ ALLEGRO_KEY_8, ALLEGRO_KEY_0, ALLEGRO_KEY_CLOSEBRACE, ALLEGRO_KEY_O, /* 0x20 */ ALLEGRO_KEY_U, ALLEGRO_KEY_OPENBRACE, ALLEGRO_KEY_I, ALLEGRO_KEY_P, /* 0x24 */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_L, ALLEGRO_KEY_J, ALLEGRO_KEY_QUOTE, /* 0x28 */ ALLEGRO_KEY_K, ALLEGRO_KEY_SEMICOLON, ALLEGRO_KEY_BACKSLASH, ALLEGRO_KEY_COMMA, /* 0x2c */ ALLEGRO_KEY_SLASH, ALLEGRO_KEY_N, ALLEGRO_KEY_M, ALLEGRO_KEY_FULLSTOP, /* 0x30 */ ALLEGRO_KEY_TAB, ALLEGRO_KEY_SPACE, ALLEGRO_KEY_BACKQUOTE, ALLEGRO_KEY_BACKSPACE, /* 0x34 */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_ESCAPE, 0, ALLEGRO_KEY_COMMAND, /* 0x38 */ ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_ALT, ALLEGRO_KEY_LEFT, /* 0x3c */ ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_DOWN, ALLEGRO_KEY_UP, 0, /* 0x40 */ 0, ALLEGRO_KEY_FULLSTOP, 0, ALLEGRO_KEY_PAD_ASTERISK, /* 0x44 */ 0, ALLEGRO_KEY_PAD_PLUS, 0, ALLEGRO_KEY_NUMLOCK, /* 0x48 */ 0, 0, 0, ALLEGRO_KEY_PAD_SLASH, /* 0x4c */ ALLEGRO_KEY_PAD_ENTER,0, ALLEGRO_KEY_PAD_MINUS, 0, /* 0x50 */ 0, ALLEGRO_KEY_PAD_EQUALS, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_1, /* 0x54 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_5, /* 0x58 */ ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_7, 0, ALLEGRO_KEY_PAD_8, /* 0x5c */ ALLEGRO_KEY_PAD_9, 0, 0, 0, /* 0x60 */ ALLEGRO_KEY_F5, ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F3, /* 0x64 */ ALLEGRO_KEY_F8, ALLEGRO_KEY_F9, 0, ALLEGRO_KEY_F11, /* 0x68 */ 0, ALLEGRO_KEY_PRINTSCREEN,0, ALLEGRO_KEY_SCROLLLOCK, /* 0x6c */ 0, ALLEGRO_KEY_F10, 0, ALLEGRO_KEY_F12, /* 0x70 */ 0, ALLEGRO_KEY_PAUSE, ALLEGRO_KEY_INSERT, ALLEGRO_KEY_HOME, /* 0x74 */ ALLEGRO_KEY_PGUP, ALLEGRO_KEY_DELETE, ALLEGRO_KEY_F4, ALLEGRO_KEY_END, /* 0x78 */ ALLEGRO_KEY_F2, ALLEGRO_KEY_PGDN, ALLEGRO_KEY_F1, ALLEGRO_KEY_LEFT, /* 0x7c */ ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_DOWN, ALLEGRO_KEY_UP, 0 }; /* get_state: * Copy a snapshot of the keyboard state into the user's structure */ static void get_state(ALLEGRO_KEYBOARD_STATE *ret_state) { _al_event_source_lock(&keyboard.es); { memcpy(ret_state, &kbdstate, sizeof(ALLEGRO_KEYBOARD_STATE)); } _al_event_source_unlock(&keyboard.es); } static ALLEGRO_KEYBOARD_DRIVER keyboard_macosx = { KEYBOARD_MACOSX, "", "", "MacOS X keyboard", osx_keyboard_init, osx_keyboard_exit, osx_get_keyboard, NULL, // ALLEGRO_METHOD(bool, set_leds, (int leds)); NULL, // ALLEGRO_METHOD(const char *, keycode_to_name, (int keycode)); get_state, }; _AL_DRIVER_INFO _al_keyboard_driver_list[] = { { KEYBOARD_MACOSX, &keyboard_macosx, 1 }, { 0, NULL, 0 } }; /* _al_osx_get_keyboard_driver: * Returns the keyboard driver. */ ALLEGRO_KEYBOARD_DRIVER* _al_osx_get_keyboard_driver(void) { return &keyboard_macosx; } /* _al_osx_keyboard_handler: * Keyboard "interrupt" handler. */ void _al_osx_keyboard_handler(int pressed, NSEvent *event, ALLEGRO_DISPLAY* dpy) { /* We need to distinguish between the raw character code (needed for * ctrl and alt) and the "shifted" character code when neither of these * is held down. This is needed to get the correct behavior when caps * lock is on (ie, letters are upper case) */ int scancode = mac_to_scancode[[event keyCode]]; if (pressed) { /* Translate OS X modifier flags to Allegro modifier flags */ int key_shifts = translate_modifier_flags([event modifierFlags]); NSString* raw_characters = [event charactersIgnoringModifiers]; NSString* upper_characters = [event characters]; const unichar raw_character = ([raw_characters length] > 0) ? [raw_characters characterAtIndex: 0] : 0; const unichar upper_character =([upper_characters length] > 0) ? [upper_characters characterAtIndex: 0] : 0; bool is_repeat = pressed ? ([event isARepeat] == YES) : false; /* Special processing to send character 1 for CTRL-A, 2 for CTRL-B etc. */ if ((key_shifts & ALLEGRO_KEYMOD_CTRL) && (isalpha(raw_character))) _handle_key_press(dpy, tolower(raw_character) - 'a' + 1, scancode, key_shifts, is_repeat); else _handle_key_press(dpy, upper_character, scancode, key_shifts, is_repeat); } else { _handle_key_release(dpy, scancode); } } /* _al_osx_keyboard_modifier: * Handles keyboard modifiers changes. */ void _al_osx_keyboard_modifiers(unsigned int modifiers, ALLEGRO_DISPLAY* dpy) { static unsigned int old_modifiers = 0; int i, changed; int key_shifts; /* Translate OS X modifier flags to Allegro modifier flags */ key_shifts = translate_modifier_flags(modifiers); for (i = 0; i < 5; i++) { changed = (modifiers ^ old_modifiers) & mod_info[i][0]; if (changed) { if (modifiers & mod_info[i][0]) { _handle_key_press(dpy, -1, mod_info[i][2], key_shifts, false); if (i == 0) { /* Caps lock requires special handling */ _handle_key_release(dpy, mod_info[0][2]); } } else { if (i == 0) { _handle_key_press(dpy, -1, mod_info[0][2], key_shifts, false); } _handle_key_release(dpy, mod_info[i][2]); } } } old_modifiers = modifiers; } /* osx_keyboard_init: * Installs the keyboard handler. */ static bool osx_keyboard_init(void) { memset(&keyboard, 0, sizeof keyboard); _al_osx_keyboard_was_installed(YES); _al_event_source_init(&keyboard.es); return true; } /* osx_keyboard_exit: * Removes the keyboard handler. */ static void osx_keyboard_exit(void) { _al_event_source_free(&keyboard.es); _al_osx_keyboard_was_installed(NO); } /* osx_get_keyboard: * Returns the keyboard object. */ static ALLEGRO_KEYBOARD* osx_get_keyboard(void) { return &keyboard; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/iphone/0000755000175000001440000000000012157230741014461 5ustar tjadenusersallegro-5.0.10/src/iphone/iphone_display.c0000644000175000001440000002754712106526615017655 0ustar tjadenusers#include #include #include #include ALLEGRO_DEBUG_CHANNEL("iphone") static ALLEGRO_DISPLAY_INTERFACE *vt; static float _screen_scale = 1.0, _screen_iscale = 1.0; static float _screen_x, _screen_y; static float _screen_w, _screen_h; static bool _screen_hack; void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d) { int w, h; _al_iphone_get_screen_size(&w, &h); _al_iphone_reset_framebuffer(); glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0, w, h, 0, -1, 1); _screen_w = w; _screen_h = h; /* We automatically adjust the view if the user doesn't use 320x480. Users * of the iphone port are adviced to provide a 320x480 mode and do their * own adjustment - but for the sake of allowing ports without knowing * any OpenGL and not having to change a single character in your * application - here you go. */ if (d->w != w || d->h != h) { double scale = 1, xoff = 0, yoff = 0; if (d->w >= d->h) { if (d->w * w > d->h * h) { scale = h * 1.0 / d->w; xoff = (w - d->h * scale) * 0.5; _screen_y = 0.5 * (d->h - w / scale); } else { scale = w * 1.0 / d->h; yoff = (h - d->w * scale) * 0.5; _screen_x = 0.5 * (d->w - h / scale); } glTranslatef(xoff, yoff, 0); glTranslatef(w, 0, 0); glRotatef(90, 0, 0, 1); glScalef(scale, scale, 1); } else { // TODO } if (!_screen_hack) { _screen_hack = true; _screen_scale = scale; _screen_iscale = 1.0 / _screen_scale; ALLEGRO_INFO("Auto-scaling/rotating %dx%d display to %.fx%.f screen.\n", d->w, d->h, _screen_w, _screen_h); ALLEGRO_DEBUG("x-off:%.f y-off:%.f scale:%.2f\n", _screen_x, _screen_y, _screen_scale); } } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void _al_iphone_translate_from_screen(ALLEGRO_DISPLAY *d, int *x, int *y) { if (!_screen_hack) return; // See _al_iphone_setup_opengl_view float ox = *x, oy = *y; if (d->w >= d->h) { *x = _screen_x + oy * _screen_iscale; *y = _screen_y + (_screen_w - ox) * _screen_iscale; } else { // TODO } } void _al_iphone_translate_to_screen(ALLEGRO_DISPLAY *d, int *ox, int *oy) { if (!_screen_hack) return; // See _al_iphone_setup_opengl_view float x = *ox, y = *oy; if (d->w >= d->h) { *ox = _screen_w - (y - _screen_y) * _screen_scale; *oy = (x - _screen_x) * _screen_scale; } else { // TODO } } void _al_iphone_clip(ALLEGRO_BITMAP const *bitmap, int x_1, int y_1, int x_2, int y_2) { ALLEGRO_BITMAP_OGL *oglb = (void *)(bitmap->parent ? bitmap->parent : bitmap); int h = oglb->bitmap.h; if (_screen_hack && oglb->is_backbuffer) { _al_iphone_translate_to_screen(bitmap->display, &x_1, &y_1); _al_iphone_translate_to_screen(bitmap->display, &x_2, &y_2); if (x_1 > x_2) { int t = x_1; x_1 = x_2; x_2 = t; } h = _screen_h; } glScissor(x_1, h - y_2, x_2 - x_1, y_2 - y_1); } /* Helper to set up GL state as we want it. */ static void setup_gl(ALLEGRO_DISPLAY *d) { ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; if (ogl->backbuffer) _al_ogl_resize_backbuffer(ogl->backbuffer, d->w, d->h); else ogl->backbuffer = _al_ogl_create_backbuffer(d); _al_iphone_setup_opengl_view(d); } static void set_rgba8888(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { eds->settings[ALLEGRO_RED_SIZE] = 8; eds->settings[ALLEGRO_GREEN_SIZE] = 8; eds->settings[ALLEGRO_BLUE_SIZE] = 8; eds->settings[ALLEGRO_ALPHA_SIZE] = 8; eds->settings[ALLEGRO_RED_SHIFT] = 0; eds->settings[ALLEGRO_GREEN_SHIFT] = 8; eds->settings[ALLEGRO_BLUE_SHIFT] = 16; eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; eds->settings[ALLEGRO_COLOR_SIZE] = 32; } static void set_rgb565(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { eds->settings[ALLEGRO_RED_SIZE] = 5; eds->settings[ALLEGRO_GREEN_SIZE] = 6; eds->settings[ALLEGRO_BLUE_SIZE] = 5; eds->settings[ALLEGRO_ALPHA_SIZE] = 0; eds->settings[ALLEGRO_RED_SHIFT] = 0; eds->settings[ALLEGRO_GREEN_SHIFT] = 5; eds->settings[ALLEGRO_BLUE_SHIFT] = 11; eds->settings[ALLEGRO_ALPHA_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 16; } #define VISUALS_COUNT 6 void _al_iphone_update_visuals(void) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); ref = _al_get_new_display_settings(); /* If we aren't called the first time, only updated scores. */ if (system->visuals) { for (int i = 0; i < system->visuals_count; i++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = system->visuals[i]; eds->score = _al_score_display_settings(eds, ref); } return; } system->visuals = al_calloc(VISUALS_COUNT, sizeof(*system->visuals)); system->visuals_count = VISUALS_COUNT; for (int i = 0; i < VISUALS_COUNT; i++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = al_calloc(1, sizeof *eds); eds->settings[ALLEGRO_RENDER_METHOD] = 1; eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; eds->settings[ALLEGRO_SWAP_METHOD] = 2; eds->settings[ALLEGRO_VSYNC] = 1; switch (i) { case 0: set_rgba8888(eds); break; case 1: set_rgb565(eds); break; case 2: set_rgba8888(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 16; break; case 3: set_rgb565(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 16; break; case 4: set_rgba8888(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 24; eds->settings[ALLEGRO_STENCIL_SIZE] = 8; break; case 5: set_rgb565(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 24; eds->settings[ALLEGRO_STENCIL_SIZE] = 8; break; } eds->score = _al_score_display_settings(eds, ref); eds->index = i; system->visuals[i] = eds; } } static ALLEGRO_DISPLAY *iphone_create_display(int w, int h) { ALLEGRO_DISPLAY_IPHONE *d = al_calloc(1, sizeof *d); ALLEGRO_DISPLAY *display = (void*)d; ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); display->ogl_extras = ogl; display->vt = _al_get_iphone_display_interface(); display->flags = al_get_new_display_flags(); if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { _al_iphone_get_screen_size(&w, &h); } display->w = w; display->h = h; ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); /* Add ourself to the list of displays. */ ALLEGRO_DISPLAY_IPHONE **add; add = _al_vector_alloc_back(&system->system.displays); *add = d; /* Each display is an event source. */ _al_event_source_init(&display->es); _al_iphone_update_visuals(); ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds[system->visuals_count]; memcpy(eds, system->visuals, sizeof(*eds) * system->visuals_count); qsort(eds, system->visuals_count, sizeof(*eds), _al_display_settings_sorter); ALLEGRO_INFO("Chose visual no. %i\n", eds[0]->index); memcpy(&display->extra_settings, eds[0], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); /* This will add an OpenGL view with an OpenGL context, then return. */ _al_iphone_add_view(display); _al_iphone_make_view_current(); _al_ogl_manage_extensions(display); _al_ogl_set_extensions(ogl->extension_api); setup_gl(display); display->flags |= ALLEGRO_OPENGL; return display; } static void iphone_destroy_display(ALLEGRO_DISPLAY *d) { (void)d; // FIXME: not supported yet } static bool iphone_set_current_display(ALLEGRO_DISPLAY *d) { (void)d; _al_iphone_make_view_current(); return true; } /* There can be only one window and only one OpenGL context, so all bitmaps * are compatible. */ static bool iphone_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) { (void)display; (void)bitmap; return true; } /* Resizing is not possible. */ static bool iphone_resize_display(ALLEGRO_DISPLAY *d, int w, int h) { (void)d; (void)w; (void)h; return false; } /* The icon must be provided in the Info.plist file, it cannot be changed * at runtime. */ static void iphone_set_icons(ALLEGRO_DISPLAY *d, int num_icons, ALLEGRO_BITMAP *bitmaps[]) { (void)d; (void)num_icons; (void)bitmaps; } /* There is no way to leave fullscreen so no window title is visible. */ static void iphone_set_window_title(ALLEGRO_DISPLAY *display, char const *title) { (void)display; (void)title; } /* The window always spans the entire screen right now. */ static void iphone_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { (void)display; (void)x; (void)y; } /* Always fullscreen. */ static bool iphone_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) { (void)display; (void)flag; (void)onoff; return false; } static void iphone_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) { (void)display; *x = 0; *y = 0; } static bool iphone_wait_for_vsync(ALLEGRO_DISPLAY *display) { (void)display; return false; } static void iphone_flip_display(ALLEGRO_DISPLAY *d) { (void)d; _al_iphone_flip_view(); } static void iphone_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, int w, int h) { (void)x; (void)y; (void)w; (void)h; iphone_flip_display(d); } static bool iphone_acknowledge_resize(ALLEGRO_DISPLAY *d) { (void)d; return false; } static bool iphone_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { (void)display; (void)cursor; return false; } static bool iphone_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { (void)display; (void)cursor_id; return false; } static bool iphone_show_mouse_cursor(ALLEGRO_DISPLAY *display) { (void)display; return false; } static bool iphone_hide_mouse_cursor(ALLEGRO_DISPLAY *display) { (void)display; return false; } /* Obtain a reference to this driver. */ ALLEGRO_DISPLAY_INTERFACE *_al_get_iphone_display_interface(void) { if (vt) return vt; vt = al_calloc(1, sizeof *vt); vt->create_display = iphone_create_display; vt->destroy_display = iphone_destroy_display; vt->set_current_display = iphone_set_current_display; vt->flip_display = iphone_flip_display; vt->update_display_region = iphone_update_display_region; vt->acknowledge_resize = iphone_acknowledge_resize; vt->create_bitmap = _al_ogl_create_bitmap; vt->create_sub_bitmap = _al_ogl_create_sub_bitmap; vt->get_backbuffer = _al_ogl_get_backbuffer; vt->set_target_bitmap = _al_ogl_set_target_bitmap; vt->is_compatible_bitmap = iphone_is_compatible_bitmap; vt->resize_display = iphone_resize_display; vt->set_icons = iphone_set_icons; vt->set_window_title = iphone_set_window_title; vt->set_window_position = iphone_set_window_position; vt->get_window_position = iphone_get_window_position; vt->set_display_flag = iphone_set_display_flag; vt->wait_for_vsync = iphone_wait_for_vsync; vt->set_mouse_cursor = iphone_set_mouse_cursor; vt->set_system_mouse_cursor = iphone_set_system_mouse_cursor; vt->show_mouse_cursor = iphone_show_mouse_cursor; vt->hide_mouse_cursor = iphone_hide_mouse_cursor; _al_ogl_add_drawing_functions(vt); return vt; } allegro-5.0.10/src/iphone/iphone_joystick.m0000644000175000001440000000653611655353155020061 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_iphone.h" ALLEGRO_DEBUG_CHANNEL("iphone") typedef struct ALLEGRO_JOYSTICK_IPHONE { ALLEGRO_JOYSTICK parent; ALLEGRO_JOYSTICK_STATE joystate; } ALLEGRO_JOYSTICK_IPHONE; static ALLEGRO_JOYSTICK_IPHONE the_joystick; static bool initialized; static bool ijoy_init_joystick(void) { ALLEGRO_JOYSTICK_IPHONE *ijoy; ALLEGRO_JOYSTICK *joy; ijoy = &the_joystick; memset(ijoy, 0, sizeof *ijoy); joy = (void *)ijoy; /* Fill in the joystick information fields. */ joy->info.num_sticks = 1; joy->info.num_buttons = 0; joy->info.stick[0].name = "Accelerometer"; joy->info.stick[0].num_axes = 3; joy->info.stick[0].axis[0].name = "X"; joy->info.stick[0].axis[1].name = "Y"; joy->info.stick[0].axis[2].name = "Z"; joy->info.stick[0].flags = ALLEGRO_JOYFLAG_ANALOGUE; // TODO: What's a good frequency to use here? _al_iphone_accelerometer_control(60); initialized = true; return true; } static void ijoy_exit_joystick(void) { _al_iphone_accelerometer_control(0); initialized = false; } static bool ijoy_reconfigure_joysticks(void) { return false; } static int ijoy_num_joysticks(void) { return 1; } static ALLEGRO_JOYSTICK *ijoy_get_joystick(int num) { if (num != 0) return NULL; ALLEGRO_DEBUG("Joystick %d acquired.\n", num); return &the_joystick.parent; } static void ijoy_release_joystick(ALLEGRO_JOYSTICK *joy) { (void)joy; ALLEGRO_DEBUG("Joystick released.\n"); initialized = false; } static void ijoy_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) { ALLEGRO_JOYSTICK_IPHONE *ijoy = (void *)joy; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); _al_event_source_lock(es); *ret_state = ijoy->joystate; _al_event_source_unlock(es); } void _al_iphone_generate_joystick_event(float x, float y, float z) { if (!initialized) return; ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); ALLEGRO_EVENT event; _al_event_source_lock(es); if (_al_event_source_needs_to_generate_event(es)) { float pos[] = {x, y, z}; for (int i = 0; i < 3; i++) { event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; event.joystick.timestamp = al_get_time(); event.joystick.stick = 0; event.joystick.axis = i; event.joystick.pos = pos[i]; event.joystick.button = 0; _al_event_source_emit_event(es, &event); } } _al_event_source_unlock(es); } static char const *ijoy_get_name(ALLEGRO_JOYSTICK *joy) { (void)joy; return "Accelerometer"; } static bool ijoy_get_active(ALLEGRO_JOYSTICK *joy) { (void)joy; return true; } static ALLEGRO_JOYSTICK_DRIVER iphone_joystick_driver = { AL_ID('I', 'P', 'H', 'O'), "", "", "iphone joystick", ijoy_init_joystick, ijoy_exit_joystick, ijoy_reconfigure_joysticks, ijoy_num_joysticks, ijoy_get_joystick, ijoy_release_joystick, ijoy_get_joystick_state, ijoy_get_name, ijoy_get_active }; ALLEGRO_JOYSTICK_DRIVER *_al_get_iphone_joystick_driver(void) { return &iphone_joystick_driver; } allegro-5.0.10/src/iphone/iphone_path.m0000644000175000001440000000310311655354150017135 0ustar tjadenusers#import #include #include ALLEGRO_PATH *_al_iphone_get_path(int id) { char str[PATH_MAX]; NSString *string; NSArray *array; NSBundle *mainBundle; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; switch (id) { case ALLEGRO_USER_HOME_PATH: string = NSHomeDirectory(); break; case ALLEGRO_TEMP_PATH: string = NSTemporaryDirectory(); break; case ALLEGRO_RESOURCES_PATH: mainBundle = [NSBundle mainBundle]; string = [mainBundle resourcePath]; break; case ALLEGRO_USER_SETTINGS_PATH: case ALLEGRO_USER_DATA_PATH: array = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, TRUE); string = (NSString *)[array objectAtIndex:0]; break; case ALLEGRO_USER_DOCUMENTS_PATH: array = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, TRUE); string = (NSString *)[array objectAtIndex:0]; break; case ALLEGRO_EXENAME_PATH: { uint32_t size = sizeof(str); if (_NSGetExecutablePath(str, &size) != 0) { [pool drain]; return NULL; } [pool drain]; return al_create_path(str); } default: [pool drain]; return NULL; } sprintf(str, "%s", [string UTF8String]); [pool drain]; return al_create_path_for_directory(str); } allegro-5.0.10/src/iphone/allegroAppDelegate.m0000644000175000001440000002124011655353277020373 0ustar tjadenusers#import "allegroAppDelegate.h" #import "EAGLView.h" #import #include ALLEGRO_DEBUG_CHANNEL("iphone") void _al_iphone_run_user_main(void); static allegroAppDelegate *global_delegate; static UIImageView *splashview; static UIWindow *splashwin; static volatile bool waiting_for_program_halt = false; static float scale_override = -1.0; /* Function: al_iphone_program_has_halted */ void al_iphone_program_has_halted(void) { waiting_for_program_halt = false; } float _al_iphone_get_screen_scale(void) { if (scale_override > 0.0) { return scale_override; } if ([[UIScreen mainScreen] respondsToSelector:NSSelectorFromString(@"scale")]) { return [[UIScreen mainScreen] scale]; } return 1.0f; } void _al_iphone_get_view(void) { return [global_delegate view]; } /* Function: al_iphone_override_screen_scale */ void al_iphone_override_screen_scale(float scale) { scale_override = scale; } void _al_iphone_add_view(ALLEGRO_DISPLAY *display) { [global_delegate set_allegro_display:display]; /* This is the same as * [global_delegate.view add_view]; * except it will run in the main thread. */ [global_delegate performSelectorOnMainThread: @selector(add_view) withObject:nil waitUntilDone: YES]; } void _al_iphone_make_view_current(void) { [global_delegate.view make_current]; } void _al_iphone_flip_view(void) { [global_delegate.view flip]; if (splashview) { [splashview removeFromSuperview]; [splashview release]; [splashwin removeFromSuperview]; [splashwin release]; splashview = nil; splashwin = nil; } } void _al_iphone_reset_framebuffer(void) { [global_delegate.view reset_framebuffer]; } /* Use a frequency to start receiving events at the freuqency, 0 to shut off * the accelerometer (according to Apple, it drains a bit of battery while on). */ void _al_iphone_accelerometer_control(int frequency) { if (frequency) { [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / frequency)]; [[UIAccelerometer sharedAccelerometer] setDelegate:global_delegate]; } else { [[UIAccelerometer sharedAccelerometer] setDelegate:nil]; } } void _al_iphone_get_screen_size(int *w, int *h) { UIScreen* screen = [UIScreen mainScreen]; if (NULL != screen) { CGRect bounds = [screen bounds]; CGFloat scale = 1.0f; if ([screen respondsToSelector:NSSelectorFromString(@"scale")]) { scale = [screen scale]; } *w = (int)(bounds.size.width * scale); *h = (int)(bounds.size.height * scale); } else { ASSERT("You should never see this message, unless Apple changed their policy and allows for removing screens from iDevices." && false); } } @implementation allegroAppDelegate @synthesize window; @synthesize view; + (void)run:(int)argc:(char **)argv { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIApplicationMain(argc, argv, nil, @"allegroAppDelegate"); [pool release]; } /* When applicationDidFinishLaunching() returns, the current view gets visible * for at least one frame. Since we have no OpenGL context in the main thread * we cannot draw anything into our OpenGL view so it means there's a short * black flicker before the first al_flip_display() no matter what. * * To prevent the black flicker we create a dummy view here which loads the * Default.png just as apple does internally. This way the moment the user * view is first displayed in the user thread we switch from displaying the * splash screen to the first user frame, without any flicker. */ - (void)display_splash_screen { UIScreen *screen = [UIScreen mainScreen]; splashwin = [[UIWindow alloc] initWithFrame:[screen bounds]]; UIImage *img = [UIImage imageNamed:@"Default.png"]; splashview = [[UIImageView alloc] initWithImage:img]; [splashwin addSubview:splashview]; [splashwin makeKeyAndVisible]; } - (void)orientation_change:(NSNotification *)notification { ALLEGRO_DISPLAY *d = allegro_display; UIDeviceOrientation o = [[UIDevice currentDevice] orientation]; int ao; (void)notification; if (d == NULL) return; switch (o) { case (UIDeviceOrientationPortrait): ao = ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; break; case (UIDeviceOrientationPortraitUpsideDown): ao = ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES; break; case (UIDeviceOrientationLandscapeRight): ao = ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES; break; case (UIDeviceOrientationLandscapeLeft): ao = ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES; break; case (UIDeviceOrientationFaceUp): ao = ALLEGRO_DISPLAY_ORIENTATION_FACE_UP; break; case (UIDeviceOrientationFaceDown): ao = ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN; break; default: return; } _al_event_source_lock(&d->es); if (_al_event_source_needs_to_generate_event(&d->es)) { ALLEGRO_EVENT event; event.display.type = ALLEGRO_EVENT_DISPLAY_ORIENTATION; event.display.timestamp = al_get_time(); event.display.source = allegro_display; event.display.orientation = ao; _al_event_source_emit_event(&d->es, &event); } _al_event_source_unlock(&d->es); } - (void)applicationDidFinishLaunching:(UIApplication *)application { ALLEGRO_INFO("App launched.\n"); application.statusBarHidden = true; global_delegate = self; // Register for device orientation notifications [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientation_change:) name:UIDeviceOrientationDidChangeNotification object:nil]; [self display_splash_screen]; _al_iphone_run_user_main(); } - (void)applicationWillTerminate:(UIApplication *)application { (void)application; ALLEGRO_EVENT event; ALLEGRO_DISPLAY *d = allegro_display; ALLEGRO_SYSTEM_IPHONE *iphone = (void *)al_get_system_driver(); iphone->wants_shutdown = true; [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; _al_event_source_lock(&d->es); if (_al_event_source_needs_to_generate_event(&d->es)) { event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; event.display.timestamp = al_get_time(); _al_event_source_emit_event(&d->es, &event); } _al_event_source_unlock(&d->es); /* When this method returns, the application terminates - so lets wait a bit * so the user app can shutdown properly, e.g. to save state as is usually * required by iphone apps. */ _al_iphone_await_termination(); } - (void)applicationWillResignActive:(UIApplication *)application { ALLEGRO_DISPLAY *d = allegro_display; ALLEGRO_EVENT event; (void)application; ALLEGRO_INFO("Application becoming inactive.\n"); waiting_for_program_halt = true; _al_event_source_lock(&d->es); if (_al_event_source_needs_to_generate_event(&d->es)) { event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; event.display.timestamp = al_current_time(); _al_event_source_emit_event(&d->es, &event); } _al_event_source_unlock(&d->es); while (waiting_for_program_halt) { // do nothing, this should be quick al_rest(0.001); } } - (void)applicationDidBecomeActive:(UIApplication *)application { ALLEGRO_DISPLAY *d = allegro_display; ALLEGRO_EVENT event; (void)application; ALLEGRO_INFO("Application becoming active...\n"); if (!d) return; _al_event_source_lock(&d->es); if (_al_event_source_needs_to_generate_event(&d->es)) { event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; event.display.timestamp = al_current_time(); _al_event_source_emit_event(&d->es, &event); } _al_event_source_unlock(&d->es); } - (void)set_allegro_display:(ALLEGRO_DISPLAY *)d { allegro_display = d; } /* Note: This must be called from the main thread. Ask Apple why - but I tried * it and otherwise things simply don't work (the screen just stays black). */ - (void)add_view { window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; view = [[EAGLView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [view set_allegro_display:allegro_display]; [window addSubview:view]; [window makeKeyAndVisible]; [view becomeFirstResponder]; } - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration { (void)accelerometer; _al_iphone_generate_joystick_event(acceleration.x, acceleration.y, acceleration.z); } - (void)dealloc { [window release]; [super dealloc]; } @end allegro-5.0.10/src/iphone/EAGLView.m0000644000175000001440000002203712106526615016210 0ustar tjadenusers#import #import #import "EAGLView.h" #include ALLEGRO_DEBUG_CHANNEL("iphone") typedef struct touch_t { int id; UITouch* touch; } touch_t; /* Every UITouch have associated touch_t structure. This destructor * is used in list which held touch information. While ending touch it will * be called and memory will be freed. */ static void touch_item_dtor(void* value, void* userdata) { al_free(value); } /* Search for touch_t associated with UITouch. */ static touch_t* find_touch(_AL_LIST* list, UITouch* nativeTouch) { _AL_LIST_ITEM* item; for (item = _al_list_front(list); item; item = _al_list_next(list, item)) { touch_t* touch = (touch_t*)_al_list_item_data(item); if (touch->touch == nativeTouch) return touch; } return NULL; } @implementation EAGLView @synthesize context; @synthesize backingWidth; @synthesize backingHeight; // You must implement this method + (Class)layerClass { return [CAEAGLLayer class]; } - (void)set_allegro_display:(ALLEGRO_DISPLAY *)display { allegro_display = display; // Get the layer CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; NSString *color_format = kEAGLColorFormatRGBA8; if (display->extra_settings.settings[ALLEGRO_COLOR_SIZE] == 16) color_format = kEAGLColorFormatRGB565; eaglLayer.opaque = YES; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, color_format, kEAGLDrawablePropertyColorFormat, nil]; context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; if (!context || ![EAGLContext setCurrentContext:context]) { [self release]; return; } /* FIXME: Make this depend on a display setting. */ [self setMultipleTouchEnabled:YES]; ALLEGRO_INFO("Created EAGLView.\n"); } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; touch_list = _al_list_create(); touch_id_set = [[NSMutableIndexSet alloc] init]; next_free_touch_id = 1; return self; } - (void)make_current { [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); } - (void)reset_framebuffer { glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); } - (void)flip { glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; } - (void)layoutSubviews { [EAGLContext setCurrentContext:context]; [self destroyFramebuffer]; [self createFramebuffer]; ALLEGRO_INFO("Initialized EAGLView.\n"); } - (BOOL)createFramebuffer { if ([self respondsToSelector:@selector(contentScaleFactor)]) { self.contentScaleFactor = _al_iphone_get_screen_scale(); ALLEGRO_INFO("Screen scale is %f\n", self.contentScaleFactor); } ALLEGRO_INFO("Creating GL framebuffer.\n"); glGenFramebuffersOES(1, &viewFramebuffer); glGenRenderbuffersOES(1, &viewRenderbuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); if (allegro_display->extra_settings.settings[ALLEGRO_DEPTH_SIZE]) { GLint depth_stencil_format; if (allegro_display->extra_settings.settings[ALLEGRO_STENCIL_SIZE]) { depth_stencil_format = GL_DEPTH24_STENCIL8_OES; } else { depth_stencil_format = GL_DEPTH_COMPONENT16_OES; } glGenRenderbuffersOES(1, &depthRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depth_stencil_format, backingWidth, backingHeight); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); if (allegro_display->extra_settings.settings[ALLEGRO_STENCIL_SIZE]) { glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); } } if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); return NO; } return YES; } - (void)destroyFramebuffer { glDeleteFramebuffersOES(1, &viewFramebuffer); viewFramebuffer = 0; glDeleteRenderbuffersOES(1, &viewRenderbuffer); viewRenderbuffer = 0; if (depthRenderbuffer) { glDeleteRenderbuffersOES(1, &depthRenderbuffer); depthRenderbuffer = 0; } } - (void)dealloc { if (touch_list) _al_list_destroy(touch_list); [touch_id_set release]; if ([EAGLContext currentContext] == context) { [EAGLContext setCurrentContext:nil]; } [context release]; [super dealloc]; } /* Handling of touch events. */ -(NSArray*)getSortedTouches:(NSSet*)touches { NSArray* unsorted = [NSArray arrayWithArray: [touches allObjects]]; NSArray* sorted = [unsorted sortedArrayUsingComparator: ^(id obj1, id obj2) { if ([obj1 timestamp] > [obj2 timestamp]) return (NSComparisonResult)NSOrderedDescending; else if ([obj1 timestamp] < [obj2 timestamp]) return (NSComparisonResult)NSOrderedAscending; else return (NSComparisonResult)NSOrderedSame; }]; return sorted; } // Handles the start of a touch -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { (void)event; //UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; // TODO: handle double-clicks (send two events?) // NSUInteger numTaps = [[touches anyObject] tapCount]; // Enumerate through all the touch objects. for (UITouch *nativeTouch in touches) { /* Create new touch_t and associate ID with UITouch. */ touch_t* touch = al_malloc(sizeof(touch_t)); touch->touch = nativeTouch; if ([touch_id_set count] != 0) { touch->id = [touch_id_set firstIndex]; [touch_id_set removeIndex:touch->id]; } else touch->id = next_free_touch_id++; _al_list_push_back_ex(touch_list, touch, touch_item_dtor); CGPoint p = [nativeTouch locationInView:self]; p.x *= _al_iphone_get_screen_scale(); p.y *= _al_iphone_get_screen_scale(); _al_iphone_generate_mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, p.x, p.y, touch->id, allegro_display); } } // Handles the continuation of a touch. -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { (void)event; touch_t* touch; // Enumerates through all touch objects for (UITouch *nativeTouch in touches) { if ((touch = find_touch(touch_list, nativeTouch))) { CGPoint p = [nativeTouch locationInView:self]; p.x *= _al_iphone_get_screen_scale(); p.y *= _al_iphone_get_screen_scale(); _al_iphone_generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, p.x, p.y, touch->id, allegro_display); } } } // Handles the end of a touch event. -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { (void)event; touch_t* touch; // Enumerates through all touch objects for (UITouch *nativeTouch in touches) { if ((touch = find_touch(touch_list, nativeTouch))) { CGPoint p = [nativeTouch locationInView:self]; p.x *= _al_iphone_get_screen_scale(); p.y *= _al_iphone_get_screen_scale(); _al_iphone_generate_mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_UP, p.x, p.y, touch->id, allegro_display); [touch_id_set addIndex:touch->id]; _al_list_remove(touch_list, touch); } } } // Qooting Apple docs: // "The system cancelled tracking for the touch, as when (for example) the user // puts the device to his or her face." -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { (void)event; touch_t* touch; // Enumerates through all touch objects for (UITouch *nativeTouch in touches) { if ((touch = find_touch(touch_list, nativeTouch))) { CGPoint p = [nativeTouch locationInView:self]; p.x *= _al_iphone_get_screen_scale(); p.y *= _al_iphone_get_screen_scale(); _al_iphone_generate_mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_UP, p.x, p.y, touch->id, allegro_display); [touch_id_set addIndex:touch->id]; _al_list_remove(touch_list, touch); } } } -(BOOL)canBecomeFirstResponder { return YES; } @end allegro-5.0.10/src/iphone/EAGLView.h0000644000175000001440000000310411521367652016201 0ustar tjadenusers#import #import #import #import #include #include #include /* This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. The view content is basically an EAGL surface you render your OpenGL scene into. Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. */ @interface EAGLView : UIView { @private EAGLContext *context; ALLEGRO_DISPLAY *allegro_display; /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ GLuint viewRenderbuffer, viewFramebuffer; /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ GLuint depthRenderbuffer; /* Stuff for managing ID's for touches. List held struct which connect UITouch with ID on Allegro site. * NSMutableIndexSet hold list of free id's which were used. 'next_free_touch_id' hold next unused ID. * * 'touch_list' serve actuall as dictionary which map UITouch do ID. */ _AL_LIST* touch_list; NSMutableIndexSet* touch_id_set; int next_free_touch_id; } @property (nonatomic, retain) EAGLContext *context; @property GLint backingWidth; @property GLint backingHeight; - (void)make_current; - (void)flip; - (void)reset_framebuffer; - (void)set_allegro_display:(ALLEGRO_DISPLAY *)display; - (BOOL) createFramebuffer; - (void) destroyFramebuffer; @end allegro-5.0.10/src/iphone/iphone_mouse.m0000644000175000001440000000617311446133765017350 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_iphone.h" typedef struct ALLEGRO_MOUSE_IPHONE { ALLEGRO_MOUSE parent; ALLEGRO_MOUSE_STATE state; } ALLEGRO_MOUSE_IPHONE; static ALLEGRO_MOUSE_IPHONE the_mouse; static bool imouse_installed; /* * Helper to generate a mouse event. */ void _al_iphone_generate_mouse_event(unsigned int type, int x, int y, unsigned int button, ALLEGRO_DISPLAY *d) { ALLEGRO_EVENT event; _al_event_source_lock(&the_mouse.parent.es); _al_iphone_translate_from_screen(d, &x, &y); if (_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) { event.mouse.type = type; event.mouse.timestamp = al_get_time(); event.mouse.display = d; event.mouse.x = x; event.mouse.y = y; event.mouse.z = 0; event.mouse.w = 0; event.mouse.dx = 0; // TODO event.mouse.dy = 0; // TODO event.mouse.dz = 0; // TODO event.mouse.dw = 0; // TODO event.mouse.button = button; event.mouse.pressure = 0.0; // TODO _al_event_source_emit_event(&the_mouse.parent.es, &event); } _al_event_source_unlock(&the_mouse.parent.es); the_mouse.state.x = x; the_mouse.state.y = y; if (type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { the_mouse.state.buttons |= (1 << button); } else if (type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { the_mouse.state.buttons &= ~(1 << button); } } static void imouse_exit(void); static bool imouse_init(void) { if (imouse_installed) imouse_exit(); memset(&the_mouse, 0, sizeof the_mouse); _al_event_source_init(&the_mouse.parent.es); imouse_installed = true; return true; } static void imouse_exit(void) { if (!imouse_installed) return; imouse_installed = false; _al_event_source_free(&the_mouse.parent.es); } static ALLEGRO_MOUSE *imouse_get_mouse(void) { ASSERT(imouse_installed); return (ALLEGRO_MOUSE *)&the_mouse; } /* We report multi-touch as different buttons. */ static unsigned int imouse_get_mouse_num_buttons(void) { return 5; } static unsigned int imouse_get_mouse_num_axes(void) { return 2; } /* Hard to accomplish on a touch screen. */ static bool imouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) { (void)display; (void)x; (void)y; return false; } static bool imouse_set_mouse_axis(int which, int z) { (void)which; (void)z; return false; } static void imouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) { ASSERT(imouse_installed); _al_event_source_lock(&the_mouse.parent.es); { *ret_state = the_mouse.state; } _al_event_source_unlock(&the_mouse.parent.es); } static ALLEGRO_MOUSE_DRIVER iphone_mouse_driver = { AL_ID('I', 'P', 'H', 'O'), "", "", "iphone mouse", imouse_init, imouse_exit, imouse_get_mouse, imouse_get_mouse_num_buttons, imouse_get_mouse_num_axes, imouse_set_mouse_xy, imouse_set_mouse_axis, imouse_get_state }; ALLEGRO_MOUSE_DRIVER *_al_get_iphone_mouse_driver(void) { return &iphone_mouse_driver; } allegro-5.0.10/src/iphone/allegroAppDelegate.h0000644000175000001440000000104111476665340020361 0ustar tjadenusers#import #include @class EAGLView; @interface allegroAppDelegate : NSObject { UIWindow *window; EAGLView *view; ALLEGRO_DISPLAY *allegro_display; } @property (nonatomic, retain) UIWindow *window; @property (nonatomic, retain) EAGLView *view; + (void)run:(int)argc:(char **)argv; - (void)add_view; - (void)set_allegro_display:(ALLEGRO_DISPLAY *)d; - (void)display_splash_screen; - (void)orientation_change:(NSNotification *)notification; @end allegro-5.0.10/src/iphone/iphone_system.c0000644000175000001440000000535711621646113017524 0ustar tjadenusers#include #include ALLEGRO_DEBUG_CHANNEL("iphone") ALLEGRO_SYSTEM_IPHONE *iphone; static ALLEGRO_SYSTEM_INTERFACE *vt; /* al_init will call this. */ ALLEGRO_SYSTEM *iphone_initialize(int flags) { (void)flags; iphone = al_calloc(1, sizeof *iphone); ALLEGRO_SYSTEM *sys = &iphone->system; iphone->mutex = al_create_mutex(); iphone->cond = al_create_cond(); sys->vt = _al_get_iphone_system_interface(); _al_vector_init(&sys->displays, sizeof (ALLEGRO_DISPLAY_IPHONE *)); _al_unix_init_time(); _al_iphone_init_path(); return sys; } /* This is called from the termination message - it has to return soon as the * user expects the app to close when it is closed. */ void _al_iphone_await_termination(void) { ALLEGRO_INFO("Application awaiting termination.\n"); al_lock_mutex(iphone->mutex); while (!iphone->has_shutdown) { al_wait_cond(iphone->cond, iphone->mutex); } al_unlock_mutex(iphone->mutex); } static ALLEGRO_DISPLAY_INTERFACE *iphone_get_display_driver(void) { return _al_get_iphone_display_interface(); } static int iphone_get_num_video_adapters(void) { return 1; } static bool iphone_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) { int w, h; (void)adapter; _al_iphone_get_screen_size(&w, &h); info->x1 = 0; info->y1 = 0; info->x2 = w; info->y2 = h; return true; } /* There is no cursor. */ static bool iphone_get_cursor_position(int *ret_x, int *ret_y) { (void)ret_x; (void)ret_y; return false; } ALLEGRO_SYSTEM_INTERFACE *_al_get_iphone_system_interface(void) { if (vt) return vt; vt = al_calloc(1, sizeof *vt); vt->initialize = iphone_initialize; vt->get_display_driver = iphone_get_display_driver; vt->get_keyboard_driver = _al_get_iphone_keyboard_driver; vt->get_mouse_driver = _al_get_iphone_mouse_driver; vt->get_joystick_driver = _al_get_iphone_joystick_driver; //xglx_vt->get_num_display_modes = _al_xglx_get_num_display_modes; //xglx_vt->get_display_mode = _al_xglx_get_display_mode; //xglx_vt->shutdown_system = xglx_shutdown_system; vt->get_num_video_adapters = iphone_get_num_video_adapters; vt->get_monitor_info = iphone_get_monitor_info; vt->get_cursor_position = iphone_get_cursor_position; vt->get_path = _al_iphone_get_path; //xglx_vt->inhibit_screensaver = xglx_inhibit_screensaver; return vt; } /* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_get_iphone_system_interface(); } allegro-5.0.10/src/iphone/iphone_main.m0000644000175000001440000000433111433551022017120 0ustar tjadenusers#import #import "allegroAppDelegate.h" #include #include #include ALLEGRO_DEBUG_CHANNEL("iphone") /* Not that there could ever be any arguments on iphone... */ static int global_argc; static char **global_argv; extern int _al_mangled_main(int, char **); /* We run the user's "main" in its own thread. */ static void *user_main(ALLEGRO_THREAD *thread, void *arg) { (void)thread; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ALLEGRO_INFO("Starting user main.\n"); _al_mangled_main(global_argc, global_argv); [pool release]; ALLEGRO_INFO("User main has returned.\n"); ALLEGRO_SYSTEM_IPHONE *iphone = (void *)al_get_system_driver(); al_lock_mutex(iphone->mutex); iphone->has_shutdown = true; al_signal_cond(iphone->cond); al_unlock_mutex(iphone->mutex); /* Apple does not allow iphone applications to shutdown and provides * no API for it: * http://developer.apple.com/iphone/library/qa/qa2008/qa1561.html * * Therefore we only call exit here if the user actually returned from * there main - in that case crashing the app is better then freezing it. */ if (!iphone->wants_shutdown) exit(0); /* "crash grazefully" */ return arg; } /* There really is no point running the user main before the application * has finished launching, so this function is called back when we receive * the applicationDidFinishLaunching message. */ void _al_iphone_run_user_main(void) { ALLEGRO_THREAD *thread = al_create_thread(user_main, NULL); al_start_thread(thread); } void _al_iphone_init_path(void) { /* On iphone, data always can only be in the resource bundle. So we set * the initial path to that. As each app is sandboxed, there is not much * else to access anyway. */ NSFileManager *fm = [NSFileManager defaultManager]; NSBundle *mainBundle = [NSBundle mainBundle]; NSString *string = [mainBundle resourcePath]; [fm changeCurrentDirectoryPath:string]; } int main(int argc, char **argv) { global_argc = argc; global_argv = argv; [allegroAppDelegate run:argc:argv]; ASSERT(false); /* can never reach */ return 0; } allegro-5.0.10/src/iphone/iphone_keyboard.c0000644000175000001440000000225411433551022017764 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_events.h" static ALLEGRO_KEYBOARD the_keyboard; static bool iphone_init_keyboard(void) { memset(&the_keyboard, 0, sizeof the_keyboard); _al_event_source_init(&the_keyboard.es); return true; } static void iphone_exit_keyboard(void) { _al_event_source_free(&the_keyboard.es); } static ALLEGRO_KEYBOARD *iphone_get_keyboard(void) { return &the_keyboard; } static bool iphone_set_keyboard_leds(int leds) { (void)leds; return false; } static char const *iphone_keycode_to_name(int keycode) { (void)keycode; return "none"; } static void iphone_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) { memset(ret_state, 0, sizeof *ret_state); } static ALLEGRO_KEYBOARD_DRIVER iphone_keyboard_driver = { AL_ID('I','P','H','O'), "", "", "iphone keyboard", iphone_init_keyboard, iphone_exit_keyboard, iphone_get_keyboard, iphone_set_keyboard_leds, iphone_keycode_to_name, iphone_get_keyboard_state }; ALLEGRO_KEYBOARD_DRIVER *_al_get_iphone_keyboard_driver(void) { return &iphone_keyboard_driver; } allegro-5.0.10/src/events.c0000644000175000001440000003645112125160224014651 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Event queues. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Event queues * * An event queue buffers events generated by event sources that were * registered with the queue. */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_system.h" struct ALLEGRO_EVENT_QUEUE { _AL_VECTOR sources; /* vector of (ALLEGRO_EVENT_SOURCE *) */ _AL_VECTOR events; /* vector of ALLEGRO_EVENT, used as circular array */ unsigned int events_head; /* write end of circular array */ unsigned int events_tail; /* read end of circular array */ _AL_MUTEX mutex; _AL_COND cond; }; /* to prevent concurrent modification of user event reference counts */ static _AL_MUTEX user_event_refcount_mutex = _AL_MUTEX_UNINITED; /* forward declarations */ static void shutdown_events(void); static bool do_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout); static void copy_event(ALLEGRO_EVENT *dest, const ALLEGRO_EVENT *src); static void ref_if_user_event(ALLEGRO_EVENT *event); static void unref_if_user_event(ALLEGRO_EVENT *event); static void discard_events_of_source(ALLEGRO_EVENT_QUEUE *queue, const ALLEGRO_EVENT_SOURCE *source); /* _al_init_events: * Initialise globals for the event system. */ void _al_init_events(void) { _al_mutex_init(&user_event_refcount_mutex); _al_add_exit_func(shutdown_events, "shutdown_events"); } /* shutdown_events: * Clean up after _al_init_events. */ static void shutdown_events(void) { _al_mutex_destroy(&user_event_refcount_mutex); } /* Function: al_create_event_queue */ ALLEGRO_EVENT_QUEUE *al_create_event_queue(void) { ALLEGRO_EVENT_QUEUE *queue = al_malloc(sizeof *queue); ASSERT(queue); if (queue) { _al_vector_init(&queue->sources, sizeof(ALLEGRO_EVENT_SOURCE *)); _al_vector_init(&queue->events, sizeof(ALLEGRO_EVENT)); _al_vector_alloc_back(&queue->events); queue->events_head = 0; queue->events_tail = 0; _AL_MARK_MUTEX_UNINITED(queue->mutex); _al_mutex_init(&queue->mutex); _al_cond_init(&queue->cond); _al_register_destructor(_al_dtor_list, queue, (void (*)(void *)) al_destroy_event_queue); } return queue; } /* Function: al_destroy_event_queue */ void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue) { ASSERT(queue); _al_unregister_destructor(_al_dtor_list, queue); /* Unregister any event sources registered with this queue. */ while (_al_vector_is_nonempty(&queue->sources)) { ALLEGRO_EVENT_SOURCE **slot = _al_vector_ref_back(&queue->sources); al_unregister_event_source(queue, *slot); } ASSERT(_al_vector_is_empty(&queue->sources)); _al_vector_free(&queue->sources); ASSERT(queue->events_head == queue->events_tail); _al_vector_free(&queue->events); _al_cond_destroy(&queue->cond); _al_mutex_destroy(&queue->mutex); al_free(queue); } /* Function: al_register_event_source */ void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT_SOURCE *source) { ALLEGRO_EVENT_SOURCE **slot; ASSERT(queue); ASSERT(source); if (!_al_vector_contains(&queue->sources, &source)) { _al_event_source_on_registration_to_queue(source, queue); _al_mutex_lock(&queue->mutex); slot = _al_vector_alloc_back(&queue->sources); *slot = source; _al_mutex_unlock(&queue->mutex); } } /* Function: al_unregister_event_source */ void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT_SOURCE *source) { bool found; ASSERT(queue); ASSERT(source); /* Remove source from our list. */ _al_mutex_lock(&queue->mutex); found = _al_vector_find_and_delete(&queue->sources, &source); _al_mutex_unlock(&queue->mutex); if (found) { /* Tell the event source that it was unregistered. */ _al_event_source_on_unregistration_from_queue(source, queue); /* Drop all the events in the queue that belonged to the source. */ _al_mutex_lock(&queue->mutex); discard_events_of_source(queue, source); _al_mutex_unlock(&queue->mutex); } } /* Function: al_is_event_queue_empty */ bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue) { ASSERT(queue); return (queue->events_head == queue->events_tail); } /* circ_array_next: * Return the next index in a circular array. */ static unsigned int circ_array_next(const _AL_VECTOR *vector, unsigned int i) { return (i + 1) % _al_vector_size(vector); } /* get_next_event_if_any: [primary thread] * Helper function. It returns a pointer to the next event in the * queue, or NULL. Optionally the event is removed from the queue. * However, the event is _not released_ (which is the caller's * responsibility). The event queue must be locked before entering * this function. */ static ALLEGRO_EVENT *get_next_event_if_any(ALLEGRO_EVENT_QUEUE *queue, bool delete) { ALLEGRO_EVENT *event; if (al_is_event_queue_empty(queue)) { return NULL; } event = _al_vector_ref(&queue->events, queue->events_tail); if (delete) { queue->events_tail = circ_array_next(&queue->events, queue->events_tail); } return event; } /* Function: al_get_next_event */ bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) { ALLEGRO_EVENT *next_event; ASSERT(queue); ASSERT(ret_event); _al_mutex_lock(&queue->mutex); next_event = get_next_event_if_any(queue, true); if (next_event) { copy_event(ret_event, next_event); /* Don't increment reference count on user events. */ } _al_mutex_unlock(&queue->mutex); return (next_event ? true : false); } /* Function: al_peek_next_event */ bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) { ALLEGRO_EVENT *next_event; ASSERT(queue); ASSERT(ret_event); _al_mutex_lock(&queue->mutex); next_event = get_next_event_if_any(queue, false); if (next_event) { copy_event(ret_event, next_event); ref_if_user_event(ret_event); } _al_mutex_unlock(&queue->mutex); return (next_event ? true : false); } /* Function: al_drop_next_event */ bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue) { ALLEGRO_EVENT *next_event; ASSERT(queue); _al_mutex_lock(&queue->mutex); next_event = get_next_event_if_any(queue, true); if (next_event) { unref_if_user_event(next_event); } _al_mutex_unlock(&queue->mutex); return (next_event ? true : false); } /* Function: al_flush_event_queue */ void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue) { unsigned int i; ASSERT(queue); _al_mutex_lock(&queue->mutex); /* Decrement reference counts on all user events. */ i = queue->events_tail; while (i != queue->events_head) { ALLEGRO_EVENT *old_ev = _al_vector_ref(&queue->events, i); unref_if_user_event(old_ev); i = circ_array_next(&queue->events, i); } queue->events_head = queue->events_tail = 0; _al_mutex_unlock(&queue->mutex); } /* [primary thread] */ /* Function: al_wait_for_event */ void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) { ALLEGRO_EVENT *next_event = NULL; ASSERT(queue); _al_mutex_lock(&queue->mutex); { while (al_is_event_queue_empty(queue)) { _al_cond_wait(&queue->cond, &queue->mutex); } if (ret_event) { next_event = get_next_event_if_any(queue, true); copy_event(ret_event, next_event); } } _al_mutex_unlock(&queue->mutex); } /* [primary thread] */ /* Function: al_wait_for_event_timed */ bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event, float secs) { ALLEGRO_TIMEOUT timeout; ASSERT(queue); ASSERT(secs >= 0); if (secs < 0.0) al_init_timeout(&timeout, 0); else al_init_timeout(&timeout, secs); return do_wait_for_event(queue, ret_event, &timeout); } /* Function: al_wait_for_event_until */ bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout) { ASSERT(queue); return do_wait_for_event(queue, ret_event, timeout); } static bool do_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout) { bool timed_out = false; ALLEGRO_EVENT *next_event = NULL; _al_mutex_lock(&queue->mutex); { int result = 0; /* Is the queue is non-empty? If not, block on a condition * variable, which will be signaled when an event is placed into * the queue. */ while (al_is_event_queue_empty(queue) && (result != -1)) { result = _al_cond_timedwait(&queue->cond, &queue->mutex, timeout); } if (result == -1) timed_out = true; else if (ret_event) { next_event = get_next_event_if_any(queue, true); copy_event(ret_event, next_event); } } _al_mutex_unlock(&queue->mutex); if (timed_out) return false; return true; } /* expand_events_array: * Expand the circular array holding events. */ static void expand_events_array(ALLEGRO_EVENT_QUEUE *queue) { /* The underlying vector grows by powers of two. */ const size_t old_size = _al_vector_size(&queue->events); const size_t new_size = old_size * 2; unsigned int i; for (i = old_size; i < new_size; i++) { _al_vector_alloc_back(&queue->events); } /* Move wrapped-around elements at the start of the array to the back. */ if (queue->events_head < queue->events_tail) { for (i = 0; i < queue->events_head; i++) { ALLEGRO_EVENT *old_ev = _al_vector_ref(&queue->events, i); ALLEGRO_EVENT *new_ev = _al_vector_ref(&queue->events, old_size + i); copy_event(new_ev, old_ev); } queue->events_head += old_size; } } /* alloc_event: * * The event source must be _locked_ before calling this function. * * [runs in background threads] */ static ALLEGRO_EVENT *alloc_event(ALLEGRO_EVENT_QUEUE *queue) { ALLEGRO_EVENT *event; unsigned int adv_head; adv_head = circ_array_next(&queue->events, queue->events_head); if (adv_head == queue->events_tail) { expand_events_array(queue); adv_head = circ_array_next(&queue->events, queue->events_head); } event = _al_vector_ref(&queue->events, queue->events_head); queue->events_head = adv_head; return event; } /* copy_event: * Copies the contents of the event SRC to DEST. */ static void copy_event(ALLEGRO_EVENT *dest, const ALLEGRO_EVENT *src) { ASSERT(dest); ASSERT(src); *dest = *src; } /* Increment a user event's reference count, if the event passed is a user * event and requires it. */ static void ref_if_user_event(ALLEGRO_EVENT *event) { if (ALLEGRO_EVENT_TYPE_IS_USER(event->type)) { ALLEGRO_USER_EVENT_DESCRIPTOR *descr = event->user.__internal__descr; if (descr) { _al_mutex_lock(&user_event_refcount_mutex); descr->refcount++; _al_mutex_unlock(&user_event_refcount_mutex); } } } /* Decrement a user event's reference count, if the event passed is a user * event and requires it. */ static void unref_if_user_event(ALLEGRO_EVENT *event) { if (ALLEGRO_EVENT_TYPE_IS_USER(event->type)) { al_unref_user_event(&event->user); } } /* Internal function: _al_event_queue_push_event * Event sources call this function when they have something to add to * the queue. If a queue cannot accept the event, the event's * refcount will not be incremented. * * If no event queues can accept the event, the event should be * returned to the event source's list of recyclable events. */ void _al_event_queue_push_event(ALLEGRO_EVENT_QUEUE *queue, const ALLEGRO_EVENT *orig_event) { ALLEGRO_EVENT *new_event; ASSERT(queue); ASSERT(orig_event); _al_mutex_lock(&queue->mutex); { new_event = alloc_event(queue); copy_event(new_event, orig_event); ref_if_user_event(new_event); /* Wake up threads that are waiting for an event to be placed in * the queue. */ _al_cond_broadcast(&queue->cond); } _al_mutex_unlock(&queue->mutex); } /* contains_event_of_source: * Return true iff the event queue contains an event from the given source. * The queue must be locked. */ static bool contains_event_of_source(const ALLEGRO_EVENT_QUEUE *queue, const ALLEGRO_EVENT_SOURCE *source) { ALLEGRO_EVENT *event; unsigned int i; i = queue->events_tail; while (i != queue->events_head) { event = _al_vector_ref(&queue->events, i); if (event->any.source == source) { return true; } i = circ_array_next(&queue->events, i); } return false; } /* Helper to get smallest fitting power of two. */ static int pot(int x) { int y = 1; while (y < x) y *= 2; return y; } /* discard_events_of_source: * Discard all the events in the queue that belong to the source. * The queue must be locked. */ static void discard_events_of_source(ALLEGRO_EVENT_QUEUE *queue, const ALLEGRO_EVENT_SOURCE *source) { _AL_VECTOR old_events; ALLEGRO_EVENT *old_event; ALLEGRO_EVENT *new_event; size_t old_size; size_t new_size; unsigned int i; if (!contains_event_of_source(queue, source)) { return; } /* Copy elements we want to keep from the old vector to a new one. */ old_events = queue->events; _al_vector_init(&queue->events, sizeof(ALLEGRO_EVENT)); i = queue->events_tail; while (i != queue->events_head) { old_event = _al_vector_ref(&old_events, i); if (old_event->any.source != source) { new_event = _al_vector_alloc_back(&queue->events); copy_event(new_event, old_event); } else { unref_if_user_event(old_event); } i = circ_array_next(&old_events, i); } queue->events_tail = 0; queue->events_head = _al_vector_size(&queue->events); /* The circular array always needs at least one unused element. */ old_size = _al_vector_size(&queue->events); new_size = pot(old_size + 1); for (i = old_size; i < new_size; i++) { _al_vector_alloc_back(&queue->events); } _al_vector_free(&old_events); } /* Function: al_unref_user_event */ void al_unref_user_event(ALLEGRO_USER_EVENT *event) { ALLEGRO_USER_EVENT_DESCRIPTOR *descr; int refcount; ASSERT(event); descr = event->__internal__descr; if (descr) { _al_mutex_lock(&user_event_refcount_mutex); ASSERT(descr->refcount > 0); refcount = --descr->refcount; _al_mutex_unlock(&user_event_refcount_mutex); if (refcount == 0) { (descr->dtor)(event); al_free(descr); } } } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/tls_dll.inc0000644000175000001440000000437612066715441015345 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread local storage. * * See LICENSE.txt for copyright information. */ #include /* Forward declaration to bypass strict warning. */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); static DWORD tls_index; void _al_tls_init_once(void) { /* nothing */ } static thread_local_state *tls_get(void) { thread_local_state *t = TlsGetValue(tls_index); return t; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { thread_local_state *data; (void)hinstDLL; (void)fdwReason; (void)lpvReserved; switch (fdwReason) { case DLL_PROCESS_ATTACH: if ((tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) { return false; } // No break: Initialize the index for first thread. // The attached process creates a new thread. case DLL_THREAD_ATTACH: // Initialize the TLS index for this thread. data = al_malloc(sizeof(*data)); if (data != NULL) { TlsSetValue(tls_index, data); initialize_tls_values(data); } break; // The thread of the attached process terminates. case DLL_THREAD_DETACH: // Release the allocated memory for this thread. data = TlsGetValue(tls_index); if (data != NULL) al_free(data); break; // DLL unload due to process termination or FreeLibrary. case DLL_PROCESS_DETACH: // Release the allocated memory for this thread. data = TlsGetValue(tls_index); if (data != NULL) al_free(data); // Release the TLS index. TlsFree(tls_index); break; default: break; } return true; } /* vim: set ft=c sts=3 sw=3: */ allegro-5.0.10/src/joynu.c0000644000175000001440000001356212125160224014507 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * New joystick API. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Joystick routines */ #define ALLEGRO_NO_COMPATIBILITY #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_exitfunc.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_system.h" /* the active joystick driver */ static ALLEGRO_JOYSTICK_DRIVER *new_joystick_driver = NULL; static ALLEGRO_EVENT_SOURCE es; /* Function: al_install_joystick */ bool al_install_joystick(void) { ALLEGRO_SYSTEM *sysdrv; ALLEGRO_JOYSTICK_DRIVER *joydrv; if (new_joystick_driver) return true; sysdrv = al_get_system_driver(); ASSERT(sysdrv); /* Currently every platform only has at most one joystick driver. */ if (sysdrv->vt->get_joystick_driver) { joydrv = sysdrv->vt->get_joystick_driver(); /* Avoid race condition in case the joystick driver generates an * event right after ->init_joystick. */ _al_event_source_init(&es); if (joydrv && joydrv->init_joystick()) { new_joystick_driver = joydrv; _al_add_exit_func(al_uninstall_joystick, "al_uninstall_joystick"); return true; } _al_event_source_free(&es); } return false; } /* Function: al_uninstall_joystick */ void al_uninstall_joystick(void) { if (new_joystick_driver) { /* perform driver clean up */ new_joystick_driver->exit_joystick(); _al_event_source_free(&es); new_joystick_driver = NULL; } } /* Function: al_is_joystick_installed */ bool al_is_joystick_installed(void) { return (new_joystick_driver) ? true : false; } /* Function: al_reconfigure_joysticks */ bool al_reconfigure_joysticks(void) { if (!new_joystick_driver) return false; /* XXX only until Windows and Mac joystick drivers are updated */ if (!new_joystick_driver->reconfigure_joysticks) { new_joystick_driver->num_joysticks(); return true; } return new_joystick_driver->reconfigure_joysticks(); } /* Function: al_get_joystick_event_source */ ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void) { if (!new_joystick_driver) return NULL; return &es; } void _al_generate_joystick_event(ALLEGRO_EVENT *event) { ASSERT(new_joystick_driver); _al_event_source_lock(&es); if (_al_event_source_needs_to_generate_event(&es)) { _al_event_source_emit_event(&es, event); } _al_event_source_unlock(&es); } /* Function: al_get_num_joysticks */ int al_get_num_joysticks(void) { if (new_joystick_driver) return new_joystick_driver->num_joysticks(); return 0; } /* Function: al_get_joystick */ ALLEGRO_JOYSTICK * al_get_joystick(int num) { ASSERT(new_joystick_driver); ASSERT(num >= 0); return new_joystick_driver->get_joystick(num); } /* Function: al_release_joystick */ void al_release_joystick(ALLEGRO_JOYSTICK *joy) { ASSERT(new_joystick_driver); ASSERT(joy); new_joystick_driver->release_joystick(joy); } /* Function: al_get_joystick_active */ bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy) { ASSERT(joy); return new_joystick_driver->get_active(joy); } /* Function: al_get_joystick_name */ const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy) { ASSERT(joy); return new_joystick_driver->get_name(joy); } /* Function: al_get_joystick_num_sticks */ int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy) { ASSERT(joy); return joy->info.num_sticks; } /* Function: al_get_joystick_stick_flags */ int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick) { ASSERT(joy); ASSERT(stick >= 0); if (stick < joy->info.num_sticks) return joy->info.stick[stick].flags; return 0; } /* Function: al_get_joystick_stick_name */ const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick) { ASSERT(joy); ASSERT(stick >= 0); if (stick < joy->info.num_sticks) return joy->info.stick[stick].name; return NULL; } /* Function: al_get_joystick_num_axes */ int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick) { ASSERT(joy); if (stick < joy->info.num_sticks) return joy->info.stick[stick].num_axes; return 0; } /* Function: al_get_joystick_axis_name */ const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis) { ASSERT(joy); ASSERT(stick >= 0); ASSERT(axis >= 0); if (stick < joy->info.num_sticks) if (axis < joy->info.stick[stick].num_axes) return joy->info.stick[stick].axis[axis].name; return NULL; } /* Function: al_get_joystick_num_buttons */ int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy) { ASSERT(joy); return joy->info.num_buttons; } /* Function: al_get_joystick_button_name */ const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button) { ASSERT(joy); ASSERT(button >= 0); if (button < joy->info.num_buttons) return joy->info.button[button].name; return NULL; } /* Function: al_get_joystick_state */ void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) { ASSERT(new_joystick_driver); ASSERT(joy); ASSERT(ret_state); new_joystick_driver->get_joystick_state(joy, ret_state); } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/evtsrc.c0000644000175000001440000001624711771523242014665 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Event sources. * * By Peter Wang. * * See readme.txt for copyright information. */ /* Title: Event sources */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_system.h" ALLEGRO_STATIC_ASSERT(evtsrc, sizeof(ALLEGRO_EVENT_SOURCE_REAL) <= sizeof(ALLEGRO_EVENT_SOURCE)); /* Internal function: _al_event_source_init * Initialise an event source structure. */ void _al_event_source_init(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; memset(es, 0, sizeof(*es)); _AL_MARK_MUTEX_UNINITED(this->mutex); _al_mutex_init(&this->mutex); _al_vector_init(&this->queues, sizeof(ALLEGRO_EVENT_QUEUE *)); this->data = 0; } /* Internal function: _al_event_source_free * Free the resources using by an event source structure. It * automatically unregisters the event source from all the event * queues it is currently registered with. */ void _al_event_source_free(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* Unregister from all queues. */ while (!_al_vector_is_empty(&this->queues)) { ALLEGRO_EVENT_QUEUE **slot = _al_vector_ref_back(&this->queues); al_unregister_event_source(*slot, es); } _al_vector_free(&this->queues); _al_mutex_destroy(&this->mutex); } /* Internal function: _al_event_source_lock * Lock the event source. See below for when you should call this function. */ void _al_event_source_lock(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; _al_mutex_lock(&this->mutex); } /* Internal function: _al_event_source_unlock * Unlock the event source. */ void _al_event_source_unlock(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; _al_mutex_unlock(&this->mutex); } /* Internal function: _al_event_source_on_registration_to_queue * This function is called by al_register_event_source() when an * event source is registered to an event queue. This gives the * event source a chance to remember which queues it is registered * to. */ void _al_event_source_on_registration_to_queue(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT_QUEUE *queue) { _al_event_source_lock(es); { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* Add the queue to the source's list. */ ALLEGRO_EVENT_QUEUE **slot = _al_vector_alloc_back(&this->queues); *slot = queue; } _al_event_source_unlock(es); } /* Internal function: _al_event_source_on_unregistration_from_queue * This function is called by al_unregister_event_source() when an * event source is unregistered from a queue. */ void _al_event_source_on_unregistration_from_queue(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT_QUEUE *queue) { _al_event_source_lock(es); { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; _al_vector_find_and_delete(&this->queues, &queue); } _al_event_source_unlock(es); } /* Internal function: _al_event_source_needs_to_generate_event * This function is called by modules that implement event sources * when some interesting thing happens. They call this to check if * they should bother generating an event of the given type, i.e. if * the given event source is actually registered with one or more * event queues. This is an optimisation to avoid allocating and * filling in unwanted event structures. * * The event source must be _locked_ before calling this function. * * [runs in background threads] */ bool _al_event_source_needs_to_generate_event(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; return !_al_vector_is_empty(&this->queues); } /* Internal function: _al_event_source_emit_event * After an event structure has been filled in, it is time for the * event source to tell the event queues it knows of about the new * event. Afterwards, the caller of this function should not touch * the event any more. * * The event source must be _locked_ before calling this function. * * [runs in background threads] */ void _al_event_source_emit_event(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT *event) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; event->any.source = es; /* Push the event to all the queues that this event source is * registered to. */ { size_t num_queues = _al_vector_size(&this->queues); unsigned int i; ALLEGRO_EVENT_QUEUE **slot; for (i = 0; i < num_queues; i++) { slot = _al_vector_ref(&this->queues, i); _al_event_queue_push_event(*slot, event); } } } /* Function: al_init_user_event_source */ void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src) { ASSERT(src); _al_event_source_init(src); } /* Function: al_destroy_user_event_source */ void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src) { if (src) { _al_event_source_free(src); } } /* Function: al_emit_user_event */ bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) { size_t num_queues; bool rc; ASSERT(src); ASSERT(event); ASSERT(ALLEGRO_EVENT_TYPE_IS_USER(event->any.type)); if (dtor) { ALLEGRO_USER_EVENT_DESCRIPTOR *descr = al_malloc(sizeof(*descr)); descr->refcount = 0; descr->dtor = dtor; event->user.__internal__descr = descr; } else { event->user.__internal__descr = NULL; } _al_event_source_lock(src); { ALLEGRO_EVENT_SOURCE_REAL *rsrc = (ALLEGRO_EVENT_SOURCE_REAL *)src; num_queues = _al_vector_size(&rsrc->queues); if (num_queues > 0) { event->user.timestamp = al_get_time(); _al_event_source_emit_event(src, event); rc = true; } else { rc = false; } } _al_event_source_unlock(src); if (dtor && !rc) { dtor(&event->user); al_free(event->user.__internal__descr); } return rc; } /* Function: al_set_event_source_data */ void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data) { ALLEGRO_EVENT_SOURCE_REAL *const rsource = (ALLEGRO_EVENT_SOURCE_REAL *)source; rsource->data = data; } /* Function: al_get_event_source_data */ intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source) { const ALLEGRO_EVENT_SOURCE_REAL *const rsource = (ALLEGRO_EVENT_SOURCE_REAL *)source; return rsource->data; } /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/transformations.c0000644000175000001440000001641112132126261016571 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Transformations. * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_transform.h" #include /* ALLEGRO_DEBUG_CHANNEL("transformations") */ /* Function: al_copy_transform */ void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src) { ASSERT(src); ASSERT(dest); memcpy(dest, src, sizeof(ALLEGRO_TRANSFORM)); } /* Function: al_use_transform */ void al_use_transform(const ALLEGRO_TRANSFORM *trans) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_DISPLAY *display; if (!target) return; /* Changes to a back buffer should affect the front buffer, and vice versa. * Currently we rely on the fact that in the OpenGL drivers the back buffer * and front buffer bitmaps are exactly the same, and the DirectX driver * doesn't support front buffer bitmaps. */ if (trans != &target->transform) al_copy_transform(&target->transform, trans); /* * When the drawing is held, we apply the transformations in software, * so the hardware transformation has to be kept at identity. */ if (!al_is_bitmap_drawing_held()) { display = target->display; if (display) { display->vt->update_transformation(display, target); } } } /* Function: al_get_current_transform */ const ALLEGRO_TRANSFORM *al_get_current_transform(void) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); if (!target) return NULL; return &target->transform; } /* Function: al_identity_transform */ void al_identity_transform(ALLEGRO_TRANSFORM *trans) { ASSERT(trans); trans->m[0][0] = 1; trans->m[0][1] = 0; trans->m[0][2] = 0; trans->m[0][3] = 0; trans->m[1][0] = 0; trans->m[1][1] = 1; trans->m[1][2] = 0; trans->m[1][3] = 0; trans->m[2][0] = 0; trans->m[2][1] = 0; trans->m[2][2] = 1; trans->m[2][3] = 0; trans->m[3][0] = 0; trans->m[3][1] = 0; trans->m[3][2] = 0; trans->m[3][3] = 1; } /* Function: al_build_transform */ void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y, float sx, float sy, float theta) { float c, s; ASSERT(trans); c = cosf(theta); s = sinf(theta); trans->m[0][0] = sx * c; trans->m[0][1] = sy * s; trans->m[0][2] = 0; trans->m[0][3] = 0; trans->m[1][0] = -sx * s; trans->m[1][1] = sy * c; trans->m[1][2] = 0; trans->m[1][3] = 0; trans->m[2][0] = 0; trans->m[2][1] = 0; trans->m[2][2] = 1; trans->m[2][3] = 0; trans->m[3][0] = x; trans->m[3][1] = y; trans->m[3][2] = 0; trans->m[3][3] = 1; } /* Function: al_invert_transform */ void al_invert_transform(ALLEGRO_TRANSFORM *trans) { float det, t; ASSERT(trans); det = trans->m[0][0] * trans->m[1][1] - trans->m[1][0] * trans->m[0][1]; t = trans->m[3][0]; trans->m[3][0] = ( trans->m[1][0] * trans->m[3][1] - t * trans->m[1][1]) / det; trans->m[3][1] = (t * trans->m[0][1] - trans->m[0][0] * trans->m[3][1]) / det; t = trans->m[0][0]; trans->m[0][0] = trans->m[1][1] / det; trans->m[1][1] = t / det; trans->m[0][1] = - trans->m[0][1] / det; trans->m[1][0] = - trans->m[1][0] / det; } /* Function: al_check_inverse */ int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol) { float det, norm, c0, c1, c3; ASSERT(trans); det = fabsf(trans->m[0][0] * trans->m[1][1] - trans->m[1][0] * trans->m[0][1]); /* We'll use the 1-norm, as it is the easiest to compute */ c0 = fabsf(trans->m[0][0]) + fabsf(trans->m[0][1]); c1 = fabsf(trans->m[1][0]) + fabsf(trans->m[1][1]); c3 = fabsf(trans->m[3][0]) + fabsf(trans->m[3][1]) + 1; norm = _ALLEGRO_MAX(_ALLEGRO_MAX(1, c0), _ALLEGRO_MAX(c1, c3)); return det > tol * norm; } /* Function: al_translate_transform */ void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y) { ASSERT(trans); trans->m[3][0] += x; trans->m[3][1] += y; } /* Function: al_rotate_transform */ void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta) { float c, s; float t; ASSERT(trans); c = cosf(theta); s = sinf(theta); t = trans->m[0][0]; trans->m[0][0] = t * c - trans->m[0][1] * s; trans->m[0][1] = t * s + trans->m[0][1] * c; t = trans->m[1][0]; trans->m[1][0] = t * c - trans->m[1][1] * s; trans->m[1][1] = t * s + trans->m[1][1] * c; t = trans->m[3][0]; trans->m[3][0] = t * c - trans->m[3][1] * s; trans->m[3][1] = t * s + trans->m[3][1] * c; } /* Function: al_scale_transform */ void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy) { ASSERT(trans); trans->m[0][0] *= sx; trans->m[0][1] *= sy; trans->m[1][0] *= sx; trans->m[1][1] *= sy; trans->m[3][0] *= sx; trans->m[3][1] *= sy; } /* Function: al_transform_coordinates */ void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y) { float t; ASSERT(trans); ASSERT(x); ASSERT(y); t = *x; *x = t * trans->m[0][0] + *y * trans->m[1][0] + trans->m[3][0]; *y = t * trans->m[0][1] + *y * trans->m[1][1] + trans->m[3][1]; } /* Function: al_compose_transform */ void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other) { float t; ASSERT(other); ASSERT(trans); /* First column */ t = trans->m[0][0]; trans->m[0][0] = other->m[0][0] * t + other->m[1][0] * trans->m[0][1]; trans->m[0][1] = other->m[0][1] * t + other->m[1][1] * trans->m[0][1]; /* Second column */ t = trans->m[1][0]; trans->m[1][0] = other->m[0][0] * t + other->m[1][0] * trans->m[1][1]; trans->m[1][1] = other->m[0][1] * t + other->m[1][1] * trans->m[1][1]; /* Fourth column */ t = trans->m[3][0]; trans->m[3][0] = other->m[0][0] * t + other->m[1][0] * trans->m[3][1] + other->m[3][0]; trans->m[3][1] = other->m[0][1] * t + other->m[1][1] * trans->m[3][1] + other->m[3][1]; } bool _al_transform_is_translation(const ALLEGRO_TRANSFORM* trans, float *dx, float *dy) { if (trans->m[0][0] == 1 && trans->m[1][0] == 0 && trans->m[2][0] == 0 && trans->m[0][1] == 0 && trans->m[1][1] == 1 && trans->m[2][1] == 0 && trans->m[0][2] == 0 && trans->m[1][2] == 0 && trans->m[2][2] == 1 && trans->m[3][2] == 0 && trans->m[0][3] == 0 && trans->m[1][3] == 0 && trans->m[2][3] == 0 && trans->m[3][3] == 1) { *dx = trans->m[3][0]; *dy = trans->m[3][1]; return true; } return false; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/file_slice.c0000644000175000001440000001201011721431531015427 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File Slices - treat a subset of a random access file * as its own file * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" typedef struct SLICE_DATA SLICE_DATA; enum { SLICE_READ = 1, SLICE_WRITE = 2, SLICE_EXPANDABLE = 4 }; struct SLICE_DATA { ALLEGRO_FILE *fp; /* parent file handle */ size_t anchor; /* beginning position relative to parent */ size_t pos; /* position relative to anchor */ size_t size; /* size of slice relative to anchor */ int mode; }; static void slice_fclose(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); /* seek to end of slice */ al_fseek(slice->fp, slice->anchor + slice->size, ALLEGRO_SEEK_SET); al_free(slice); } static size_t slice_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { SLICE_DATA *slice = al_get_file_userdata(f); if (!(slice->mode & SLICE_READ)) { /* no read permissions */ return 0; } if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { /* don't read past the buffer size if not expandable */ size = slice->size - slice->pos; } if (!size) { return 0; } else { /* unbuffered, read directly from parent file */ size_t b = al_fread(slice->fp, ptr, size); slice->pos += b; if (slice->pos > slice->size) slice->size = slice->pos; return b; } } static size_t slice_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) { SLICE_DATA *slice = al_get_file_userdata(f); if (!(slice->mode & SLICE_WRITE)) { /* no write permissions */ return 0; } if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { /* don't write past the buffer size if not expandable */ size = slice->size - slice->pos; } if (!size) { return 0; } else { /* unbuffered, write directly to parent file */ size_t b = al_fwrite(slice->fp, ptr, size); slice->pos += b; if (slice->pos > slice->size) slice->size = slice->pos; return b; } } static bool slice_fflush(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return al_fflush(slice->fp); } static int64_t slice_ftell(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->pos; } static bool slice_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) { SLICE_DATA *slice = al_get_file_userdata(f); if (whence == ALLEGRO_SEEK_SET) { offset = slice->anchor + offset; } else if (whence == ALLEGRO_SEEK_CUR) { offset = slice->anchor + slice->pos + offset; } else if (whence == ALLEGRO_SEEK_END) { offset = slice->anchor + slice->size + offset; } else { return false; } if ((size_t) offset < slice->anchor) { offset = slice->anchor; } else if ((size_t) offset > slice->anchor + slice->size) { offset = slice->anchor + slice->size; } if (al_fseek(slice->fp, offset, ALLEGRO_SEEK_SET)) { slice->pos = offset - slice->anchor; return true; } return false; } static bool slice_feof(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->pos >= slice->size; } static bool slice_ferror(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return al_ferror(slice->fp); } static void slice_fclearerr(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); al_fclearerr(slice->fp); } static off_t slice_fsize(ALLEGRO_FILE *f) { SLICE_DATA *slice = al_get_file_userdata(f); return slice->size; } static const ALLEGRO_FILE_INTERFACE fi = { NULL, slice_fclose, slice_fread, slice_fwrite, slice_fflush, slice_ftell, slice_fseek, slice_feof, slice_ferror, slice_fclearerr, NULL, slice_fsize }; /* Function: al_fopen_slice */ ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode) { SLICE_DATA *userdata = al_malloc(sizeof(*userdata)); if (!userdata) { return NULL; } memset(userdata, 0, sizeof(*userdata)); if (strstr(mode, "r") || strstr(mode, "R")) { userdata->mode |= SLICE_READ; } if (strstr(mode, "w") || strstr(mode, "W")) { userdata->mode |= SLICE_WRITE; } if (strstr(mode, "e") || strstr(mode, "E")) { userdata->mode |= SLICE_EXPANDABLE; } userdata->fp = fp; userdata->anchor = al_ftell(fp); userdata->size = initial_size; return al_create_file_handle(&fi, userdata); } allegro-5.0.10/src/bitmap_lock.c0000644000175000001440000000757612124553574015654 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Bitmap locking routines. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_pixels.h" /* Function: al_lock_bitmap_region */ ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap, int x, int y, int width, int height, int format, int flags) { ASSERT(x >= 0); ASSERT(y >= 0); ASSERT(width >= 0); ASSERT(height >= 0); /* For sub-bitmaps */ if (bitmap->parent) { x += bitmap->xofs; y += bitmap->yofs; bitmap = bitmap->parent; } if (bitmap->locked) return NULL; ASSERT(x+width <= bitmap->w); ASSERT(y+height <= bitmap->h); bitmap->lock_x = x; bitmap->lock_y = y; bitmap->lock_w = width; bitmap->lock_h = height; bitmap->lock_flags = flags; if (bitmap->flags & ALLEGRO_MEMORY_BITMAP) { int f = _al_get_real_pixel_format(al_get_current_display(), format); if (f < 0) { return NULL; } ASSERT(bitmap->memory); if (format == ALLEGRO_PIXEL_FORMAT_ANY || bitmap->format == format || f == bitmap->format) { bitmap->locked_region.data = bitmap->memory + bitmap->pitch * y + x * al_get_pixel_size(bitmap->format); bitmap->locked_region.format = bitmap->format; bitmap->locked_region.pitch = bitmap->pitch; bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap->format); } else { bitmap->locked_region.pitch = al_get_pixel_size(f) * width; bitmap->locked_region.data = al_malloc(bitmap->locked_region.pitch*height); bitmap->locked_region.format = f; bitmap->locked_region.pixel_size = al_get_pixel_size(f); if (!(bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY)) { _al_convert_bitmap_data( bitmap->memory, bitmap->format, bitmap->pitch, bitmap->locked_region.data, f, bitmap->locked_region.pitch, x, y, 0, 0, width, height); } } } else { if (!bitmap->vt->lock_region(bitmap, x, y, width, height, format, flags)) { return NULL; } } bitmap->locked = true; return &bitmap->locked_region; } /* Function: al_lock_bitmap */ ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap, int format, int flags) { return al_lock_bitmap_region(bitmap, 0, 0, bitmap->w, bitmap->h, format, flags); } /* Function: al_unlock_bitmap */ void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap) { /* For sub-bitmaps */ if (bitmap->parent) { bitmap = bitmap->parent; } if (!(bitmap->flags & ALLEGRO_MEMORY_BITMAP)) { bitmap->vt->unlock_region(bitmap); } else { if (bitmap->locked_region.format != 0 && bitmap->locked_region.format != bitmap->format) { if (!(bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) { _al_convert_bitmap_data( bitmap->locked_region.data, bitmap->locked_region.format, bitmap->locked_region.pitch, bitmap->memory, bitmap->format, bitmap->pitch, 0, 0, bitmap->lock_x, bitmap->lock_y, bitmap->lock_w, bitmap->lock_h); } al_free(bitmap->locked_region.data); } } bitmap->locked = false; } /* Function: al_is_bitmap_locked */ bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap) { return bitmap->locked; } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/bitmap_draw.c0000644000175000001440000001566712125155766015663 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Bitmap drawing routines. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_memblit.h" static ALLEGRO_COLOR solid_white = {1, 1, 1, 1}; static void _bitmap_drawer(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, int flags) { ALLEGRO_BITMAP *dest = al_get_target_bitmap(); ALLEGRO_DISPLAY *display = dest->display; ASSERT(bitmap->parent == NULL); ASSERT(!(flags & (ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL))); ASSERT(bitmap != dest && bitmap != dest->parent); /* If destination is memory, do a memory blit */ if (dest->flags & ALLEGRO_MEMORY_BITMAP) { _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); } else { /* if source is memory or incompatible */ if ((bitmap->flags & ALLEGRO_MEMORY_BITMAP) || (!al_is_compatible_bitmap(bitmap))) { if (display && display->vt->draw_memory_bitmap_region) { display->vt->draw_memory_bitmap_region(display, bitmap, sx, sy, sw, sh, flags); } else { _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); } } else { /* Compatible display bitmap, use full acceleration */ bitmap->vt->draw_bitmap_region(bitmap, tint, sx, sy, sw, sh, flags); } } } static void _draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float angle, float xscale, float yscale, float sx, float sy, float sw, float sh, float dx, float dy, int flags) { ALLEGRO_TRANSFORM backup; ALLEGRO_TRANSFORM t; ALLEGRO_BITMAP *parent = bitmap; float const orig_sw = sw; float const orig_sh = sh; ASSERT(bitmap); al_copy_transform(&backup, al_get_current_transform()); al_identity_transform(&t); if (bitmap->parent) { parent = bitmap->parent; sx += bitmap->xofs; sy += bitmap->yofs; } if (sx < 0) { sw += sx; al_translate_transform(&t, -sx, 0); sx = 0; } if (sy < 0) { sh += sy; al_translate_transform(&t, 0, -sy); sy = 0; } if (sx + sw > parent->w) sw = parent->w - sx; if (sy + sh > parent->h) sh = parent->h - sy; if (flags & ALLEGRO_FLIP_HORIZONTAL) { al_scale_transform(&t, -1, 1); al_translate_transform(&t, orig_sw, 0); flags &= ~ALLEGRO_FLIP_HORIZONTAL; } if (flags & ALLEGRO_FLIP_VERTICAL) { al_scale_transform(&t, 1, -1); al_translate_transform(&t, 0, orig_sh); flags &= ~ALLEGRO_FLIP_VERTICAL; } al_translate_transform(&t, -cx, -cy); al_scale_transform(&t, xscale, yscale); al_rotate_transform(&t, angle); al_translate_transform(&t, dx, dy); al_compose_transform(&t, &backup); al_use_transform(&t); _bitmap_drawer(parent, tint, sx, sy, sw, sh, flags); al_use_transform(&backup); } /* Function: al_draw_tinted_bitmap_region */ void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags) { _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, 0, 0, 0, 1, 1, sx, sy, sw, sh, dx, dy, flags); } /* Function: al_draw_tinted_bitmap */ void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float dx, float dy, int flags) { ASSERT(bitmap); al_draw_tinted_bitmap_region(bitmap, tint, 0, 0, bitmap->w, bitmap->h, dx, dy, flags); } /* Function: al_draw_bitmap */ void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags) { al_draw_tinted_bitmap(bitmap, solid_white, dx, dy, flags); } /* Function: al_draw_bitmap_region */ void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, int flags) { al_draw_tinted_bitmap_region(bitmap, solid_white, sx, sy, sw, sh, dx, dy, flags); } /* Function: al_draw_tinted_scaled_bitmap */ void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags) { _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, 0, 0, 0, dw / sw, dh / sh, sx, sy, sw, sh, dx, dy, flags); } /* Function: al_draw_scaled_bitmap */ void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags) { al_draw_tinted_scaled_bitmap(bitmap, solid_white, sx, sy, sw, sh, dx, dy, dw, dh, flags); } /* Function: al_draw_tinted_rotated_bitmap * * angle is specified in radians and moves clockwise * on the screen. */ void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float angle, int flags) { al_draw_tinted_scaled_rotated_bitmap(bitmap, tint, cx, cy, dx, dy, 1, 1, angle, flags); } /* Function: al_draw_rotated_bitmap */ void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float angle, int flags) { al_draw_tinted_rotated_bitmap(bitmap, solid_white, cx, cy, dx, dy, angle, flags); } /* Function: al_draw_tinted_scaled_rotated_bitmap */ void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags) { _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, cx, cy, angle, xscale, yscale, 0, 0, bitmap->w, bitmap->h, dx, dy, flags); } /* Function: al_draw_tinted_scaled_rotated_bitmap_region */ void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags) { _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, cx, cy, angle, xscale, yscale, sx, sy, sw, sh, dx, dy, flags); } /* Function: al_draw_scaled_rotated_bitmap */ void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags) { al_draw_tinted_scaled_rotated_bitmap(bitmap, solid_white, cx, cy, dx, dy, xscale, yscale, angle, flags); } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/src/blenders.c0000644000175000001440000000260212146021714015135 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory bitmap blending routines * * by Trent Gamblin. * */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_display.h" #include void _al_blend_memory(ALLEGRO_COLOR *scol, ALLEGRO_BITMAP *dest, int dx, int dy, ALLEGRO_COLOR *result) { ALLEGRO_COLOR dcol; int op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend; dcol = al_get_pixel(dest, dx, dy); al_get_separate_blender(&op, &src_blend, &dest_blend, &alpha_op, &alpha_src_blend, &alpha_dest_blend); _al_blend_inline(scol, &dcol, op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend, result); (void) _al_blend_alpha_inline; // silence compiler } allegro-5.0.10/src/threads.c0000644000175000001440000002230111465364352015002 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Public threads interface. * * By Peter Wang. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_system.h" typedef enum THREAD_STATE { THREAD_STATE_CREATED, /* -> starting or -> joining */ THREAD_STATE_STARTING, /* -> started */ THREAD_STATE_STARTED, /* -> joining */ THREAD_STATE_JOINING, /* -> joined */ THREAD_STATE_JOINED, /* -> destroyed */ THREAD_STATE_DESTROYED, THREAD_STATE_DETACHED } THREAD_STATE; struct ALLEGRO_THREAD { _AL_THREAD thread; _AL_MUTEX mutex; _AL_COND cond; THREAD_STATE thread_state; void *proc; void *arg; void *retval; }; struct ALLEGRO_MUTEX { _AL_MUTEX mutex; }; struct ALLEGRO_COND { _AL_COND cond; }; static void thread_func_trampoline(_AL_THREAD *inner, void *_outer) { ALLEGRO_THREAD *outer = (ALLEGRO_THREAD *) _outer; ALLEGRO_SYSTEM *system = al_get_system_driver(); (void)inner; if (system && system->vt && system->vt->thread_init) { system->vt->thread_init(outer); } /* Wait to start the actual user thread function. The thread could also be * destroyed before ever running the user function. */ _al_mutex_lock(&outer->mutex); while (outer->thread_state == THREAD_STATE_CREATED) { _al_cond_wait(&outer->cond, &outer->mutex); } _al_mutex_unlock(&outer->mutex); if (outer->thread_state == THREAD_STATE_STARTING) { outer->thread_state = THREAD_STATE_STARTED; outer->retval = ((void *(*)(ALLEGRO_THREAD *, void *))outer->proc)(outer, outer->arg); } if (system && system->vt && system->vt->thread_exit) { system->vt->thread_exit(outer); } } static void detached_thread_func_trampoline(_AL_THREAD *inner, void *_outer) { ALLEGRO_THREAD *outer = (ALLEGRO_THREAD *) _outer; (void)inner; ((void *(*)(void *))outer->proc)(outer->arg); al_free(outer); } static ALLEGRO_THREAD *create_thread(void) { ALLEGRO_THREAD *outer; outer = al_malloc(sizeof(*outer)); if (!outer) { return NULL; } _AL_MARK_MUTEX_UNINITED(outer->mutex); /* required */ outer->retval = NULL; return outer; } /* Function: al_create_thread */ ALLEGRO_THREAD *al_create_thread( void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg) { ALLEGRO_THREAD *outer = create_thread(); outer->thread_state = THREAD_STATE_CREATED; _al_mutex_init(&outer->mutex); _al_cond_init(&outer->cond); outer->arg = arg; outer->proc = proc; _al_thread_create(&outer->thread, thread_func_trampoline, outer); /* XXX _al_thread_create should return an error code */ return outer; } /* Function: al_run_detached_thread */ void al_run_detached_thread(void *(*proc)(void *arg), void *arg) { ALLEGRO_THREAD *outer = create_thread(); outer->thread_state = THREAD_STATE_DETACHED; outer->arg = arg; outer->proc = proc; _al_thread_create(&outer->thread, detached_thread_func_trampoline, outer); _al_thread_detach(&outer->thread); } /* Function: al_start_thread */ void al_start_thread(ALLEGRO_THREAD *thread) { ASSERT(thread); switch (thread->thread_state) { case THREAD_STATE_CREATED: _al_mutex_lock(&thread->mutex); thread->thread_state = THREAD_STATE_STARTING; _al_cond_broadcast(&thread->cond); _al_mutex_unlock(&thread->mutex); break; case THREAD_STATE_STARTING: break; case THREAD_STATE_STARTED: break; /* invalid cases */ case THREAD_STATE_JOINING: ASSERT(thread->thread_state != THREAD_STATE_JOINING); break; case THREAD_STATE_JOINED: ASSERT(thread->thread_state != THREAD_STATE_JOINED); break; case THREAD_STATE_DESTROYED: ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); break; case THREAD_STATE_DETACHED: ASSERT(thread->thread_state != THREAD_STATE_DETACHED); break; } } /* Function: al_join_thread */ void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value) { ASSERT(thread); /* If al_join_thread() is called soon after al_start_thread(), the thread * function may not yet have noticed the STARTING state and executed the * user's thread function. Hence we must wait until the thread enters the * STARTED state. */ while (thread->thread_state == THREAD_STATE_STARTING) { al_rest(0.001); } switch (thread->thread_state) { case THREAD_STATE_CREATED: /* fall through */ case THREAD_STATE_STARTED: _al_mutex_lock(&thread->mutex); thread->thread_state = THREAD_STATE_JOINING; _al_cond_broadcast(&thread->cond); _al_mutex_unlock(&thread->mutex); _al_mutex_destroy(&thread->mutex); _al_thread_join(&thread->thread); thread->thread_state = THREAD_STATE_JOINED; break; case THREAD_STATE_STARTING: ASSERT(thread->thread_state != THREAD_STATE_STARTING); break; case THREAD_STATE_JOINING: ASSERT(thread->thread_state != THREAD_STATE_JOINING); break; case THREAD_STATE_JOINED: ASSERT(thread->thread_state != THREAD_STATE_JOINED); break; case THREAD_STATE_DESTROYED: ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); break; case THREAD_STATE_DETACHED: ASSERT(thread->thread_state != THREAD_STATE_DETACHED); break; } if (ret_value) { *ret_value = thread->retval; } } /* Function: al_set_thread_should_stop */ void al_set_thread_should_stop(ALLEGRO_THREAD *thread) { ASSERT(thread); _al_thread_set_should_stop(&thread->thread); } /* Function: al_get_thread_should_stop */ bool al_get_thread_should_stop(ALLEGRO_THREAD *thread) { ASSERT(thread); return _al_get_thread_should_stop(&thread->thread); } /* Function: al_destroy_thread */ void al_destroy_thread(ALLEGRO_THREAD *thread) { if (!thread) { return; } /* Join if required. */ switch (thread->thread_state) { case THREAD_STATE_CREATED: /* fall through */ case THREAD_STATE_STARTING: /* fall through */ case THREAD_STATE_STARTED: al_join_thread(thread, NULL); break; case THREAD_STATE_JOINING: ASSERT(thread->thread_state != THREAD_STATE_JOINING); break; case THREAD_STATE_JOINED: break; case THREAD_STATE_DESTROYED: ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); break; case THREAD_STATE_DETACHED: ASSERT(thread->thread_state != THREAD_STATE_DETACHED); break; } /* May help debugging. */ thread->thread_state = THREAD_STATE_DESTROYED; al_free(thread); } /* Function: al_create_mutex */ ALLEGRO_MUTEX *al_create_mutex(void) { ALLEGRO_MUTEX *mutex = al_malloc(sizeof(*mutex)); if (mutex) { _AL_MARK_MUTEX_UNINITED(mutex->mutex); _al_mutex_init(&mutex->mutex); } return mutex; } /* Function: al_create_mutex_recursive */ ALLEGRO_MUTEX *al_create_mutex_recursive(void) { ALLEGRO_MUTEX *mutex = al_malloc(sizeof(*mutex)); if (mutex) { _AL_MARK_MUTEX_UNINITED(mutex->mutex); _al_mutex_init_recursive(&mutex->mutex); } return mutex; } /* Function: al_lock_mutex */ void al_lock_mutex(ALLEGRO_MUTEX *mutex) { ASSERT(mutex); _al_mutex_lock(&mutex->mutex); } /* Function: al_unlock_mutex */ void al_unlock_mutex(ALLEGRO_MUTEX *mutex) { ASSERT(mutex); _al_mutex_unlock(&mutex->mutex); } /* Function: al_destroy_mutex */ void al_destroy_mutex(ALLEGRO_MUTEX *mutex) { if (mutex) { _al_mutex_destroy(&mutex->mutex); al_free(mutex); } } /* Function: al_create_cond */ ALLEGRO_COND *al_create_cond(void) { ALLEGRO_COND *cond = al_malloc(sizeof(*cond)); if (cond) { _al_cond_init(&cond->cond); } return cond; } /* Function: al_destroy_cond */ void al_destroy_cond(ALLEGRO_COND *cond) { if (cond) { _al_cond_destroy(&cond->cond); al_free(cond); } } /* Function: al_wait_cond */ void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex) { ASSERT(cond); ASSERT(mutex); _al_cond_wait(&cond->cond, &mutex->mutex); } /* Function: al_wait_cond_until */ int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, const ALLEGRO_TIMEOUT *timeout) { ASSERT(cond); ASSERT(mutex); ASSERT(timeout); return _al_cond_timedwait(&cond->cond, &mutex->mutex, timeout); } /* Function: al_broadcast_cond */ void al_broadcast_cond(ALLEGRO_COND *cond) { ASSERT(cond); _al_cond_broadcast(&cond->cond); } /* Function: al_signal_cond */ void al_signal_cond(ALLEGRO_COND *cond) { ASSERT(cond); _al_cond_signal(&cond->cond); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/convert.c0000644000175000001440000072527211426530105015035 0ustar tjadenusers// Warning: This file was created by make_converters.py - do not edit. #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_convert.h" static void argb_8888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_4444_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_4444(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGB_565(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGB_555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_5551(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_1555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_XBGR_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx * 3; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif int dst_pixel = ALLEGRO_CONVERT_RGB_888_TO_BGR_888(src_pixel); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1 * 3; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_BGR_565(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_BGR_555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBX_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_XRGB_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 16 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_F32(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_4444(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGB_565_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGB_565_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_565_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGB_555_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGB_555_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgb_555_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_5551_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void argb_1555_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xbgr_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_4444(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx * 3; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif int dst_pixel = ALLEGRO_CONVERT_BGR_888_TO_RGB_888(src_pixel); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1 * 3; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGB_565(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGB_555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_5551(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_1555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_XBGR_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_BGR_565(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_BGR_555(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBX_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_XRGB_8888(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 16 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_F32(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 4 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint8_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 1 - width * 3; int dst_gap = dst_pitch / 2 - width; src_ptr += sx * 3; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_4444(src_pixel); src_ptr += 1 * 3; dst_ptr += 1; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_BGR_565_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_BGR_565_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_565_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_BGR_555_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_BGR_555_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void bgr_555_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgbx_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void xrgb_8888_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_f32_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; ALLEGRO_COLOR *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 16 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void abgr_8888_le_to_rgba_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint32_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 4 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_argb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgba_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_argb_4444(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_4444(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgb_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgb_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgb_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgba_5551(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_5551(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_argb_1555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_1555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_abgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_xbgr_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_XBGR_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_bgr_888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 1 - width * 3; src_ptr += sx; dst_ptr += dx * 3; for (y = 0; y < height; y++) { uint8_t *dst_end = dst_ptr + width * 3; while (dst_ptr < dst_end) { int dst_pixel = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_888(*src_ptr); #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif src_ptr += 1; dst_ptr += 1 * 3; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_bgr_565(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_565(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_bgr_555(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 2 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint16_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_555(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_rgbx_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBX_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_xrgb_8888(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_XRGB_8888(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_abgr_f32(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 16 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { ALLEGRO_COLOR *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_F32(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } static void rgba_4444_to_abgr_8888_le(void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { int y; uint16_t *src_ptr = (void *)((char *)src + sy * src_pitch); uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / 2 - width; int dst_gap = dst_pitch / 4 - width; src_ptr += sx; dst_ptr += dx; for (y = 0; y < height; y++) { uint32_t *dst_end = dst_ptr + width; while (dst_ptr < dst_end) { *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(*src_ptr); dst_ptr++; src_ptr++; } src_ptr += src_gap; dst_ptr += dst_gap; } } void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] [ALLEGRO_NUM_PIXEL_FORMATS])(void *, int, void *, int, int, int, int, int, int, int) = { {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, argb_8888_to_rgba_8888, argb_8888_to_argb_4444, argb_8888_to_rgb_888, argb_8888_to_rgb_565, argb_8888_to_rgb_555, argb_8888_to_rgba_5551, argb_8888_to_argb_1555, argb_8888_to_abgr_8888, argb_8888_to_xbgr_8888, argb_8888_to_bgr_888, argb_8888_to_bgr_565, argb_8888_to_bgr_555, argb_8888_to_rgbx_8888, argb_8888_to_xrgb_8888, argb_8888_to_abgr_f32, argb_8888_to_abgr_8888_le, argb_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgba_8888_to_argb_8888, NULL, rgba_8888_to_argb_4444, rgba_8888_to_rgb_888, rgba_8888_to_rgb_565, rgba_8888_to_rgb_555, rgba_8888_to_rgba_5551, rgba_8888_to_argb_1555, rgba_8888_to_abgr_8888, rgba_8888_to_xbgr_8888, rgba_8888_to_bgr_888, rgba_8888_to_bgr_565, rgba_8888_to_bgr_555, rgba_8888_to_rgbx_8888, rgba_8888_to_xrgb_8888, rgba_8888_to_abgr_f32, rgba_8888_to_abgr_8888_le, rgba_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, argb_4444_to_argb_8888, argb_4444_to_rgba_8888, NULL, argb_4444_to_rgb_888, argb_4444_to_rgb_565, argb_4444_to_rgb_555, argb_4444_to_rgba_5551, argb_4444_to_argb_1555, argb_4444_to_abgr_8888, argb_4444_to_xbgr_8888, argb_4444_to_bgr_888, argb_4444_to_bgr_565, argb_4444_to_bgr_555, argb_4444_to_rgbx_8888, argb_4444_to_xrgb_8888, argb_4444_to_abgr_f32, argb_4444_to_abgr_8888_le, argb_4444_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgb_888_to_argb_8888, rgb_888_to_rgba_8888, rgb_888_to_argb_4444, NULL, rgb_888_to_rgb_565, rgb_888_to_rgb_555, rgb_888_to_rgba_5551, rgb_888_to_argb_1555, rgb_888_to_abgr_8888, rgb_888_to_xbgr_8888, rgb_888_to_bgr_888, rgb_888_to_bgr_565, rgb_888_to_bgr_555, rgb_888_to_rgbx_8888, rgb_888_to_xrgb_8888, rgb_888_to_abgr_f32, rgb_888_to_abgr_8888_le, rgb_888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgb_565_to_argb_8888, rgb_565_to_rgba_8888, rgb_565_to_argb_4444, rgb_565_to_rgb_888, NULL, rgb_565_to_rgb_555, rgb_565_to_rgba_5551, rgb_565_to_argb_1555, rgb_565_to_abgr_8888, rgb_565_to_xbgr_8888, rgb_565_to_bgr_888, rgb_565_to_bgr_565, rgb_565_to_bgr_555, rgb_565_to_rgbx_8888, rgb_565_to_xrgb_8888, rgb_565_to_abgr_f32, rgb_565_to_abgr_8888_le, rgb_565_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgb_555_to_argb_8888, rgb_555_to_rgba_8888, rgb_555_to_argb_4444, rgb_555_to_rgb_888, rgb_555_to_rgb_565, NULL, rgb_555_to_rgba_5551, rgb_555_to_argb_1555, rgb_555_to_abgr_8888, rgb_555_to_xbgr_8888, rgb_555_to_bgr_888, rgb_555_to_bgr_565, rgb_555_to_bgr_555, rgb_555_to_rgbx_8888, rgb_555_to_xrgb_8888, rgb_555_to_abgr_f32, rgb_555_to_abgr_8888_le, rgb_555_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgba_5551_to_argb_8888, rgba_5551_to_rgba_8888, rgba_5551_to_argb_4444, rgba_5551_to_rgb_888, rgba_5551_to_rgb_565, rgba_5551_to_rgb_555, NULL, rgba_5551_to_argb_1555, rgba_5551_to_abgr_8888, rgba_5551_to_xbgr_8888, rgba_5551_to_bgr_888, rgba_5551_to_bgr_565, rgba_5551_to_bgr_555, rgba_5551_to_rgbx_8888, rgba_5551_to_xrgb_8888, rgba_5551_to_abgr_f32, rgba_5551_to_abgr_8888_le, rgba_5551_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, argb_1555_to_argb_8888, argb_1555_to_rgba_8888, argb_1555_to_argb_4444, argb_1555_to_rgb_888, argb_1555_to_rgb_565, argb_1555_to_rgb_555, argb_1555_to_rgba_5551, NULL, argb_1555_to_abgr_8888, argb_1555_to_xbgr_8888, argb_1555_to_bgr_888, argb_1555_to_bgr_565, argb_1555_to_bgr_555, argb_1555_to_rgbx_8888, argb_1555_to_xrgb_8888, argb_1555_to_abgr_f32, argb_1555_to_abgr_8888_le, argb_1555_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, abgr_8888_to_argb_8888, abgr_8888_to_rgba_8888, abgr_8888_to_argb_4444, abgr_8888_to_rgb_888, abgr_8888_to_rgb_565, abgr_8888_to_rgb_555, abgr_8888_to_rgba_5551, abgr_8888_to_argb_1555, NULL, abgr_8888_to_xbgr_8888, abgr_8888_to_bgr_888, abgr_8888_to_bgr_565, abgr_8888_to_bgr_555, abgr_8888_to_rgbx_8888, abgr_8888_to_xrgb_8888, abgr_8888_to_abgr_f32, abgr_8888_to_abgr_8888_le, abgr_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, xbgr_8888_to_argb_8888, xbgr_8888_to_rgba_8888, xbgr_8888_to_argb_4444, xbgr_8888_to_rgb_888, xbgr_8888_to_rgb_565, xbgr_8888_to_rgb_555, xbgr_8888_to_rgba_5551, xbgr_8888_to_argb_1555, xbgr_8888_to_abgr_8888, NULL, xbgr_8888_to_bgr_888, xbgr_8888_to_bgr_565, xbgr_8888_to_bgr_555, xbgr_8888_to_rgbx_8888, xbgr_8888_to_xrgb_8888, xbgr_8888_to_abgr_f32, xbgr_8888_to_abgr_8888_le, xbgr_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, bgr_888_to_argb_8888, bgr_888_to_rgba_8888, bgr_888_to_argb_4444, bgr_888_to_rgb_888, bgr_888_to_rgb_565, bgr_888_to_rgb_555, bgr_888_to_rgba_5551, bgr_888_to_argb_1555, bgr_888_to_abgr_8888, bgr_888_to_xbgr_8888, NULL, bgr_888_to_bgr_565, bgr_888_to_bgr_555, bgr_888_to_rgbx_8888, bgr_888_to_xrgb_8888, bgr_888_to_abgr_f32, bgr_888_to_abgr_8888_le, bgr_888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, bgr_565_to_argb_8888, bgr_565_to_rgba_8888, bgr_565_to_argb_4444, bgr_565_to_rgb_888, bgr_565_to_rgb_565, bgr_565_to_rgb_555, bgr_565_to_rgba_5551, bgr_565_to_argb_1555, bgr_565_to_abgr_8888, bgr_565_to_xbgr_8888, bgr_565_to_bgr_888, NULL, bgr_565_to_bgr_555, bgr_565_to_rgbx_8888, bgr_565_to_xrgb_8888, bgr_565_to_abgr_f32, bgr_565_to_abgr_8888_le, bgr_565_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, bgr_555_to_argb_8888, bgr_555_to_rgba_8888, bgr_555_to_argb_4444, bgr_555_to_rgb_888, bgr_555_to_rgb_565, bgr_555_to_rgb_555, bgr_555_to_rgba_5551, bgr_555_to_argb_1555, bgr_555_to_abgr_8888, bgr_555_to_xbgr_8888, bgr_555_to_bgr_888, bgr_555_to_bgr_565, NULL, bgr_555_to_rgbx_8888, bgr_555_to_xrgb_8888, bgr_555_to_abgr_f32, bgr_555_to_abgr_8888_le, bgr_555_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgbx_8888_to_argb_8888, rgbx_8888_to_rgba_8888, rgbx_8888_to_argb_4444, rgbx_8888_to_rgb_888, rgbx_8888_to_rgb_565, rgbx_8888_to_rgb_555, rgbx_8888_to_rgba_5551, rgbx_8888_to_argb_1555, rgbx_8888_to_abgr_8888, rgbx_8888_to_xbgr_8888, rgbx_8888_to_bgr_888, rgbx_8888_to_bgr_565, rgbx_8888_to_bgr_555, NULL, rgbx_8888_to_xrgb_8888, rgbx_8888_to_abgr_f32, rgbx_8888_to_abgr_8888_le, rgbx_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, xrgb_8888_to_argb_8888, xrgb_8888_to_rgba_8888, xrgb_8888_to_argb_4444, xrgb_8888_to_rgb_888, xrgb_8888_to_rgb_565, xrgb_8888_to_rgb_555, xrgb_8888_to_rgba_5551, xrgb_8888_to_argb_1555, xrgb_8888_to_abgr_8888, xrgb_8888_to_xbgr_8888, xrgb_8888_to_bgr_888, xrgb_8888_to_bgr_565, xrgb_8888_to_bgr_555, xrgb_8888_to_rgbx_8888, NULL, xrgb_8888_to_abgr_f32, xrgb_8888_to_abgr_8888_le, xrgb_8888_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, abgr_f32_to_argb_8888, abgr_f32_to_rgba_8888, abgr_f32_to_argb_4444, abgr_f32_to_rgb_888, abgr_f32_to_rgb_565, abgr_f32_to_rgb_555, abgr_f32_to_rgba_5551, abgr_f32_to_argb_1555, abgr_f32_to_abgr_8888, abgr_f32_to_xbgr_8888, abgr_f32_to_bgr_888, abgr_f32_to_bgr_565, abgr_f32_to_bgr_555, abgr_f32_to_rgbx_8888, abgr_f32_to_xrgb_8888, NULL, abgr_f32_to_abgr_8888_le, abgr_f32_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, abgr_8888_le_to_argb_8888, abgr_8888_le_to_rgba_8888, abgr_8888_le_to_argb_4444, abgr_8888_le_to_rgb_888, abgr_8888_le_to_rgb_565, abgr_8888_le_to_rgb_555, abgr_8888_le_to_rgba_5551, abgr_8888_le_to_argb_1555, abgr_8888_le_to_abgr_8888, abgr_8888_le_to_xbgr_8888, abgr_8888_le_to_bgr_888, abgr_8888_le_to_bgr_565, abgr_8888_le_to_bgr_555, abgr_8888_le_to_rgbx_8888, abgr_8888_le_to_xrgb_8888, abgr_8888_le_to_abgr_f32, NULL, abgr_8888_le_to_rgba_4444, }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rgba_4444_to_argb_8888, rgba_4444_to_rgba_8888, rgba_4444_to_argb_4444, rgba_4444_to_rgb_888, rgba_4444_to_rgb_565, rgba_4444_to_rgb_555, rgba_4444_to_rgba_5551, rgba_4444_to_argb_1555, rgba_4444_to_abgr_8888, rgba_4444_to_xbgr_8888, rgba_4444_to_bgr_888, rgba_4444_to_bgr_565, rgba_4444_to_bgr_555, rgba_4444_to_rgbx_8888, rgba_4444_to_xrgb_8888, rgba_4444_to_abgr_f32, rgba_4444_to_abgr_8888_le, NULL, }, }; // Warning: This file was created by make_converters.py - do not edit. allegro-5.0.10/src/tri_soft.c0000644000175000001440000006456612007146062015211 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Software triangle implementation functions. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_pixels.h" #include "allegro5/internal/aintern_tri_soft.h" #include ALLEGRO_DEBUG_CHANNEL("tri_soft") #define MIN _ALLEGRO_MIN #define MAX _ALLEGRO_MAX typedef void (*shader_draw)(uintptr_t, int, int, int); typedef void (*shader_init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*); typedef void (*shader_first)(uintptr_t, int, int, int, int); typedef void (*shader_step)(uintptr_t, int); typedef struct { ALLEGRO_BITMAP *target; ALLEGRO_COLOR cur_color; } state_solid_any_2d; static void shader_solid_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { state_solid_any_2d* s = (state_solid_any_2d*)state; s->target = al_get_target_bitmap(); s->cur_color = v1->color; (void)v2; (void)v3; } static void shader_solid_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) { (void)state; (void)x1; (void)y; (void)left_minor; (void)left_major; } static void shader_solid_any_step(uintptr_t state, int minor) { (void)state; (void)minor; } /*----------------------------------------------------------------------------*/ typedef struct { state_solid_any_2d solid; ALLEGRO_COLOR color_dx; ALLEGRO_COLOR color_dy; ALLEGRO_COLOR color_const; /* These are catched for the left edge walking */ ALLEGRO_COLOR minor_color; ALLEGRO_COLOR major_color; /* We use these to increase the precision of interpolation */ float off_x; float off_y; } state_grad_any_2d; #define PLANE_DETS(var, u1, u2, u3) \ float var##_det = u1 * minor3 - u2 * minor2 + u3 * minor1; \ float var##_det_x = u1 * y32 - u2 * y31 + u3 * y21; \ float var##_det_y = u1 * x23 - u2 * x13 + u3 * x12; #define INIT_PREAMBLE \ const float x1 = 0; \ const float y1 = 0; \ \ const float x2 = v2->x - v1->x; \ const float y2 = v2->y - v1->y; \ \ const float x3 = v3->x - v1->x; \ const float y3 = v3->y - v1->y; \ \ const float minor1 = x1 * y2 - x2 * y1; \ const float minor2 = x1 * y3 - x3 * y1; \ const float minor3 = x2 * y3 - x3 * y2; \ \ const float y32 = y3 - y2; \ const float y31 = y3 - y1; \ const float y21 = y2 - y1; \ \ const float x23 = x2 - x3; \ const float x13 = x1 - x3; \ const float x12 = x1 - x2; \ \ const float det_u = minor3 - minor1 + minor2; static void shader_grad_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { INIT_PREAMBLE ALLEGRO_COLOR v1c = v1->color; ALLEGRO_COLOR v2c = v2->color; ALLEGRO_COLOR v3c = v3->color; PLANE_DETS(r, v1c.r, v2c.r, v3c.r) PLANE_DETS(g, v1c.g, v2c.g, v3c.g) PLANE_DETS(b, v1c.b, v2c.b, v3c.b) PLANE_DETS(a, v1c.a, v2c.a, v3c.a) state_grad_any_2d* s = (state_grad_any_2d*)state; s->solid.target = al_get_target_bitmap(); s->off_x = v1->x - 0.5f; s->off_y = v1->y + 0.5f; if (det_u == 0.0) { s->color_dx = s->color_dy = s->color_const = al_map_rgba_f(0, 0, 0, 0); } else { s->color_dx.r = -r_det_x / det_u; s->color_dy.r = -r_det_y / det_u; s->color_const.r = r_det / det_u; s->color_dx.g = -g_det_x / det_u; s->color_dy.g = -g_det_y / det_u; s->color_const.g = g_det / det_u; s->color_dx.b = -b_det_x / det_u; s->color_dy.b = -b_det_y / det_u; s->color_const.b = b_det / det_u; s->color_dx.a = -a_det_x / det_u; s->color_dy.a = -a_det_y / det_u; s->color_const.a = a_det / det_u; } } static void shader_grad_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) { state_grad_any_2d* s = (state_grad_any_2d*)state; const float cur_x = (float)x1 - s->off_x; const float cur_y = (float)y - s->off_y; s->solid.cur_color.r = cur_x * s->color_dx.r + cur_y * s->color_dy.r + s->color_const.r; s->solid.cur_color.g = cur_x * s->color_dx.g + cur_y * s->color_dy.g + s->color_const.g; s->solid.cur_color.b = cur_x * s->color_dx.b + cur_y * s->color_dy.b + s->color_const.b; s->solid.cur_color.a = cur_x * s->color_dx.a + cur_y * s->color_dy.a + s->color_const.a; s->minor_color.r = (float)left_minor * s->color_dx.r + s->color_dy.r; s->minor_color.g = (float)left_minor * s->color_dx.g + s->color_dy.g; s->minor_color.b = (float)left_minor * s->color_dx.b + s->color_dy.b; s->minor_color.a = (float)left_minor * s->color_dx.a + s->color_dy.a; s->major_color.r = (float)left_major * s->color_dx.r + s->color_dy.r; s->major_color.g = (float)left_major * s->color_dx.g + s->color_dy.g; s->major_color.b = (float)left_major * s->color_dx.b + s->color_dy.b; s->major_color.a = (float)left_major * s->color_dx.a + s->color_dy.a; } static void shader_grad_any_step(uintptr_t state, int minor) { state_grad_any_2d* s = (state_grad_any_2d*)state; if (minor) { s->solid.cur_color.r += s->minor_color.r; s->solid.cur_color.g += s->minor_color.g; s->solid.cur_color.b += s->minor_color.b; s->solid.cur_color.a += s->minor_color.a; } else { s->solid.cur_color.r += s->major_color.r; s->solid.cur_color.g += s->major_color.g; s->solid.cur_color.b += s->major_color.b; s->solid.cur_color.a += s->major_color.a; } } /*========================== Textured Shaders ================================*/ #define SHADE_COLORS(A, B) \ A.r = B.r * A.r; \ A.g = B.g * A.g; \ A.b = B.b * A.b; \ A.a = B.a * A.a; typedef struct { ALLEGRO_BITMAP *target; ALLEGRO_COLOR cur_color; float du_dx, du_dy, u_const; float dv_dx, dv_dy, v_const; double u, v; double minor_du; double minor_dv; double major_du; double major_dv; float off_x; float off_y; ALLEGRO_BITMAP* texture; int w, h; } state_texture_solid_any_2d; static void shader_texture_solid_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { INIT_PREAMBLE PLANE_DETS(u, v1->u, v2->u, v3->u) PLANE_DETS(v, v1->v, v2->v, v3->v) state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; s->target = al_get_target_bitmap(); s->cur_color = v1->color; s->off_x = v1->x - 0.5f; s->off_y = v1->y + 0.5f; s->w = al_get_bitmap_width(s->texture); s->h = al_get_bitmap_height(s->texture); if (det_u == 0.0f) { s->du_dx = s->du_dy = s->u_const = 0.0f; s->dv_dx = s->dv_dy = s->v_const = 0.0f; } else { s->du_dx = -u_det_x / det_u; s->du_dy = -u_det_y / det_u; s->u_const = u_det / det_u; s->dv_dx = -v_det_x / det_u; s->dv_dy = -v_det_y / det_u; s->v_const = v_det / det_u; } } static void shader_texture_solid_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; const float cur_x = (float)x1 - s->off_x; const float cur_y = (float)y - s->off_y; s->u = cur_x * s->du_dx + cur_y * s->du_dy + s->u_const; s->v = cur_x * s->dv_dx + cur_y * s->dv_dy + s->v_const; s->minor_du = (double)left_minor * s->du_dx + s->du_dy; s->minor_dv = (double)left_minor * s->dv_dx + s->dv_dy; s->major_du = (float)left_major * s->du_dx + s->du_dy; s->major_dv = (float)left_major * s->dv_dx + s->dv_dy; } static void shader_texture_solid_any_step(uintptr_t state, int minor) { state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; if (minor) { s->u += s->minor_du; s->v += s->minor_dv; } else { s->u += s->major_du; s->v += s->major_dv; } } /*----------------------------------------------------------------------------*/ typedef struct { state_texture_solid_any_2d solid; ALLEGRO_COLOR color_dx; ALLEGRO_COLOR color_dy; ALLEGRO_COLOR color_const; /* These are catched for the left edge walking */ ALLEGRO_COLOR minor_color; ALLEGRO_COLOR major_color; } state_texture_grad_any_2d; static void shader_texture_grad_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { INIT_PREAMBLE ALLEGRO_COLOR v1c = v1->color; ALLEGRO_COLOR v2c = v2->color; ALLEGRO_COLOR v3c = v3->color; PLANE_DETS(r, v1c.r, v2c.r, v3c.r) PLANE_DETS(g, v1c.g, v2c.g, v3c.g) PLANE_DETS(b, v1c.b, v2c.b, v3c.b) PLANE_DETS(a, v1c.a, v2c.a, v3c.a) PLANE_DETS(u, v1->u, v2->u, v3->u) PLANE_DETS(v, v1->v, v2->v, v3->v) state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; s->solid.target = al_get_target_bitmap(); s->solid.w = al_get_bitmap_width(s->solid.texture); s->solid.h = al_get_bitmap_height(s->solid.texture); s->solid.off_x = v1->x - 0.5f; s->solid.off_y = v1->y + 0.5f; if (det_u == 0.0) { s->solid.du_dx = s->solid.du_dy = s->solid.u_const = 0.0; s->solid.dv_dx = s->solid.dv_dy = s->solid.v_const = 0.0; s->color_dx = s->color_dy = s->color_const = al_map_rgba_f(0, 0, 0, 0); } else { s->solid.du_dx = -u_det_x / det_u; s->solid.du_dy = -u_det_y / det_u; s->solid.u_const = u_det / det_u; s->solid.dv_dx = -v_det_x / det_u; s->solid.dv_dy = -v_det_y / det_u; s->solid.v_const = v_det / det_u; s->color_dx.r = -r_det_x / det_u; s->color_dy.r = -r_det_y / det_u; s->color_const.r = r_det / det_u; s->color_dx.g = -g_det_x / det_u; s->color_dy.g = -g_det_y / det_u; s->color_const.g = g_det / det_u; s->color_dx.b = -b_det_x / det_u; s->color_dy.b = -b_det_y / det_u; s->color_const.b = b_det / det_u; s->color_dx.a = -a_det_x / det_u; s->color_dy.a = -a_det_y / det_u; s->color_const.a = a_det / det_u; } } static void shader_texture_grad_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) { state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; float cur_x; float cur_y; shader_texture_solid_any_first(state, x1, y, left_minor, left_major); cur_x = (float)x1 - s->solid.off_x; cur_y = (float)y - s->solid.off_y; s->solid.cur_color.r = cur_x * s->color_dx.r + cur_y * s->color_dy.r + s->color_const.r; s->solid.cur_color.g = cur_x * s->color_dx.g + cur_y * s->color_dy.g + s->color_const.g; s->solid.cur_color.b = cur_x * s->color_dx.b + cur_y * s->color_dy.b + s->color_const.b; s->solid.cur_color.a = cur_x * s->color_dx.a + cur_y * s->color_dy.a + s->color_const.a; s->minor_color.r = (float)left_minor * s->color_dx.r + s->color_dy.r; s->minor_color.g = (float)left_minor * s->color_dx.g + s->color_dy.g; s->minor_color.b = (float)left_minor * s->color_dx.b + s->color_dy.b; s->minor_color.a = (float)left_minor * s->color_dx.a + s->color_dy.a; s->major_color.r = (float)left_major * s->color_dx.r + s->color_dy.r; s->major_color.g = (float)left_major * s->color_dx.g + s->color_dy.g; s->major_color.b = (float)left_major * s->color_dx.b + s->color_dy.b; s->major_color.a = (float)left_major * s->color_dx.a + s->color_dy.a; } static void shader_texture_grad_any_step(uintptr_t state, int minor) { state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; shader_texture_solid_any_step(state, minor); if (minor) { s->solid.cur_color.r += s->minor_color.r; s->solid.cur_color.g += s->minor_color.g; s->solid.cur_color.b += s->minor_color.b; s->solid.cur_color.a += s->minor_color.a; } else { s->solid.cur_color.r += s->major_color.r; s->solid.cur_color.g += s->major_color.g; s->solid.cur_color.b += s->major_color.b; s->solid.cur_color.a += s->major_color.a; } } /* Include generated routines. */ #include "scanline_drawers.inc" static void triangle_stepper(uintptr_t state, shader_init init, shader_first first, shader_step step, shader_draw draw, ALLEGRO_VERTEX* vtx1, ALLEGRO_VERTEX* vtx2, ALLEGRO_VERTEX* vtx3) { float Coords[6] = {vtx1->x - 0.5f, vtx1->y + 0.5f, vtx2->x - 0.5f, vtx2->y + 0.5f, vtx3->x - 0.5f, vtx3->y + 0.5f}; float *V1 = Coords, *V2 = &Coords[2], *V3 = &Coords[4], *s; float left_error = 0; float right_error = 0; float left_y_delta; float right_y_delta; float left_x_delta; float right_x_delta; int left_first, right_first, left_step, right_step; int left_x, right_x, cur_y, mid_y, end_y; float left_d_er, right_d_er; /* The reason these things are declared implicitly, is because we need to determine which of the edges is on the left, and which is on the right (because they are treated differently, as described above) We then can reuse these values in the actual calculation */ float major_x_delta, major_y_delta, minor_x_delta, minor_y_delta; int major_on_the_left; // sort vertices so that V1 <= V2 <= V3 if (V2[1] < V1[1]) { s = V2; V2 = V1; V1 = s; } if (V3[1] < V1[1]) { s = V3; V3 = V1; V1 = s; } if (V3[1] < V2[1]) { s = V3; V3 = V2; V2 = s; } /* We set our integer based coordinates to be above their floating point counterparts */ cur_y = ceilf(V1[1]); mid_y = ceilf(V2[1]); end_y = ceilf(V3[1]); if (cur_y == end_y) return; /* As per definition, we take the ceiling */ left_x = ceilf(V1[0]); /* Determine which edge is the left one V1-V2 | / V3 When the cross product is negative, the major is on the left */ major_x_delta = V3[0] - V1[0]; major_y_delta = V3[1] - V1[1]; minor_x_delta = V2[0] - V1[0]; minor_y_delta = V2[1] - V1[1]; if (major_x_delta * minor_y_delta - major_y_delta * minor_x_delta < 0) major_on_the_left = 1; else major_on_the_left = 0; init(state, vtx1, vtx2, vtx3); /* Do the first segment, if it exists */ if (cur_y != mid_y) { /* As per definition, we take the floor */ right_x = floorf(V1[0]); /* Depending on where V2 is located, choose the correct delta's */ if (major_on_the_left) { left_x_delta = major_x_delta; right_x_delta = minor_x_delta; left_y_delta = major_y_delta; right_y_delta = minor_y_delta; } else { left_x_delta = minor_x_delta; right_x_delta = major_x_delta; left_y_delta = minor_y_delta; right_y_delta = major_y_delta; } /* Calculate the initial errors... doesn't look too pretty, but it only has to be done a couple of times per triangle drawing operation, so its not that bad */ left_error = ((float)cur_y - V1[1]) * left_x_delta - ((float)left_x - V1[0]) * left_y_delta; right_error = ((float)cur_y - V1[1]) * right_x_delta - ((float)right_x - V1[0]) * right_y_delta; /* Calculate the first step of the edge steppers, it is potentially different from all other steps */ left_first = ceilf((left_error) / left_y_delta); /* Introduce a tiny bias into the calculation, a problem with the floorf implementation because it does not have a properly defined 0 point. I think this is a hack, however, so if anyone has a better idea of how to fix this, by all means implement it. N.B. the same offset in the bottom segment as well */ right_first = floorf((right_error) / right_y_delta - 0.000001f); /* Calculate the normal steps */ left_step = ceilf(left_x_delta / left_y_delta); left_d_er = -(float)left_step * left_y_delta; right_step = ceilf(right_x_delta / right_y_delta); right_d_er = -(float)right_step * right_y_delta; /* Take the first step */ if (cur_y < mid_y) { left_x += left_first; left_error -= (float)left_first * left_y_delta; right_x += right_first; right_error -= (float)right_first * right_y_delta; first(state, left_x, cur_y, left_step, left_step - 1); if (right_x >= left_x) { draw(state, left_x, cur_y, right_x); } cur_y++; left_error += left_x_delta; right_error += right_x_delta; } /* ...and then continue taking normal steps until we finish the segment */ while (cur_y < mid_y) { left_error += left_d_er; left_x += left_step; /* If we dip to the right of the line, we shift one pixel to the left If dx > 0, this corresponds to taking the minor step If dx < 0, this corresponds to taking the major step */ if (left_error + left_y_delta <= 0) { left_error += left_y_delta; left_x -= 1; step(state, 0); } else step(state, 1); right_error += right_d_er; right_x += right_step; if (right_error <= 0) { right_error += right_y_delta; right_x -= 1; } if (right_x >= left_x) { draw(state, left_x, cur_y, right_x); } cur_y++; left_error += left_x_delta; right_error += right_x_delta; } } /* Draw the second segment, if possible */ if (cur_y < end_y) { if (major_on_the_left) { right_x = ceilf(V2[0]); left_x_delta = major_x_delta; right_x_delta = V3[0] - V2[0]; left_y_delta = major_y_delta; right_y_delta = V3[1] - V2[1]; left_error = ((float)cur_y - V1[1]) * left_x_delta - ((float)left_x - V1[0]) * left_y_delta; right_error = ((float)cur_y - V2[1]) * right_x_delta - ((float)right_x - V2[0]) * right_y_delta; } else { right_x = floorf(V2[0]); left_x_delta = V3[0] - V2[0]; right_x_delta = major_x_delta; left_y_delta = V3[1] - V2[1]; right_y_delta = major_y_delta; left_error = ((float)cur_y - V2[1]) * left_x_delta - ((float)left_x - V2[0]) * left_y_delta; right_error = ((float)cur_y - V1[1]) * right_x_delta - ((float)right_x - V1[0]) * right_y_delta; } left_first = ceilf((left_error) / left_y_delta); right_first = floorf((right_error) / right_y_delta - 0.000001f); left_step = ceilf(left_x_delta / left_y_delta); left_d_er = -(float)left_step * left_y_delta; right_step = ceilf(right_x_delta / right_y_delta); right_d_er = -(float)right_step * right_y_delta; if (cur_y < end_y) { left_x += left_first; left_error -= (float)left_first * left_y_delta; right_x += right_first; right_error -= (float)right_first * right_y_delta; first(state, left_x, cur_y, left_step, left_step - 1); if (right_x >= left_x) { draw(state, left_x, cur_y, right_x); } cur_y++; left_error += left_x_delta; right_error += right_x_delta; } while (cur_y < end_y) { left_error += left_d_er; left_x += left_step; if (left_error + left_y_delta <= 0) { left_error += left_y_delta; left_x -= 1; step(state, 0); } else step(state, 1); right_error += right_d_er; right_x += right_step; if (right_error <= 0) { right_error += right_y_delta; right_x -= 1; } if (right_x >= left_x) { draw(state, left_x, cur_y, right_x); } cur_y++; left_error += left_x_delta; right_error += right_x_delta; } } } /* This one will check to see what exactly we need to draw... I.e. this will call all of the actual renderers and set the appropriate callbacks */ void _al_triangle_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { int shade = 1; int grad = 1; int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR v1c, v2c, v3c; v1c = v1->color; v2c = v2->color; v3c = v3->color; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { shade = 0; } if ((v1c.r == v2c.r && v2c.r == v3c.r) && (v1c.g == v2c.g && v2c.g == v3c.g) && (v1c.b == v2c.b && v2c.b == v3c.b) && (v1c.a == v2c.a && v2c.a == v3c.a)) { grad = 0; } if (texture) { if (grad) { state_texture_grad_any_2d state; state.solid.texture = texture; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_opaque); } } else { int white = 0; state_texture_solid_any_2d state; if (v1c.r == 1 && v1c.g == 1 && v1c.b == 1 && v1c.a == 1) { white = 1; } state.texture = texture; if (shade) { if (white) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade_white); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade); } } else { if (white) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque_white); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque); } } } } else { if (grad) { state_grad_any_2d state; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_opaque); } } else { state_solid_any_2d state; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_opaque); } } } } static int bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int w, int h) { ASSERT(bmp); if (!al_is_bitmap_locked(bmp)) return 0; if (x1 + w > bmp->lock_x && y1 + h > bmp->lock_y && x1 < bmp->lock_x + bmp->lock_w && y1 < bmp->lock_y + bmp->lock_h) return 1; return 0; } void _al_draw_soft_triangle( ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*first)(uintptr_t, int, int, int, int), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int, int)) { /* ALLEGRO_VERTEX copy_v1, copy_v2; <- may be needed for clipping later on */ ALLEGRO_VERTEX* vtx1 = v1; ALLEGRO_VERTEX* vtx2 = v2; ALLEGRO_VERTEX* vtx3 = v3; ALLEGRO_BITMAP *target = al_get_target_bitmap(); int need_unlock = 0; ALLEGRO_LOCKED_REGION *lr; int min_x, max_x, min_y, max_y; int clip_min_x, clip_min_y, clip_max_x, clip_max_y; al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); clip_max_x += clip_min_x; clip_max_y += clip_min_y; /* TODO: Need to clip them first, make a copy of the vertices first then */ /* Lock the region we are drawing to. We are choosing the minimum and maximum possible pixels touched from the formula (easily verified by following the above algorithm. */ min_x = (int)floorf(MIN(vtx1->x, MIN(vtx2->x, vtx3->x))) - 1; min_y = (int)floorf(MIN(vtx1->y, MIN(vtx2->y, vtx3->y))) - 1; max_x = (int)ceilf(MAX(vtx1->x, MAX(vtx2->x, vtx3->x))) + 1; max_y = (int)ceilf(MAX(vtx1->y, MAX(vtx2->y, vtx3->y))) + 1; /* TODO: This bit is temporary, the min max's will be guaranteed to be within the bitmap once clipping is implemented */ if (min_x >= clip_max_x || min_y >= clip_max_y) return; if (max_x >= clip_max_x) max_x = clip_max_x; if (max_y >= clip_max_y) max_y = clip_max_y; if (max_x < clip_min_x || max_y < clip_min_y) return; if (min_x < clip_min_x) min_x = clip_min_x; if (min_y < clip_min_y) min_y = clip_min_y; if (al_is_bitmap_locked(target)) { if (!bitmap_region_is_locked(target, min_x, min_y, max_x - min_x, max_y - min_y)) return; } else { if (!(lr = al_lock_bitmap_region(target, min_x, min_y, max_x - min_x, max_y - min_y, ALLEGRO_PIXEL_FORMAT_ANY, 0))) return; need_unlock = 1; } triangle_stepper(state, init, first, step, draw, v1, v2, v3); if (need_unlock) al_unlock_bitmap(target); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/path.c0000644000175000001440000003120311463140703014273 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Filesystem path routines. * * By Thomas Fjellstrom. * * See LICENSE.txt for copyright information. */ /* Title: Filesystem path routines */ #include #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_vector.h" #include "allegro5/internal/aintern_path.h" /* get_segment: * Return the i'th directory component of a path. */ static ALLEGRO_USTR *get_segment(const ALLEGRO_PATH *path, unsigned i) { ALLEGRO_USTR **seg = _al_vector_ref(&path->segments, i); return *seg; } /* get_segment_cstr: * Return the i'th directory component of a path as a C string. */ static const char *get_segment_cstr(const ALLEGRO_PATH *path, unsigned i) { return al_cstr(get_segment(path, i)); } /* replace_backslashes: * Replace backslashes by slashes. */ static void replace_backslashes(ALLEGRO_USTR *path) { al_ustr_find_replace_cstr(path, 0, "\\", "/"); } /* parse_path_string: * * Parse a path string according to the following grammar. The last * component, if it is not followed by a directory separator, is interpreted * as the filename component, unless it is "." or "..". * * GRAMMAR * * path ::= "//" c+ "/" nonlast [Windows only] * | c ":" nonlast [Windows only] * | nonlast * * nonlast ::= c* "/" nonlast * | last * * last ::= "." * | ".." * | filename * * filename ::= c* [but not "." and ".."] * * c ::= any character but '/' */ static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path) { ALLEGRO_USTR_INFO dot_info; ALLEGRO_USTR_INFO dotdot_info; const ALLEGRO_USTR * dot = al_ref_cstr(&dot_info, "."); const ALLEGRO_USTR * dotdot = al_ref_cstr(&dotdot_info, ".."); ALLEGRO_USTR *piece = al_ustr_new(""); int pos = 0; bool on_windows; /* We compile the drive handling code on non-Windows platforms to prevent * it becoming broken. */ #ifdef ALLEGRO_WINDOWS on_windows = true; #else on_windows = false; #endif if (on_windows) { /* UNC \\server\share name */ if (al_ustr_has_prefix_cstr(str, "//")) { int slash = al_ustr_find_chr(str, 2, '/'); if (slash == -1 || slash == 2) { /* Missing slash or server component is empty. */ goto Error; } al_ustr_assign_substr(path->drive, str, pos, slash); pos = slash + 1; } else { /* Drive letter. */ int colon = al_ustr_offset(str, 1); if (colon > -1 && al_ustr_get(str, colon) == ':') { /* Include the colon in the drive string. */ al_ustr_assign_substr(path->drive, str, 0, colon + 1); pos = colon + 1; } } } for (;;) { int slash = al_ustr_find_chr(str, pos, '/'); if (slash == -1) { /* Last component. */ al_ustr_assign_substr(piece, str, pos, al_ustr_size(str)); if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) { al_append_path_component(path, al_cstr(piece)); } else { /* This might be an empty string, but that's okay. */ al_ustr_assign(path->filename, piece); } break; } /* Non-last component. */ al_ustr_assign_substr(piece, str, pos, slash); al_append_path_component(path, al_cstr(piece)); pos = slash + 1; } al_ustr_free(piece); return true; Error: al_ustr_free(piece); return false; } /* Function: al_create_path */ ALLEGRO_PATH *al_create_path(const char *str) { ALLEGRO_PATH *path; path = al_malloc(sizeof(ALLEGRO_PATH)); if (!path) return NULL; path->drive = al_ustr_new(""); path->filename = al_ustr_new(""); _al_vector_init(&path->segments, sizeof(ALLEGRO_USTR *)); path->basename = al_ustr_new(""); path->full_string = al_ustr_new(""); if (str != NULL) { ALLEGRO_USTR *copy = al_ustr_new(str); replace_backslashes(copy); if (!parse_path_string(copy, path)) { al_destroy_path(path); path = NULL; } al_ustr_free(copy); } return path; } /* Function: al_create_path_for_directory */ ALLEGRO_PATH *al_create_path_for_directory(const char *str) { ALLEGRO_PATH *path = al_create_path(str); if (al_ustr_length(path->filename)) { ALLEGRO_USTR *last = path->filename; path->filename = al_ustr_new(""); al_append_path_component(path, al_cstr(last)); al_ustr_free(last); } return path; } /* Function: al_clone_path */ ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) { ALLEGRO_PATH *clone; unsigned int i; ASSERT(path); clone = al_create_path(NULL); if (!clone) { return NULL; } al_ustr_assign(clone->drive, path->drive); al_ustr_assign(clone->filename, path->filename); for (i = 0; i < _al_vector_size(&path->segments); i++) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&clone->segments); (*slot) = al_ustr_dup(get_segment(path, i)); } return clone; } /* Function: al_get_path_num_components */ int al_get_path_num_components(const ALLEGRO_PATH *path) { ASSERT(path); return _al_vector_size(&path->segments); } /* Function: al_get_path_component */ const char *al_get_path_component(const ALLEGRO_PATH *path, int i) { ASSERT(path); ASSERT(i < (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); return get_segment_cstr(path, i); } /* Function: al_replace_path_component */ void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s) { ASSERT(path); ASSERT(s); ASSERT(i < (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); al_ustr_assign_cstr(get_segment(path, i), s); } /* Function: al_remove_path_component */ void al_remove_path_component(ALLEGRO_PATH *path, int i) { ASSERT(path); ASSERT(i < (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); al_ustr_free(get_segment(path, i)); _al_vector_delete_at(&path->segments, i); } /* Function: al_insert_path_component */ void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s) { ALLEGRO_USTR **slot; ASSERT(path); ASSERT(i <= (int)_al_vector_size(&path->segments)); if (i < 0) i = _al_vector_size(&path->segments) + i; ASSERT(i >= 0); slot = _al_vector_alloc_mid(&path->segments, i); (*slot) = al_ustr_new(s); } /* Function: al_get_path_tail */ const char *al_get_path_tail(const ALLEGRO_PATH *path) { ASSERT(path); if (al_get_path_num_components(path) == 0) return NULL; return al_get_path_component(path, -1); } /* Function: al_drop_path_tail */ void al_drop_path_tail(ALLEGRO_PATH *path) { if (al_get_path_num_components(path) > 0) { al_remove_path_component(path, -1); } } /* Function: al_append_path_component */ void al_append_path_component(ALLEGRO_PATH *path, const char *s) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&path->segments); (*slot) = al_ustr_new(s); } static bool path_is_absolute(const ALLEGRO_PATH *path) { /* If the first segment is empty, we have an absolute path. */ return (_al_vector_size(&path->segments) > 0) && (al_ustr_size(get_segment(path, 0)) == 0); } /* Function: al_join_paths */ bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail) { unsigned i; ASSERT(path); ASSERT(tail); /* Don't bother concating if the tail is an absolute path. */ if (path_is_absolute(tail)) { return false; } /* We ignore tail->drive. The other option is to do nothing if tail * contains a drive letter. */ al_ustr_assign(path->filename, tail->filename); for (i = 0; i < _al_vector_size(&tail->segments); i++) { al_append_path_component(path, get_segment_cstr(tail, i)); } return true; } /* Function: al_rebase_path */ bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail) { unsigned i; ASSERT(head); ASSERT(tail); /* Don't bother concating if the tail is an absolute path. */ if (path_is_absolute(tail)) { return false; } al_set_path_drive(tail, al_get_path_drive(head)); for (i = 0; i < _al_vector_size(&head->segments); i++) { al_insert_path_component(tail, i, get_segment_cstr(head, i)); } return true; } static void path_to_ustr(const ALLEGRO_PATH *path, int32_t delim, ALLEGRO_USTR *str) { unsigned i; al_ustr_assign(str, path->drive); for (i = 0; i < _al_vector_size(&path->segments); i++) { al_ustr_append(str, get_segment(path, i)); al_ustr_append_chr(str, delim); } al_ustr_append(str, path->filename); } /* Function: al_path_cstr */ const char *al_path_cstr(const ALLEGRO_PATH *path, char delim) { path_to_ustr(path, delim, path->full_string); return al_cstr(path->full_string); } /* Function: al_destroy_path */ void al_destroy_path(ALLEGRO_PATH *path) { unsigned i; if (!path) { return; } if (path->drive) { al_ustr_free(path->drive); path->drive = NULL; } if (path->filename) { al_ustr_free(path->filename); path->filename = NULL; } for (i = 0; i < _al_vector_size(&path->segments); i++) { al_ustr_free(get_segment(path, i)); } _al_vector_free(&path->segments); if (path->basename) { al_ustr_free(path->basename); path->basename = NULL; } if (path->full_string) { al_ustr_free(path->full_string); path->full_string = NULL; } al_free(path); } /* Function: al_set_path_drive */ void al_set_path_drive(ALLEGRO_PATH *path, const char *drive) { ASSERT(path); if (drive) al_ustr_assign_cstr(path->drive, drive); else al_ustr_truncate(path->drive, 0); } /* Function: al_get_path_drive */ const char *al_get_path_drive(const ALLEGRO_PATH *path) { ASSERT(path); return al_cstr(path->drive); } /* Function: al_set_path_filename */ void al_set_path_filename(ALLEGRO_PATH *path, const char *filename) { ASSERT(path); if (filename) al_ustr_assign_cstr(path->filename, filename); else al_ustr_truncate(path->filename, 0); } /* Function: al_get_path_filename */ const char *al_get_path_filename(const ALLEGRO_PATH *path) { ASSERT(path); return al_cstr(path->filename); } /* Function: al_get_path_extension */ const char *al_get_path_extension(const ALLEGRO_PATH *path) { int pos; ASSERT(path); pos = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); if (pos == -1) pos = al_ustr_size(path->filename); return al_cstr(path->filename) + pos; /* include dot */ } /* Function: al_set_path_extension */ bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension) { int dot; ASSERT(path); if (al_ustr_size(path->filename) == 0) { return false; } dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); if (dot >= 0) { al_ustr_truncate(path->filename, dot); } al_ustr_append_cstr(path->filename, extension); return true; } /* Function: al_get_path_basename */ const char *al_get_path_basename(const ALLEGRO_PATH *path) { int dot; ASSERT(path); dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); if (dot >= 0) { al_ustr_assign_substr(path->basename, path->filename, 0, dot); return al_cstr(path->basename); } return al_cstr(path->filename); } /* Function: al_make_path_canonical */ bool al_make_path_canonical(ALLEGRO_PATH *path) { unsigned i; ASSERT(path); for (i = 0; i < _al_vector_size(&path->segments); ) { if (strcmp(get_segment_cstr(path, i), ".") == 0) al_remove_path_component(path, i); else i++; } /* Remove leading '..'s on absolute paths. */ if (_al_vector_size(&path->segments) >= 1 && al_ustr_size(get_segment(path, 0)) == 0) { while (_al_vector_size(&path->segments) >= 2 && strcmp(get_segment_cstr(path, 1), "..") == 0) { al_remove_path_component(path, 1); } } return true; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/memdraw.c0000644000175000001440000001010712147526552015005 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory bitmap drawing routines * * Based on Michael Bukin's C drawing functions. * * Conversion to the new API by Trent Gamblin. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_memdraw.h" typedef struct { float x[4]; } float4; void _al_draw_pixel_memory(ALLEGRO_BITMAP *bitmap, float x, float y, ALLEGRO_COLOR *color) { ALLEGRO_COLOR result; int ix, iy; /* * Probably not worth it to check for identity */ al_transform_coordinates(al_get_current_transform(), &x, &y); ix = (int)x; iy = (int)y; _al_blend_memory(color, bitmap, ix, iy, &result); _al_put_pixel(bitmap, ix, iy, result); } void _al_clear_bitmap_by_locking(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color) { ALLEGRO_LOCKED_REGION *lr; int x1, y1, w, h; int x, y; unsigned char *line_ptr; /* This function is not just used on memory bitmaps, but also on OpenGL * video bitmaps which are not the current target, or when locked. */ ASSERT(bitmap); ASSERT(bitmap->flags & (ALLEGRO_MEMORY_BITMAP | _ALLEGRO_INTERNAL_OPENGL)); x1 = bitmap->cl; y1 = bitmap->ct; w = bitmap->cr_excl - x1; h = bitmap->cb_excl - y1; if (w <= 0 || h <= 0) return; /* XXX what about pre-locked bitmaps? */ lr = al_lock_bitmap_region(bitmap, x1, y1, w, h, ALLEGRO_PIXEL_FORMAT_ANY, 0); if (!lr) return; /* Write a single pixel so we can get the raw value. */ _al_put_pixel(bitmap, x1, y1, *color); /* Fill in the region. */ line_ptr = lr->data; switch (lr->pixel_size) { case 2: { int pixel_value = bmp_read16(line_ptr); for (y = y1; y < y1 + h; y++) { if (pixel_value == 0) { /* fast path */ memset(line_ptr, 0, 2 * w); } else { uint16_t *data = (uint16_t *)line_ptr; for (x = 0; x < w; x++) { bmp_write16(data, pixel_value); data++; } } line_ptr += lr->pitch; } break; } case 3: { int pixel_value = READ3BYTES(line_ptr); for (y = y1; y < y1 + h; y++) { unsigned char *data = (unsigned char *)line_ptr; if (pixel_value == 0) { /* fast path */ memset(data, 0, 3 * w); } else { for (x = 0; x < w; x++) { WRITE3BYTES(data, pixel_value); data += 3; } } line_ptr += lr->pitch; } break; } case 4: { int pixel_value = bmp_read32(line_ptr); for (y = y1; y < y1 + h; y++) { uint32_t *data = (uint32_t *)line_ptr; /* Special casing pixel_value == 0 doesn't seem to make any * difference to speed, so don't bother. */ for (x = 0; x < w; x++) { bmp_write32(data, pixel_value); data++; } line_ptr += lr->pitch; } break; } case sizeof(float4): { float4 *data = (float4 *)line_ptr; float4 pixel_value = *data; for (y = y1; y < y1 + h; y++) { data = (float4 *)line_ptr; for (x = 0; x < w; x++) { *data = pixel_value; data++; } line_ptr += lr->pitch; } break; } default: ASSERT(false); break; } al_unlock_bitmap(bitmap); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/display_settings.c0000644000175000001440000010426711771527410016745 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Additional display settings (like multisample). * * Original code from AllegroGL. * * Heavily modified by Elias Pschernig. * * See readme.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_display.h" #include ALLEGRO_DEBUG_CHANNEL("display") /* Function: al_set_new_display_option */ void al_set_new_display_option(int option, int value, int importance) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; extras = _al_get_new_display_settings(); switch (importance) { case ALLEGRO_REQUIRE: extras->required |= (int64_t)1 << option; extras->suggested &= ~((int64_t)1 << option); break; case ALLEGRO_SUGGEST: extras->suggested |= (int64_t)1 << option; extras->required &= ~((int64_t)1 << option); break; case ALLEGRO_DONTCARE: extras->required &= ~((int64_t)1 << option); extras->suggested &= ~((int64_t)1 << option); break; } extras->settings[option] = value; } /* Function: al_get_new_display_option */ int al_get_new_display_option(int option, int *importance) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; extras = _al_get_new_display_settings(); if (extras->required & ((int64_t)1 << option)) { if (importance) *importance = ALLEGRO_REQUIRE; return extras->settings[option]; } if (extras->suggested & ((int64_t)1 << option)) { if (importance) *importance = ALLEGRO_SUGGEST; return extras->settings[option]; } if (importance) *importance = ALLEGRO_DONTCARE; return 0; } /* Function: al_get_display_option */ int al_get_display_option(ALLEGRO_DISPLAY *display, int option) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; extras = &display->extra_settings; return extras->settings[option]; } /* Function: al_reset_new_display_options */ void al_reset_new_display_options(void) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; extras = _al_get_new_display_settings(); _al_fill_display_settings(extras); } #define req ref->required #define sug ref->suggested /* _al_fill_display_settings() * Will fill in missing settings by 'guessing' what the user intended. */ void _al_fill_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) { int all_components = (1<settings[ALLEGRO_COLOR_SIZE] = ref->settings[ALLEGRO_RED_SIZE] + ref->settings[ALLEGRO_GREEN_SIZE] + ref->settings[ALLEGRO_BLUE_SIZE] + ref->settings[ALLEGRO_ALPHA_SIZE]; /* Round depth to 8 bits */ ref->settings[ALLEGRO_COLOR_SIZE] = (ref->settings[ALLEGRO_COLOR_SIZE] + 7) / 8; } /* If only some components were set, guess the others */ else if ((req | sug) & all_components) { int avg = ((req | sug) & (1<settings[ALLEGRO_RED_SIZE]: 0) + ((req | sug) & (1<settings[ALLEGRO_GREEN_SIZE]: 0) + ((req | sug) & (1<settings[ALLEGRO_BLUE_SIZE]: 0) + ((req | sug) & (1<settings[ALLEGRO_ALPHA_SIZE]: 0); int num = ((req | sug) & (1<settings[ALLEGRO_RED_SIZE] = avg; } if (((req | sug) & (1<settings[ALLEGRO_GREEN_SIZE] = avg; } if (((req | sug) & (1<settings[ALLEGRO_BLUE_SIZE] = avg; } if (((req | sug) & (1<settings[ALLEGRO_ALPHA_SIZE] = avg; } /* If color depth wasn't defined, figure it out */ if (((req | sug) & (1<settings[ALLEGRO_COLOR_SIZE], eds->settings[ALLEGRO_RED_SIZE], eds->settings[ALLEGRO_GREEN_SIZE], eds->settings[ALLEGRO_BLUE_SIZE], eds->settings[ALLEGRO_ALPHA_SIZE], eds->settings[ALLEGRO_DEPTH_SIZE], eds->settings[ALLEGRO_STENCIL_SIZE], eds->settings[ALLEGRO_ACC_RED_SIZE], eds->settings[ALLEGRO_ACC_RED_SIZE], eds->settings[ALLEGRO_ACC_RED_SIZE], eds->settings[ALLEGRO_ACC_RED_SIZE], eds->settings[ALLEGRO_SAMPLES], eds->settings[ALLEGRO_SAMPLE_BUFFERS]); } int _al_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) { int score = 0; debug_display_settings(eds); if (eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] != ref->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { if (req & (1<settings[ALLEGRO_VSYNC] != ref->settings[ALLEGRO_VSYNC]) { if (req & (1<settings[ALLEGRO_COLOR_SIZE] != ref->settings[ALLEGRO_COLOR_SIZE]) { if (req & (1<settings[ALLEGRO_COLOR_SIZE] < ref->settings[ALLEGRO_COLOR_SIZE]) score += (96 * eds->settings[ALLEGRO_COLOR_SIZE]) / ref->settings[ALLEGRO_COLOR_SIZE]; else score += 96 + 96 / (1 + eds->settings[ALLEGRO_COLOR_SIZE] - ref->settings[ALLEGRO_COLOR_SIZE]); } /* check colour component widths here and Allegro formatness */ if ((req & (1<settings[ALLEGRO_RED_SIZE] != ref->settings[ALLEGRO_RED_SIZE])) { ALLEGRO_DEBUG("Red depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_RED_SIZE] < ref->settings[ALLEGRO_RED_SIZE]) { score += (16 * eds->settings[ALLEGRO_RED_SIZE]) / ref->settings[ALLEGRO_RED_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_RED_SIZE] - ref->settings[ALLEGRO_RED_SIZE]); } } if ((req & (1<settings[ALLEGRO_GREEN_SIZE] != ref->settings[ALLEGRO_GREEN_SIZE])) { ALLEGRO_DEBUG("Green depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_GREEN_SIZE] < ref->settings[ALLEGRO_GREEN_SIZE]) { score += (16 * eds->settings[ALLEGRO_GREEN_SIZE]) / ref->settings[ALLEGRO_GREEN_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_GREEN_SIZE] - ref->settings[ALLEGRO_GREEN_SIZE]); } } if ((req & (1<settings[ALLEGRO_BLUE_SIZE] != ref->settings[ALLEGRO_BLUE_SIZE])) { ALLEGRO_DEBUG("Blue depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_BLUE_SIZE] < ref->settings[ALLEGRO_BLUE_SIZE]) { score += (16 * eds->settings[ALLEGRO_BLUE_SIZE]) / ref->settings[ALLEGRO_BLUE_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_BLUE_SIZE] - ref->settings[ALLEGRO_BLUE_SIZE]); } } if ((req & (1<settings[ALLEGRO_ALPHA_SIZE] != ref->settings[ALLEGRO_ALPHA_SIZE])) { ALLEGRO_DEBUG("Alpha depth requirement not met (%d instead of %d).\n", eds->settings[ALLEGRO_ALPHA_SIZE], ref->settings[ALLEGRO_ALPHA_SIZE]); return -1; } if (sug & (1<settings[ALLEGRO_ALPHA_SIZE] < ref->settings[ALLEGRO_ALPHA_SIZE]) { score += (16 * eds->settings[ALLEGRO_ALPHA_SIZE]) / ref->settings[ALLEGRO_ALPHA_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_ALPHA_SIZE] - ref->settings[ALLEGRO_ALPHA_SIZE]); } } if ((req & (1<settings[ALLEGRO_ACC_RED_SIZE] != ref->settings[ALLEGRO_ACC_RED_SIZE])) { ALLEGRO_DEBUG("Accumulator Red depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_ACC_RED_SIZE] < ref->settings[ALLEGRO_ACC_RED_SIZE]) { score += (16 * eds->settings[ALLEGRO_ACC_RED_SIZE]) / ref->settings[ALLEGRO_ACC_RED_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_RED_SIZE] - ref->settings[ALLEGRO_ACC_RED_SIZE]); } } if ((req & (1<settings[ALLEGRO_ACC_GREEN_SIZE] != ref->settings[ALLEGRO_ACC_GREEN_SIZE])) { ALLEGRO_DEBUG("Accumulator Green depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_ACC_GREEN_SIZE] < ref->settings[ALLEGRO_ACC_GREEN_SIZE]) { score += (16 * eds->settings[ALLEGRO_ACC_GREEN_SIZE]) / ref->settings[ALLEGRO_ACC_GREEN_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_GREEN_SIZE] - ref->settings[ALLEGRO_ACC_GREEN_SIZE]); } } if ((req & (1<settings[ALLEGRO_ACC_BLUE_SIZE] != ref->settings[ALLEGRO_ACC_BLUE_SIZE])) { ALLEGRO_DEBUG("Accumulator Blue depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_ACC_BLUE_SIZE] < ref->settings[ALLEGRO_ACC_BLUE_SIZE]) { score += (16 * eds->settings[ALLEGRO_ACC_BLUE_SIZE]) / ref->settings[ALLEGRO_ACC_BLUE_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_BLUE_SIZE] - ref->settings[ALLEGRO_ACC_BLUE_SIZE]); } } if ((req & (1<settings[ALLEGRO_ACC_ALPHA_SIZE] != ref->settings[ALLEGRO_ACC_ALPHA_SIZE])) { ALLEGRO_DEBUG("Accumulator Alpha depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_ACC_ALPHA_SIZE] < ref->settings[ALLEGRO_ACC_ALPHA_SIZE]) { score += (16 * eds->settings[ALLEGRO_ACC_ALPHA_SIZE]) / ref->settings[ALLEGRO_ACC_ALPHA_SIZE]; } else { score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_ALPHA_SIZE] - ref->settings[ALLEGRO_ACC_ALPHA_SIZE]); } } if (!eds->settings[ALLEGRO_SINGLE_BUFFER] != !ref->settings[ALLEGRO_SINGLE_BUFFER]) { if (req & (1<settings[ALLEGRO_STEREO] != !ref->settings[ALLEGRO_STEREO]) { if (req & (1<settings[ALLEGRO_AUX_BUFFERS] < ref->settings[ALLEGRO_AUX_BUFFERS])) { ALLEGRO_DEBUG("Aux Buffer requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_AUX_BUFFERS] < ref->settings[ALLEGRO_AUX_BUFFERS]) { score += (64 * eds->settings[ALLEGRO_AUX_BUFFERS]) / ref->settings[ALLEGRO_AUX_BUFFERS]; } else { score += 64 + 64 / (1 + eds->settings[ALLEGRO_AUX_BUFFERS] - ref->settings[ALLEGRO_AUX_BUFFERS]); } } if ((req & (1<settings[ALLEGRO_DEPTH_SIZE] != ref->settings[ALLEGRO_DEPTH_SIZE])) { ALLEGRO_DEBUG("Z-Buffer requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_DEPTH_SIZE] < ref->settings[ALLEGRO_DEPTH_SIZE]) { score += (64 * eds->settings[ALLEGRO_DEPTH_SIZE]) / ref->settings[ALLEGRO_DEPTH_SIZE]; } else { score += 64 + 64 / (1 + eds->settings[ALLEGRO_DEPTH_SIZE] - ref->settings[ALLEGRO_DEPTH_SIZE]); } } if ((req & (1<settings[ALLEGRO_STENCIL_SIZE] != ref->settings[ALLEGRO_STENCIL_SIZE])) { ALLEGRO_DEBUG("Stencil depth requirement not met.\n"); return -1; } if (sug & (1<settings[ALLEGRO_STENCIL_SIZE] < ref->settings[ALLEGRO_STENCIL_SIZE]) { score += (64 * eds->settings[ALLEGRO_STENCIL_SIZE]) / ref->settings[ALLEGRO_STENCIL_SIZE]; } else { score += 64 + 64 / (1 + eds->settings[ALLEGRO_STENCIL_SIZE] - ref->settings[ALLEGRO_STENCIL_SIZE]); } } if ((req & (1<settings[ALLEGRO_RENDER_METHOD] != ref->settings[ALLEGRO_RENDER_METHOD]) || (ref->settings[ALLEGRO_RENDER_METHOD] == 2))) { ALLEGRO_DEBUG("Render Method requirement not met.\n"); return -1; } if ((sug & (1<settings[ALLEGRO_RENDER_METHOD] == ref->settings[ALLEGRO_RENDER_METHOD])) { score += 1024; } else if (eds->settings[ALLEGRO_RENDER_METHOD] == 1) { score++; /* Add 1 for hw accel */ } if ((req & (1<settings[ALLEGRO_SAMPLE_BUFFERS] != ref->settings[ALLEGRO_SAMPLE_BUFFERS])) { ALLEGRO_DEBUG("Multisample Buffers requirement not met\n"); return -1; } else if (sug & (1<settings[ALLEGRO_SAMPLE_BUFFERS] == ref->settings[ALLEGRO_SAMPLE_BUFFERS]) { score += 128; } } if ((req & (1<settings[ALLEGRO_SAMPLES] != ref->settings[ALLEGRO_SAMPLES])) { ALLEGRO_DEBUG("Multisample Samples requirement not met\n"); return -1; } if (sug & (1<settings[ALLEGRO_SAMPLES] < ref->settings[ALLEGRO_SAMPLES]) { score += (64 * eds->settings[ALLEGRO_SAMPLES]) / ref->settings[ALLEGRO_SAMPLES]; } else { score += 64 + 64 / (1 + eds->settings[ALLEGRO_SAMPLES] - ref->settings[ALLEGRO_SAMPLES]); } } if (!eds->settings[ALLEGRO_FLOAT_COLOR] != !ref->settings[ALLEGRO_FLOAT_COLOR]) { if (req & (1<settings[ALLEGRO_FLOAT_DEPTH] != !ref->settings[ALLEGRO_FLOAT_DEPTH]) { if (req & (1<score == f1->score) { if (f0->index < f1->index) return -1; else return 1; } else if (f0->score > f1->score) { return -1; } else { return 1; } } int _al_deduce_color_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) { /* dummy value to check if the format was detected */ int format = ALLEGRO_PIXEL_FORMAT_ANY; if (eds->settings[ALLEGRO_RED_SIZE] == 8 && eds->settings[ALLEGRO_GREEN_SIZE] == 8 && eds->settings[ALLEGRO_BLUE_SIZE] == 8) { if (eds->settings[ALLEGRO_ALPHA_SIZE] == 8 && eds->settings[ALLEGRO_COLOR_SIZE] == 32) { if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 0 && eds->settings[ALLEGRO_BLUE_SHIFT] == 8 && eds->settings[ALLEGRO_GREEN_SHIFT] == 16 && eds->settings[ALLEGRO_RED_SHIFT] == 24) { format = ALLEGRO_PIXEL_FORMAT_RGBA_8888; } else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 24 && eds->settings[ALLEGRO_RED_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; } else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 24 && eds->settings[ALLEGRO_RED_SHIFT] == 16 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_BLUE_SHIFT] == 0) { format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; } } else if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0 && eds->settings[ALLEGRO_COLOR_SIZE] == 24) { if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_RED_SHIFT] == 16) { format = ALLEGRO_PIXEL_FORMAT_RGB_888; } else if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { format = ALLEGRO_PIXEL_FORMAT_BGR_888; } } else if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0 && eds->settings[ALLEGRO_COLOR_SIZE] == 32) { if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_RED_SHIFT] == 16) { format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; } else if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { format = ALLEGRO_PIXEL_FORMAT_XBGR_8888; } else if (eds->settings[ALLEGRO_RED_SHIFT] == 24 && eds->settings[ALLEGRO_GREEN_SHIFT] == 16 && eds->settings[ALLEGRO_BLUE_SHIFT] == 8) { format = ALLEGRO_PIXEL_FORMAT_RGBX_8888; } } } else if (eds->settings[ALLEGRO_RED_SIZE] == 5 && eds->settings[ALLEGRO_GREEN_SIZE] == 6 && eds->settings[ALLEGRO_BLUE_SIZE] == 5) { if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && eds->settings[ALLEGRO_BLUE_SHIFT] == 11) { format = ALLEGRO_PIXEL_FORMAT_BGR_565; } else if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && eds->settings[ALLEGRO_RED_SHIFT] == 11) { format = ALLEGRO_PIXEL_FORMAT_RGB_565; } } else if (eds->settings[ALLEGRO_RED_SIZE] == 5 && eds->settings[ALLEGRO_GREEN_SIZE] == 5 && eds->settings[ALLEGRO_BLUE_SIZE] == 5) { if (eds->settings[ALLEGRO_ALPHA_SIZE] == 1 && eds->settings[ALLEGRO_COLOR_SIZE] == 16) { if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 0 && eds->settings[ALLEGRO_BLUE_SHIFT] == 1 && eds->settings[ALLEGRO_GREEN_SHIFT] == 6 && eds->settings[ALLEGRO_RED_SHIFT] == 11) { format = ALLEGRO_PIXEL_FORMAT_RGBA_5551; } if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 15 && eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && eds->settings[ALLEGRO_RED_SHIFT] == 10) { format = ALLEGRO_PIXEL_FORMAT_ARGB_1555; } } } else if (eds->settings[ALLEGRO_RED_SIZE] == 4 && eds->settings[ALLEGRO_GREEN_SIZE] == 4 && eds->settings[ALLEGRO_BLUE_SIZE] == 4) { if (eds->settings[ALLEGRO_ALPHA_SIZE] == 4 && eds->settings[ALLEGRO_COLOR_SIZE] == 16) { if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 12 && eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && eds->settings[ALLEGRO_GREEN_SHIFT] == 4 && eds->settings[ALLEGRO_RED_SHIFT] == 8) { format = ALLEGRO_PIXEL_FORMAT_ARGB_4444; } else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 12 && eds->settings[ALLEGRO_BLUE_SHIFT] == 8 && eds->settings[ALLEGRO_GREEN_SHIFT] == 4 && eds->settings[ALLEGRO_RED_SHIFT] == 0) { format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; } } } if (format == ALLEGRO_PIXEL_FORMAT_ANY) { ALLEGRO_WARN( "Could not deduce color format, sizes = (%d,%d,%d,%d,%d), shifts = (%d,%d,%d,%d)\n", eds->settings[ALLEGRO_RED_SIZE], eds->settings[ALLEGRO_GREEN_SIZE], eds->settings[ALLEGRO_BLUE_SIZE], eds->settings[ALLEGRO_ALPHA_SIZE], eds->settings[ALLEGRO_COLOR_SIZE], eds->settings[ALLEGRO_RED_SHIFT], eds->settings[ALLEGRO_GREEN_SHIFT], eds->settings[ALLEGRO_BLUE_SHIFT], eds->settings[ALLEGRO_ALPHA_SHIFT]); } return format; } void _al_set_color_components(int format, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, int importance) { ALLEGRO_EXTRA_DISPLAY_SETTINGS old_eds; memcpy(&old_eds, _al_get_new_display_settings(), sizeof(old_eds)); _al_set_new_display_settings(eds); al_set_new_display_option(ALLEGRO_RED_SIZE, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_GREEN_SIZE, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_BLUE_SIZE, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, ALLEGRO_DONTCARE); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 0, ALLEGRO_DONTCARE); switch (format) { case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); break; case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); break; case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 1, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 24, importance); break; case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: /* With OpenGL drivers, we never "know" the actual pixel * format. We use glReadPixels when we lock the screen, so * we can always lock the screen in any format we want. There * is no "display format". * * Therefore it makes no sense to fail display creation * if either an RGB or RGBX format was requested but the * other seems available only in WGL/GLX (those really report * the number of bits used for red/green/blue/alpha to us only. * They never report any "X bits".). */ al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, ALLEGRO_SUGGEST); break; case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); break; } switch (format) { case ALLEGRO_PIXEL_FORMAT_RGBA_8888: case ALLEGRO_PIXEL_FORMAT_ABGR_8888: case ALLEGRO_PIXEL_FORMAT_ARGB_8888: case ALLEGRO_PIXEL_FORMAT_RGB_888: case ALLEGRO_PIXEL_FORMAT_BGR_888: case ALLEGRO_PIXEL_FORMAT_RGBX_8888: case ALLEGRO_PIXEL_FORMAT_XRGB_8888: case ALLEGRO_PIXEL_FORMAT_XBGR_8888: al_set_new_display_option(ALLEGRO_RED_SIZE, 8, importance); al_set_new_display_option(ALLEGRO_GREEN_SIZE, 8, importance); al_set_new_display_option(ALLEGRO_BLUE_SIZE, 8, importance); break; case ALLEGRO_PIXEL_FORMAT_BGR_565: case ALLEGRO_PIXEL_FORMAT_RGB_565: al_set_new_display_option(ALLEGRO_RED_SIZE, 5, importance); al_set_new_display_option(ALLEGRO_GREEN_SIZE, 6, importance); al_set_new_display_option(ALLEGRO_BLUE_SIZE, 5, importance); break; case ALLEGRO_PIXEL_FORMAT_RGBA_5551: case ALLEGRO_PIXEL_FORMAT_ARGB_1555: al_set_new_display_option(ALLEGRO_RED_SIZE, 5, importance); al_set_new_display_option(ALLEGRO_GREEN_SIZE, 5, importance); al_set_new_display_option(ALLEGRO_BLUE_SIZE, 5, importance); break; case ALLEGRO_PIXEL_FORMAT_ARGB_4444: case ALLEGRO_PIXEL_FORMAT_RGBA_4444: al_set_new_display_option(ALLEGRO_RED_SIZE, 4, importance); al_set_new_display_option(ALLEGRO_GREEN_SIZE, 4, importance); al_set_new_display_option(ALLEGRO_BLUE_SIZE, 4, importance); break; } switch (format) { case ALLEGRO_PIXEL_FORMAT_RGBA_8888: case ALLEGRO_PIXEL_FORMAT_ABGR_8888: case ALLEGRO_PIXEL_FORMAT_ARGB_8888: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); break; case ALLEGRO_PIXEL_FORMAT_RGB_888: case ALLEGRO_PIXEL_FORMAT_BGR_888: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 24, importance); break; case ALLEGRO_PIXEL_FORMAT_RGBX_8888: case ALLEGRO_PIXEL_FORMAT_XRGB_8888: case ALLEGRO_PIXEL_FORMAT_XBGR_8888: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); break; case ALLEGRO_PIXEL_FORMAT_BGR_565: case ALLEGRO_PIXEL_FORMAT_RGB_565: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_RGBA_5551: case ALLEGRO_PIXEL_FORMAT_ARGB_1555: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 1, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_ARGB_4444: case ALLEGRO_PIXEL_FORMAT_RGBA_4444: al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 4, importance); al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); break; } switch (format) { case ALLEGRO_PIXEL_FORMAT_RGBA_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 24, importance); break; case ALLEGRO_PIXEL_FORMAT_ABGR_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); break; case ALLEGRO_PIXEL_FORMAT_ARGB_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_RGB_888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_BGR_888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); break; case ALLEGRO_PIXEL_FORMAT_XRGB_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); break; case ALLEGRO_PIXEL_FORMAT_RGBX_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 24, importance); break; case ALLEGRO_PIXEL_FORMAT_XBGR_8888: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); break; case ALLEGRO_PIXEL_FORMAT_BGR_565: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 11, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); break; case ALLEGRO_PIXEL_FORMAT_RGB_565: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 11, importance); break; case ALLEGRO_PIXEL_FORMAT_RGBA_5551: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 1, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 6, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 11, importance); break; case ALLEGRO_PIXEL_FORMAT_ARGB_1555: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 15, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 10, importance); break; case ALLEGRO_PIXEL_FORMAT_ARGB_4444: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 12, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 4, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); case ALLEGRO_PIXEL_FORMAT_RGBA_4444: al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 12, importance); al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 4, importance); al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); break; } memcpy(eds, _al_get_new_display_settings(), sizeof(*eds)); _al_set_new_display_settings(&old_eds); } allegro-5.0.10/src/bitmap_pixel.c0000644000175000001440000000727412125154244016030 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Bitmap pixel manipulation. * * See LICENSE.txt for copyright information. */ #include /* for memset */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_pixels.h" ALLEGRO_DEBUG_CHANNEL("bitmap") /* Function: al_get_pixel */ ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y) { ALLEGRO_LOCKED_REGION *lr; char *data; ALLEGRO_COLOR color; if (bitmap->parent) { x += bitmap->xofs; y += bitmap->yofs; bitmap = bitmap->parent; } if (bitmap->locked) { x -= bitmap->lock_x; y -= bitmap->lock_y; if (x < 0 || y < 0 || x >= bitmap->lock_w || y >= bitmap->lock_h) { ALLEGRO_ERROR("Out of bounds."); memset(&color, 0, sizeof(ALLEGRO_COLOR)); return color; } data = bitmap->locked_region.data; data += y * bitmap->locked_region.pitch; data += x * al_get_pixel_size(bitmap->locked_region.format); _AL_INLINE_GET_PIXEL(bitmap->locked_region.format, data, color, false); } else { /* FIXME: must use clip not full bitmap */ if (x < 0 || y < 0 || x >= bitmap->w || y >= bitmap->h) { memset(&color, 0, sizeof(ALLEGRO_COLOR)); return color; } if (!(lr = al_lock_bitmap_region(bitmap, x, y, 1, 1, bitmap->format, ALLEGRO_LOCK_READONLY))) { memset(&color, 0, sizeof(ALLEGRO_COLOR)); return color; } /* FIXME: check for valid pixel format */ data = lr->data; _AL_INLINE_GET_PIXEL(bitmap->format, data, color, false); al_unlock_bitmap(bitmap); } return color; } void _al_put_pixel(ALLEGRO_BITMAP *bitmap, int x, int y, ALLEGRO_COLOR color) { ALLEGRO_LOCKED_REGION *lr; char *data; if (bitmap->parent) { x += bitmap->xofs; y += bitmap->yofs; bitmap = bitmap->parent; } if (x < bitmap->cl || y < bitmap->ct || x >= bitmap->cr_excl || y >= bitmap->cb_excl) { return; } if (bitmap->locked) { x -= bitmap->lock_x; y -= bitmap->lock_y; if (x < 0 || y < 0 || x >= bitmap->lock_w || y >= bitmap->lock_h) { return; } data = bitmap->locked_region.data; data += y * bitmap->locked_region.pitch; data += x * al_get_pixel_size(bitmap->locked_region.format); _AL_INLINE_PUT_PIXEL(bitmap->locked_region.format, data, color, false); } else { lr = al_lock_bitmap_region(bitmap, x, y, 1, 1, bitmap->format, ALLEGRO_LOCK_WRITEONLY); if (!lr) return; /* FIXME: check for valid pixel format */ data = lr->data; _AL_INLINE_PUT_PIXEL(bitmap->format, data, color, false); al_unlock_bitmap(bitmap); } } /* Function: al_put_pixel */ void al_put_pixel(int x, int y, ALLEGRO_COLOR color) { _al_put_pixel(al_get_target_bitmap(), x, y, color); } /* Function: al_put_blended_pixel */ void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color) { ALLEGRO_COLOR result; ALLEGRO_BITMAP* bitmap = al_get_target_bitmap(); _al_blend_memory(&color, bitmap, x, y, &result); _al_put_pixel(bitmap, x, y, result); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/exitfunc.c0000644000175000001440000000435012125160224015163 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * List of functions to call at program cleanup. * * By Shawn Hargreaves. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_exitfunc.h" /* dynamic registration system for cleanup code */ struct al_exit_func { void (*funcptr)(void); const char *desc; struct al_exit_func *next; }; static struct al_exit_func *exit_func_list = NULL; /* _al_add_exit_func: * Adds a function to the list that need to be called on Allegro shutdown. * `desc' should point to a statically allocated string to help with * debugging. */ void _al_add_exit_func(void (*func)(void), const char *desc) { struct al_exit_func *n; for (n = exit_func_list; n; n = n->next) if (n->funcptr == func) return; n = al_malloc(sizeof(struct al_exit_func)); if (!n) return; n->next = exit_func_list; n->funcptr = func; n->desc = desc; exit_func_list = n; } /* _al_remove_exit_func: * Removes a function from the list that need to be called on Allegro * shutdown. */ void _al_remove_exit_func(void (*func)(void)) { struct al_exit_func *iter = exit_func_list, *prev = NULL; while (iter) { if (iter->funcptr == func) { if (prev) prev->next = iter->next; else exit_func_list = iter->next; al_free(iter); return; } prev = iter; iter = iter->next; } } /* _al_run_exit_funcs: * Run all the functions registered with _al_add_exit_func, in reverse order of * registration. */ void _al_run_exit_funcs(void) { while (exit_func_list) { void (*func)(void) = exit_func_list->funcptr; _al_remove_exit_func(func); (*func)(); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/src/mouse_cursor.c0000644000175000001440000000537512057122717016104 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Mouse cursors. * * See LICENSE.txt for copyright information. */ #include "allegro5/allegro.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_system.h" /* Function: al_create_mouse_cursor */ ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus) { ALLEGRO_SYSTEM *sysdrv = al_get_system_driver(); ASSERT(bmp); ASSERT(sysdrv->vt->create_mouse_cursor); return sysdrv->vt->create_mouse_cursor(bmp, x_focus, y_focus); } /* Function: al_destroy_mouse_cursor */ void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_SYSTEM *sysdrv; if (!cursor) { return; } sysdrv = al_get_system_driver(); ASSERT(sysdrv->vt->destroy_mouse_cursor); sysdrv->vt->destroy_mouse_cursor(cursor); } /* Function: al_set_mouse_cursor */ bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { if (!cursor) { return false; } if (display) { ASSERT(display->vt->set_mouse_cursor); return display->vt->set_mouse_cursor(display, cursor); } return false; } /* Function: al_set_system_mouse_cursor */ bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) { /* XXX should you be able to set ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE? */ ASSERT(cursor_id > ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE); ASSERT(cursor_id < ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS); ASSERT(display); if (cursor_id <= ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE) { return false; } if (cursor_id > ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS) { return false; } if (!display) { return false; } ASSERT(display->vt->set_system_mouse_cursor); return display->vt->set_system_mouse_cursor(display, cursor_id); } /* Function: al_show_mouse_cursor */ bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display) { if (display) { ASSERT(display->vt->show_mouse_cursor); return display->vt->show_mouse_cursor(display); } return false; } /* Function: al_hide_mouse_cursor */ bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display) { if (display) { ASSERT(display->vt->hide_mouse_cursor); return display->vt->hide_mouse_cursor(display); } return false; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/0000755000175000001440000000000012157230515014032 5ustar tjadenusersallegro-5.0.10/include/allegro5/0000755000175000001440000000000012157230744015550 5ustar tjadenusersallegro-5.0.10/include/allegro5/mouse_cursor.h0000644000175000001440000000402112057357022020441 0ustar tjadenusers#ifndef __al_included_allegro5_mouse_cursor_h #define __al_included_allegro5_mouse_cursor_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_MOUSE_CURSOR ALLEGRO_MOUSE_CURSOR; typedef enum ALLEGRO_SYSTEM_MOUSE_CURSOR { ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE = 0, ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT = 1, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW = 2, ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY = 3, ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION = 4, ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT = 5, ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE = 6, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N = 7, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W = 8, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S = 9, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E = 10, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW = 11, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW = 12, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE = 13, ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE = 14, ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS = 15, ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION = 16, ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK = 17, ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT = 18, ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE = 19, ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS } ALLEGRO_SYSTEM_MOUSE_CURSOR; struct ALLEGRO_BITMAP; struct ALLEGRO_DISPLAY; AL_FUNC(ALLEGRO_MOUSE_CURSOR *, al_create_mouse_cursor, ( struct ALLEGRO_BITMAP *sprite, int xfocus, int yfocus)); AL_FUNC(void, al_destroy_mouse_cursor, (ALLEGRO_MOUSE_CURSOR *)); AL_FUNC(bool, al_set_mouse_cursor, (struct ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor)); AL_FUNC(bool, al_set_system_mouse_cursor, (struct ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)); AL_FUNC(bool, al_show_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); AL_FUNC(bool, al_hide_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/path.h0000644000175000001440000000406011771527476016671 0ustar tjadenusers#ifndef __al_included_allegro5_path_h #define __al_included_allegro5_path_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif #ifdef ALLEGRO_WINDOWS # define ALLEGRO_NATIVE_PATH_SEP '\\' # define ALLEGRO_NATIVE_DRIVE_SEP ':' #else # define ALLEGRO_NATIVE_PATH_SEP '/' # define ALLEGRO_NATIVE_DRIVE_SEP '\0' #endif typedef struct ALLEGRO_PATH ALLEGRO_PATH; AL_FUNC(ALLEGRO_PATH*, al_create_path, (const char *str)); AL_FUNC(ALLEGRO_PATH*, al_create_path_for_directory, (const char *str)); AL_FUNC(ALLEGRO_PATH*, al_clone_path, (const ALLEGRO_PATH *path)); AL_FUNC(int, al_get_path_num_components, (const ALLEGRO_PATH *path)); AL_FUNC(const char*, al_get_path_component, (const ALLEGRO_PATH *path, int i)); AL_FUNC(void, al_replace_path_component, (ALLEGRO_PATH *path, int i, const char *s)); AL_FUNC(void, al_remove_path_component, (ALLEGRO_PATH *path, int i)); AL_FUNC(void, al_insert_path_component, (ALLEGRO_PATH *path, int i, const char *s)); AL_FUNC(const char*, al_get_path_tail, (const ALLEGRO_PATH *path)); AL_FUNC(void, al_drop_path_tail, (ALLEGRO_PATH *path)); AL_FUNC(void, al_append_path_component, (ALLEGRO_PATH *path, const char *s)); AL_FUNC(bool, al_join_paths, (ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)); AL_FUNC(bool, al_rebase_path, (const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)); AL_FUNC(const char*, al_path_cstr, (const ALLEGRO_PATH *path, char delim)); AL_FUNC(void, al_destroy_path, (ALLEGRO_PATH *path)); AL_FUNC(void, al_set_path_drive, (ALLEGRO_PATH *path, const char *drive)); AL_FUNC(const char*, al_get_path_drive, (const ALLEGRO_PATH *path)); AL_FUNC(void, al_set_path_filename, (ALLEGRO_PATH *path, const char *filename)); AL_FUNC(const char*, al_get_path_filename, (const ALLEGRO_PATH *path)); AL_FUNC(const char*, al_get_path_extension, (const ALLEGRO_PATH *path)); AL_FUNC(bool, al_set_path_extension, (ALLEGRO_PATH *path, char const *extension)); AL_FUNC(const char*, al_get_path_basename, (const ALLEGRO_PATH *path)); AL_FUNC(bool, al_make_path_canonical, (ALLEGRO_PATH *path)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/fmaths.h0000644000175000001440000000225011426530515017177 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Fixed point math routines. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_fmaths_h #define __al_included_allegro5_fmaths_h #include "allegro5/base.h" #include "allegro5/fixed.h" #ifdef __cplusplus extern "C" { #endif AL_FUNC(al_fixed, al_fixsqrt, (al_fixed x)); AL_FUNC(al_fixed, al_fixhypot, (al_fixed x, al_fixed y)); AL_FUNC(al_fixed, al_fixatan, (al_fixed x)); AL_FUNC(al_fixed, al_fixatan2, (al_fixed y, al_fixed x)); AL_ARRAY(al_fixed, _al_fix_cos_tbl); AL_ARRAY(al_fixed, _al_fix_tan_tbl); AL_ARRAY(al_fixed, _al_fix_acos_tbl); #ifdef __cplusplus } #endif #include "allegro5/inline/fmaths.inl" #endif allegro-5.0.10/include/allegro5/transformations.h0000644000175000001440000000251012057357022021146 0ustar tjadenusers#ifndef __al_included_allegro5_transformations_h #define __al_included_allegro5_transformations_h #include "allegro5/display.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_TRANSFORM */ typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM; struct ALLEGRO_TRANSFORM { float m[4][4]; }; /* Transformations*/ AL_FUNC(void, al_use_transform, (const ALLEGRO_TRANSFORM* trans)); AL_FUNC(void, al_copy_transform, (ALLEGRO_TRANSFORM* dest, const ALLEGRO_TRANSFORM* src)); AL_FUNC(void, al_identity_transform, (ALLEGRO_TRANSFORM* trans)); AL_FUNC(void, al_build_transform, (ALLEGRO_TRANSFORM* trans, float x, float y, float sx, float sy, float theta)); AL_FUNC(void, al_translate_transform, (ALLEGRO_TRANSFORM* trans, float x, float y)); AL_FUNC(void, al_rotate_transform, (ALLEGRO_TRANSFORM* trans, float theta)); AL_FUNC(void, al_scale_transform, (ALLEGRO_TRANSFORM* trans, float sx, float sy)); AL_FUNC(void, al_transform_coordinates, (const ALLEGRO_TRANSFORM* trans, float* x, float* y)); AL_FUNC(void, al_compose_transform, (ALLEGRO_TRANSFORM* trans, const ALLEGRO_TRANSFORM* other)); AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_transform, (void)); AL_FUNC(void, al_invert_transform, (ALLEGRO_TRANSFORM *trans)); AL_FUNC(int, al_check_inverse, (const ALLEGRO_TRANSFORM *trans, float tol)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/bitmap_io.h0000644000175000001440000000244511426530515017666 0ustar tjadenusers#ifndef __al_included_allegro5_bitmap_io_h #define __al_included_allegro5_bitmap_io_h #include "allegro5/bitmap.h" #include "allegro5/file.h" #ifdef __cplusplus extern "C" { #endif typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_LOADER_FUNCTION)(const char *filename); typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_FS_LOADER_FUNCTION)(ALLEGRO_FILE *fp); typedef bool (*ALLEGRO_IIO_SAVER_FUNCTION)(const char *filename, ALLEGRO_BITMAP *bitmap); typedef bool (*ALLEGRO_IIO_FS_SAVER_FUNCTION)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bitmap); AL_FUNC(bool, al_register_bitmap_loader, (const char *ext, ALLEGRO_IIO_LOADER_FUNCTION loader)); AL_FUNC(bool, al_register_bitmap_saver, (const char *ext, ALLEGRO_IIO_SAVER_FUNCTION saver)); AL_FUNC(bool, al_register_bitmap_loader_f, (const char *ext, ALLEGRO_IIO_FS_LOADER_FUNCTION fs_loader)); AL_FUNC(bool, al_register_bitmap_saver_f, (const char *ext, ALLEGRO_IIO_FS_SAVER_FUNCTION fs_saver)); AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap, (const char *filename)); AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_f, (ALLEGRO_FILE *fp, const char *ident)); AL_FUNC(bool, al_save_bitmap, (const char *filename, ALLEGRO_BITMAP *bitmap)); AL_FUNC(bool, al_save_bitmap_f, (ALLEGRO_FILE *fp, const char *ident, ALLEGRO_BITMAP *bitmap)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/fullscreen_mode.h0000644000175000001440000000102512057113157021062 0ustar tjadenusers#ifndef __al_included_allegro5_fullscreen_mode_h #define __al_included_allegro5_fullscreen_mode_h #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_DISPLAY_MODE */ typedef struct ALLEGRO_DISPLAY_MODE { int width; int height; int format; int refresh_rate; } ALLEGRO_DISPLAY_MODE; AL_FUNC(int, al_get_num_display_modes, (void)); AL_FUNC(ALLEGRO_DISPLAY_MODE*, al_get_display_mode, (int index, ALLEGRO_DISPLAY_MODE *mode)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/file.h0000644000175000001440000000713511721431531016637 0ustar tjadenusers#ifndef __al_included_allegro5_file_h #define __al_included_allegro5_file_h #include "allegro5/base.h" #include "allegro5/path.h" #include "allegro5/utf8.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_FILE */ typedef struct ALLEGRO_FILE ALLEGRO_FILE; /* Type: ALLEGRO_FILE_INTERFACE */ typedef struct ALLEGRO_FILE_INTERFACE { AL_METHOD(void *, fi_fopen, (const char *path, const char *mode)); AL_METHOD(void, fi_fclose, (ALLEGRO_FILE *handle)); AL_METHOD(size_t, fi_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); AL_METHOD(size_t, fi_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); AL_METHOD(bool, fi_fflush, (ALLEGRO_FILE *f)); AL_METHOD(int64_t, fi_ftell, (ALLEGRO_FILE *f)); AL_METHOD(bool, fi_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); AL_METHOD(bool, fi_feof, (ALLEGRO_FILE *f)); AL_METHOD(bool, fi_ferror, (ALLEGRO_FILE *f)); AL_METHOD(void, fi_fclearerr, (ALLEGRO_FILE *f)); AL_METHOD(int, fi_fungetc, (ALLEGRO_FILE *f, int c)); AL_METHOD(off_t, fi_fsize, (ALLEGRO_FILE *f)); } ALLEGRO_FILE_INTERFACE; /* Enum: ALLEGRO_SEEK */ typedef enum ALLEGRO_SEEK { ALLEGRO_SEEK_SET = 0, ALLEGRO_SEEK_CUR, ALLEGRO_SEEK_END } ALLEGRO_SEEK; /* The basic operations. */ AL_FUNC(ALLEGRO_FILE*, al_fopen, (const char *path, const char *mode)); AL_FUNC(ALLEGRO_FILE*, al_fopen_interface, (const ALLEGRO_FILE_INTERFACE *vt, const char *path, const char *mode)); AL_FUNC(ALLEGRO_FILE*, al_create_file_handle, (const ALLEGRO_FILE_INTERFACE *vt, void *userdata)); AL_FUNC(void, al_fclose, (ALLEGRO_FILE *f)); AL_FUNC(size_t, al_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); AL_FUNC(size_t, al_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); AL_FUNC(bool, al_fflush, (ALLEGRO_FILE *f)); AL_FUNC(int64_t, al_ftell, (ALLEGRO_FILE *f)); AL_FUNC(bool, al_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); AL_FUNC(bool, al_feof, (ALLEGRO_FILE *f)); AL_FUNC(bool, al_ferror, (ALLEGRO_FILE *f)); AL_FUNC(void, al_fclearerr, (ALLEGRO_FILE *f)); AL_FUNC(int, al_fungetc, (ALLEGRO_FILE *f, int c)); AL_FUNC(int64_t, al_fsize, (ALLEGRO_FILE *f)); /* Convenience functions. */ AL_FUNC(int, al_fgetc, (ALLEGRO_FILE *f)); AL_FUNC(int, al_fputc, (ALLEGRO_FILE *f, int c)); AL_FUNC(int16_t, al_fread16le, (ALLEGRO_FILE *f)); AL_FUNC(int16_t, al_fread16be, (ALLEGRO_FILE *f)); AL_FUNC(size_t, al_fwrite16le, (ALLEGRO_FILE *f, int16_t w)); AL_FUNC(size_t, al_fwrite16be, (ALLEGRO_FILE *f, int16_t w)); AL_FUNC(int32_t, al_fread32le, (ALLEGRO_FILE *f)); AL_FUNC(int32_t, al_fread32be, (ALLEGRO_FILE *f)); AL_FUNC(size_t, al_fwrite32le, (ALLEGRO_FILE *f, int32_t l)); AL_FUNC(size_t, al_fwrite32be, (ALLEGRO_FILE *f, int32_t l)); AL_FUNC(char*, al_fgets, (ALLEGRO_FILE *f, char * const p, size_t max)); AL_FUNC(ALLEGRO_USTR *, al_fget_ustr, (ALLEGRO_FILE *f)); AL_FUNC(int, al_fputs, (ALLEGRO_FILE *f, const char *p)); /* Specific to stdio backend. */ AL_FUNC(ALLEGRO_FILE*, al_fopen_fd, (int fd, const char *mode)); AL_FUNC(ALLEGRO_FILE*, al_make_temp_file, (const char *tmpl, ALLEGRO_PATH **ret_path)); /* Specific to slices. */ AL_FUNC(ALLEGRO_FILE*, al_fopen_slice, (ALLEGRO_FILE *fp, size_t initial_size, const char *mode)); /* Thread-local state. */ AL_FUNC(const ALLEGRO_FILE_INTERFACE *, al_get_new_file_interface, (void)); AL_FUNC(void, al_set_new_file_interface, (const ALLEGRO_FILE_INTERFACE * file_interface)); AL_FUNC(void, al_set_standard_file_interface, (void)); /* ALLEGRO_FILE field accessors */ AL_FUNC(void *, al_get_file_userdata, (ALLEGRO_FILE *f)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/base.h0000644000175000001440000000506612157230515016636 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Base header, defines basic stuff needed by pretty much * everything else. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_base_h #define __al_included_allegro5_base_h #ifndef ALLEGRO_NO_STD_HEADERS #include #ifdef _MSC_VER /* enable posix for limits.h and only limits.h enabling it for all msvc headers will potentially disable a lot of commonly used msvcrt functions */ #define _POSIX_ #include #undef _POSIX_ #else #include #endif #include #include #include #include #include #include #endif #if (defined DEBUGMODE) && (defined FORTIFY) #include #endif #if (defined DEBUGMODE) && (defined DMALLOC) #include #endif #include "allegro5/internal/alconfig.h" #ifdef __cplusplus extern "C" { #endif #define ALLEGRO_VERSION 5 #define ALLEGRO_SUB_VERSION 0 #define ALLEGRO_WIP_VERSION 10 /* Not sure we need it, but since ALLEGRO_VERSION_STR contains it: * 0 = SVN * 1 = first release * 2... = hotfixes? * * Note x.y.z (= x.y.z.0) has release number 1, and x.y.z.1 has release * number 2, just to confuse you. */ #define ALLEGRO_RELEASE_NUMBER 1 #define ALLEGRO_VERSION_STR "5.0.10" #define ALLEGRO_DATE_STR "2013" #define ALLEGRO_DATE 20130616 /* yyyymmdd */ #define ALLEGRO_VERSION_INT \ ((ALLEGRO_VERSION << 24) | (ALLEGRO_SUB_VERSION << 16) | \ (ALLEGRO_WIP_VERSION << 8) | ALLEGRO_RELEASE_NUMBER) AL_FUNC(uint32_t, al_get_allegro_version, (void)); AL_FUNC(int, al_run_main, (int argc, char **argv, int (*)(int, char **))); /*******************************************/ /************ Some global stuff ************/ /*******************************************/ /* Type: ALLEGRO_PI */ #define ALLEGRO_PI 3.14159265358979323846 #define AL_ID(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/mouse.h0000644000175000001440000000510312057357022017046 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Mouse routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_mouse_h #define __al_included_allegro5_mouse_h #include "allegro5/base.h" #include "allegro5/events.h" #ifdef __cplusplus extern "C" { #endif /* Allow up to four extra axes for future expansion. */ #define ALLEGRO_MOUSE_MAX_EXTRA_AXES 4 typedef struct ALLEGRO_MOUSE ALLEGRO_MOUSE; /* Type: ALLEGRO_MOUSE_STATE */ typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE; struct ALLEGRO_MOUSE_STATE { /* (x, y) Primary mouse position * (z) Mouse wheel position (1D 'wheel'), or, * (w, z) Mouse wheel position (2D 'ball') * display - the display the mouse is on (coordinates are relative to this) * pressure - the pressure appleid to the mouse (for stylus/tablet) */ int x; int y; int z; int w; int more_axes[ALLEGRO_MOUSE_MAX_EXTRA_AXES]; int buttons; float pressure; struct ALLEGRO_DISPLAY *display; }; AL_FUNC(bool, al_is_mouse_installed, (void)); AL_FUNC(bool, al_install_mouse, (void)); AL_FUNC(void, al_uninstall_mouse, (void)); AL_FUNC(unsigned int, al_get_mouse_num_buttons, (void)); AL_FUNC(unsigned int, al_get_mouse_num_axes, (void)); AL_FUNC(bool, al_set_mouse_xy, (struct ALLEGRO_DISPLAY *display, int x, int y)); AL_FUNC(bool, al_set_mouse_z, (int z)); AL_FUNC(bool, al_set_mouse_w, (int w)); AL_FUNC(bool, al_set_mouse_axis, (int axis, int value)); AL_FUNC(void, al_get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); AL_FUNC(bool, al_mouse_button_down, (const ALLEGRO_MOUSE_STATE *state, int button)); AL_FUNC(int, al_get_mouse_state_axis, (const ALLEGRO_MOUSE_STATE *state, int axis)); AL_FUNC(bool, al_get_mouse_cursor_position, (int *ret_x, int *ret_y)); AL_FUNC(bool, al_grab_mouse, (struct ALLEGRO_DISPLAY *display)); AL_FUNC(bool, al_ungrab_mouse, (void)); AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_mouse_event_source, (void)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/allegro5.h0000644000175000001440000000002611426530515017426 0ustar tjadenusers#include "allegro.h" allegro-5.0.10/include/allegro5/joystick.h0000644000175000001440000000536512057357022017567 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Joystick routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_joystick_h #define __al_included_allegro5_joystick_h #include "allegro5/base.h" #include "allegro5/events.h" #ifdef __cplusplus extern "C" { #endif /* internal values */ #define _AL_MAX_JOYSTICK_AXES 3 #define _AL_MAX_JOYSTICK_STICKS 8 #define _AL_MAX_JOYSTICK_BUTTONS 32 /* Type: ALLEGRO_JOYSTICK */ typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK; /* Type: ALLEGRO_JOYSTICK_STATE */ typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE; struct ALLEGRO_JOYSTICK_STATE { struct { float axis[_AL_MAX_JOYSTICK_AXES]; /* -1.0 to 1.0 */ } stick[_AL_MAX_JOYSTICK_STICKS]; int button[_AL_MAX_JOYSTICK_BUTTONS]; /* 0 to 32767 */ }; /* Enum: ALLEGRO_JOYFLAGS */ enum ALLEGRO_JOYFLAGS { ALLEGRO_JOYFLAG_DIGITAL = 0x01, ALLEGRO_JOYFLAG_ANALOGUE = 0x02 }; AL_FUNC(bool, al_install_joystick, (void)); AL_FUNC(void, al_uninstall_joystick, (void)); AL_FUNC(bool, al_is_joystick_installed, (void)); AL_FUNC(bool, al_reconfigure_joysticks, (void)); AL_FUNC(int, al_get_num_joysticks, (void)); AL_FUNC(ALLEGRO_JOYSTICK *, al_get_joystick, (int joyn)); AL_FUNC(void, al_release_joystick, (ALLEGRO_JOYSTICK *)); AL_FUNC(bool, al_get_joystick_active, (ALLEGRO_JOYSTICK *)); AL_FUNC(const char*, al_get_joystick_name, (ALLEGRO_JOYSTICK *)); AL_FUNC(int, al_get_joystick_num_sticks, (ALLEGRO_JOYSTICK *)); AL_FUNC(int, al_get_joystick_stick_flags, (ALLEGRO_JOYSTICK *, int stick)); /* junk? */ AL_FUNC(const char*, al_get_joystick_stick_name, (ALLEGRO_JOYSTICK *, int stick)); AL_FUNC(int, al_get_joystick_num_axes, (ALLEGRO_JOYSTICK *, int stick)); AL_FUNC(const char*, al_get_joystick_axis_name, (ALLEGRO_JOYSTICK *, int stick, int axis)); AL_FUNC(int, al_get_joystick_num_buttons, (ALLEGRO_JOYSTICK *)); AL_FUNC(const char*, al_get_joystick_button_name, (ALLEGRO_JOYSTICK *, int buttonn)); AL_FUNC(void, al_get_joystick_state, (ALLEGRO_JOYSTICK *, ALLEGRO_JOYSTICK_STATE *ret_state)); AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_joystick_event_source, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/allegro_iphone.h0000644000175000001440000000145611476665340020725 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * */ #ifndef A5_IPHONE_ALLEGRO_H #define A5_IPHONE_ALLEGRO_H #ifdef __cplusplus extern "C" { #endif /* * Public iPhone-related API */ AL_FUNC(void, al_iphone_program_has_halted, (void)); AL_FUNC(void, al_iphone_override_screen_scale, (float scale)); #ifdef __cplusplus } #endif #endif /* A5_IPONE_ALLEGRO_H */ allegro-5.0.10/include/allegro5/blender.h0000644000175000001440000000207212146027215017330 0ustar tjadenusers#ifndef __al_included_allegro5_blender_h #define __al_included_allegro5_blender_h #ifdef __cplusplus extern "C" { #endif /* * Blending modes */ enum ALLEGRO_BLEND_MODE { ALLEGRO_ZERO = 0, ALLEGRO_ONE = 1, ALLEGRO_ALPHA = 2, ALLEGRO_INVERSE_ALPHA = 3, ALLEGRO_SRC_COLOR = 4, ALLEGRO_DEST_COLOR = 5, ALLEGRO_INVERSE_SRC_COLOR = 6, ALLEGRO_INVERSE_DEST_COLOR = 7, ALLEGRO_NUM_BLEND_MODES }; enum ALLEGRO_BLEND_OPERATIONS { ALLEGRO_ADD = 0, ALLEGRO_SRC_MINUS_DEST = 1, ALLEGRO_DEST_MINUS_SRC = 2, ALLEGRO_NUM_BLEND_OPERATIONS }; AL_FUNC(void, al_set_blender, (int op, int source, int dest)); AL_FUNC(void, al_get_blender, (int *op, int *source, int *dest)); AL_FUNC(void, al_set_separate_blender, (int op, int source, int dest, int alpha_op, int alpha_source, int alpha_dest)); AL_FUNC(void, al_get_separate_blender, (int *op, int *source, int *dest, int *alpha_op, int *alpha_src, int *alpha_dest)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/threads.h0000644000175000001440000000425711465364352017367 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_threads_h #define __al_included_allegro5_threads_h #include "allegro5/altime.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_THREAD */ typedef struct ALLEGRO_THREAD ALLEGRO_THREAD; /* Type: ALLEGRO_MUTEX */ typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX; /* Type: ALLEGRO_COND */ typedef struct ALLEGRO_COND ALLEGRO_COND; AL_FUNC(ALLEGRO_THREAD *, al_create_thread, (void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)); AL_FUNC(void, al_start_thread, (ALLEGRO_THREAD *outer)); AL_FUNC(void, al_join_thread, (ALLEGRO_THREAD *outer, void **ret_value)); AL_FUNC(void, al_set_thread_should_stop, (ALLEGRO_THREAD *outer)); AL_FUNC(bool, al_get_thread_should_stop, (ALLEGRO_THREAD *outer)); AL_FUNC(void, al_destroy_thread, (ALLEGRO_THREAD *thread)); AL_FUNC(void, al_run_detached_thread, (void *(*proc)(void *arg), void *arg)); AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex, (void)); AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex_recursive, (void)); AL_FUNC(void, al_lock_mutex, (ALLEGRO_MUTEX *mutex)); AL_FUNC(void, al_unlock_mutex, (ALLEGRO_MUTEX *mutex)); AL_FUNC(void, al_destroy_mutex, (ALLEGRO_MUTEX *mutex)); AL_FUNC(ALLEGRO_COND *, al_create_cond, (void)); AL_FUNC(void, al_destroy_cond, (ALLEGRO_COND *cond)); AL_FUNC(void, al_wait_cond, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)); AL_FUNC(int, al_wait_cond_until, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, const ALLEGRO_TIMEOUT *timeout)); AL_FUNC(void, al_broadcast_cond, (ALLEGRO_COND *cond)); AL_FUNC(void, al_signal_cond, (ALLEGRO_COND *cond)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/opengl/0000755000175000001440000000000012157230742017032 5ustar tjadenusersallegro-5.0.10/include/allegro5/opengl/gl_ext.h0000644000175000001440000000713011426530515020465 0ustar tjadenusers #ifndef __al_included_allegro5_gl_ext_h #define __al_included_allegro5_gl_ext_h /* * MSVC declares the following extensions and MinGW doesn't. In order to * export the same symbols on both platforms we removed the extensions from * MSVC. */ #ifdef ALLEGRO_MSVC #undef GL_EXT_vertex_array #undef GL_EXT_paletted_texture #undef GL_WIN_swap_hint #undef GL_WIN_draw_range_elements #endif /* GL extension definitions. */ /* For example: * * #define GL_BGRA 0x80E1 * */ #if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE) #include "allegro5/opengl/GLext/gl_ext_defs.h" #endif #if defined ALLEGRO_WINDOWS && !defined ALLEGRO_EXCLUDE_WGL #include "allegro5/opengl/GLext/wgl_ext_defs.h" #elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX #include "allegro5/opengl/GLext/glx_ext_defs.h" #endif /* GL extension types */ /* For example: * * typedef void (APIENTRY * _ALLEGRO_glBlendEquation_t (GLenum); * */ #ifndef APIENTRY #define APIENTRY #define APIENTRY_defined #endif #define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_gl##name##_t) args; # include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_wgl##name##_t) args; # include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_glX##name##_t) args; # include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #endif #ifdef APIENTRY_defined #undef APIENTRY #undef APIENTRY_defined #endif /* GL extension declarations */ /* For example: * * #define glBlendEquation _al_glBlendEquation * extern _ALLEGRO_glBlendEquation_t _al_glBlendEquation; * */ #define AGL_API(type, name, args) AL_VAR(_ALLEGRO_gl##name##_t, _al_gl##name); # include "allegro5/opengl/GLext/gl_ext_alias.h" # include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) AL_VAR(_ALLEGRO_wgl##name##_t, _al_wgl##name); # include "allegro5/opengl/GLext/wgl_ext_alias.h" # include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) extern _ALLEGRO_glX##name##_t _al_glX##name; # include "allegro5/opengl/GLext/glx_ext_alias.h" # include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #endif /* A list of all supported extensions. * * For example: * int ALLEGRO_GL_ARB_imaging; * */ typedef struct ALLEGRO_OGL_EXT_LIST { # define AGL_EXT(name, ver) int ALLEGRO_GL_##name; # include "allegro5/opengl/GLext/gl_ext_list.h" # undef AGL_EXT #ifdef ALLEGRO_UNIX # define AGL_EXT(name, ver) int ALLEGRO_GLX_##name; # include "allegro5/opengl/GLext/glx_ext_list.h" # undef AGL_EXT #elif defined ALLEGRO_WINDOWS # define AGL_EXT(name, ver) int ALLEGRO_WGL_##name; # include "allegro5/opengl/GLext/wgl_ext_list.h" # undef AGL_EXT #endif } ALLEGRO_OGL_EXT_LIST; /* GL extension Structure. Holds the pointers to all the functions * of all extensions, for a single context. * * Example: * ALLEGRO_BlendEquation_t BlendEquation; */ typedef struct ALLEGRO_OGL_EXT_API { #define AGL_API(type, name, args) _ALLEGRO_gl##name##_t name; # include "allegro5/opengl/GLext/gl_ext_api.h" #undef AGL_API #ifdef ALLEGRO_WINDOWS #define AGL_API(type, name, args) _ALLEGRO_wgl##name##_t name; # include "allegro5/opengl/GLext/wgl_ext_api.h" #undef AGL_API #elif defined ALLEGRO_UNIX #define AGL_API(type, name, args) _ALLEGRO_glX##name##_t name; # include "allegro5/opengl/GLext/glx_ext_api.h" #undef AGL_API #endif } ALLEGRO_OGL_EXT_API; #endif allegro-5.0.10/include/allegro5/opengl/GLext/0000755000175000001440000000000012157230742020055 5ustar tjadenusersallegro-5.0.10/include/allegro5/opengl/GLext/gl_ext_api.h0000644000175000001440000043343612123163152022347 0ustar tjadenusers/* */ #ifdef _ALLEGRO_GL_VERSION_1_2 AGL_API(void, BlendColor, (GLclampf, GLclampf, GLclampf, GLclampf)) AGL_API(void, BlendEquation, (GLenum)) AGL_API(void, DrawRangeElements, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) AGL_API(void, ColorTable, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ColorTableParameterfv, (GLenum, GLenum, const GLfloat *)) AGL_API(void, ColorTableParameteriv, (GLenum, GLenum, const GLint *)) AGL_API(void, CopyColorTable, (GLenum, GLenum, GLint, GLint, GLsizei)) AGL_API(void, GetColorTable, (GLenum, GLenum, GLenum, GLvoid *)) AGL_API(void, GetColorTableParameterfv, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetColorTableParameteriv, (GLenum, GLenum, GLint *)) AGL_API(void, ColorSubTable, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyColorSubTable, (GLenum, GLsizei, GLint, GLint, GLsizei)) AGL_API(void, TexImage3D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) #endif #if defined _ALLEGRO_GL_ARB_imaging AGL_API(void, ConvolutionFilter1D, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ConvolutionFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ConvolutionParameterf, (GLenum, GLenum, GLfloat)) AGL_API(void, ConvolutionParameterfv, (GLenum, GLenum, const GLfloat *)) AGL_API(void, ConvolutionParameteri, (GLenum, GLenum, GLint)) AGL_API(void, ConvolutionParameteriv, (GLenum, GLenum, const GLint *)) AGL_API(void, CopyConvolutionFilter1D, (GLenum, GLenum, GLint, GLint, GLsizei)) AGL_API(void, CopyConvolutionFilter2D, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, GetConvolutionFilter, (GLenum, GLenum, GLenum, GLvoid *)) AGL_API(void, GetConvolutionParameterfv, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetConvolutionParameteriv, (GLenum, GLenum, GLint *)) AGL_API(void, GetSeparableFilter, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) AGL_API(void, SeparableFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) AGL_API(void, GetHistogram, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) AGL_API(void, GetHistogramParameterfv, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetHistogramParameteriv, (GLenum, GLenum, GLint *)) AGL_API(void, GetMinmax, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) AGL_API(void, GetMinmaxParameterfv, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetMinmaxParameteriv, (GLenum, GLenum, GLint *)) AGL_API(void, Histogram, (GLenum, GLsizei, GLenum, GLboolean)) AGL_API(void, Minmax, (GLenum, GLenum, GLboolean)) AGL_API(void, ResetHistogram, (GLenum)) AGL_API(void, ResetMinmax, (GLenum)) #endif #if defined _ALLEGRO_GL_VERSION_1_3 AGL_API(void, ActiveTexture, (GLenum)) AGL_API(void, ClientActiveTexture, (GLenum)) AGL_API(void, MultiTexCoord1d, (GLenum, GLdouble)) AGL_API(void, MultiTexCoord1dv, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord1f, (GLenum, GLfloat)) AGL_API(void, MultiTexCoord1fv, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord1i, (GLenum, GLint)) AGL_API(void, MultiTexCoord1iv, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord1s, (GLenum, GLshort)) AGL_API(void, MultiTexCoord1sv, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord2d, (GLenum, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord2dv, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord2f, (GLenum, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord2fv, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord2i, (GLenum, GLint, GLint)) AGL_API(void, MultiTexCoord2iv, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord2s, (GLenum, GLshort, GLshort)) AGL_API(void, MultiTexCoord2sv, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord3d, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord3dv, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord3f, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord3fv, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord3i, (GLenum, GLint, GLint, GLint)) AGL_API(void, MultiTexCoord3iv, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord3s, (GLenum, GLshort, GLshort, GLshort)) AGL_API(void, MultiTexCoord3sv, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord4d, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord4dv, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord4f, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord4fv, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord4i, (GLenum, GLint, GLint, GLint, GLint)) AGL_API(void, MultiTexCoord4iv, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord4s, (GLenum, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, MultiTexCoord4sv, (GLenum, const GLshort *)) AGL_API(void, LoadTransposeMatrixf, (const GLfloat *)) AGL_API(void, LoadTransposeMatrixd, (const GLdouble *)) AGL_API(void, MultTransposeMatrixf, (const GLfloat *)) AGL_API(void, MultTransposeMatrixd, (const GLdouble *)) AGL_API(void, SampleCoverage, (GLclampf, GLboolean)) AGL_API(void, CompressedTexImage3D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexImage2D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexImage1D, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage1D, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetCompressedTexImage, (GLenum, GLint, GLvoid *)) #endif #if defined _ALLEGRO_GL_VERSION_1_4 AGL_API(void, BlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum)) AGL_API(void, FogCoordf, (GLfloat)) AGL_API(void, FogCoordfv, (const GLfloat *)) AGL_API(void, FogCoordd, (GLdouble)) AGL_API(void, FogCoorddv, (const GLdouble *)) AGL_API(void, FogCoordPointer, (GLenum, GLsizei, const GLvoid *)) AGL_API(void, MultiDrawArrays, (GLenum, GLint *, GLsizei *, GLsizei)) AGL_API(void, MultiDrawElements, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) AGL_API(void, PointParameterf, (GLenum, GLfloat)) AGL_API(void, PointParameterfv, (GLenum, const GLfloat *)) AGL_API(void, PointParameteri, (GLenum, GLint)) AGL_API(void, PointParameteriv, (GLenum, const GLint *)) AGL_API(void, SecondaryColor3b, (GLbyte, GLbyte, GLbyte)) AGL_API(void, SecondaryColor3bv, (const GLbyte *)) AGL_API(void, SecondaryColor3d, (GLdouble, GLdouble, GLdouble)) AGL_API(void, SecondaryColor3dv, (const GLdouble *)) AGL_API(void, SecondaryColor3f, (GLfloat, GLfloat, GLfloat)) AGL_API(void, SecondaryColor3fv, (const GLfloat *)) AGL_API(void, SecondaryColor3i, (GLint, GLint, GLint)) AGL_API(void, SecondaryColor3iv, (const GLint *)) AGL_API(void, SecondaryColor3s, (GLshort, GLshort, GLshort)) AGL_API(void, SecondaryColor3sv, (const GLshort *)) AGL_API(void, SecondaryColor3ub, (GLubyte, GLubyte, GLubyte)) AGL_API(void, SecondaryColor3ubv, (const GLubyte *)) AGL_API(void, SecondaryColor3ui, (GLuint, GLuint, GLuint)) AGL_API(void, SecondaryColor3uiv, (const GLuint *)) AGL_API(void, SecondaryColor3us, (GLushort, GLushort, GLushort)) AGL_API(void, SecondaryColor3usv, (const GLushort *)) AGL_API(void, SecondaryColorPointer, (GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, WindowPos2d, (GLdouble, GLdouble)) AGL_API(void, WindowPos2dv, (const GLdouble *)) AGL_API(void, WindowPos2f, (GLfloat, GLfloat)) AGL_API(void, WindowPos2fv, (const GLfloat *)) AGL_API(void, WindowPos2i, (GLint, GLint)) AGL_API(void, WindowPos2iv, (const GLint *)) AGL_API(void, WindowPos2s, (GLshort, GLshort)) AGL_API(void, WindowPos2sv, (const GLshort *)) AGL_API(void, WindowPos3d, (GLdouble, GLdouble, GLdouble)) AGL_API(void, WindowPos3dv, (const GLdouble *)) AGL_API(void, WindowPos3f, (GLfloat, GLfloat, GLfloat)) AGL_API(void, WindowPos3fv, (const GLfloat *)) AGL_API(void, WindowPos3i, (GLint, GLint, GLint)) AGL_API(void, WindowPos3iv, (const GLint *)) AGL_API(void, WindowPos3s, (GLshort, GLshort, GLshort)) AGL_API(void, WindowPos3sv, (const GLshort *)) #endif #if defined _ALLEGRO_GL_VERSION_1_5 AGL_API(void, BindBuffer, (GLenum, GLuint)) AGL_API(void, DeleteBuffers, (GLsizei, const GLuint *)) AGL_API(void, GenBuffers, (GLsizei, GLuint *)) AGL_API(GLboolean, IsBuffer, (GLuint)) AGL_API(void, BufferData, (GLenum, GLsizeiptr, const GLvoid *, GLenum)) AGL_API(void, BufferSubData, (GLenum, GLintptr, GLsizeiptr, const GLvoid *)) AGL_API(void, GetBufferSubData, (GLenum, GLintptr, GLsizeiptr, GLvoid *)) AGL_API(GLvoid*, MapBuffer, (GLenum, GLenum)) AGL_API(GLboolean, UnmapBuffer, (GLenum)) AGL_API(void, GetBufferParameteriv, (GLenum, GLenum, GLint *)) AGL_API(void, GetBufferPointerv, (GLenum, GLenum, GLvoid* *)) AGL_API(void, GenQueries, (GLsizei, GLuint *)) AGL_API(void, DeleteQueries, (GLsizei, const GLuint *)) AGL_API(GLboolean, IsQuery, (GLuint)) AGL_API(void, BeginQuery, (GLenum, GLuint)) AGL_API(void, EndQuery, (GLenum)) AGL_API(void, GetQueryiv, (GLenum, GLenum, GLint *)) AGL_API(void, GetQueryObjectiv, (GLuint, GLenum, GLint *)) AGL_API(void, GetQueryObjectuiv, (GLuint, GLenum, GLuint *)) #endif #if defined _ALLEGRO_GL_VERSION_2_0 AGL_API(void, BlendEquationSeparate, (GLenum, GLenum)) AGL_API(GLuint, CreateProgram, (void)) AGL_API(GLuint, CreateShader, (GLenum)) AGL_API(void, DeleteProgram, (GLuint)) AGL_API(void, DeleteShader, (GLuint)) AGL_API(void, AttachShader, (GLuint, GLuint)) AGL_API(void, DetachShader, (GLuint, GLuint)) AGL_API(void, ShaderSource, (GLuint, GLsizei, const GLchar **, const GLint *)) AGL_API(void, CompileShader, (GLuint)) AGL_API(GLboolean, IsProgram, (GLuint)) AGL_API(GLboolean, IsShader, (GLuint)) AGL_API(void, LinkProgram, (GLuint)) AGL_API(void, UseProgram, (GLuint)) AGL_API(void, ValidateProgram, (GLuint)) AGL_API(void, Uniform1f, (GLint, GLfloat)) AGL_API(void, Uniform2f, (GLint, GLfloat, GLfloat)) AGL_API(void, Uniform3f, (GLint, GLfloat, GLfloat, GLfloat)) AGL_API(void, Uniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, Uniform1i, (GLint, GLint)) AGL_API(void, Uniform2i, (GLint, GLint, GLint)) AGL_API(void, Uniform3i, (GLint, GLint, GLint, GLint)) AGL_API(void, Uniform4i, (GLint, GLint, GLint, GLint, GLint)) AGL_API(void, Uniform1fv, (GLint, GLsizei, const GLfloat *)) AGL_API(void, Uniform2fv, (GLint, GLsizei, const GLfloat *)) AGL_API(void, Uniform3fv, (GLint, GLsizei, const GLfloat *)) AGL_API(void, Uniform4fv, (GLint, GLsizei, const GLfloat *)) AGL_API(void, Uniform1iv, (GLint, GLsizei, const GLint *)) AGL_API(void, Uniform2iv, (GLint, GLsizei, const GLint *)) AGL_API(void, Uniform3iv, (GLint, GLsizei, const GLint *)) AGL_API(void, Uniform4iv, (GLint, GLsizei, const GLint *)) AGL_API(void, UniformMatrix2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, GetShaderfv, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetShaderiv, (GLuint, GLenum, GLint *)) AGL_API(void, GetProgramfv, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetProgramiv, (GLuint, GLenum, GLint *)) AGL_API(void, GetShaderInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, GetProgramInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, GetAttachedShaders, (GLuint, GLsizei, GLsizei *, GLuint *)) AGL_API(GLint, GetUniformLocation, (GLuint, const GLchar *)) AGL_API(void, GetActiveUniform, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) AGL_API(void, GetUniformfv, (GLuint, GLint, GLfloat *)) AGL_API(void, GetUniformiv, (GLuint, GLint, GLint *)) AGL_API(void, GetShaderSource, (GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, VertexAttrib1f, (GLuint, GLfloat)) AGL_API(void, VertexAttrib1s, (GLuint, GLshort)) AGL_API(void, VertexAttrib1d, (GLuint, GLdouble)) AGL_API(void, VertexAttrib2f, (GLuint, GLfloat, GLfloat)) AGL_API(void, VertexAttrib2s, (GLuint, GLshort, GLshort)) AGL_API(void, VertexAttrib2d, (GLuint, GLdouble, GLdouble)) AGL_API(void, VertexAttrib3f, (GLuint, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib3s, (GLuint, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib3d, (GLuint, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib4f, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib4s, (GLuint, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib4d, (GLuint, GLdouble,GLdouble,GLdouble,GLdouble)) AGL_API(void, VertexAttrib4Nub, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) AGL_API(void, VertexAttrib1fv, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib1sv, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib1dv, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib2fv, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib2sv, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib2dv, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib3fv, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib3sv, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib3dv, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4fv, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib4sv, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4dv, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4iv, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4bv, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4ubv, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4usv, (GLuint, const GLushort *)) AGL_API(void, VertexAttrib4uiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttrib4Nbv, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4Nsv, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4Niv, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4Nubv, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4Nusv, (GLuint, const GLushort *)) AGL_API(void, VertexAttrib4Nuiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttribPointer,(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) AGL_API(void, EnableVertexAttribArray, (GLuint)) AGL_API(void, DisableVertexAttribArray, (GLuint)) AGL_API(void, BindAttribLocation, (GLuint, GLuint, const GLchar *)) AGL_API(void, GetActiveAttrib, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) AGL_API(GLint, GetAttribLocation, (GLuint, const GLchar *)) AGL_API(void, GetVertexAttribdv, (GLuint, GLenum, GLdouble *)) AGL_API(void, GetVertexAttribfv, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVertexAttribiv, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribPointerv, (GLuint, GLenum, GLvoid **)) AGL_API(void, DrawBuffers, (GLsizei n, const GLenum *)) AGL_API(void, StencilOpSeparate, (GLenum, GLenum, GLenum, GLenum)) AGL_API(void, StencilFuncSeparate, (GLenum, GLenum, GLint, GLuint)) #endif #if defined _ALLEGRO_GL_VERSION_2_1 AGL_API(void, UniformMatrix2x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix3x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix2x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix4x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix3x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, UniformMatrix4x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) #endif #if defined _ALLEGRO_GL_VERSION_3_0 /* OpenGL 3.0 also reuses entry points from these extensions: */ /* ARB_framebuffer_object */ /* ARB_map_buffer_range */ /* ARB_vertex_array_object */ AGL_API(void, ColorMaski, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) AGL_API(void, GetBooleani_v, (GLenum, GLuint, GLboolean *)) AGL_API(void, GetIntegeri_v, (GLenum, GLuint, GLint *)) AGL_API(void, Enablei, (GLenum, GLuint)) AGL_API(void, Disablei, (GLenum, GLuint)) AGL_API(GLboolean, IsEnabledi, (GLenum, GLuint)) AGL_API(void, BeginTransformFeedback, (GLenum)) AGL_API(void, EndTransformFeedback, (void)) AGL_API(void, BindBufferRange, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) AGL_API(void, BindBufferBase, (GLenum, GLuint, GLuint)) AGL_API(void, TransformFeedbackVaryings, (GLuint, GLsizei, const GLint *, GLenum)) AGL_API(void, GetTransformFeedbackVarying, (GLuint, GLuint, GLint *)) AGL_API(void, ClampColor, (GLenum, GLenum)) AGL_API(void, BeginConditionalRender, (GLuint, GLenum)) AGL_API(void, EndConditionalRender, (void)) AGL_API(void, VertexAttribI1i, (GLuint, GLint)) AGL_API(void, VertexAttribI2i, (GLuint, GLint, GLint)) AGL_API(void, VertexAttribI3i, (GLuint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI4i, (GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI1ui, (GLuint, GLuint)) AGL_API(void, VertexAttribI2ui, (GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI3ui, (GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI4ui, (GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI1iv, (GLuint, const GLint *)) AGL_API(void, VertexAttribI2iv, (GLuint, const GLint *)) AGL_API(void, VertexAttribI3iv, (GLuint, const GLint *)) AGL_API(void, VertexAttribI4iv, (GLuint, const GLint *)) AGL_API(void, VertexAttribI1uiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI2uiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI3uiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4uiv, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4bv, (GLuint, const GLbyte *)) AGL_API(void, VertexAttribI4sv, (GLuint, const GLshort *)) AGL_API(void, VertexAttribI4ubv, (GLuint, const GLubyte *)) AGL_API(void, VertexAttribI4usv, (GLuint, const GLushort *)) AGL_API(void, VertexAttribIPointer, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetVertexAttribIiv, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribIuiv, (GLuint, GLenum, GLuint *)) AGL_API(void, GetUniformuiv, (GLuint, GLint, GLuint *)) AGL_API(void, BindFragDataLocation, (GLuint, GLuint, const GLchar *)) AGL_API(GLint, GetFragDataLocation, (GLuint, const GLchar *)) AGL_API(void, Uniform1ui, (GLint, GLuint)) AGL_API(void, Uniform2ui, (GLint, GLuint, GLuint)) AGL_API(void, Uniform3ui, (GLint, GLuint, GLuint, GLuint)) AGL_API(void, Uniform4ui, (GLint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, Uniform1uiv, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform2uiv, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform3uiv, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform4uiv, (GLint, GLsizei, const GLuint *)) AGL_API(void, TexParameterIiv, (GLenum, GLenum, const GLint *)) AGL_API(void, TexParameterIuiv, (GLenum, GLenum, const GLuint *)) AGL_API(void, GetTexParameterIiv, (GLenum, GLenum, GLint *)) AGL_API(void, GetTexParameterIuiv, (GLenum, GLenum, GLuint *)) AGL_API(void, ClearBufferiv, (GLenum, GLint, const GLint *)) AGL_API(void, ClearBufferuiv, (GLenum, GLint, const GLuint *)) AGL_API(void, ClearBufferfv, (GLenum, GLint, const GLfloat *)) AGL_API(void, ClearBufferfi, (GLenum, GLint, GLfloat, GLint)) AGL_API(const GLubyte *, GetStringi, (GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_VERSION_3_1 /* OpenGL 3.1 also reuses entry points from these extensions: */ /* ARB_copy_buffer */ /* ARB_uniform_buffer_object */ AGL_API(void, DrawArraysInstanced, (GLenum, GLint, GLsizei, GLsizei)) AGL_API(void, DrawElementsInstanced, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) AGL_API(void, TexBuffer, (GLenum, GLenum, GLuint)) AGL_API(void, PrimitiveRestartIndex, (GLuint)) #endif #if defined _ALLEGRO_GL_VERSION_3_2 /* OpenGL 3.2 also reuses entry points from these extensions: */ /* ARB_draw_elements_base_vertex */ /* ARB_provoking_vertex */ /* ARB_sync */ /* ARB_texture_multisample */ AGL_API(void, GetInteger64i_v, (GLenum target, GLuint index, GLint64 *data)) AGL_API(void, GetBufferParameteri64v, (GLenum target, GLenum pname, GLint64 *params)) AGL_API(void, ProgramParameteri, (GLuint program, GLenum pname, GLint value)) AGL_API(void, FramebufferTexture, (GLenum target, GLenum attachment, GLuint texture, GLint level)) #endif #if defined _ALLEGRO_GL_VERSION_3_3 /* OpenGL 3.3 also reuses entry points from these extensions: */ /* ARB_blend_func_extended */ /* ARB_sampler_objects */ /* ARB_explicit_attrib_location, but it has none */ /* ARB_occlusion_query2 (no entry points) */ /* ARB_shader_bit_encoding (no entry points) */ /* ARB_texture_rgb10_a2ui (no entry points) */ /* ARB_texture_swizzle (no entry points) */ /* ARB_timer_query */ /* ARB_vertex_type_2_10_10_10_rev */ #endif /* */ /* */ #ifdef _ALLEGRO_GL_ARB_multitexture AGL_API(void, ActiveTextureARB, (GLenum)) AGL_API(void, ClientActiveTextureARB, (GLenum)) AGL_API(void, MultiTexCoord1dARB, (GLenum, GLdouble)) AGL_API(void, MultiTexCoord1dvARB, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord1fARB, (GLenum, GLfloat)) AGL_API(void, MultiTexCoord1fvARB, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord1iARB, (GLenum, GLint)) AGL_API(void, MultiTexCoord1ivARB, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord1sARB, (GLenum, GLshort)) AGL_API(void, MultiTexCoord1svARB, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord2dARB, (GLenum, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord2dvARB, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord2fARB, (GLenum, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord2fvARB, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord2iARB, (GLenum, GLint, GLint)) AGL_API(void, MultiTexCoord2ivARB, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord2sARB, (GLenum, GLshort, GLshort)) AGL_API(void, MultiTexCoord2svARB, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord3dARB, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord3dvARB, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord3fARB, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord3fvARB, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord3iARB, (GLenum, GLint, GLint, GLint)) AGL_API(void, MultiTexCoord3ivARB, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord3sARB, (GLenum, GLshort, GLshort, GLshort)) AGL_API(void, MultiTexCoord3svARB, (GLenum, const GLshort *)) AGL_API(void, MultiTexCoord4dARB, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, MultiTexCoord4dvARB, (GLenum, const GLdouble *)) AGL_API(void, MultiTexCoord4fARB, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, MultiTexCoord4fvARB, (GLenum, const GLfloat *)) AGL_API(void, MultiTexCoord4iARB, (GLenum, GLint, GLint, GLint, GLint)) AGL_API(void, MultiTexCoord4ivARB, (GLenum, const GLint *)) AGL_API(void, MultiTexCoord4sARB, (GLenum, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, MultiTexCoord4svARB, (GLenum, const GLshort *)) #endif #if defined _ALLEGRO_GL_ARB_transpose_matrix AGL_API(void, LoadTransposeMatrixfARB, (const GLfloat *)) AGL_API(void, LoadTransposeMatrixdARB, (const GLdouble *)) AGL_API(void, MultTransposeMatrixfARB, (const GLfloat *)) AGL_API(void, MultTransposeMatrixdARB, (const GLdouble *)) #endif #if defined _ALLEGRO_GL_ARB_multisample AGL_API(void, SampleCoverageARB, (GLclampf, GLboolean)) #endif #if defined _ALLEGRO_GL_ARB_texture_compression AGL_API(void, CompressedTexImage3DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexImage2DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexImage1DARB, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage3DARB, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage2DARB, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTexSubImage1DARB, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetCompressedTexImageARB, (GLenum, GLint, GLvoid *)) #endif #if defined _ALLEGRO_GL_ARB_point_parameters AGL_API(void, PointParameterfARB, (GLenum, GLfloat)) AGL_API(void, PointParameterfvARB, (GLenum, const GLfloat *)) #endif #if defined _ALLEGRO_GL_ARB_vertex_blend AGL_API(void, WeightbvARB, (GLint, const GLbyte *)) AGL_API(void, WeightsvARB, (GLint, const GLshort *)) AGL_API(void, WeightivARB, (GLint, const GLint *)) AGL_API(void, WeightfvARB, (GLint, const GLfloat *)) AGL_API(void, WeightdvARB, (GLint, const GLdouble *)) AGL_API(void, WeightubvARB, (GLint, const GLubyte *)) AGL_API(void, WeightusvARB, (GLint, const GLushort *)) AGL_API(void, WeightuivARB, (GLint, const GLuint *)) AGL_API(void, WeightPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, VertexBlendARB, (GLint)) #endif #if defined _ALLEGRO_GL_ARB_matrix_palette AGL_API(void, CurrentPaletteMatrixARB, (GLint)) AGL_API(void, MatrixIndexubvARB, (GLint, const GLubyte *)) AGL_API(void, MatrixIndexusvARB, (GLint, const GLushort *)) AGL_API(void, MatrixIndexuivARB, (GLint, const GLuint *)) AGL_API(void, MatrixIndexPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_ARB_window_pos AGL_API(void, WindowPos2dARB, (GLdouble, GLdouble)) AGL_API(void, WindowPos2dvARB, (const GLdouble *)) AGL_API(void, WindowPos2fARB, (GLfloat, GLfloat)) AGL_API(void, WindowPos2fvARB, (const GLfloat *)) AGL_API(void, WindowPos2iARB, (GLint, GLint)) AGL_API(void, WindowPos2ivARB, (const GLint *)) AGL_API(void, WindowPos2sARB, (GLshort, GLshort)) AGL_API(void, WindowPos2svARB, (const GLshort *)) AGL_API(void, WindowPos3dARB, (GLdouble, GLdouble, GLdouble)) AGL_API(void, WindowPos3dvARB, (const GLdouble *)) AGL_API(void, WindowPos3fARB, (GLfloat, GLfloat, GLfloat)) AGL_API(void, WindowPos3fvARB, (const GLfloat *)) AGL_API(void, WindowPos3iARB, (GLint, GLint, GLint)) AGL_API(void, WindowPos3ivARB, (const GLint *)) AGL_API(void, WindowPos3sARB, (GLshort, GLshort, GLshort)) AGL_API(void, WindowPos3svARB, (const GLshort *)) #endif #if defined _ALLEGRO_GL_ARB_vertex_program AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) AGL_API(void, ProgramStringARB, (GLenum, GLenum, GLsizei, const GLvoid *)) AGL_API(void, BindProgramARB, (GLenum, GLuint)) AGL_API(void, DeleteProgramsARB, (GLsizei, const GLuint *)) AGL_API(void, GenProgramsARB, (GLsizei, GLuint *)) AGL_API(void, ProgramEnvParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, ProgramEnvParameter4dvARB, (GLenum, GLuint, const GLdouble *)) AGL_API(void, ProgramEnvParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramEnvParameter4fvARB, (GLenum, GLuint, const GLfloat *)) AGL_API(void, ProgramLocalParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, ProgramLocalParameter4dvARB, (GLenum, GLuint, const GLdouble *)) AGL_API(void, ProgramLocalParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramLocalParameter4fvARB, (GLenum, GLuint, const GLfloat *)) AGL_API(void, GetProgramEnvParameterdvARB, (GLenum, GLuint, GLdouble *)) AGL_API(void, GetProgramEnvParameterfvARB, (GLenum, GLuint, GLfloat *)) AGL_API(void, GetProgramLocalParameterdvARB, (GLenum, GLuint, GLdouble *)) AGL_API(void, GetProgramLocalParameterfvARB, (GLenum, GLuint, GLfloat *)) AGL_API(void, GetProgramivARB, (GLenum, GLenum, GLint *)) AGL_API(void, GetProgramStringARB, (GLenum, GLenum, GLvoid *)) AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid* *)) AGL_API(GLboolean, IsProgramARB, (GLuint)) #endif #if defined _ALLEGRO_GL_ARB_vertex_buffer_object AGL_API(void, BindBufferARB, (GLenum, GLuint)) AGL_API(void, DeleteBuffersARB, (GLsizei, const GLuint *)) AGL_API(void, GenBuffersARB, (GLsizei, GLuint *)) AGL_API(GLboolean, IsBufferARB, (GLuint)) AGL_API(void, BufferDataARB, (GLenum, GLsizeiptrARB, const GLvoid *, GLenum)) AGL_API(void, BufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *)) AGL_API(void, GetBufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *)) AGL_API(GLvoid*, MapBufferARB, (GLenum, GLenum)) AGL_API(GLboolean, UnmapBufferARB, (GLenum)) AGL_API(void, GetBufferParameterivARB, (GLenum, GLenum, GLint *)) AGL_API(void, GetBufferPointervARB, (GLenum, GLenum, GLvoid* *)) #endif #if defined _ALLEGRO_GL_ARB_occlusion_query AGL_API(void, GenQueriesARB, (GLsizei, GLuint *)) AGL_API(void, DeleteQueriesARB, (GLsizei, const GLuint *)) AGL_API(GLboolean, IsQueryARB, (GLuint)) AGL_API(void, BeginQueryARB, (GLenum, GLuint)) AGL_API(void, EndQueryARB, (GLenum)) AGL_API(void, GetQueryivARB, (GLenum, GLenum, GLint *)) AGL_API(void, GetQueryObjectivARB, (GLuint, GLenum, GLint *)) AGL_API(void, GetQueryObjectuivARB, (GLuint, GLenum, GLuint *)) #endif #if defined _ALLEGRO_GL_ARB_shader_objects AGL_API(void, DeleteObjectARB, (GLhandleARB)) AGL_API(GLhandleARB, GetHandleARB, (GLenum)) AGL_API(void, DetachObjectARB, (GLhandleARB, GLhandleARB)) AGL_API(GLhandleARB, CreateShaderObjectARB, (GLenum)) AGL_API(void, ShaderSourceARB, (GLhandleARB, GLsizei, const GLcharARB **, const GLint *)) AGL_API(void, CompileShaderARB, (GLhandleARB)) AGL_API(GLhandleARB, CreateProgramObjectARB, (void)) AGL_API(void, AttachObjectARB, (GLhandleARB, GLhandleARB)) AGL_API(void, LinkProgramARB, (GLhandleARB)) AGL_API(void, UseProgramObjectARB, (GLhandleARB)) AGL_API(void, ValidateProgramARB, (GLhandleARB)) AGL_API(void, Uniform1fARB, (GLint, GLfloat)) AGL_API(void, Uniform2fARB, (GLint, GLfloat, GLfloat)) AGL_API(void, Uniform3fARB, (GLint, GLfloat, GLfloat, GLfloat)) AGL_API(void, Uniform4fARB, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, Uniform1iARB, (GLint, GLint)) AGL_API(void, Uniform2iARB, (GLint, GLint, GLint)) AGL_API(void, Uniform3iARB, (GLint, GLint, GLint, GLint)) AGL_API(void, Uniform4iARB, (GLint, GLint, GLint, GLint, GLint)) AGL_API(void, Uniform1fvARB, (GLint, GLsizei, GLfloat *)) AGL_API(void, Uniform2fvARB, (GLint, GLsizei, GLfloat *)) AGL_API(void, Uniform3fvARB, (GLint, GLsizei, GLfloat *)) AGL_API(void, Uniform4fvARB, (GLint, GLsizei, GLfloat *)) AGL_API(void, Uniform1ivARB, (GLint, GLsizei, GLint *)) AGL_API(void, Uniform2ivARB, (GLint, GLsizei, GLint *)) AGL_API(void, Uniform3ivARB, (GLint, GLsizei, GLint *)) AGL_API(void, Uniform4ivARB, (GLint, GLsizei, GLint *)) AGL_API(void, UniformMatrix2fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) AGL_API(void, UniformMatrix3fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) AGL_API(void, UniformMatrix4fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) AGL_API(void, GetObjectParameterfvARB, (GLhandleARB, GLenum, GLfloat *)) AGL_API(void, GetObjectParameterivARB, (GLhandleARB, GLenum, GLint *)) AGL_API(void, GetInfoLogARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) AGL_API(void, GetAttachedObjectsARB, (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *)) AGL_API(GLint, GetUniformLocationARB, (GLhandleARB, const GLcharARB *)) AGL_API(void, GetActiveUniformARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) AGL_API(void, GetUniformfvARB, (GLhandleARB, GLint, GLfloat *)) AGL_API(void, GetUniformivARB, (GLhandleARB, GLint, GLint *)) AGL_API(void, GetShaderSourceARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) #endif #ifdef _ALLEGRO_GL_ARB_vertex_shader #ifndef GL_ARB_vertex_program AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) #endif AGL_API(void, BindAttribLocationARB, (GLhandleARB, GLuint, const GLcharARB *)) AGL_API(void, GetActiveAttribARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) AGL_API(GLint, GetAttribLocationARB, (GLhandleARB, const GLcharARB *)) #ifndef GL_ARB_vertex_program AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid **)) #endif #endif #if defined _ALLEGRO_GL_ARB_draw_buffers AGL_API(void, DrawBuffersARB, (GLsizei n, const GLenum *bufs)) #endif #if defined _ALLEGRO_GL_ARB_color_buffer_float AGL_API(void, ClampColorARB, (GLenum, GLenum clamp)) #endif #if defined _ALLEGRO_GL_ARB_draw_instanced AGL_API(void, DrawArraysInstancedARB, (GLenum, GLint, GLsizei, GLsizei)) AGL_API(void, DrawElementsInstancedARB, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) #endif #if defined _ALLEGRO_GL_ARB_framebuffer_object AGL_API(GLboolean, IsRenderbuffer, (GLuint)) AGL_API(void, BindRenderbuffer, (GLenum, GLuint)) AGL_API(void, DeleteRenderbuffers, (GLsizei, const GLuint *)) AGL_API(void, GenRenderbuffers, (GLsizei, GLuint *)) AGL_API(void, RenderbufferStorage, (GLenum, GLenum, GLsizei, GLsizei)) AGL_API(void, GetRenderbufferParameteriv, (GLenum, GLenum, GLint *)) AGL_API(GLboolean, IsFramebuffer, (GLuint)) AGL_API(void, BindFramebuffer, (GLenum, GLuint)) AGL_API(void, DeleteFramebuffers, (GLsizei, const GLuint *)) AGL_API(void, GenFramebuffers, (GLsizei, GLuint *)) AGL_API(GLenum, CheckFramebufferStatus, (GLenum)) AGL_API(void, FramebufferTexture1D, (GLenum, GLenum, GLenum, GLuint, GLint)) AGL_API(void, FramebufferTexture2D, (GLenum, GLenum, GLenum, GLuint, GLint)) AGL_API(void, FramebufferTexture3D, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) AGL_API(void, FramebufferRenderbuffer, (GLenum, GLenum, GLenum, GLuint)) AGL_API(void, GetFramebufferAttachmentParameteriv, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GenerateMipmap, (GLenum)) AGL_API(void, BlitFramebuffer, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) AGL_API(void, RenderbufferStorageMultisample, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) AGL_API(void, FramebufferTextureLayer, (GLenum, GLenum, GLuint, GLint, GLint)) #endif #if defined _ALLEGRO_GL_ARB_geometry_shader4 AGL_API(void, ProgramParameteriARB, (GLuint, GLenum, GLint)) AGL_API(void, FramebufferTextureARB, (GLenum, GLenum, GLuint, GLint)) AGL_API(void, FramebufferTextureLayerARB, (GLenum, GLenum, GLuint, GLint, GLint)) AGL_API(void, FramebufferTextureFaceARB, (GLenum, GLenum, GLuint, GLint, GLenum)) #endif #if defined _ALLEGRO_GL_ARB_instanced_arrays AGL_API(void, VertexAttribDivisor, (GLuint, GLuint)) #endif #if defined _ALLEGRO_GL_ARB_map_buffer_range AGL_API(void, MapBufferRange, (GLenum, GLintptr, GLsizeiptr, GLbitfield)) AGL_API(void, FlushMappedBufferRange, (GLenum, GLintptr, GLsizeiptr)) #endif #if defined _ALLEGRO_GL_ARB_texture_buffer_object AGL_API(void, TexBufferARB, (GLenum, GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_ARB_vertex_array_object AGL_API(void, BindVertexArray, (GLuint)) AGL_API(void, DeleteVertexArrays, (GLsizei, const GLuint *)) AGL_API(void, GenVertexArrays, (GLsizei, GLuint *)) AGL_API(GLboolean, IsVertexArray, (GLuint)) #endif #if defined _ALLEGRO_GL_ARB_uniform_buffer_object AGL_API(void, GetUniformIndices, (GLuint, GLsizei, const GLchar* *, GLuint *)) AGL_API(void, GetActiveUniformsiv, (GLuint, GLsizei, const GLuint *, GLenum, GLint *)) AGL_API(void, GetActiveUniformName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(GLuint, GetUniformBlockIndex, (GLuint, const GLchar *)) AGL_API(void, GetActiveUniformBlockiv, (GLuint, GLuint, GLenum, GLint *)) AGL_API(void, GetActiveUniformBlockName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, UniformBlockBinding, (GLuint, GLuint, GLuint)) #endif #if defined _ALLEGRO_GL_ARB_copy_buffer AGL_API(void, CopyBufferSubData, (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) #endif #if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex AGL_API(void, DrawElementsBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) AGL_API(void, DrawRangeElementsBaseVertex, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) AGL_API(void, DrawElementsInstancedBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex)) AGL_API(void, MultiDrawElementsBaseVertex, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex)) #endif #if defined _ALLEGRO_GL_ARB_provoking_vertex AGL_API(void, ProvokingVertex, (GLenum mode)) #endif #if defined _ALLEGRO_GL_ARB_sync AGL_API(GLsync, FenceSync, (GLenum condition, GLbitfield flags)) AGL_API(GLboolean, IsSync, (GLsync sync)) AGL_API(void, DeleteSync, (GLsync sync)) AGL_API(GLenum, ClientWaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) AGL_API(void, WaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) AGL_API(void, GetInteger64v, (GLenum pname, GLint64 *params)) AGL_API(void, GetSynciv, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)) #endif #if defined _ALLEGRO_GL_ARB_texture_multisample AGL_API(void, TexImage2DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) AGL_API(void, TexImage3DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) AGL_API(void, GetMultisamplefv, (GLenum pname, GLuint index, GLfloat *val)) AGL_API(void, SampleMaski, (GLuint index, GLbitfield mask)) #endif #if defined _ALLEGRO_GL_ARB_draw_buffers_blend AGL_API(void, BlendEquationi, (GLuint buf, GLenum mode)) AGL_API(void, BlendEquationSeparatei, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) AGL_API(void, BlendFunci, (GLuint buf, GLenum src, GLenum dst)) AGL_API(void, BlendFuncSeparatei, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) #endif #if defined _ALLEGRO_GL_ARB_sample_shading AGL_API(void, MinSampleShading, (GLclampf value)) #endif #if defined _ALLEGRO_GL_ARB_shading_language_include AGL_API(void, NamedStringARB, (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string)) AGL_API(void, DeleteNamedStringARB, (GLint namelen, const GLchar *name)) AGL_API(void, CompileShaderIncludeARB, (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length)) AGL_API(GLboolean, IsNamedStringARB, (GLint namelen, const GLchar *name)) AGL_API(void, GetNamedStringARB, (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string)) AGL_API(void, GetNamedStringivARB, (GLint namelen, const GLchar *name, GLenum pname, GLint *params)) #endif #if defined _ALLEGRO_GL_ARB_blend_func_extended AGL_API(void, BindFragDataLocationIndexed, (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)) AGL_API(GLint, GetFragDataIndex, (GLuint program, const GLchar *name)) #endif #if defined _ALLEGRO_GL_ARB_sampler_objects AGL_API(void, GenSamplers, (GLsizei count, GLuint *samplers)) AGL_API(void, DeleteSamplers, (GLsizei count, const GLuint *samplers)) AGL_API(GLboolean, IsSampler, (GLuint sampler)) AGL_API(void, BindSampler, (GLenum unit, GLuint sampler)) AGL_API(void, SamplerParameteri, (GLuint sampler, GLenum pname, GLint param)) AGL_API(void, SamplerParameteriv, (GLuint sampler, GLenum pname, const GLint *param)) AGL_API(void, SamplerParameterf, (GLuint sampler, GLenum pname, GLfloat param)) AGL_API(void, SamplerParameterfv, (GLuint sampler, GLenum pname, const GLfloat *param)) AGL_API(void, SamplerParameterIiv, (GLuint sampler, GLenum pname, const GLint *param)) AGL_API(void, SamplerParameterIuiv, (GLuint sampler, GLenum pname, const GLuint *param)) AGL_API(void, GetSamplerParameteriv, (GLuint sampler, GLenum pname, GLint *params)) AGL_API(void, GetSamplerParameterIiv, (GLuint sampler, GLenum pname, GLint *params)) AGL_API(void, GetSamplerParameterfv, (GLuint sampler, GLenum pname, GLfloat *params)) AGL_API(void, GetSamplerParameterIfv, (GLuint sampler, GLenum pname, GLfloat *params)) #endif #if defined _ALLEGRO_GL_ARB_timer_query AGL_API(void, QueryCounter, (GLuint id, GLenum target)) AGL_API(void, GetQueryObjecti64v, (GLuint id, GLenum pname, GLint64 *params)) AGL_API(void, GetQueryObjectui64v, (GLuint id, GLenum pname, GLuint64 *params)) #endif #if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev AGL_API(void, VertexP2ui, (GLenum type, GLuint value)) AGL_API(void, VertexP2uiv, (GLenum type, const GLuint *value)) AGL_API(void, VertexP3ui, (GLenum type, GLuint value)) AGL_API(void, VertexP3uiv, (GLenum type, const GLuint *value)) AGL_API(void, VertexP4ui, (GLenum type, GLuint value)) AGL_API(void, VertexP4uiv, (GLenum type, const GLuint *value)) AGL_API(void, TexCoordP1ui, (GLenum type, GLuint coords)) AGL_API(void, TexCoordP1uiv, (GLenum type, const GLuint *coords)) AGL_API(void, TexCoordP2ui, (GLenum type, GLuint coords)) AGL_API(void, TexCoordP2uiv, (GLenum type, const GLuint *coords)) AGL_API(void, TexCoordP3ui, (GLenum type, GLuint coords)) AGL_API(void, TexCoordP3uiv, (GLenum type, const GLuint *coords)) AGL_API(void, TexCoordP4ui, (GLenum type, GLuint coords)) AGL_API(void, TexCoordP4uiv, (GLenum type, const GLuint *coords)) AGL_API(void, MultiTexCoordP1ui, (GLenum texture, GLenum type, GLuint coords)) AGL_API(void, MultiTexCoordP1uiv, (GLenum texture, GLenum type, const GLuint *coords)) AGL_API(void, MultiTexCoordP2ui, (GLenum texture, GLenum type, GLuint coords)) AGL_API(void, MultiTexCoordP2uiv, (GLenum texture, GLenum type, const GLuint *coords)) AGL_API(void, MultiTexCoordP3ui, (GLenum texture, GLenum type, GLuint coords)) AGL_API(void, MultiTexCoordP3uiv, (GLenum texture, GLenum type, const GLuint *coords)) AGL_API(void, MultiTexCoordP4ui, (GLenum texture, GLenum type, GLuint coords)) AGL_API(void, MultiTexCoordP4uiv, (GLenum texture, GLenum type, const GLuint *coords)) AGL_API(void, NormalP3ui, (GLenum type, GLuint coords)) AGL_API(void, NormalP3uiv, (GLenum type, const GLuint *coords)) AGL_API(void, ColorP3ui, (GLenum type, GLuint color)) AGL_API(void, ColorP3uiv, (GLenum type, const GLuint *color)) AGL_API(void, ColorP4ui, (GLenum type, GLuint color)) AGL_API(void, ColorP4uiv, (GLenum type, const GLuint *color)) AGL_API(void, SecondaryColorP3ui, (GLenum type, GLuint color)) AGL_API(void, SecondaryColorP3uiv, (GLenum type, const GLuint *color)) AGL_API(void, VertexAttribP1ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) AGL_API(void, VertexAttribP1uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) AGL_API(void, VertexAttribP2ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) AGL_API(void, VertexAttribP2uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) AGL_API(void, VertexAttribP3ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) AGL_API(void, VertexAttribP3uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) AGL_API(void, VertexAttribP4ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) AGL_API(void, VertexAttribP4uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) #endif #if defined _ALLEGRO_GL_ARB_draw_indirect AGL_API(void, DrawArraysIndirect, (GLenum mode, const GLvoid *indirect)) AGL_API(void, DrawElementsIndirect, (GLenum mode, GLenum type, const GLvoid *indirect)) #endif #if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 AGL_API(void, Uniform1d, (GLint location, GLdouble x)) AGL_API(void, Uniform2d, (GLint location, GLdouble x, GLdouble y)) AGL_API(void, Uniform3d, (GLint location, GLdouble x, GLdouble y, GLdouble z)) AGL_API(void, Uniform4d, (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) AGL_API(void, Uniform1dv, (GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, Uniform2dv, (GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, Uniform3dv, (GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, Uniform4dv, (GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, UniformMatrix2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix2x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix2x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix3x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix3x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix4x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, UniformMatrix4x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, GetUniformdv, (GLuint program, GLint location, GLdouble *params)) AGL_API(void, ProgramUniform1dEXT, (GLuint program, GLint location, GLdouble x)) AGL_API(void, ProgramUniform2dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y)) AGL_API(void, ProgramUniform3dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z)) AGL_API(void, ProgramUniform4dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) AGL_API(void, ProgramUniform1dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, ProgramUniform2dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, ProgramUniform3dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, ProgramUniform4dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix2x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix2x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix3x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix3x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix4x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) AGL_API(void, ProgramUniformMatrix4x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) #endif #if defined _ALLEGRO_GL_ARB_shader_subroutine AGL_API(GLint, GetSubroutineUniformLocation, (GLuint program, GLenum shadertype, const GLchar *name)) AGL_API(GLuint, GetSubroutineIndex, (GLuint program, GLenum shadertype, const GLchar *name)) AGL_API(void, GetActiveSubroutineUniformiv, (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values)) AGL_API(void, GetActiveSubroutineUniformName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) AGL_API(void, GetActiveSubroutineName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) AGL_API(void, UniformSubroutinesuiv, (GLenum shadertype, GLsizei count, const GLuint *indices)) AGL_API(void, GetUniformSubroutineuiv, (GLenum shadertype, GLint location, GLuint *params)) AGL_API(void, GetProgramStageiv, (GLuint program, GLenum shadertype, GLenum pname, GLint *values)) #endif #if defined _ALLEGRO_GL_ARB_tessellation_shader AGL_API(void, PatchParameteri, (GLenum pname, GLint value)) AGL_API(void, PatchParameterfv, (GLenum pname, const GLfloat *values)) #endif #if defined _ALLEGRO_GL_ARB_transform_feedback2 AGL_API(void, BindTransformFeedback, (GLenum target, GLuint id)) AGL_API(void, DeleteTransformFeedbacks, (GLsizei n, const GLuint *ids)) AGL_API(void, GenTransformFeedbacks, (GLsizei n, GLuint *ids)) AGL_API(GLboolean, IsTransformFeedback, (GLuint id)) AGL_API(void, PauseTransformFeedback, (void)) AGL_API(void, ResumeTransformFeedback, (void)) AGL_API(void, DrawTransformFeedback, (GLenum mode, GLuint id)) #endif #if defined _ALLEGRO_GL_ARB_transform_feedback3 AGL_API(void, DrawTransformFeedbackStream, (GLenum mode, GLuint id, GLuint stream)) AGL_API(void, BeginQueryIndexed, (GLenum target, GLuint index, GLuint id)) AGL_API(void, EndQueryIndexed, (GLenum target, GLuint index)) AGL_API(void, GetQueryIndexediv, (GLenum target, GLuint index, GLenum pname, GLint *params)) #endif /* */ #if defined _ALLEGRO_GL_EXT_blend_color AGL_API(void, BlendColorEXT, (GLclampf, GLclampf, GLclampf, GLclampf)) #endif #if defined _ALLEGRO_GL_EXT_polygon_offset AGL_API(void, PolygonOffsetEXT, (GLfloat, GLfloat)) #endif #if defined _ALLEGRO_GL_EXT_texture3D AGL_API(void, TexImage3DEXT, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) #endif #if defined _ALLEGRO_GL_SGIS_texture_filter4 AGL_API(void, GetTexFilterFuncSGIS, (GLenum, GLenum, GLfloat *)) AGL_API(void, TexFilterFuncSGIS, (GLenum, GLenum, GLsizei, const GLfloat *)) #endif #if defined _ALLEGRO_GL_EXT_subtexture AGL_API(void, TexSubImage1DEXT, (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, TexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_copy_texture AGL_API(void, CopyTexImage1DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) AGL_API(void, CopyTexImage2DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) AGL_API(void, CopyTexSubImage1DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei)) AGL_API(void, CopyTexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, CopyTexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) #endif #if defined _ALLEGRO_GL_EXT_histogram AGL_API(void, GetHistogramEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) AGL_API(void, GetHistogramParameterfvEXT, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetHistogramParameterivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, GetMinmaxEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) AGL_API(void, GetMinmaxParameterfvEXT, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetMinmaxParameterivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, HistogramEXT, (GLenum, GLsizei, GLenum, GLboolean)) AGL_API(void, MinmaxEXT, (GLenum, GLenum, GLboolean)) AGL_API(void, ResetHistogramEXT, (GLenum)) AGL_API(void, ResetMinmaxEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_EXT_convolution AGL_API(void, ConvolutionFilter1DEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ConvolutionFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ConvolutionParameterfEXT, (GLenum, GLenum, GLfloat)) AGL_API(void, ConvolutionParameterfvEXT, (GLenum, GLenum, const GLfloat *)) AGL_API(void, ConvolutionParameteriEXT, (GLenum, GLenum, GLint)) AGL_API(void, ConvolutionParameterivEXT, (GLenum, GLenum, const GLint *)) AGL_API(void, CopyConvolutionFilter1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei)) AGL_API(void, CopyConvolutionFilter2DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, GetConvolutionFilterEXT, (GLenum, GLenum, GLenum, GLvoid *)) AGL_API(void, GetConvolutionParameterfvEXT, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetConvolutionParameterivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, GetSeparableFilterEXT, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) AGL_API(void, SeparableFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) #endif #if defined _ALLEGRO_GL_SGI_color_table AGL_API(void, ColorTableSGI, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, ColorTableParameterfvSGI, (GLenum, GLenum, const GLfloat *)) AGL_API(void, ColorTableParameterivSGI, (GLenum, GLenum, const GLint *)) AGL_API(void, CopyColorTableSGI, (GLenum, GLenum, GLint, GLint, GLsizei)) AGL_API(void, GetColorTableSGI, (GLenum, GLenum, GLenum, GLvoid *)) AGL_API(void, GetColorTableParameterfvSGI, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetColorTableParameterivSGI, (GLenum, GLenum, GLint *)) #endif #if defined _ALLEGRO_GL_SGIX_pixel_texture AGL_API(void, PixelTexGenSGIX, (GLenum)) #endif #if defined _ALLEGRO_GL_SGIS_pixel_texture AGL_API(void, PixelTexGenParameteriSGIS, (GLenum, GLint)) AGL_API(void, PixelTexGenParameterivSGIS, (GLenum, const GLint *)) AGL_API(void, PixelTexGenParameterfSGIS, (GLenum, GLfloat)) AGL_API(void, PixelTexGenParameterfvSGIS, (GLenum, const GLfloat *)) AGL_API(void, GetPixelTexGenParameterivSGIS, (GLenum, GLint *)) AGL_API(void, GetPixelTexGenParameterfvSGIS, (GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIS_texture4D AGL_API(void, TexImage4DSGIS, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TexSubImage4DSGIS, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_texture_object AGL_API(GLboolean, AreTexturesResidentEXT, (GLsizei, const GLuint *, GLboolean *)) AGL_API(void, BindTextureEXT, (GLenum, GLuint)) AGL_API(void, DeleteTexturesEXT, (GLsizei, const GLuint *)) AGL_API(void, GenTexturesEXT, (GLsizei, GLuint *)) AGL_API(GLboolean, IsTextureEXT, (GLuint)) AGL_API(void, PrioritizeTexturesEXT, (GLsizei, const GLuint *, const GLclampf *)) #endif #if defined _ALLEGRO_GL_SGIS_detail_texture AGL_API(void, DetailTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) AGL_API(void, GetDetailTexFuncSGIS, (GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIS_sharpen_texture AGL_API(void, SharpenTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) AGL_API(void, GetSharpenTexFuncSGIS, (GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIS_multisample AGL_API(void, SampleMaskSGIS, (GLclampf, GLboolean)) AGL_API(void, SamplePatternSGIS, (GLenum)) #endif #if defined _ALLEGRO_GL_EXT_vertex_array AGL_API(void, ArrayElementEXT, (GLint)) AGL_API(void, ColorPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) AGL_API(void, DrawArraysEXT, (GLenum, GLint, GLsizei)) AGL_API(void, EdgeFlagPointerEXT, (GLsizei, GLsizei, const GLboolean *)) AGL_API(void, GetPointervEXT, (GLenum, GLvoid* *)) AGL_API(void, IndexPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) AGL_API(void, NormalPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) AGL_API(void, TexCoordPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) AGL_API(void, VertexPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_blend_minmax AGL_API(void, BlendEquationEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_SGIX_sprite AGL_API(void, SpriteParameterfSGIX, (GLenum, GLfloat)) AGL_API(void, SpriteParameterfvSGIX, (GLenum, const GLfloat *)) AGL_API(void, SpriteParameteriSGIX, (GLenum, GLint)) AGL_API(void, SpriteParameterivSGIX, (GLenum, const GLint *)) #endif #if defined _ALLEGRO_GL_EXT_point_parameters AGL_API(void, PointParameterfEXT, (GLenum, GLfloat)) AGL_API(void, PointParameterfvEXT, (GLenum, const GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIS_point_parameters AGL_API(void, PointParameterfSGIS, (GLenum, GLfloat)) AGL_API(void, PointParameterfvSGIS, (GLenum, const GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIX_instruments AGL_API(GLint, GetInstrumentsSGIX, (void)) AGL_API(void, InstrumentsBufferSGIX, (GLsizei, GLint *)) AGL_API(GLint, PollInstrumentsSGIX, (GLint *)) AGL_API(void, ReadInstrumentsSGIX, (GLint)) AGL_API(void, StartInstrumentsSGIX, (void)) AGL_API(void, StopInstrumentsSGIX, (GLint)) #endif #if defined _ALLEGRO_GL_SGIX_framezoom AGL_API(void, FrameZoomSGIX, (GLint)) #endif #if defined _ALLEGRO_GL_SGIX_tag_sample_buffer AGL_API(void, TagSampleBufferSGIX, (void)) #endif #if defined _ALLEGRO_GL_SGIX_polynomial_ffd AGL_API(void, DeformationMap3dSGIX, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *)) AGL_API(void, DeformationMap3fSGIX, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *)) AGL_API(void, DeformSGIX, (GLbitfield)) AGL_API(void, LoadIdentityDeformationMapSGIX, (GLbitfield)) #endif #if defined _ALLEGRO_GL_SGIX_reference_plane AGL_API(void, ReferencePlaneSGIX, (const GLdouble *)) #endif #if defined _ALLEGRO_GL_SGIX_flush_raster AGL_API(void, FlushRasterSGIX, (void)) #endif #if defined _ALLEGRO_GL_SGIS_fog_function AGL_API(void, FogFuncSGIS, (GLsizei, const GLfloat *)) AGL_API(void, GetFogFuncSGIS, (GLfloat *)) #endif #if defined _ALLEGRO_GL_HP_image_transform AGL_API(void, ImageTransformParameteriHP, (GLenum, GLenum, GLint)) AGL_API(void, ImageTransformParameterfHP, (GLenum, GLenum, GLfloat)) AGL_API(void, ImageTransformParameterivHP, (GLenum, GLenum, const GLint *)) AGL_API(void, ImageTransformParameterfvHP, (GLenum, GLenum, const GLfloat *)) AGL_API(void, GetImageTransformParameterivHP, (GLenum, GLenum, GLint *)) AGL_API(void, GetImageTransformParameterfvHP, (GLenum, GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_EXT_color_subtable #ifndef GL_EXT_paletted_texture AGL_API(void, ColorSubTableEXT, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) #endif AGL_API(void, CopyColorSubTableEXT, (GLenum, GLsizei, GLint, GLint, GLsizei)) #endif #if defined _ALLEGRO_GL_PGI_misc_hints AGL_API(void, HintPGI, (GLenum, GLint)) #endif #if defined _ALLEGRO_GL_EXT_paletted_texture AGL_API(void, ColorTableEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, GetColorTableEXT, (GLenum, GLenum, GLenum, GLvoid *)) AGL_API(void, GetColorTableParameterivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, GetColorTableParameterfvEXT, (GLenum, GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIX_list_priority AGL_API(void, GetListParameterfvSGIX, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetListParameterivSGIX, (GLuint, GLenum, GLint *)) AGL_API(void, ListParameterfSGIX, (GLuint, GLenum, GLfloat)) AGL_API(void, ListParameterfvSGIX, (GLuint, GLenum, const GLfloat *)) AGL_API(void, ListParameteriSGIX, (GLuint, GLenum, GLint)) AGL_API(void, ListParameterivSGIX, (GLuint, GLenum, const GLint *)) #endif #if defined _ALLEGRO_GL_EXT_index_material AGL_API(void, IndexMaterialEXT, (GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_EXT_index_func AGL_API(void, IndexFuncEXT, (GLenum, GLclampf)) #endif #if defined _ALLEGRO_GL_EXT_compiled_vertex_array AGL_API(void, LockArraysEXT, (GLint, GLsizei)) AGL_API(void, UnlockArraysEXT, (void)) #endif #if defined _ALLEGRO_GL_EXT_cull_vertex AGL_API(void, CullParameterdvEXT, (GLenum, GLdouble *)) AGL_API(void, CullParameterfvEXT, (GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_SGIX_fragment_lighting AGL_API(void, FragmentColorMaterialSGIX, (GLenum, GLenum)) AGL_API(void, FragmentLightfSGIX, (GLenum, GLenum, GLfloat)) AGL_API(void, FragmentLightfvSGIX, (GLenum, GLenum, const GLfloat *)) AGL_API(void, FragmentLightiSGIX, (GLenum, GLenum, GLint)) AGL_API(void, FragmentLightivSGIX, (GLenum, GLenum, const GLint *)) AGL_API(void, FragmentLightModelfSGIX, (GLenum, GLfloat)) AGL_API(void, FragmentLightModelfvSGIX, (GLenum, const GLfloat *)) AGL_API(void, FragmentLightModeliSGIX, (GLenum, GLint)) AGL_API(void, FragmentLightModelivSGIX, (GLenum, const GLint *)) AGL_API(void, FragmentMaterialfSGIX, (GLenum, GLenum, GLfloat)) AGL_API(void, FragmentMaterialfvSGIX, (GLenum, GLenum, const GLfloat *)) AGL_API(void, FragmentMaterialiSGIX, (GLenum, GLenum, GLint)) AGL_API(void, FragmentMaterialivSGIX, (GLenum, GLenum, const GLint *)) AGL_API(void, GetFragmentLightfvSGIX, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetFragmentLightivSGIX, (GLenum, GLenum, GLint *)) AGL_API(void, GetFragmentMaterialfvSGIX, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetFragmentMaterialivSGIX, (GLenum, GLenum, GLint *)) AGL_API(void, LightEnviSGIX, (GLenum, GLint)) #endif #if defined _ALLEGRO_GL_EXT_draw_range_elements AGL_API(void, DrawRangeElementsEXT, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_light_texture AGL_API(void, ApplyTextureEXT, (GLenum)) AGL_API(void, TextureLightEXT, (GLenum)) AGL_API(void, TextureMaterialEXT, (GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_SGIX_async AGL_API(void, AsyncMarkerSGIX, (GLuint)) AGL_API(GLint, FinishAsyncSGIX, (GLuint *)) AGL_API(GLint, PollAsyncSGIX, (GLuint *)) AGL_API(GLuint, GenAsyncMarkersSGIX, (GLsizei)) AGL_API(void, DeleteAsyncMarkersSGIX, (GLuint, GLsizei)) AGL_API(GLboolean, IsAsyncMarkerSGIX, (GLuint)) #endif #if defined _ALLEGRO_GL_INTEL_parallel_arrays AGL_API(void, VertexPointervINTEL, (GLint, GLenum, const GLvoid* *)) AGL_API(void, NormalPointervINTEL, (GLenum, const GLvoid* *)) AGL_API(void, ColorPointervINTEL, (GLint, GLenum, const GLvoid* *)) AGL_API(void, TexCoordPointervINTEL, (GLint, GLenum, const GLvoid* *)) #endif #if defined _ALLEGRO_GL_EXT_pixel_transform AGL_API(void, PixelTransformParameteriEXT, (GLenum, GLenum, GLint)) AGL_API(void, PixelTransformParameterfEXT, (GLenum, GLenum, GLfloat)) AGL_API(void, PixelTransformParameterivEXT, (GLenum, GLenum, const GLint *)) AGL_API(void, PixelTransformParameterfvEXT, (GLenum, GLenum, const GLfloat *)) #endif #if defined _ALLEGRO_GL_EXT_secondary_color AGL_API(void, SecondaryColor3bEXT, (GLbyte, GLbyte, GLbyte)) AGL_API(void, SecondaryColor3bvEXT, (const GLbyte *)) AGL_API(void, SecondaryColor3dEXT, (GLdouble, GLdouble, GLdouble)) AGL_API(void, SecondaryColor3dvEXT, (const GLdouble *)) AGL_API(void, SecondaryColor3fEXT, (GLfloat, GLfloat, GLfloat)) AGL_API(void, SecondaryColor3fvEXT, (const GLfloat *)) AGL_API(void, SecondaryColor3iEXT, (GLint, GLint, GLint)) AGL_API(void, SecondaryColor3ivEXT, (const GLint *)) AGL_API(void, SecondaryColor3sEXT, (GLshort, GLshort, GLshort)) AGL_API(void, SecondaryColor3svEXT, (const GLshort *)) AGL_API(void, SecondaryColor3ubEXT, (GLubyte, GLubyte, GLubyte)) AGL_API(void, SecondaryColor3ubvEXT, (const GLubyte *)) AGL_API(void, SecondaryColor3uiEXT, (GLuint, GLuint, GLuint)) AGL_API(void, SecondaryColor3uivEXT, (const GLuint *)) AGL_API(void, SecondaryColor3usEXT, (GLushort, GLushort, GLushort)) AGL_API(void, SecondaryColor3usvEXT, (const GLushort *)) AGL_API(void, SecondaryColorPointerEXT, (GLint, GLenum, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_texture_perturb_normal AGL_API(void, TextureNormalEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_EXT_multi_draw_arrays AGL_API(void, MultiDrawArraysEXT, (GLenum, GLint *, GLsizei *, GLsizei)) AGL_API(void, MultiDrawElementsEXT, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) #endif #if defined _ALLEGRO_GL_EXT_fog_coord AGL_API(void, FogCoordfEXT, (GLfloat)) AGL_API(void, FogCoordfvEXT, (const GLfloat *)) AGL_API(void, FogCoorddEXT, (GLdouble)) AGL_API(void, FogCoorddvEXT, (const GLdouble *)) AGL_API(void, FogCoordPointerEXT, (GLenum, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_coordinate_frame AGL_API(void, Tangent3bEXT, (GLbyte, GLbyte, GLbyte)) AGL_API(void, Tangent3bvEXT, (const GLbyte *)) AGL_API(void, Tangent3dEXT, (GLdouble, GLdouble, GLdouble)) AGL_API(void, Tangent3dvEXT, (const GLdouble *)) AGL_API(void, Tangent3fEXT, (GLfloat, GLfloat, GLfloat)) AGL_API(void, Tangent3fvEXT, (const GLfloat *)) AGL_API(void, Tangent3iEXT, (GLint, GLint, GLint)) AGL_API(void, Tangent3ivEXT, (const GLint *)) AGL_API(void, Tangent3sEXT, (GLshort, GLshort, GLshort)) AGL_API(void, Tangent3svEXT, (const GLshort *)) AGL_API(void, Binormal3bEXT, (GLbyte, GLbyte, GLbyte)) AGL_API(void, Binormal3bvEXT, (const GLbyte *)) AGL_API(void, Binormal3dEXT, (GLdouble, GLdouble, GLdouble)) AGL_API(void, Binormal3dvEXT, (const GLdouble *)) AGL_API(void, Binormal3fEXT, (GLfloat, GLfloat, GLfloat)) AGL_API(void, Binormal3fvEXT, (const GLfloat *)) AGL_API(void, Binormal3iEXT, (GLint, GLint, GLint)) AGL_API(void, Binormal3ivEXT, (const GLint *)) AGL_API(void, Binormal3sEXT, (GLshort, GLshort, GLshort)) AGL_API(void, Binormal3svEXT, (const GLshort *)) AGL_API(void, TangentPointerEXT, (GLenum, GLsizei, const GLvoid *)) AGL_API(void, BinormalPointerEXT, (GLenum, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_SUNX_constant_data AGL_API(void, FinishTextureSUNX, (void)) #endif #if defined _ALLEGRO_GL_SUN_global_alpha AGL_API(void, GlobalAlphaFactorbSUN, (GLbyte)) AGL_API(void, GlobalAlphaFactorsSUN, (GLshort)) AGL_API(void, GlobalAlphaFactoriSUN, (GLint)) AGL_API(void, GlobalAlphaFactorfSUN, (GLfloat)) AGL_API(void, GlobalAlphaFactordSUN, (GLdouble)) AGL_API(void, GlobalAlphaFactorubSUN, (GLubyte)) AGL_API(void, GlobalAlphaFactorusSUN, (GLushort)) AGL_API(void, GlobalAlphaFactoruiSUN, (GLuint)) #endif #if defined _ALLEGRO_GL_SUN_triangle_list AGL_API(void, ReplacementCodeuiSUN, (GLuint)) AGL_API(void, ReplacementCodeusSUN, (GLushort)) AGL_API(void, ReplacementCodeubSUN, (GLubyte)) AGL_API(void, ReplacementCodeuivSUN, (const GLuint *)) AGL_API(void, ReplacementCodeusvSUN, (const GLushort *)) AGL_API(void, ReplacementCodeubvSUN, (const GLubyte *)) AGL_API(void, ReplacementCodePointerSUN, (GLenum, GLsizei, const GLvoid* *)) #endif #if defined _ALLEGRO_GL_SUN_vertex AGL_API(void, Color4ubVertex2fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat)) AGL_API(void, Color4ubVertex2fvSUN, (const GLubyte *, const GLfloat *)) AGL_API(void, Color4ubVertex3fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) AGL_API(void, Color4ubVertex3fvSUN, (const GLubyte *, const GLfloat *)) AGL_API(void, Color3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, Color3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) AGL_API(void, Normal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, Normal3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) AGL_API(void, Color4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, Color4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord2fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord2fVertex3fvSUN, (const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord4fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord4fVertex4fvSUN, (const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord2fColor4ubVertex3fSUN, (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord2fColor4ubVertex3fvSUN, (const GLfloat *, const GLubyte *, const GLfloat *)) AGL_API(void, TexCoord2fColor3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord2fColor3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord2fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord2fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord2fColor4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord2fColor4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, TexCoord4fColor4fNormal3fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, TexCoord4fColor4fNormal3fVertex4fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiVertex3fvSUN, (const GLuint *, const GLfloat *)) AGL_API(void, ReplacementCodeuiColor4ubVertex3fSUN, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiColor4ubVertex3fvSUN, (const GLuint *, const GLubyte *, const GLfloat *)) AGL_API(void, ReplacementCodeuiColor3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiColor3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) #endif #if defined _ALLEGRO_GL_EXT_blend_func_separate AGL_API(void, BlendFuncSeparateEXT, (GLenum, GLenum, GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_INGR_blend_func_separate AGL_API(void, BlendFuncSeparateINGR, (GLenum, GLenum, GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_EXT_vertex_weighting AGL_API(void, VertexWeightfEXT, (GLfloat)) AGL_API(void, VertexWeightfvEXT, (const GLfloat *)) AGL_API(void, VertexWeightPointerEXT, (GLsizei, GLenum, GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_NV_vertex_array_range AGL_API(void, FlushVertexArrayRangeNV, (void)) AGL_API(void, VertexArrayRangeNV, (GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_NV_register_combiners AGL_API(void, CombinerParameterfvNV, (GLenum, const GLfloat *)) AGL_API(void, CombinerParameterfNV, (GLenum, GLfloat)) AGL_API(void, CombinerParameterivNV, (GLenum, const GLint *)) AGL_API(void, CombinerParameteriNV, (GLenum, GLint)) AGL_API(void, CombinerInputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum)) AGL_API(void, CombinerOutputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean)) AGL_API(void, FinalCombinerInputNV, (GLenum, GLenum, GLenum, GLenum)) AGL_API(void, GetCombinerInputParameterfvNV, (GLenum, GLenum, GLenum, GLenum, GLfloat *)) AGL_API(void, GetCombinerInputParameterivNV, (GLenum, GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetCombinerOutputParameterfvNV, (GLenum, GLenum, GLenum, GLfloat *)) AGL_API(void, GetCombinerOutputParameterivNV, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetFinalCombinerInputParameterfvNV, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetFinalCombinerInputParameterivNV, (GLenum, GLenum, GLint *)) #endif #if defined _ALLEGRO_GL_MESA_resize_buffers AGL_API(void, ResizeBuffersMESA, (void)) #endif #if defined _ALLEGRO_GL_MESA_window_pos AGL_API(void, WindowPos2dMESA, (GLdouble, GLdouble)) AGL_API(void, WindowPos2dvMESA, (const GLdouble *)) AGL_API(void, WindowPos2fMESA, (GLfloat, GLfloat)) AGL_API(void, WindowPos2fvMESA, (const GLfloat *)) AGL_API(void, WindowPos2iMESA, (GLint, GLint)) AGL_API(void, WindowPos2ivMESA, (const GLint *)) AGL_API(void, WindowPos2sMESA, (GLshort, GLshort)) AGL_API(void, WindowPos2svMESA, (const GLshort *)) AGL_API(void, WindowPos3dMESA, (GLdouble, GLdouble, GLdouble)) AGL_API(void, WindowPos3dvMESA, (const GLdouble *)) AGL_API(void, WindowPos3fMESA, (GLfloat, GLfloat, GLfloat)) AGL_API(void, WindowPos3fvMESA, (const GLfloat *)) AGL_API(void, WindowPos3iMESA, (GLint, GLint, GLint)) AGL_API(void, WindowPos3ivMESA, (const GLint *)) AGL_API(void, WindowPos3sMESA, (GLshort, GLshort, GLshort)) AGL_API(void, WindowPos3svMESA, (const GLshort *)) AGL_API(void, WindowPos4dMESA, (GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, WindowPos4dvMESA, (const GLdouble *)) AGL_API(void, WindowPos4fMESA, (GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, WindowPos4fvMESA, (const GLfloat *)) AGL_API(void, WindowPos4iMESA, (GLint, GLint, GLint, GLint)) AGL_API(void, WindowPos4ivMESA, (const GLint *)) AGL_API(void, WindowPos4sMESA, (GLshort, GLshort, GLshort, GLshort)) AGL_API(void, WindowPos4svMESA, (const GLshort *)) #endif #if defined _ALLEGRO_GL_IBM_multimode_draw_arrays AGL_API(void, MultiModeDrawArraysIBM, (GLenum, const GLint *, const GLsizei *, GLsizei, GLint)) AGL_API(void, MultiModeDrawElementsIBM, (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint)) #endif #ifdef AGK_IBM_vertex_array_lists AGL_API(void, ColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, SecondaryColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, EdgeFlagPointerListIBM, (GLint, const GLboolean* *, GLint)) AGL_API(void, FogCoordPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, IndexPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, NormalPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, TexCoordPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) AGL_API(void, VertexPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) #endif #if defined _ALLEGRO_GL_3DFX_tbuffer AGL_API(void, TbufferMask3DFX, (GLuint)) #endif #if defined _ALLEGRO_GL_EXT_multisample AGL_API(void, SampleMaskEXT, (GLclampf, GLboolean)) AGL_API(void, SamplePatternEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_SGIS_texture_color_mask AGL_API(void, TextureColorMaskSGIS, (GLboolean, GLboolean, GLboolean, GLboolean)) #endif #if defined _ALLEGRO_GL_SGIX_igloo_interface AGL_API(void, IglooInterfaceSGIX, (GLenum, const GLvoid *)) #endif #if defined _ALLEGRO_GL_NV_fence AGL_API(void, DeleteFencesNV, (GLsizei, const GLuint *)) AGL_API(void, GenFencesNV, (GLsizei, GLuint *)) AGL_API(GLboolean, IsFenceNV, (GLuint)) AGL_API(GLboolean, TestFenceNV, (GLuint)) AGL_API(void, GetFenceivNV, (GLuint, GLenum, GLint *)) AGL_API(void, FinishFenceNV, (GLuint)) AGL_API(void, SetFenceNV, (GLuint, GLenum)) #endif #if defined _ALLEGRO_GL_NV_evaluators AGL_API(void, MapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *)) AGL_API(void, MapParameterivNV, (GLenum, GLenum, const GLint *)) AGL_API(void, MapParameterfvNV, (GLenum, GLenum, const GLfloat *)) AGL_API(void, GetMapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *)) AGL_API(void, GetMapParameterivNV, (GLenum, GLenum, GLint *)) AGL_API(void, GetMapParameterfvNV, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetMapAttribParameterivNV, (GLenum, GLuint, GLenum, GLint *)) AGL_API(void, GetMapAttribParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) AGL_API(void, EvalMapsNV, (GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_NV_register_combiners2 AGL_API(void, CombinerStageParameterfvNV, (GLenum, GLenum, const GLfloat *)) AGL_API(void, GetCombinerStageParameterfvNV, (GLenum, GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_NV_vertex_program AGL_API(GLboolean, AreProgramsResidentNV, (GLsizei, const GLuint *, GLboolean *)) AGL_API(void, BindProgramNV, (GLenum, GLuint)) AGL_API(void, DeleteProgramsNV, (GLsizei, const GLuint *)) AGL_API(void, ExecuteProgramNV, (GLenum, GLuint, const GLfloat *)) AGL_API(void, GenProgramsNV, (GLsizei, GLuint *)) AGL_API(void, GetProgramParameterdvNV, (GLenum, GLuint, GLenum, GLdouble *)) AGL_API(void, GetProgramParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) AGL_API(void, GetProgramivNV, (GLuint, GLenum, GLint *)) AGL_API(void, GetProgramStringNV, (GLuint, GLenum, GLubyte *)) AGL_API(void, GetTrackMatrixivNV, (GLenum, GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribdvNV, (GLuint, GLenum, GLdouble *)) AGL_API(void, GetVertexAttribfvNV, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVertexAttribivNV, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribPointervNV, (GLuint, GLenum, GLvoid* *)) AGL_API(GLboolean, IsProgramNV, (GLuint)) AGL_API(void, LoadProgramNV, (GLenum, GLuint, GLsizei, const GLubyte *)) AGL_API(void, ProgramParameter4dNV, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, ProgramParameter4dvNV, (GLenum, GLuint, const GLdouble *)) AGL_API(void, ProgramParameter4fNV, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramParameter4fvNV, (GLenum, GLuint, const GLfloat *)) AGL_API(void, ProgramParameters4dvNV, (GLenum, GLuint, GLuint, const GLdouble *)) AGL_API(void, ProgramParameters4fvNV, (GLenum, GLuint, GLuint, const GLfloat *)) AGL_API(void, RequestResidentProgramsNV, (GLsizei, const GLuint *)) AGL_API(void, TrackMatrixNV, (GLenum, GLuint, GLenum, GLenum)) AGL_API(void, VertexAttribPointerNV, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, VertexAttrib1dNV, (GLuint, GLdouble)) AGL_API(void, VertexAttrib1dvNV, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib1fNV, (GLuint, GLfloat)) AGL_API(void, VertexAttrib1fvNV, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib1sNV, (GLuint, GLshort)) AGL_API(void, VertexAttrib1svNV, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib2dNV, (GLuint, GLdouble, GLdouble)) AGL_API(void, VertexAttrib2dvNV, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib2fNV, (GLuint, GLfloat, GLfloat)) AGL_API(void, VertexAttrib2fvNV, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib2sNV, (GLuint, GLshort, GLshort)) AGL_API(void, VertexAttrib2svNV, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib3dNV, (GLuint, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib3dvNV, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib3fNV, (GLuint, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib3fvNV, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib3sNV, (GLuint, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib3svNV, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4dNV, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexAttrib4dvNV, (GLuint, const GLdouble *)) AGL_API(void, VertexAttrib4fNV, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexAttrib4fvNV, (GLuint, const GLfloat *)) AGL_API(void, VertexAttrib4sNV, (GLuint, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, VertexAttrib4svNV, (GLuint, const GLshort *)) AGL_API(void, VertexAttrib4ubNV, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) AGL_API(void, VertexAttrib4ubvNV, (GLuint, const GLubyte *)) AGL_API(void, VertexAttribs1dvNV, (GLuint, GLsizei, const GLdouble *)) AGL_API(void, VertexAttribs1fvNV, (GLuint, GLsizei, const GLfloat *)) AGL_API(void, VertexAttribs1svNV, (GLuint, GLsizei, const GLshort *)) AGL_API(void, VertexAttribs2dvNV, (GLuint, GLsizei, const GLdouble *)) AGL_API(void, VertexAttribs2fvNV, (GLuint, GLsizei, const GLfloat *)) AGL_API(void, VertexAttribs2svNV, (GLuint, GLsizei, const GLshort *)) AGL_API(void, VertexAttribs3dvNV, (GLuint, GLsizei, const GLdouble *)) AGL_API(void, VertexAttribs3fvNV, (GLuint, GLsizei, const GLfloat *)) AGL_API(void, VertexAttribs3svNV, (GLuint, GLsizei, const GLshort *)) AGL_API(void, VertexAttribs4dvNV, (GLuint, GLsizei, const GLdouble *)) AGL_API(void, VertexAttribs4fvNV, (GLuint, GLsizei, const GLfloat *)) AGL_API(void, VertexAttribs4svNV, (GLuint, GLsizei, const GLshort *)) AGL_API(void, VertexAttribs4ubvNV, (GLuint, GLsizei, const GLubyte *)) #endif #if defined _ALLEGRO_GL_ATI_envmap_bumpmap AGL_API(void, TexBumpParameterivATI, (GLenum, const GLint *)) AGL_API(void, TexBumpParameterfvATI, (GLenum, const GLfloat *)) AGL_API(void, GetTexBumpParameterivATI, (GLenum, GLint *)) AGL_API(void, GetTexBumpParameterfvATI, (GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_ATI_fragment_shader AGL_API(GLuint, GenFragmentShadersATI, (GLuint)) AGL_API(void, BindFragmentShaderATI, (GLuint)) AGL_API(void, DeleteFragmentShaderATI, (GLuint)) AGL_API(void, BeginFragmentShaderATI, (void)) AGL_API(void, EndFragmentShaderATI, (void)) AGL_API(void, PassTexCoordATI, (GLuint, GLuint, GLenum)) AGL_API(void, SampleMapATI, (GLuint, GLuint, GLenum)) AGL_API(void, ColorFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, ColorFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, ColorFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, AlphaFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, AlphaFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, AlphaFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, SetFragmentShaderConstantATI, (GLuint, const GLfloat *)) #endif #if defined _ALLEGRO_GL_ATI_pn_triangles AGL_API(void, PNTrianglesiATI, (GLenum, GLint)) AGL_API(void, PNTrianglesfATI, (GLenum, GLfloat)) #endif #if defined _ALLEGRO_GL_ATI_vertex_array_object AGL_API(GLuint, NewObjectBufferATI, (GLsizei, const GLvoid *, GLenum)) AGL_API(GLboolean, IsObjectBufferATI, (GLuint)) AGL_API(void, UpdateObjectBufferATI, (GLuint, GLuint, GLsizei, const GLvoid *, GLenum)) AGL_API(void, GetObjectBufferfvATI, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetObjectBufferivATI, (GLuint, GLenum, GLint *)) AGL_API(void, FreeObjectBufferATI, (GLuint)) AGL_API(void, ArrayObjectATI, (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint)) AGL_API(void, GetArrayObjectfvATI, (GLenum, GLenum, GLfloat *)) AGL_API(void, GetArrayObjectivATI, (GLenum, GLenum, GLint *)) AGL_API(void, VariantArrayObjectATI, (GLuint, GLenum, GLsizei, GLuint, GLuint)) AGL_API(void, GetVariantArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVariantArrayObjectivATI, (GLuint, GLenum, GLint *)) #endif #if defined _ALLEGRO_GL_EXT_vertex_shader AGL_API(void, BeginVertexShaderEXT, (void)) AGL_API(void, EndVertexShaderEXT, (void)) AGL_API(void, BindVertexShaderEXT, (GLuint)) AGL_API(GLuint, GenVertexShadersEXT, (GLuint)) AGL_API(void, DeleteVertexShaderEXT, (GLuint)) AGL_API(void, ShaderOp1EXT, (GLenum, GLuint, GLuint)) AGL_API(void, ShaderOp2EXT, (GLenum, GLuint, GLuint, GLuint)) AGL_API(void, ShaderOp3EXT, (GLenum, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, SwizzleEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) AGL_API(void, WriteMaskEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) AGL_API(void, InsertComponentEXT, (GLuint, GLuint, GLuint)) AGL_API(void, ExtractComponentEXT, (GLuint, GLuint, GLuint)) AGL_API(GLuint, GenSymbolsEXT, (GLenum, GLenum, GLenum, GLuint)) AGL_API(void, SetInvariantEXT, (GLuint, GLenum, const GLvoid *)) AGL_API(void, SetLocalConstantEXT, (GLuint, GLenum, const GLvoid *)) AGL_API(void, VariantbvEXT, (GLuint, const GLbyte *)) AGL_API(void, VariantsvEXT, (GLuint, const GLshort *)) AGL_API(void, VariantivEXT, (GLuint, const GLint *)) AGL_API(void, VariantfvEXT, (GLuint, const GLfloat *)) AGL_API(void, VariantdvEXT, (GLuint, const GLdouble *)) AGL_API(void, VariantubvEXT, (GLuint, const GLubyte *)) AGL_API(void, VariantusvEXT, (GLuint, const GLushort *)) AGL_API(void, VariantuivEXT, (GLuint, const GLuint *)) AGL_API(void, VariantPointerEXT, (GLuint, GLenum, GLuint, const GLvoid *)) AGL_API(void, EnableVariantClientStateEXT, (GLuint)) AGL_API(void, DisableVariantClientStateEXT, (GLuint)) AGL_API(GLuint, BindLightParameterEXT, (GLenum, GLenum)) AGL_API(GLuint, BindMaterialParameterEXT, (GLenum, GLenum)) AGL_API(GLuint, BindTexGenParameterEXT, (GLenum, GLenum, GLenum)) AGL_API(GLuint, BindTextureUnitParameterEXT, (GLenum, GLenum)) AGL_API(GLuint, BindParameterEXT, (GLenum)) AGL_API(GLboolean, IsVariantEnabledEXT, (GLuint, GLenum)) AGL_API(void, GetVariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) AGL_API(void, GetVariantIntegervEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetVariantFloatvEXT, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVariantPointervEXT, (GLuint, GLenum, GLvoid* *)) AGL_API(void, GetInvariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) AGL_API(void, GetInvariantIntegervEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetInvariantFloatvEXT, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetLocalConstantBooleanvEXT, (GLuint, GLenum, GLboolean *)) AGL_API(void, GetLocalConstantIntegervEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetLocalConstantFloatvEXT, (GLuint, GLenum, GLfloat *)) #endif #if defined _ALLEGRO_GL_ATI_vertex_streams AGL_API(void, VertexStream1sATI, (GLenum, GLshort)) AGL_API(void, VertexStream1svATI, (GLenum, const GLshort *)) AGL_API(void, VertexStream1iATI, (GLenum, GLint)) AGL_API(void, VertexStream1ivATI, (GLenum, const GLint *)) AGL_API(void, VertexStream1fATI, (GLenum, GLfloat)) AGL_API(void, VertexStream1fvATI, (GLenum, const GLfloat *)) AGL_API(void, VertexStream1dATI, (GLenum, GLdouble)) AGL_API(void, VertexStream1dvATI, (GLenum, const GLdouble *)) AGL_API(void, VertexStream2sATI, (GLenum, GLshort, GLshort)) AGL_API(void, VertexStream2svATI, (GLenum, const GLshort *)) AGL_API(void, VertexStream2iATI, (GLenum, GLint, GLint)) AGL_API(void, VertexStream2ivATI, (GLenum, const GLint *)) AGL_API(void, VertexStream2fATI, (GLenum, GLfloat, GLfloat)) AGL_API(void, VertexStream2fvATI, (GLenum, const GLfloat *)) AGL_API(void, VertexStream2dATI, (GLenum, GLdouble, GLdouble)) AGL_API(void, VertexStream2dvATI, (GLenum, const GLdouble *)) AGL_API(void, VertexStream3sATI, (GLenum, GLshort, GLshort, GLshort)) AGL_API(void, VertexStream3svATI, (GLenum, const GLshort *)) AGL_API(void, VertexStream3iATI, (GLenum, GLint, GLint, GLint)) AGL_API(void, VertexStream3ivATI, (GLenum, const GLint *)) AGL_API(void, VertexStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexStream3fvATI, (GLenum, const GLfloat *)) AGL_API(void, VertexStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexStream3dvATI, (GLenum, const GLdouble *)) AGL_API(void, VertexStream4sATI, (GLenum, GLshort, GLshort, GLshort, GLshort)) AGL_API(void, VertexStream4svATI, (GLenum, const GLshort *)) AGL_API(void, VertexStream4iATI, (GLenum, GLint, GLint, GLint, GLint)) AGL_API(void, VertexStream4ivATI, (GLenum, const GLint *)) AGL_API(void, VertexStream4fATI, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, VertexStream4fvATI, (GLenum, const GLfloat *)) AGL_API(void, VertexStream4dATI, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, VertexStream4dvATI, (GLenum, const GLdouble *)) AGL_API(void, NormalStream3bATI, (GLenum, GLbyte, GLbyte, GLbyte)) AGL_API(void, NormalStream3bvATI, (GLenum, const GLbyte *)) AGL_API(void, NormalStream3sATI, (GLenum, GLshort, GLshort, GLshort)) AGL_API(void, NormalStream3svATI, (GLenum, const GLshort *)) AGL_API(void, NormalStream3iATI, (GLenum, GLint, GLint, GLint)) AGL_API(void, NormalStream3ivATI, (GLenum, const GLint *)) AGL_API(void, NormalStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, NormalStream3fvATI, (GLenum, const GLfloat *)) AGL_API(void, NormalStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, NormalStream3dvATI, (GLenum, const GLdouble *)) AGL_API(void, ClientActiveVertexStreamATI, (GLenum)) AGL_API(void, VertexBlendEnviATI, (GLenum, GLint)) AGL_API(void, VertexBlendEnvfATI, (GLenum, GLfloat)) #endif #if defined _ALLEGRO_GL_ATI_element_array AGL_API(void, ElementPointerATI, (GLenum, const GLvoid *)) AGL_API(void, DrawElementArrayATI, (GLenum, GLsizei)) AGL_API(void, DrawRangeElementArrayATI, (GLenum, GLuint, GLuint, GLsizei)) #endif #if defined _ALLEGRO_GL_SUN_mesh_array AGL_API(void, DrawMeshArraysSUN, (GLenum, GLint, GLsizei, GLsizei)) #endif #if defined _ALLEGRO_GL_NV_occlusion_query AGL_API(void, GenOcclusionQueriesNV, (GLsizei, GLuint *)) AGL_API(void, DeleteOcclusionQueriesNV, (GLsizei, const GLuint *)) AGL_API(GLboolean, IsOcclusionQueryNV, (GLuint)) AGL_API(void, BeginOcclusionQueryNV, (GLuint)) AGL_API(void, EndOcclusionQueryNV, (void)) AGL_API(void, GetOcclusionQueryivNV, (GLuint, GLenum, GLint *)) AGL_API(void, GetOcclusionQueryuivNV, (GLuint, GLenum, GLuint *)) #endif #if defined _ALLEGRO_GL_NV_point_sprite AGL_API(void, PointParameteriNV, (GLenum, GLint)) AGL_API(void, PointParameterivNV, (GLenum, const GLint *)) #endif #if defined _ALLEGRO_GL_EXT_stencil_two_side AGL_API(void, ActiveStencilFaceEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_APPLE_element_array AGL_API(void, ElementPointerAPPLE, (GLenum, const GLvoid *)) AGL_API(void, DrawElementArrayAPPLE, (GLenum, GLint, GLsizei)) AGL_API(void, DrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, GLint, GLsizei)) AGL_API(void, MultiDrawElementArrayAPPLE, (GLenum, const GLint *, const GLsizei *, GLsizei)) AGL_API(void, MultiDrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei)) #endif #if defined _ALLEGRO_GL_APPLE_fence AGL_API(void, GenFencesAPPLE, (GLsizei, GLuint *)) AGL_API(void, DeleteFencesAPPLE, (GLsizei, const GLuint *)) AGL_API(void, SetFenceAPPLE, (GLuint)) AGL_API(GLboolean, IsFenceAPPLE, (GLuint)) AGL_API(GLboolean, TestFenceAPPLE, (GLuint)) AGL_API(void, FinishFenceAPPLE, (GLuint)) AGL_API(GLboolean, TestObjectAPPLE, (GLenum, GLuint)) AGL_API(void, FinishObjectAPPLE, (GLenum, GLint)) #endif #if defined _ALLEGRO_GL_APPLE_vertex_array_object AGL_API(void, BindVertexArrayAPPLE, (GLuint)) AGL_API(void, DeleteVertexArraysAPPLE, (GLsizei, const GLuint *)) AGL_API(void, GenVertexArraysAPPLE, (GLsizei, const GLuint *)) AGL_API(GLboolean, IsVertexArrayAPPLE, (GLuint)) #endif #if defined _ALLEGRO_GL_APPLE_vertex_array_range AGL_API(void, VertexArrayRangeAPPLE, (GLsizei, GLvoid *)) AGL_API(void, FlushVertexArrayRangeAPPLE, (GLsizei, GLvoid *)) AGL_API(void, VertexArrayParameteriAPPLE, (GLenum, GLint)) #endif #if defined _ALLEGRO_GL_ATI_draw_buffers AGL_API(void, DrawBuffersATI, (GLsizei, const GLenum *)) #endif #if defined _ALLEGRO_GL_NV_fragment_program AGL_API(void, ProgramNamedParameter4fNV, (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramNamedParameter4dNV, (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, ProgramNamedParameter4fvNV, (GLuint, GLsizei, const GLubyte *, const GLfloat *)) AGL_API(void, ProgramNamedParameter4dvNV, (GLuint, GLsizei, const GLubyte *, const GLdouble *)) AGL_API(void, GetProgramNamedParameterfvNV, (GLuint, GLsizei, const GLubyte *, GLfloat *)) AGL_API(void, GetProgramNamedParameterdvNV, (GLuint, GLsizei, const GLubyte *, GLdouble *)) #endif #if defined _ALLEGRO_GL_NV_half_float AGL_API(void, Vertex2hNV, (GLhalfNV, GLhalfNV)) AGL_API(void, Vertex2hvNV, (const GLhalfNV *)) AGL_API(void, Vertex3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, Vertex3hvNV, (const GLhalfNV *)) AGL_API(void, Vertex4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, Vertex4hvNV, (const GLhalfNV *)) AGL_API(void, Normal3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, Normal3hvNV, (const GLhalfNV *)) AGL_API(void, Color3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, Color3hvNV, (const GLhalfNV *)) AGL_API(void, Color4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, Color4hvNV, (const GLhalfNV *)) AGL_API(void, TexCoord1hNV, (GLhalfNV)) AGL_API(void, TexCoord1hvNV, (const GLhalfNV *)) AGL_API(void, TexCoord2hNV, (GLhalfNV, GLhalfNV)) AGL_API(void, TexCoord2hvNV, (const GLhalfNV *)) AGL_API(void, TexCoord3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, TexCoord3hvNV, (const GLhalfNV *)) AGL_API(void, TexCoord4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, TexCoord4hvNV, (const GLhalfNV *)) AGL_API(void, MultiTexCoord1hNV, (GLenum, GLhalfNV)) AGL_API(void, MultiTexCoord1hvNV, (GLenum, const GLhalfNV *)) AGL_API(void, MultiTexCoord2hNV, (GLenum, GLhalfNV, GLhalfNV)) AGL_API(void, MultiTexCoord2hvNV, (GLenum, const GLhalfNV *)) AGL_API(void, MultiTexCoord3hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, MultiTexCoord3hvNV, (GLenum, const GLhalfNV *)) AGL_API(void, MultiTexCoord4hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, MultiTexCoord4hvNV, (GLenum, const GLhalfNV *)) AGL_API(void, FogCoordhNV, (GLhalfNV)) AGL_API(void, FogCoordhvNV, (const GLhalfNV *)) AGL_API(void, SecondaryColor3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, SecondaryColor3hvNV, (const GLhalfNV *)) AGL_API(void, VertexWeighthNV, (GLhalfNV)) AGL_API(void, VertexWeighthvNV, (const GLhalfNV *)) AGL_API(void, VertexAttrib1hNV, (GLuint, GLhalfNV)) AGL_API(void, VertexAttrib1hvNV, (GLuint, const GLhalfNV *)) AGL_API(void, VertexAttrib2hNV, (GLuint, GLhalfNV, GLhalfNV)) AGL_API(void, VertexAttrib2hvNV, (GLuint, const GLhalfNV *)) AGL_API(void, VertexAttrib3hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, VertexAttrib3hvNV, (GLuint, const GLhalfNV *)) AGL_API(void, VertexAttrib4hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) AGL_API(void, VertexAttrib4hvNV, (GLuint, const GLhalfNV *)) AGL_API(void, VertexAttribs1hvNV, (GLuint, GLsizei, const GLhalfNV *)) AGL_API(void, VertexAttribs2hvNV, (GLuint, GLsizei, const GLhalfNV *)) AGL_API(void, VertexAttribs3hvNV, (GLuint, GLsizei, const GLhalfNV *)) AGL_API(void, VertexAttribs4hvNV, (GLuint, GLsizei, const GLhalfNV *)) #endif #if defined _ALLEGRO_GL_NV_pixel_data_range AGL_API(void, PixelDataRangeNV, (GLenum, GLsizei, GLvoid *)) AGL_API(void, FlushPixelDataRangeNV, (GLenum)) #endif #if defined _ALLEGRO_GL_NV_primitive_restart AGL_API(void, PrimitiveRestartNV, (void)) AGL_API(void, PrimitiveRestartIndexNV, (GLuint)) #endif #if defined _ALLEGRO_GL_ATI_map_object_buffer AGL_API(GLvoid*, MapObjectBufferATI, (GLuint)) AGL_API(void, UnmapObjectBufferATI, (GLuint)) #endif #if defined _ALLEGRO_GL_ATI_separate_stencil AGL_API(void, StencilOpSeparateATI, (GLenum, GLenum, GLenum, GLenum)) AGL_API(void, StencilFuncSeparateATI, (GLenum, GLenum, GLint, GLuint)) #endif #if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object AGL_API(void, VertexAttribArrayObjectATI, (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint)) AGL_API(void, GetVertexAttribArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) AGL_API(void, GetVertexAttribArrayObjectivATI, (GLuint, GLenum, GLint *)) #endif #if defined _ALLEGRO_GL_OES_byte_coordinates AGL_API(void, Vertex2bOES, ( GLbyte, GLbyte )) AGL_API(void, Vertex3bOES, ( GLbyte, GLbyte, GLbyte )) AGL_API(void, Vertex4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) AGL_API(void, Vertex2bvOES, ( const GLbyte * )) AGL_API(void, Vertex3bvOES, ( const GLbyte * )) AGL_API(void, Vertex4bvOES, ( const GLbyte * )) AGL_API(void, TexCoord1bOES, ( GLbyte )) AGL_API(void, TexCoord2bOES, ( GLbyte, GLbyte )) AGL_API(void, TexCoord3bOES, ( GLbyte, GLbyte, GLbyte )) AGL_API(void, TexCoord4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) AGL_API(void, TexCoord1bvOES, ( const GLbyte * )) AGL_API(void, TexCoord2bvOES, ( const GLbyte * )) AGL_API(void, TexCoord3bvOES, ( const GLbyte * )) AGL_API(void, TexCoord4bvOES, ( const GLbyte * )) AGL_API(void, MultiTexCoord1bOES, ( GLenum, GLbyte )) AGL_API(void, MultiTexCoord2bOES, ( GLenum, GLbyte, GLbyte )) AGL_API(void, MultiTexCoord3bOES, ( GLenum, GLbyte, GLbyte, GLbyte )) AGL_API(void, MultiTexCoord4bOES, ( GLenum, GLbyte, GLbyte, GLbyte, GLbyte )) AGL_API(void, MultiTexCoord1bvOES, ( GLenum texture, const GLbyte * )) AGL_API(void, MultiTexCoord2bvOES, ( GLenum texture, const GLbyte * )) AGL_API(void, MultiTexCoord3bvOES, ( GLenum texture, const GLbyte * )) AGL_API(void, MultiTexCoord4bvOES, ( GLenum texture, const GLbyte * )) #endif #if defined _ALLEGRO_GL_OES_fixed_point AGL_API(void, Vertex2xOES, (GLfixed, GLfixed)) AGL_API(void, Vertex3xOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, Vertex4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, Vertex2xvOES, (const GLfixed *)) AGL_API(void, Vertex3xvOES, (const GLfixed *)) AGL_API(void, Vertex4xvOES, (const GLfixed *)) AGL_API(void, Normal3xOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, Normal3xvOES, (const GLfixed *)) AGL_API(void, TexCoord1xOES, (GLfixed)) AGL_API(void, TexCoord2xOES, (GLfixed, GLfixed)) AGL_API(void, TexCoord3xOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, TexCoord4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, TexCoord1xvOES, (const GLfixed *)) AGL_API(void, TexCoord2xvOES, (const GLfixed *)) AGL_API(void, TexCoord3xvOES, (const GLfixed *)) AGL_API(void, TexCoord4xvOES, (const GLfixed *)) AGL_API(void, MultiTexCoord1xOES, (GLenum, GLfixed)) AGL_API(void, MultiTexCoord2xOES, (GLenum, GLfixed, GLfixed)) AGL_API(void, MultiTexCoord3xOES, (GLenum, GLfixed, GLfixed, GLfixed)) AGL_API(void, MultiTexCoord4xOES, (GLenum, GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, MultiTexCoord1xvOES, (GLenum, const GLfixed *)) AGL_API(void, MultiTexCoord2xvOES, (GLenum, const GLfixed *)) AGL_API(void, MultiTexCoord3xvOES, (GLenum, const GLfixed *)) AGL_API(void, MultiTexCoord4xvOES, (GLenum, const GLfixed *)) AGL_API(void, Color3xOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, Color4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, Color3xvOES, (const GLfixed *)) AGL_API(void, Color4xvOES, (const GLfixed *)) AGL_API(void, IndexxOES, (GLfixed)) AGL_API(void, IndexxvOES, (const GLfixed *)) AGL_API(void, RectxOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, RectxvOES, (const GLfixed [2], const GLfixed [2])) AGL_API(void, DepthRangexOES, (GLclampx, GLclampx)) AGL_API(void, LoadMatrixxOES, (const GLfixed [16])) AGL_API(void, MultMatrixxOES, (const GLfixed [16])) AGL_API(void, LoadTransposeMatrixxOES, (const GLfixed [16])) AGL_API(void, MultTransposeMatrixxOES, (const GLfixed [16])) AGL_API(void, RotatexOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, ScalexOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, TranslatexOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, FrustumxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, OrthoxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, TexGenxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, TexGenxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetTexGenxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, ClipPlanexOES, (GLenum, const GLfixed *)) AGL_API(void, GetClipPlanexOES, (GLenum, GLfixed *)) AGL_API(void, RasterPos2xOES, (GLfixed, GLfixed)) AGL_API(void, RasterPos3xOES, (GLfixed, GLfixed, GLfixed)) AGL_API(void, RasterPos4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, RasterPos2xvOES, (const GLfixed *)) AGL_API(void, RasterPos3xvOES, (const GLfixed *)) AGL_API(void, RasterPos4xvOES, (const GLfixed *)) AGL_API(void, MaterialxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, MaterialxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetMaterialxOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, LightxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, LightxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetLightxOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, LightModelxOES, (GLenum, GLfixed)) AGL_API(void, LightModelxvOES, (GLenum, const GLfixed *)) AGL_API(void, PointSizexOES, (GLfixed size)) AGL_API(void, LineWidthxOES, (GLfixed width)) AGL_API(void, PolygonOffsetxOES, (GLfixed factor, GLfixed units)) AGL_API(void, PixelStorex, (GLenum pname, GLfixed param)) AGL_API(void, PixelTransferxOES, (GLenum pname, GLfixed param)) AGL_API(void, PixelMapx, (GLenum, GLint, const GLfixed *)) AGL_API(void, GetPixelMapxv, (GLenum, GLint, GLfixed *)) AGL_API(void, ConvolutionParameterxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, ConvolutionParameterxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetConvolutionParameterxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, GetHistogramParameterxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, PixelZoomxOES, (GLfixed, GLfixed)) AGL_API(void, BitmapxOES, (GLsizei, GLsizei, GLfixed, GLfixed, GLfixed, GLfixed, const GLubyte *)) AGL_API(void, TexParameterxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, TexParameterxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetTexParameterxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, GetTexLevelParameterxvOES, (GLenum, GLint, GLenum, GLfixed *)) AGL_API(void, PrioritizeTexturesxOES, (GLsizei, GLuint *, GLclampx *)) AGL_API(void, TexEnvxOES, (GLenum, GLenum, GLfixed)) AGL_API(void, TexEnvxvOES, (GLenum, GLenum, const GLfixed *)) AGL_API(void, GetTexEnvxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, FogxOES, (GLenum, GLfixed)) AGL_API(void, FogxvOES, (GLenum, const GLfixed *)) AGL_API(void, SampleCoverageOES, (GLclampx, GLboolean)) AGL_API(void, AlphaFuncxOES, (GLenum, GLclampx)) AGL_API(void, BlendColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) AGL_API(void, ClearColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) AGL_API(void, ClearDepthxOES, (GLclampx)) AGL_API(void, ClearAccumxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) AGL_API(void, AccumxOES, (GLenum, GLfixed)) AGL_API(void, Map1xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) AGL_API(void, Map2xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) AGL_API(void, MapGrid1xOES, (GLint, GLfixed, GLfixed)) AGL_API(void, MapGrid2xOES, (GLint, GLfixed, GLfixed, GLfixed, GLfixed)) AGL_API(void, GetMapxvOES, (GLenum, GLenum, GLfixed *)) AGL_API(void, EvalCoord1xOES, (GLfixed)) AGL_API(void, EvalCoord2xOES, (GLfixed, GLfixed)) AGL_API(void, EvalCoord1xvOES, (const GLfixed *)) AGL_API(void, EvalCoord2xvOES, (const GLfixed *)) AGL_API(void, FeedbackBufferxOES, (GLsizei, GLenum, GLfixed *)) AGL_API(void, PassThroughxOES, (GLfixed)) AGL_API(void, GetFixedvOES, (GLenum, GLfixed *)) #endif #if defined _ALLEGRO_GL_OES_single_precision AGL_API(void, DepthRangefOES, (GLclampf, GLclampf)) AGL_API(void, FrustumfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, OrthofOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ClipPlanefOES, (GLenum, const GLfloat*)) AGL_API(void, GetClipPlanefOES, (GLenum, GLfloat*)) AGL_API(void, ClearDepthfOES, (GLclampd)) #endif #if defined _ALLEGRO_GL_OES_query_matrix AGL_API(GLbitfield, QueryMatrixxOES, (GLfixed [16], GLint [16] )) #endif #if defined _ALLEGRO_GL_EXT_depth_bounds_test AGL_API(void, DepthBoundsEXT, (GLclampd, GLclampd)) #endif #if defined _ALLEGRO_GL_EXT_blend_equation_separate AGL_API(void, BlendEquationSeparateEXT, (GLenum, GLenum)) #endif #if defined _ALLEGRO_GL_EXT_framebuffer_object AGL_API(GLboolean, IsRenderbufferEXT, (GLuint)) AGL_API(void, BindRenderbufferEXT, (GLenum, GLuint)) AGL_API(void, DeleteRenderbuffersEXT, (GLsizei, const GLuint *)) AGL_API(void, GenRenderbuffersEXT, (GLsizei, GLuint *)) AGL_API(void, RenderbufferStorageEXT, (GLenum, GLenum, GLsizei, GLsizei)) AGL_API(void, GetRenderbufferParameterivEXT, (GLenum, GLenum, GLint*)) AGL_API(GLboolean, IsFramebufferEXT, (GLuint)) AGL_API(void, BindFramebufferEXT, (GLenum, GLuint)) AGL_API(void, DeleteFramebuffersEXT, (GLsizei, const GLuint *)) AGL_API(void, GenFramebuffersEXT, (GLsizei, GLuint *)) AGL_API(GLenum, CheckFramebufferStatusEXT, (GLenum)) AGL_API(void, FramebufferTexture1DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) AGL_API(void, FramebufferTexture2DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) AGL_API(void, FramebufferTexture3DEXT, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) AGL_API(void, FramebufferRenderbufferEXT, (GLenum, GLenum, GLenum, GLuint)) AGL_API(void, GetFramebufferAttachmentParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GenerateMipmapEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_GREMEDY_string_marker AGL_API(void, StringMarkerGREMEDY, (GLsizei, const GLvoid *)) #endif #if defined _ALLEGRO_GL_EXT_stencil_clear_tag AGL_API(void, StencilClearTagEXT, (GLsizei, GLuint)) #endif #if defined _ALLEGRO_GL_EXT_framebuffer_blit AGL_API(void, BlitFramebufferEXT, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) #endif #if defined _ALLEGRO_GL_EXT_framebuffer_multisample AGL_API(void, RenderbufferStorageMultisampleEXT, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) #endif #if defined _ALLEGRO_GL_EXT_timer_query AGL_API(void, GetQueryObjecti64vEXT, (GLuint, GLenum, GLint64EXT *)) AGL_API(void, GetQueryObjectui64vEXT, (GLuint, GLenum, GLuint64EXT *)) #endif #if defined _ALLEGRO_GL_EXT_gpu_program_parameters AGL_API(void, ProgramEnvParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) AGL_API(void, ProgramLocalParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) #endif #if defined _ALLEGRO_GL_APPLE_flush_buffer_range AGL_API(void, BufferParameteriAPPLE, (GLenum, GLenum, GLint)) AGL_API(void, FlushMappedBufferRangeAPPLE, (GLenum, GLintptr, GLsizeiptr)) #endif #if defined _ALLEGRO_GL_EXT_bindable_uniform AGL_API(void, UniformBufferEXT, (GLuint, GLint, GLuint)) AGL_API(GLint, GetUniformBufferSizeEXT, (GLuint, GLint)) AGL_API(GLintptr, GetUniformOffsetEXT, (GLuint program, GLint)) #endif #if defined _ALLEGRO_GL_EXT_draw_buffers2 AGL_API(void, ColorMaskIndexedEXT, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *)) AGL_API(void, EnableIndexedEXT, (GLenum, GLuint)) AGL_API(void, DisableIndexedEXT, (GLenum, GLuint)) AGL_API(GLboolean, IsEnabledIndexedEXT, (GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_EXT_draw_instanced AGL_API(void, DrawArraysInstancedEXT, (GLenum, GLint, GLsizei, GLsizei)) AGL_API(void, DrawElementsInstancedEXT, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) #endif #if defined _ALLEGRO_GL_EXT_geometry_shader4 AGL_API(void, ProgramParameteriEXT, (GLuint, GLenum, GLint)) AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) #if !defined _ALLEGRO_GL_EXT_texture_array AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) #endif AGL_API(void, FramebufferTextureFaceEXT, (GLenum, GLenum, GLuint, GLint, GLenum)) #endif #if defined _ALLEGRO_GL_EXT_gpu_shader4 AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) AGL_API(void, Uniform1uiEXT, (GLint, GLuint)) AGL_API(void, Uniform2uiEXT, (GLint, GLuint, GLuint)) AGL_API(void, Uniform3uiEXT, (GLint, GLuint, GLuint, GLuint)) AGL_API(void, Uniform4uiEXT, (GLint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, Uniform1uivEXT, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform2uivEXT, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform3uivEXT, (GLint, GLsizei, const GLuint *)) AGL_API(void, Uniform4uivEXT, (GLint, GLsizei, const GLuint *)) AGL_API(void, GetUniformuivEXT, (GLuint, GLint location, GLint *)) AGL_API(void, BindFragDataLocationEXT, (GLuint, GLuint, const GLchar *)) AGL_API(GLint, GetFragDataLocationEXT, (GLuint, const GLchar *)) #endif #if defined _ALLEGRO_GL_EXT_texture_array AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) #endif #if defined _ALLEGRO_GL_EXT_texture_buffer_object AGL_API(void, TexBufferEXT, (GLenum, GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_texture_integer AGL_API(void, ClearColorIiEXT, (GLint, GLint, GLint, GLint)) AGL_API(void, ClearColorIuiEXT, (GLuint, GLuint, GLuint, GLuint)) AGL_API(void, TexParameterIivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, TexParameterIuivEXT, (GLenum, GLenum, GLuint *)) AGL_API(void, GetTexParameterIivEXT, (GLenum, GLenum, GLint *)) AGL_API(void, GetTexParameterIiuvEXT, (GLenum, GLenum, GLuint *)) #endif #if defined _ALLEGRO_GL_NV_depth_buffer_float AGL_API(void, DepthRangedNV, (GLdouble, GLdouble)) AGL_API(void, ClearDepthdNV, (GLdouble)) AGL_API(void, DepthBoundsdNV, (GLdouble, GLdouble)) #endif #if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage AGL_API(void, RenderbufferStorageMultsampleCoverageNV, (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) #endif #if defined _ALLEGRO_GL_NV_geometry_program4 AGL_API(void, ProgramVertexLimitNV, (GLenum, GLint)) #if !defined _ALLEGRO_GL_EXT_geometry_shader4 AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) #if !defined _ALLEGRO_GL_EXT_texture_array AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) #endif #endif #endif #if defined _ALLEGRO_GL_NV_gpu_program4 AGL_API(void, ProgramLocalParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, ProgramLocalParameterI4ivNV, (GLenum, GLuint, const GLint *)) AGL_API(void, ProgramLocalParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) AGL_API(void, ProgramLocalParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, ProgramLocalParameterI4uivNV, (GLenum, GLuint, const GLuint *)) AGL_API(void, ProgramLocalParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) AGL_API(void, ProgramEnvParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, ProgramEnvParameterI4ivNV, (GLenum, GLuint, const GLint *)) AGL_API(void, ProgramEnvParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) AGL_API(void, ProgramEnvParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, ProgramEnvParameterI4uivNV, (GLenum, GLuint, const GLuint *)) AGL_API(void, ProgramEnvParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) AGL_API(void, GetProgramLocalParameterIivNV, (GLenum, GLuint, GLint *)) AGL_API(void, GetProgramLocalParameterIuivNV,(GLenum, GLuint, GLuint *)) AGL_API(void, GetProgramEnvParameterIivNV, (GLenum, GLuint, GLint *)) AGL_API(void, GetProgramEnvParameterIuivNV, (GLenum, GLuint, GLuint *)) #endif #if defined _ALLEGRO_GL_NV_parameter_buffer_object #if !defined _ALLEGRO_GL_NV_transform_feedback AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) #endif AGL_API(void, ProgramBufferParametersfvNV, (GLenum, GLuint, GLuint, GLsizei, const GLfloat *)) AGL_API(void, ProgramBufferParametersIivNV, (GLenum, GLuint, GLuint, GLsizei, const GLint *)) AGL_API(void, ProgramBufferParametersIuivNV,(GLenum, GLuint, GLuint, GLuint, const GLuint *)) #if !defined _ALLEGRO_GL_EXT_draw_buffers2 AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLboolean *)) #endif #endif #if defined _ALLEGRO_GL_NV_transform_feedback AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) AGL_API(void, TransformFeedbackAttribsNV, (GLsizei, const GLint *, GLenum)) AGL_API(void, TransformFeedbackVaryingsNV,(GLuint, GLsizei, const GLint *, GLenum)) AGL_API(void, BeginTransformFeedbackNV, (GLenum)) AGL_API(void, EndTransformFeedbackNV, (void)) AGL_API(GLint, GetVaryingLocationNV, (GLuint, const GLchar *)) AGL_API(void, GetActiveVaryingNV, (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *)) AGL_API(void, ActiveVaryingNV, (GLuint, const GLchar *)) AGL_API(void, GetTransformFeedbackVaryingNV, (GLuint, GLuint, GLint *)) #if !defined _ALLEGRO_GL_EXT_draw_buffers2 AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) /*AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *))*/ #endif #endif #if defined _ALLEGRO_GL_NV_vertex_program4 #ifndef _ALLEGRO_GL_EXT_gpu_shader4 AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) #endif #endif #if defined _ALLEGRO_GL_GREMEDY_frame_terminator AGL_API(void, FrameTerminatorGREMEDY, (void)) #endif #if defined _ALLEGRO_GL_NV_conditional_render AGL_API(void, BeginConditionalRenderNV, (GLuint, GLenum)) AGL_API(void, EndConditionalRenderNV, (void)) #endif #if defined _ALLEGRO_GL_EXT_transform_feedback AGL_API(void, BeginTransformFeedbackEXT, (GLenum)) AGL_API(void, EndTransformFeedbackEXT, (void)) AGL_API(void, BindBufferRangeEXT, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) AGL_API(void, BindBufferOffsetEXT, (GLenum, GLuint, GLuint, GLintptr)) AGL_API(void, BindBufferBaseEXT, (GLenum, GLuint, GLuint)) AGL_API(void, TransformFeedbackVaryingsEXT, (GLuint, GLsizei, const GLint *, GLenum)) AGL_API(void, GetTransformFeedbackVaryingEXT, (GLuint, GLuint, GLint *)) #endif #if defined _ALLEGRO_GL_EXT_direct_state_access AGL_API(void, ClientAttribDefaultEXT, (GLbitfield)) AGL_API(void, PushClientAttribDefaultEXT, (GLbitfield)) AGL_API(void, MatrixLoadfEXT, (GLenum, const GLfloat *)) AGL_API(void, MatrixLoaddEXT, (GLenum, const GLdouble *)) AGL_API(void, MatrixMultfEXT, (GLenum, const GLfloat *)) AGL_API(void, MatrixMultdEXT, (GLenum, const GLdouble *)) AGL_API(void, MatrixLoadIdentityEXT, (GLenum)) AGL_API(void, MatrixRotatefEXT, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, MatrixRotatedEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, MatrixScalefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, MatrixScaledEXT, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, MatrixTranslatefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) AGL_API(void, MatrixTranslatedEXT, (GLenum, GLdouble, GLdouble, GLdouble)) AGL_API(void, MatrixFrustumEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, MatrixOrthoEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, MatrixPopEXT, (GLenum)) AGL_API(void, MatrixPushEXT, (GLenum)) AGL_API(void, MatrixLoadTransposefEXT, (GLenum, const GLfloat *)) AGL_API(void, MatrixLoadTransposedEXT, (GLenum, const GLdouble *)) AGL_API(void, MatrixMultTransposefEXT, (GLenum, const GLfloat *)) AGL_API(void, MatrixMultTransposedEXT, (GLenum, const GLdouble *)) AGL_API(void, TextureParameterfEXT, (GLuint, GLenum, GLenum, GLfloat)) AGL_API(void, TextureParameterfvEXT, (GLuint, GLenum, GLenum, const GLfloat *)) AGL_API(void, TextureParameteriEXT, (GLuint, GLenum, GLenum, GLint)) AGL_API(void, TextureParameterivEXT, (GLuint, GLenum, GLenum, const GLint *)) AGL_API(void, TextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, TextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) AGL_API(void, CopyTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) AGL_API(void, CopyTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei)) AGL_API(void, CopyTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, GetTextureImageEXT, (GLuint, GLenum, GLint, GLenum, GLenum, GLvoid *)) AGL_API(void, GetTextureParameterfvEXT, (GLuint, GLenum, GLenum, GLfloat *)) AGL_API(void, GetTextureParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) AGL_API(void, GetTextureLevelParameterfvEXT, (GLuint, GLenum, GLint, GLenum, GLfloat *)) AGL_API(void, GetTextureLevelParameterivEXT, (GLuint, GLenum, GLint, GLenum, GLint *)) AGL_API(void, TextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, TextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, MultiTexParameterfEXT, (GLenum, GLenum, GLenum, GLfloat)) AGL_API(void, MultiTexParameterfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) AGL_API(void, MultiTexParameteriEXT, (GLenum, GLenum, GLenum, GLint)) AGL_API(void, MultiTexParameterivEXT, (GLenum, GLenum, GLenum, const GLint *)) AGL_API(void, MultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, MultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, MultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, MultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) AGL_API(void, CopyMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) AGL_API(void, CopyMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei)) AGL_API(void, CopyMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, GetMultiTexImageEXT, (GLenum, GLenum, GLint, GLenum, GLenum, GLvoid *)) AGL_API(void, GetMultiTexParameterfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) AGL_API(void, GetMultiTexParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetMultiTexLevelParameterfvEXT, (GLenum, GLenum, GLint, GLenum, GLfloat *)) AGL_API(void, GetMultiTexLevelParameterivEXT, (GLenum, GLenum, GLint, GLenum, GLint *)) AGL_API(void, MultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) AGL_API(void, MultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) AGL_API(void, CopyMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) AGL_API(void, BindMultiTextureEXT, (GLenum, GLenum, GLuint)) AGL_API(void, EnableClientStateIndexedEXT, (GLenum, GLuint)) AGL_API(void, DisableClientStateIndexedEXT, (GLenum, GLuint)) AGL_API(void, MultiTexCoordPointerEXT, (GLenum, GLint, GLenum, GLsizei, const GLvoid *)) AGL_API(void, MultiTexEnvfEXT, (GLenum, GLenum, GLenum, GLfloat)) AGL_API(void, MultiTexEnvfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) AGL_API(void, MultiTexEnviEXT, (GLenum, GLenum, GLenum, GLint)) AGL_API(void, MultiTexEnvivEXT, (GLenum, GLenum, GLenum, const GLint *)) AGL_API(void, MultiTexGendEXT, (GLenum, GLenum, GLenum, GLdouble)) AGL_API(void, MultiTexGendvEXT, (GLenum, GLenum, GLenum, const GLdouble *)) AGL_API(void, MultiTexGenfEXT, (GLenum, GLenum, GLenum, GLfloat)) AGL_API(void, MultiTexGenfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) AGL_API(void, MultiTexGeniEXT, (GLenum, GLenum, GLenum, GLint)) AGL_API(void, MultiTexGenivEXT, (GLenum, GLenum, GLenum, const GLint *)) AGL_API(void, GetMultiTexEnvfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) AGL_API(void, GetMultiTexEnvivEXT, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetMultiTexGendvEXT, (GLenum, GLenum, GLenum, GLdouble *)) AGL_API(void, GetMultiTexGenfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) AGL_API(void, GetMultiTexGenivEXT, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetFloatIndexedvEXT, (GLenum, GLuint, GLfloat *)) AGL_API(void, GetDoubleIndexedvEXT, (GLenum, GLuint, GLdouble *)) AGL_API(void, GetPointerIndexedvEXT, (GLenum, GLuint, GLvoid* *)) AGL_API(void, CompressedTextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetCompressedTextureImageEXT, (GLuint, GLenum, GLint, GLvoid *)) AGL_API(void, CompressedMultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) AGL_API(void, CompressedMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, CompressedMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) AGL_API(void, GetCompressedMultiTexImageEXT, (GLenum, GLenum, GLint, GLvoid *)) AGL_API(void, NamedProgramStringEXT, (GLuint, GLenum, GLenum, GLsizei, const GLvoid *)) AGL_API(void, NamedProgramLocalParameter4dEXT, (GLuint, GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) AGL_API(void, NamedProgramLocalParameter4dvEXT, (GLuint, GLenum, GLuint, const GLdouble *)) AGL_API(void, NamedProgramLocalParameter4fEXT, (GLuint, GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, NamedProgramLocalParameter4fvEXT, (GLuint, GLenum, GLuint, const GLfloat *)) AGL_API(void, GetNamedProgramLocalParameterdvEXT, (GLuint, GLenum, GLuint, GLdouble *)) AGL_API(void, GetNamedProgramLocalParameterfvEXT, (GLuint, GLenum, GLuint, GLfloat *)) AGL_API(void, GetNamedProgramivEXT, (GLuint, GLenum, GLenum, GLint *)) AGL_API(void, GetNamedProgramStringEXT, (GLuint, GLenum, GLenum, GLvoid *)) AGL_API(void, NamedProgramLocalParameters4fvEXT, (GLuint, GLenum, GLuint, GLsizei, const GLfloat *)) AGL_API(void, NamedProgramLocalParameterI4iEXT, (GLuint, GLenum, GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, NamedProgramLocalParameterI4ivEXT, (GLuint, GLenum, GLuint, const GLint *)) AGL_API(void, NamedProgramLocalParametersI4ivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLint *)) AGL_API(void, NamedProgramLocalParameterI4uiEXT, (GLuint, GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, NamedProgramLocalParameterI4uivEXT, (GLuint, GLenum, GLuint, const GLuint *)) AGL_API(void, NamedProgramLocalParametersI4uivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLuint *)) AGL_API(void, GetNamedProgramLocalParameterIivEXT, (GLuint, GLenum, GLuint, GLint *)) AGL_API(void, GetNamedProgramLocalParameterIuivEXT, (GLuint, GLenum, GLuint, GLuint *)) AGL_API(void, TextureParameterIivEXT, (GLuint, GLenum, GLenum, const GLint *)) AGL_API(void, TextureParameterIuivEXT, (GLuint, GLenum, GLenum, const GLuint *)) AGL_API(void, GetTextureParameterIivEXT, (GLuint, GLenum, GLenum, GLint *)) AGL_API(void, GetTextureParameterIuivEXT, (GLuint, GLenum, GLenum, GLuint *)) AGL_API(void, MultiTexParameterIivEXT, (GLenum, GLenum, GLenum, const GLint *)) AGL_API(void, MultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, const GLuint *)) AGL_API(void, GetMultiTexParameterIivEXT, (GLenum, GLenum, GLenum, GLint *)) AGL_API(void, GetMultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, GLuint *)) AGL_API(void, ProgramUniform1fEXT, (GLuint, GLint, GLfloat)) AGL_API(void, ProgramUniform2fEXT, (GLuint, GLint, GLfloat, GLfloat)) AGL_API(void, ProgramUniform3fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramUniform4fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) AGL_API(void, ProgramUniform1iEXT, (GLuint, GLint, GLint)) AGL_API(void, ProgramUniform2iEXT, (GLuint, GLint, GLint, GLint)) AGL_API(void, ProgramUniform3iEXT, (GLuint, GLint, GLint, GLint, GLint)) AGL_API(void, ProgramUniform4iEXT, (GLuint, GLint, GLint, GLint, GLint, GLint)) AGL_API(void, ProgramUniform1fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) AGL_API(void, ProgramUniform2fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) AGL_API(void, ProgramUniform3fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) AGL_API(void, ProgramUniform4fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) AGL_API(void, ProgramUniform1ivEXT, (GLuint, GLint, GLsizei, const GLint *)) AGL_API(void, ProgramUniform2ivEXT, (GLuint, GLint, GLsizei, const GLint *)) AGL_API(void, ProgramUniform3ivEXT, (GLuint, GLint, GLsizei, const GLint *)) AGL_API(void, ProgramUniform4ivEXT, (GLuint, GLint, GLsizei, const GLint *)) AGL_API(void, ProgramUniformMatrix2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix2x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix3x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix2x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix4x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix3x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniformMatrix4x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) AGL_API(void, ProgramUniform1uiEXT, (GLuint, GLint, GLuint)) AGL_API(void, ProgramUniform2uiEXT, (GLuint, GLint, GLuint, GLuint)) AGL_API(void, ProgramUniform3uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint)) AGL_API(void, ProgramUniform4uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) AGL_API(void, ProgramUniform1uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) AGL_API(void, ProgramUniform2uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) AGL_API(void, ProgramUniform3uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) AGL_API(void, ProgramUniform4uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) AGL_API(void, NamedBufferDataEXT, (GLuint, GLsizeiptr, const GLvoid *, GLenum)) AGL_API(void, NamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, const GLvoid *)) AGL_API(GLvoid*, MapNamedBufferEXT, (GLuint, GLenum)) AGL_API(GLboolean, UnmapNamedBufferEXT, (GLuint)) AGL_API(void, GetNamedBufferParameterivEXT, (GLuint, GLenum, GLint *)) AGL_API(void, GetNamedBufferPointervEXT, (GLuint, GLenum, GLvoid* *)) AGL_API(void, GetNamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, GLvoid *)) AGL_API(void, TextureBufferEXT, (GLuint, GLenum, GLenum, GLuint)) AGL_API(void, MultiTexBufferEXT, (GLenum, GLenum, GLenum, GLuint)) AGL_API(void, NamedRenderbufferStorageEXT, (GLuint, GLenum, GLsizei, GLsizei)) AGL_API(void, GetNamedRenderbufferParameterivEXT, (GLuint, GLenum, GLint *)) AGL_API(GLenum, CheckNamedFramebufferStatusEXT, (GLuint, GLenum)) AGL_API(void, NamedFramebufferTexture1DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) AGL_API(void, NamedFramebufferTexture2DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) AGL_API(void, NamedFramebufferTexture3DEXT, (GLuint, GLenum, GLenum, GLuint, GLint, GLint)) AGL_API(void, NamedFramebufferRenderbufferEXT, (GLuint, GLenum, GLenum, GLuint)) AGL_API(void, GetNamedFramebufferAttachmentParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) AGL_API(void, GenerateTextureMipmapEXT, (GLuint, GLenum)) AGL_API(void, GenerateMultiTexMipmapEXT, (GLenum, GLenum)) AGL_API(void, FramebufferDrawBufferEXT, (GLuint, GLenum)) AGL_API(void, FramebufferDrawBuffersEXT, (GLuint, GLsizei, const GLenum *)) AGL_API(void, FramebufferReadBufferEXT, (GLuint, GLenum)) AGL_API(void, GetFramebufferParameterivEXT, (GLuint, GLenum, GLint *)) AGL_API(void, NamedRenderbufferStorageMultisampleEXT, (GLuint, GLsizei, GLenum, GLsizei, GLsizei)) AGL_API(void, NamedRenderbufferStorageMultisampleCoverageEXT, (GLuint, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) AGL_API(void, NamedFramebufferTextureEXT, (GLuint, GLenum, GLuint, GLint)) AGL_API(void, NamedFramebufferTextureLayerEXT, (GLuint, GLenum, GLuint, GLint, GLint)) AGL_API(void, NamedFramebufferTextureFaceEXT, (GLuint, GLenum, GLuint, GLint, GLenum)) AGL_API(void, TextureRenderbufferEXT, (GLuint, GLenum, GLuint)) AGL_API(void, MultiTexRenderbufferEXT, (GLenum, GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_NV_explicit_multisample AGL_API(void, GetMultisamplefvNV, (GLenum, GLuint, GLfloat *)) AGL_API(void, SampleMaskIndexedNV, (GLuint, GLbitfield)) AGL_API(void, TexRenderbufferNV, (GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_NV_transform_feedback2 AGL_API(void, BindTransformFeedbackNV, (GLenum, GLuint)) AGL_API(void, DeleteTransformFeedbacksNV, (GLsizei, const GLuint *)) AGL_API(void, GenTransformFeedbacksNV, (GLsizei, GLuint *)) AGL_API(GLboolean, IsTransformFeedbackNV, (GLuint)) AGL_API(void, PauseTransformFeedbackNV, (void)) AGL_API(void, ResumeTransformFeedbackNV, (void)) AGL_API(void, DrawTransformFeedbackNV, (GLenum, GLuint)) #endif #if defined _ALLEGRO_GL_AMD_performance_monitor AGL_API(void, GetPerfMonitorGroupsAMD, (GLint *, GLsizei, GLuint *)) AGL_API(void, GetPerfMonitorCountersAMD, (GLuint, GLint *, GLint *, GLsizei, GLuint *)) AGL_API(void, GetPerfMonitorGroupStringAMD, (GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, GetPerfMonitorCounterStringAMD, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) AGL_API(void, GetPerfMonitorCounterInfoAMD, (GLuint, GLuint, GLenum, void *)) AGL_API(void, GenPerfMonitorsAMD, (GLsizei, GLuint *)) AGL_API(void, DeletePerfMonitorsAMD, (GLsizei, GLuint *)) AGL_API(void, SelectPerfMonitorCountersAMD, (GLuint, GLboolean, GLuint, GLint, GLuint *)) AGL_API(void, BeginPerfMonitorAMD, (GLuint)) AGL_API(void, EndPerfMonitorAMD, (GLuint)) AGL_API(void, GetPerfMonitorCounterDataAMD, (GLuint, GLenum, GLsizei, GLuint *, GLint *)) #endif #if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator AGL_API(void, TessellationFactorAMD, (GLfloat)) AGL_API(void, TessellationModeAMD, (GLenum)) #endif #if defined _ALLEGRO_GL_EXT_provoking_vertex AGL_API(void, ProvokingVertexEXT, (GLenum)) #endif #if defined _ALLEGRO_GL_AMD_draw_buffers_blend AGL_API(void, BlendFuncIndexedAMD, (GLuint buf, GLenum src, GLenum dst)) AGL_API(void, BlendFuncSeparateIndexedAMD, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) AGL_API(void, BlendEquationIndexedAMD, (GLuint buf, GLenum mode)) AGL_API(void, BlendEquationSeparateIndexedAMD, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) #endif #if defined _ALLEGRO_GL_APPLE_texture_range AGL_API(void, TextureRangeAPPLE, (GLenum target, GLsizei length, const GLvoid *pointer)) AGL_API(void, GetTexParameterPointervAPPLE, (GLenum target, GLenum pname, GLvoid* *params)) #endif #if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators AGL_API(void, EnableVertexAttribAPPLE, (GLuint index, GLenum pname)) AGL_API(void, DisableVertexAttribAPPLE, (GLuint index, GLenum pname)) AGL_API(GLboolean, IsVertexAttribEnabledAPPLE, (GLuint index, GLenum pname)) AGL_API(void, MapVertexAttrib1dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) AGL_API(void, MapVertexAttrib1fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) AGL_API(void, MapVertexAttrib2dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) AGL_API(void, MapVertexAttrib2fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) #endif #if defined _ALLEGRO_GL_APPLE_object_purgeable AGL_API(GLenum, ObjectPurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) AGL_API(GLenum, ObjectUnpurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) AGL_API(void, GetObjectParameterivAPPLE, (GLenum objectType, GLuint name, GLenum pname, GLint *params)) #endif #if defined _ALLEGRO_GL_NV_video_capture AGL_API(void, BeginVideoCaptureNV, (GLuint video_capture_slot)) AGL_API(void, BindVideoCaptureStreamBufferNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset)) AGL_API(void, BindVideoCaptureStreamTextureNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture)) AGL_API(void, EndVideoCaptureNV, (GLuint video_capture_slot)) AGL_API(void, GetVideoCaptureivNV, (GLuint video_capture_slot, GLenum pname, GLint *params)) AGL_API(void, GetVideoCaptureStreamivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params)) AGL_API(void, GetVideoCaptureStreamfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params)) AGL_API(void, GetVideoCaptureStreamdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params)) AGL_API(GLenum, VideoCaptureNV, (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time)) AGL_API(void, VideoCaptureStreamParameterivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params)) AGL_API(void, VideoCaptureStreamParameterfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params)) AGL_API(void, VideoCaptureStreamParameterdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params)) #endif #if defined _ALLEGRO_GL_EXT_separate_shader_objects AGL_API(void, UseShaderProgramEXT, (GLenum type, GLuint program)) AGL_API(void, ActiveProgramEXT, (GLuint program)) AGL_API(GLuint, CreateShaderProgramEXT, (GLenum type, const GLchar *string)) #endif #if defined _ALLEGRO_GL_NV_shader_buffer_load AGL_API(void, MakeBufferResidentNV, (GLenum target, GLenum access)) AGL_API(void, MakeBufferNonResidentNV, (GLenum target)) AGL_API(GLboolean, IsBufferResidentNV, (GLenum target)) AGL_API(void, MakeNamedBufferResidentNV, (GLuint buffer, GLenum access)) AGL_API(void, MakeNamedBufferNonResidentNV, (GLuint buffer)) AGL_API(GLboolean, IsNamedBufferResidentNV, (GLuint buffer)) AGL_API(void, GetBufferParameterui64vNV, (GLenum target, GLenum pname, GLuint64EXT *params)) AGL_API(void, GetNamedBufferParameterui64vNV, (GLuint buffer, GLenum pname, GLuint64EXT *params)) AGL_API(void, GetIntegerui64vNV, (GLenum value, GLuint64EXT *result)) AGL_API(void, Uniformui64NV, (GLint location, GLuint64EXT value)) AGL_API(void, Uniformui64vNV, (GLint location, GLsizei count, const GLuint64EXT *value)) AGL_API(void, GetUniformui64vNV, (GLuint program, GLint location, GLuint64EXT *params)) AGL_API(void, ProgramUniformui64NV, (GLuint program, GLint location, GLuint64EXT value)) AGL_API(void, ProgramUniformui64vNV, (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value)) #endif #if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory AGL_API(void, BufferAddressRangeNV, (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length)) AGL_API(void, VertexFormatNV, (GLint size, GLenum type, GLsizei stride)) AGL_API(void, NormalFormatNV, (GLenum type, GLsizei stride)) AGL_API(void, ColorFormatNV, (GLint size, GLenum type, GLsizei stride)) AGL_API(void, IndexFormatNV, (GLenum type, GLsizei stride)) AGL_API(void, TexCoordFormatNV, (GLint size, GLenum type, GLsizei stride)) AGL_API(void, EdgeFlagFormatNV, (GLsizei stride)) AGL_API(void, SecondaryColorFormatNV, (GLint size, GLenum type, GLsizei stride)) AGL_API(void, FogCoordFormatNV, (GLenum type, GLsizei stride)) AGL_API(void, VertexAttribFormatNV, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride)) AGL_API(void, VertexAttribIFormatNV, (GLuint index, GLint size, GLenum type, GLsizei stride)) AGL_API(void, GetIntegerui64i_vNV, (GLenum value, GLuint index, GLuint64EXT *result)) #endif #if defined _ALLEGRO_GL_NV_texture_barrier AGL_API(void, TextureBarrierNV, (void)) #endif allegro-5.0.10/include/allegro5/opengl/GLext/glx_ext_defs.h0000644000175000001440000004207711364043251022707 0ustar tjadenusers/* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ #define __glxext_h_ #include #undef __glxext_h_ #ifndef GLX_VERSION_1_3 #define _ALLEGRO_GLX_VERSION_1_3 #define GLX_VERSION_1_3 #define GLX_WINDOW_BIT 0x00000001 #define GLX_PIXMAP_BIT 0x00000002 #define GLX_PBUFFER_BIT 0x00000004 #define GLX_RGBA_BIT 0x00000001 #define GLX_COLOR_INDEX_BIT 0x00000002 #define GLX_PBUFFER_CLOBBER_MASK 0x08000000 #define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 #define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 #define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 #define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 #define GLX_AUX_BUFFERS_BIT 0x00000010 #define GLX_DEPTH_BUFFER_BIT 0x00000020 #define GLX_STENCIL_BUFFER_BIT 0x00000040 #define GLX_ACCUM_BUFFER_BIT 0x00000080 #define GLX_CONFIG_CAVEAT 0x20 #define GLX_X_VISUAL_TYPE 0x22 #define GLX_TRANSPARENT_TYPE 0x23 #define GLX_TRANSPARENT_INDEX_VALUE 0x24 #define GLX_TRANSPARENT_RED_VALUE 0x25 #define GLX_TRANSPARENT_GREEN_VALUE 0x26 #define GLX_TRANSPARENT_BLUE_VALUE 0x27 #define GLX_TRANSPARENT_ALPHA_VALUE 0x28 #define GLX_DONT_CARE 0xFFFFFFFF #define GLX_NONE 0x8000 #define GLX_SLOW_CONFIG 0x8001 #define GLX_TRUE_COLOR 0x8002 #define GLX_DIRECT_COLOR 0x8003 #define GLX_PSEUDO_COLOR 0x8004 #define GLX_STATIC_COLOR 0x8005 #define GLX_GRAY_SCALE 0x8006 #define GLX_STATIC_GRAY 0x8007 #define GLX_TRANSPARENT_RGB 0x8008 #define GLX_TRANSPARENT_INDEX 0x8009 #define GLX_VISUAL_ID 0x800B #define GLX_SCREEN 0x800C #define GLX_NON_CONFORMANT_CONFIG 0x800D #define GLX_DRAWABLE_TYPE 0x8010 #define GLX_RENDER_TYPE 0x8011 #define GLX_X_RENDERABLE 0x8012 #define GLX_FBCONFIG_ID 0x8013 #define GLX_RGBA_TYPE 0x8014 #define GLX_COLOR_INDEX_TYPE 0x8015 #define GLX_MAX_PBUFFER_WIDTH 0x8016 #define GLX_MAX_PBUFFER_HEIGHT 0x8017 #define GLX_MAX_PBUFFER_PIXELS 0x8018 #define GLX_PRESERVED_CONTENTS 0x801B #define GLX_LARGEST_PBUFFER 0x801C #define GLX_WIDTH 0x801D #define GLX_HEIGHT 0x801E #define GLX_EVENT_MASK 0x801F #define GLX_DAMAGED 0x8020 #define GLX_SAVED 0x8021 #define GLX_WINDOW 0x8022 #define GLX_PBUFFER 0x8023 #define GLX_PBUFFER_HEIGHT 0x8040 #define GLX_PBUFFER_WIDTH 0x8041 #endif #ifndef GLX_VERSION_1_4 #define _ALLEGRO_GLX_VERSION_1_4 #define GLX_VERSION_1_4 #define GLX_SAMPLE_BUFFERS 100000 #define GLX_SAMPLES 100001 #endif #ifndef GLX_ARB_get_proc_address #define _ALLEGRO_GLX_ARB_get_proc_address #define GLX_ARB_get_proc_address typedef void (*__GLXextFuncPtr)(void); #endif #ifndef GLX_ARB_multisample #define _ALLEGRO_GLX_ARB_multisample #define GLX_ARB_multisample #define GLX_SAMPLE_BUFFERS_ARB 100000 #define GLX_SAMPLES_ARB 100001 #endif #ifndef GLX_ARB_vertex_buffer_object #define GLX_ARB_vertex_buffer_object #define _ALLEGRO_GLX_ARB_vertex_buffer_object #define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 #endif #ifndef GLX_ARB_fbconfig_float #define GLX_ARB_fbconfig_float #define _ALLEGRO_GLX_ARB_fbconfig_float #define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 #define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 #endif #ifndef GLX_ARB_create_context #define GLX_ARB_create_context #define _ALLEGRO_GLX_ARB_create_context #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 #define GLX_CONTEXT_FLAGS_ARB 0x2094 #endif #ifndef GLX_ARB_create_context_profile #define GLX_ARB_create_context_profile #define _ALLEGRO_GLX_ARB_create_context_profile #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 #endif #ifndef GLX_SGIS_multisample #define _ALLEGRO_GLX_SGIS_multisample #define GLX_SGIS_multisample #define GLX_SAMPLE_BUFFERS_SGIS 100000 #define GLX_SAMPLES_SGIS 100001 #endif /* Fix for system headers that define GLX_VERSION_1_4 but do not define * GLX_SAMPLES and GLX_SAMPLE_BUFFERS. */ #ifndef GLX_SAMPLES #define GLX_SAMPLE_BUFFERS 100000 #define GLX_SAMPLES 100001 #endif #ifndef GLX_EXT_visual_info #define _ALLEGRO_GLX_EXT_visual_info #define GLX_EXT_visual_info #define GLX_X_VISUAL_TYPE_EXT 0x22 #define GLX_TRANSPARENT_TYPE_EXT 0x23 #define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 #define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 #define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 #define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 #define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 #define GLX_NONE_EXT 0x8000 #define GLX_TRUE_COLOR_EXT 0x8002 #define GLX_DIRECT_COLOR_EXT 0x8003 #define GLX_PSEUDO_COLOR_EXT 0x8004 #define GLX_STATIC_COLOR_EXT 0x8005 #define GLX_GRAY_SCALE_EXT 0x8006 #define GLX_STATIC_GRAY_EXT 0x8007 #define GLX_TRANSPARENT_RGB_EXT 0x8008 #define GLX_TRANSPARENT_INDEX_EXT 0x8009 #endif #ifndef GLX_EXT_visual_rating #define _ALLEGRO_GLX_EXT_visual_rating #define GLX_EXT_visual_rating #define GLX_VISUAL_CAVEAT_EXT 0x20 #define GLX_SLOW_VISUAL_EXT 0x8001 #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D /* GLX_NONE_EXT */ #endif #ifndef GLX_EXT_import_context #define _ALLEGRO_GLX_EXT_import_context #define GLX_EXT_import_context #define GLX_SHARE_CONTEXT_EXT 0x800A #define GLX_VISUAL_ID_EXT 0x800B #define GLX_SCREEN_EXT 0x800C #endif #ifndef GLX_SGIX_fbconfig #define _ALLEGRO_GLX_SGIX_fbconfig #define GLX_SGIX_fbconfig typedef XID GLXFBConfigIDSGIX; typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; #define GLX_WINDOW_BIT_SGIX 0x00000001 #define GLX_PIXMAP_BIT_SGIX 0x00000002 #define GLX_RGBA_BIT_SGIX 0x00000001 #define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 #define GLX_DRAWABLE_TYPE_SGIX 0x8010 #define GLX_RENDER_TYPE_SGIX 0x8011 #define GLX_X_RENDERABLE_SGIX 0x8012 #define GLX_FBCONFIG_ID_SGIX 0x8013 #define GLX_RGBA_TYPE_SGIX 0x8014 #define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 /* GLX_SCREEN_EXT */ #endif #ifndef GLX_SGIX_pbuffer #define _ALLEGRO_GLX_SGIX_pbuffer #define GLX_SGIX_pbuffer typedef XID GLXPbufferSGIX; typedef struct { int type; unsigned long serial; /* # of last request processed by server */ Bool send_event; /* true if this came for SendEvent request */ Display *display; /* display the event was read from */ GLXDrawable drawable; /* i.d. of Drawable */ int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ unsigned int mask; /* mask indicating which buffers are affected*/ int x, y; int width, height; int count; /* if nonzero, at least this many more */ } GLXBufferClobberEventSGIX; #define GLX_PBUFFER_BIT_SGIX 0x00000004 #define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 #define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 #define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 #define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 #define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 #define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 #define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 #define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 #define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 #define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 #define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 #define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 #define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 #define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 #define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A #define GLX_PRESERVED_CONTENTS_SGIX 0x801B #define GLX_LARGEST_PBUFFER_SGIX 0x801C #define GLX_WIDTH_SGIX 0x801D #define GLX_HEIGHT_SGIX 0x801E #define GLX_EVENT_MASK_SGIX 0x801F #define GLX_DAMAGED_SGIX 0x8020 #define GLX_SAVED_SGIX 0x8021 #define GLX_WINDOW_SGIX 0x8022 #define GLX_PBUFFER_SGIX 0x8023 #endif #ifndef GLX_SGIX_video_resize #define _ALLEGRO_GLX_SGIX_video_resize #define GLX_SGIX_video_resize #define GLX_SYNC_FRAME_SGIX 0x00000000 #define GLX_SYNC_SWAP_SGIX 0x00000001 #endif #ifndef GLX_SGIX_dmbuffer #define _ALLEGRO_GLX_SGIX_dmbuffer #define GLX_SGIX_dmbuffer #define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 #endif #ifndef GLX_SGIS_blended_overlay #define _ALLEGRO_GLX_SGIS_blended_overlay #define GLX_SGIS_blended_overlay #define GLX_BLENDED_RGBA_SGIS 0x8025 #endif #ifndef GLX_SGIS_shared_multisample #define _ALLEGRO_GLX_SGIS_shared_multisample #define GLX_SGIS_shared_multisample #define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 #define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 #endif #ifndef GLX_3DFX_multisample #define _ALLEGRO_GLX_3DFX_multisample #define GLX_3DFX_multisample #define GLX_SAMPLE_BUFFERS_3DFX 0x8050 #define GLX_SAMPLES_3DFX 0x8051 #endif #ifndef GLX_MESA_set_3dfx_mode #define _ALLEGRO_GLX_MESA_set_3dfx_mode #define GLX_MESA_set_3dfx_mode #define GLX_3DFX_WINDOW_MODE_MESA 0x1 #define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 #endif #ifndef GLX_SGIX_visual_select_group #define _ALLEGRO_GLX_SGIX_visual_select_group #define GLX_SGIX_visual_select_group #define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 #endif #ifndef GLX_OML_swap_method #define _ALLEGRO_GLX_OML_swap_method #define GLX_OML_swap_method #define GLX_SWAP_METHOD_OML 0x8060 #define GLX_SWAP_EXCHANGE_OML 0x8061 #define GLX_SWAP_COPY_OML 0x8062 #define GLX_SWAP_UNDEFINED_OML 0x8063 #endif #ifndef GLX_SGIX_video_source #define _ALLEGRO_GLX_SGIX_video_source #define GLX_SGIX_video_source typedef XID GLXVideoSourceSGIX; #endif #ifndef GLX_SGI_video_sync #define GLX_SGI_video_sync #define _ALLEGRO_GLX_SGI_video_sync #endif #ifndef GLX_SGI_swap_control #define GLX_SGI_swap_control #define _ALLEGRO_GLX_SGI_swap_control #endif #ifndef GLX_SGI_make_current_read #define GLX_SGI_make_current_read #define _ALLEGRO_GLX_SGI_make_current_read #endif #ifndef GLX_SGI_cushion #define GLX_SGI_cushion #define _ALLEGRO_GLX_SGI_cushion #endif #ifndef GLX_SGIX_swap_group #define GLX_SGIX_swap_group #define _ALLEGRO_GLX_SGIX_swap_group #endif #ifndef GLX_SGIX_swap_barrier #define GLX_SGIX_swap_barrier #define _ALLEGRO_GLX_SGIX_swap_barrier #endif #ifndef GLX_SUN_get_transparent_index #define GLX_SUN_get_transparent_index #define _ALLEGRO_GLX_SUN_get_transparent_index #endif #ifndef GLX_MESA_copy_sub_buffer #define GLX_MESA_copy_sub_buffer #define _ALLEGRO_GLX_MESA_copy_sub_buffer #endif #ifndef GLX_MESA_pixmap_colormap #define GLX_MESA_pixmap_colormap #define _ALLEGRO_GLX_MESA_pixmap_colormap #endif #ifndef GLX_MESA_release_buffers #define GLX_MESA_release_buffers #define _ALLEGRO_GLX_MESA_release_buffers #endif #ifndef GLX_OML_sync_control #define GLX_OML_sync_control #define _ALLEGRO_GLX_OML_sync_control #endif #ifndef GLX_SGIX_hyperpipe #define GLX_SGIX_hyperpipe #define _ALLEGRO_GLX_SGIX_hyperpipe #define GLX_HYPERPIPE_ID_SGIX 0x8030 #define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 #define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 #define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 #define GLX_PIPE_RECT_SGIX 0x00000001 #define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 #define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 #define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 #define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 #define GLX_BAD_HYPERPIPE_SGIX 92 typedef struct { char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; int networkId; } GLXHyperpipeNetworkSGIX; typedef struct { char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; int channel; unsigned int participationType; int timeSlice; } GLXHyperpipeConfigSGIX; typedef struct { char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; int srcXOrigin; int srcYOrigin; int srcWidth; int srcHeight; int destXOrigin; int destYOrigin; int destWidth; int destHeight; } GLXPipeRect; typedef struct { char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; int XOrigin; int YOrigin; int maxHeight; int maxWidth; } GLXPipeRectLimits; #endif #ifndef GLX_MESA_agp_offset #define GLX_MESA_agp_offset #define _ALLEGRO_GLX_MESA_agp_offset #endif #ifndef GLX_EXT_framebuffer_sRGB #define GLX_EXT_framebuffer_sRGB #define _ALLEGRO_GLX_EXT_framebuffer_sRGB #define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 #endif #ifndef GLX_EXT_fbconfig_packed_float #define GLX_EXT_fbconfig_packed_float #define _ALLEGRO_GLX_EXT_fbconfig_packed_float #define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 #define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 #endif #ifndef GLX_EXT_texture_from_pixmap #define GLX_EXT_texture_from_pixmap #define _ALLEGRO_GLX_EXT_texture_from_pixmap #define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 #define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 #define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 #define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 #define GLX_Y_INVERTED_EXT 0x20D4 #define GLX_TEXTURE_FORMAT_EXT 0x20D5 #define GLX_TEXTURE_TARGET_EXT 0x20D6 #define GLX_MIPMAP_TEXTURE_EXT 0x20D7 #define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 #define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 #define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA #define GLX_TEXTURE_1D_BIT_EXT 0x00000001 #define GLX_TEXTURE_2D_BIT_EXT 0x00000002 #define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 #define GLX_TEXTURE_1D_EXT 0x20DB #define GLX_TEXTURE_2D_EXT 0x20DC #define GLX_TEXTURE_RECTANGLE_EXT 0x20DD #define GLX_FRONT_LEFT_EXT 0x20DE #define GLX_FRONT_RIGHT_EXT 0x20DF #define GLX_BACK_LEFT_EXT 0x20E0 #define GLX_BACK_RIGHT_EXT 0x20E1 #define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT #define GLX_BACK_EXT GLX_BACK_LEFT_EXT #define GLX_AUX0_EXT 0x20E2 #define GLX_AUX1_EXT 0x20E3 #define GLX_AUX2_EXT 0x20E4 #define GLX_AUX3_EXT 0x20E5 #define GLX_AUX4_EXT 0x20E6 #define GLX_AUX5_EXT 0x20E7 #define GLX_AUX6_EXT 0x20E8 #define GLX_AUX7_EXT 0x20E9 #define GLX_AUX8_EXT 0x20EA #define GLX_AUX9_EXT 0x20EB #endif #ifndef GLX_NV_present_video #define GLX_NV_present_video #define _ALLEGRO_GLX_NV_present_video #define GLX_GLX_NUM_VIDEO_SLOTS_NV 0x20F0 #endif #ifndef GLX_NV_video_output #define GLX_NV_video_output #define _ALLEGRO_GLX_NV_video_output #define GLX_VIDEO_OUT_COLOR_NV 0x20C3 #define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 #define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 #define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 #define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 #define GLX_VIDEO_OUT_FRAME_NV 0x20C8 #define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 #define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA typedef unsigned int GLXVideoDeviceNV; #endif #ifndef GLX_NV_swap_group #define GLX_NV_swap_group #define _ALLEGRO_GLX_NV_swap_group #endif #ifndef GLX_NV_video_capture #define GLX_NV_video_capture #define _ALLEGRO_GLX_NV_video_capture #define GLX_DEVICE_ID_NV 0x20CD #define GLX_UNIQUE_ID_NV 0x20CE #define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF typedef XID GLXVideoCaptureDeviceNV; #endif #ifndef GLX_EXT_swap_control #define GLX_EXT_swap_control #define _ALLEGRO_GLX_EXT_swap_control #define GLX_SWAP_INTERVAL_EXT 0x20F1 #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 #endif #ifndef GLX_NV_copy_image #define GLX_NV_copy_image #define _ALLEGRO_GLX_NV_copy_image #endif #ifndef GLX_INTEL_swap_event #define GLX_INTEL_swap_event #define _ALLEGRO_GLX_INTEL_swap_event #define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 #define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 #define GLX_COPY_COMPLETE_INTEL 0x8181 #define GLX_FLIP_COMPLETE_INTEL 0x8182 #endif allegro-5.0.10/include/allegro5/opengl/GLext/gl_ext_defs.h0000644000175000001440000061066211364043251022520 0ustar tjadenusers/* */ #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #define _ALLEGRO_GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_INT_8_8_8_8 0x8035 #define GL_UNSIGNED_INT_10_10_10_2 0x8036 #define GL_RESCALE_NORMAL 0x803A #define GL_TEXTURE_BINDING_3D 0x806A #define GL_PACK_SKIP_IMAGES 0x806B #define GL_PACK_IMAGE_HEIGHT 0x806C #define GL_UNPACK_SKIP_IMAGES 0x806D #define GL_UNPACK_IMAGE_HEIGHT 0x806E #define GL_TEXTURE_3D 0x806F #define GL_PROXY_TEXTURE_3D 0x8070 #define GL_TEXTURE_DEPTH 0x8071 #define GL_TEXTURE_WRAP_R 0x8072 #define GL_MAX_3D_TEXTURE_SIZE 0x8073 #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_BGR 0x80E0 #define GL_BGRA 0x80E1 #define GL_MAX_ELEMENTS_VERTICES 0x80E8 #define GL_MAX_ELEMENTS_INDICES 0x80E9 #define GL_CLAMP_TO_EDGE 0x812F #define GL_TEXTURE_MIN_LOD 0x813A #define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define GL_SINGLE_COLOR 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR 0x81FA #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E #endif #ifndef GL_ARB_imaging #define GL_ARB_imaging #define _ALLEGRO_GL_ARB_imaging #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 #define GL_FUNC_ADD 0x8006 #define GL_MIN 0x8007 #define GL_MAX 0x8008 #define GL_BLEND_EQUATION 0x8009 #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 #define GL_REDUCE 0x8016 #define GL_CONVOLUTION_FORMAT 0x8017 #define GL_CONVOLUTION_WIDTH 0x8018 #define GL_CONVOLUTION_HEIGHT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH 0x801A #define GL_MAX_CONVOLUTION_HEIGHT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define GL_POST_CONVOLUTION_RED_BIAS 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define GL_HISTOGRAM 0x8024 #define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 #define GL_HISTOGRAM_GREEN_SIZE 0x8029 #define GL_HISTOGRAM_BLUE_SIZE 0x802A #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D #define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 #define GL_COLOR_MATRIX 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB #define GL_COLOR_TABLE 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define GL_PROXY_COLOR_TABLE 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 #define GL_COLOR_TABLE_WIDTH 0x80D9 #define GL_COLOR_TABLE_RED_SIZE 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF #define GL_CONSTANT_BORDER 0x8151 #define GL_REPLICATE_BORDER 0x8153 #define GL_CONVOLUTION_BORDER_COLOR 0x8154 #endif #ifndef GL_VERSION_1_3 #define GL_VERSION_1_3 1 #define _ALLEGRO_GL_VERSION_1_3 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define GL_MAX_TEXTURE_UNITS 0x84E2 #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 #define GL_MULTISAMPLE 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_ALPHA_TO_ONE 0x809F #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_MULTISAMPLE_BIT 0x20000000 #define GL_NORMAL_MAP 0x8511 #define GL_REFLECTION_MAP 0x8512 #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_COMPRESSED_ALPHA 0x84E9 #define GL_COMPRESSED_LUMINANCE 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB #define GL_COMPRESSED_INTENSITY 0x84EC #define GL_COMPRESSED_RGB 0x84ED #define GL_COMPRESSED_RGBA 0x84EE #define GL_TEXTURE_COMPRESSION_HINT 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define GL_TEXTURE_COMPRESSED 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_CLAMP_TO_BORDER 0x812D #define GL_CLAMP_TO_BORDER_SGIS 0x812D #define GL_COMBINE 0x8570 #define GL_COMBINE_RGB 0x8571 #define GL_COMBINE_ALPHA 0x8572 #define GL_SOURCE0_RGB 0x8580 #define GL_SOURCE1_RGB 0x8581 #define GL_SOURCE2_RGB 0x8582 #define GL_SOURCE0_ALPHA 0x8588 #define GL_SOURCE1_ALPHA 0x8589 #define GL_SOURCE2_ALPHA 0x858A #define GL_OPERAND0_RGB 0x8590 #define GL_OPERAND1_RGB 0x8591 #define GL_OPERAND2_RGB 0x8592 #define GL_OPERAND0_ALPHA 0x8598 #define GL_OPERAND1_ALPHA 0x8599 #define GL_OPERAND2_ALPHA 0x859A #define GL_RGB_SCALE 0x8573 #define GL_ADD_SIGNED 0x8574 #define GL_INTERPOLATE 0x8575 #define GL_SUBTRACT 0x84E7 #define GL_CONSTANT 0x8576 #define GL_PRIMARY_COLOR 0x8577 #define GL_PREVIOUS 0x8578 #define GL_DOT3_RGB 0x86AE #define GL_DOT3_RGBA 0x86AF #endif #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 #define _ALLEGRO_GL_VERSION_1_4 #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_POINT_SIZE_MIN 0x8126 #define GL_POINT_SIZE_MAX 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define GL_POINT_DISTANCE_ATTENUATION 0x8129 #define GL_GENERATE_MIPMAP 0x8191 #define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT32 0x81A7 #define GL_MIRRORED_REPEAT 0x8370 #define GL_FOG_COORDINATE_SOURCE 0x8450 #define GL_FOG_COORDINATE 0x8451 #define GL_FRAGMENT_DEPTH 0x8452 #define GL_CURRENT_FOG_COORDINATE 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 #define GL_FOG_COORDINATE_ARRAY 0x8457 #define GL_COLOR_SUM 0x8458 #define GL_CURRENT_SECONDARY_COLOR 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D #define GL_SECONDARY_COLOR_ARRAY 0x845E #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_TEXTURE_LOD_BIAS 0x8501 #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_TEXTURE_DEPTH_SIZE 0x884A #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_COMPARE_R_TO_TEXTURE 0x884E #endif #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #define _ALLEGRO_GL_VERSION_1_5 /* New types */ #include typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; /* Renamed enumerants */ #define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE #define GL_FOG_COORD GL_FOG_COORDINATE #define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE #define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE #define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE #define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER #define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY #define GL_SRC0_RGB GL_SOURCE0_RGB #define GL_SRC1_RGB GL_SOURCE1_RGB #define GL_SRC2_RGB GL_SOURCE2_RGB #define GL_SRC0_ALPHA GL_SOURCE0_ALPHA #define GL_SRC1_ALPHA GL_SOURCE1_ALPHA #define GL_SRC2_ALPHA GL_SOURCE2_ALPHA /* Promoted exts */ #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_READ_ONLY 0x88B8 #define GL_WRITE_ONLY 0x88B9 #define GL_READ_WRITE 0x88BA #define GL_BUFFER_ACCESS 0x88BB #define GL_BUFFER_MAPPED 0x88BC #define GL_BUFFER_MAP_POINTER 0x88BD #define GL_STREAM_DRAW 0x88E0 #define GL_STREAM_READ 0x88E1 #define GL_STREAM_COPY 0x88E2 #define GL_STATIC_DRAW 0x88E4 #define GL_STATIC_READ 0x88E5 #define GL_STATIC_COPY 0x88E6 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_DYNAMIC_READ 0x88E9 #define GL_DYNAMIC_COPY 0x88EA #define GL_SAMPLES_PASSED 0x8914 #define GL_QUERY_COUNTER_BITS 0x8864 #define GL_CURRENT_QUERY 0x8865 #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #endif #ifndef GL_VERSION_2_0 #define GL_VERSION_2_0 1 #define _ALLEGRO_GL_VERSION_2_0 /* New types */ typedef char GLchar; #define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_CURRENT_VERTEX_ATTRIB 0x8626 #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_STENCIL_BACK_FUNC 0x8800 #define GL_STENCIL_BACK_FAIL 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define GL_MAX_DRAW_BUFFERS 0x8824 #define GL_DRAW_BUFFER0 0x8825 #define GL_DRAW_BUFFER1 0x8826 #define GL_DRAW_BUFFER2 0x8827 #define GL_DRAW_BUFFER3 0x8828 #define GL_DRAW_BUFFER4 0x8829 #define GL_DRAW_BUFFER5 0x882A #define GL_DRAW_BUFFER6 0x882B #define GL_DRAW_BUFFER7 0x882C #define GL_DRAW_BUFFER8 0x882D #define GL_DRAW_BUFFER9 0x882E #define GL_DRAW_BUFFER10 0x882F #define GL_DRAW_BUFFER11 0x8830 #define GL_DRAW_BUFFER12 0x8831 #define GL_DRAW_BUFFER13 0x8832 #define GL_DRAW_BUFFER14 0x8833 #define GL_DRAW_BUFFER15 0x8834 #define GL_BLEND_EQUATION_ALPHA 0x883D #define GL_POINT_SPRITE 0x8861 #define GL_COORD_REPLACE 0x8862 #define GL_MAX_VERTEX_ATTRIBS 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_MAX_TEXTURE_COORDS 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A #define GL_MAX_VARYING_FLOATS 0x8B4B #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define GL_SHADER_TYPE 0x8B4F #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 #define GL_INT_VEC2 0x8B53 #define GL_INT_VEC3 0x8B54 #define GL_INT_VEC4 0x8B55 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC4 0x8B59 #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_3D 0x8B5F #define GL_SAMPLER_CUBE 0x8B60 #define GL_SAMPLER_1D_SHADOW 0x8B61 #define GL_SAMPLER_2D_SHADOW 0x8B62 #define GL_DELETE_STATUS 0x8B80 #define GL_COMPILE_STATUS 0x8B81 #define GL_LINK_STATUS 0x8B82 #define GL_VALIDATE_STATUS 0x8B83 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_ATTACHED_SHADERS 0x8B85 #define GL_ACTIVE_UNIFORMS 0x8B86 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_ACTIVE_ATTRIBUTES 0x8B89 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B #define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_CURRENT_PROGRAM 0x8B8D #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define GL_LOWER_LEFT 0x8CA1 #define GL_UPPER_LEFT 0x8CA2 #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #endif #ifndef GL_VERSION_2_1 #define GL_VERSION_2_1 1 #define _ALLEGRO_GL_VERSION_2_1 #define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F #define GL_PIXEL_PACK_BUFFER 0x88EB #define GL_PIXEL_UNPACK_BUFFER 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF #define GL_FLOAT_MAT2x3 0x8B65 #define GL_FLOAT_MAT2x4 0x8B66 #define GL_FLOAT_MAT3x2 0x8B67 #define GL_FLOAT_MAT3x4 0x8B68 #define GL_FLOAT_MAT4x2 0x8B69 #define GL_FLOAT_MAT4x3 0x8B6A #define GL_SRGB 0x8C40 #define GL_SRGB8 0x8C41 #define GL_SRGB_ALPHA 0x8C42 #define GL_SRGB8_ALPHA8 0x8C43 #define GL_SLUMINANCE_ALPHA 0x8C44 #define GL_SLUMINANCE8_ALPHA8 0x8C45 #define GL_SLUMINANCE 0x8C46 #define GL_SLUMINANCE8 0x8C47 #define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 #define GL_COMPRESSED_SLUMINANCE 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B #endif #ifndef GL_VERSION_3_0 #define GL_VERSION_3_0 #define _ALLEGRO_GL_VERSION_3_0 #define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB #define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 #define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 #define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 #define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 #define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 #define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 #define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES #define GL_MAJOR_VERSION 0x821B #define GL_MINOR_VERSION 0x821C #define GL_NUM_EXTENSIONS 0x821D #define GL_CONTEXT_FLAGS 0x821E #define GL_DEPTH_BUFFER 0x8223 #define GL_STENCIL_BUFFER 0x8224 #define GL_COMPRESSED_RED 0x8225 #define GL_COMPRESSED_RG 0x8226 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 #define GL_RGBA32F 0x8814 #define GL_RGB32F 0x8815 #define GL_RGBA16F 0x881A #define GL_RGB16F 0x881B #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 #define GL_CLAMP_VERTEX_COLOR 0x891A #define GL_CLAMP_FRAGMENT_COLOR 0x891B #define GL_CLAMP_READ_COLOR 0x891C #define GL_FIXED_ONLY 0x891D #define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS #define GL_TEXTURE_RED_TYPE 0x8C10 #define GL_TEXTURE_GREEN_TYPE 0x8C11 #define GL_TEXTURE_BLUE_TYPE 0x8C12 #define GL_TEXTURE_ALPHA_TYPE 0x8C13 #define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #define GL_TEXTURE_DEPTH_TYPE 0x8C16 #define GL_UNSIGNED_NORMALIZED 0x8C17 #define GL_TEXTURE_1D_ARRAY 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 #define GL_TEXTURE_2D_ARRAY 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B #define GL_RGB9_E5 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E #define GL_TEXTURE_SHARED_SIZE 0x8C3F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 #define GL_PRIMITIVES_GENERATED 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 #define GL_RASTERIZER_DISCARD 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B #define GL_INTERLEAVED_ATTRIBS 0x8C8C #define GL_SEPARATE_ATTRIBS 0x8C8D #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F #define GL_RGBA32UI 0x8D70 #define GL_RGB32UI 0x8D71 #define GL_RGBA16UI 0x8D76 #define GL_RGB16UI 0x8D77 #define GL_RGBA8UI 0x8D7C #define GL_RGB8UI 0x8D7D #define GL_RGBA32I 0x8D82 #define GL_RGB32I 0x8D83 #define GL_RGBA16I 0x8D88 #define GL_RGB16I 0x8D89 #define GL_RGBA8I 0x8D8E #define GL_RGB8I 0x8D8F #define GL_RED_INTEGER 0x8D94 #define GL_GREEN_INTEGER 0x8D95 #define GL_BLUE_INTEGER 0x8D96 #define GL_ALPHA_INTEGER 0x8D97 #define GL_RGB_INTEGER 0x8D98 #define GL_RGBA_INTEGER 0x8D99 #define GL_BGR_INTEGER 0x8D9A #define GL_BGRA_INTEGER 0x8D9B #define GL_SAMPLER_1D_ARRAY 0x8DC0 #define GL_SAMPLER_2D_ARRAY 0x8DC1 #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 #define GL_UNSIGNED_INT_VEC2 0x8DC6 #define GL_UNSIGNED_INT_VEC3 0x8DC7 #define GL_UNSIGNED_INT_VEC4 0x8DC8 #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA #define GL_INT_SAMPLER_3D 0x8DCB #define GL_INT_SAMPLER_CUBE 0x8DCC #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 #define GL_QUERY_WAIT 0x8E13 #define GL_QUERY_NO_WAIT 0x8E14 #define GL_QUERY_BY_REGION_WAIT 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 #endif #ifndef GL_VERSION_3_0_DEPRECATED #define GL_VERSION_3_0_DEPRECATED #define _ALLEGRO_GL_VERSION_3_0_DEPRECATED #define GL_CLAMP_VERTEX_COLOR 0x891A #define GL_CLAMP_FRAGMENT_COLOR 0x891B #define GL_ALPHA_INTEGER 0x8D97 /* Reuse tokens from ARB_framebuffer_object */ /* reuse GL_TEXTURE_LUMINANCE_TYPE */ /* reuse GL_TEXTURE_INTENSITY_TYPE */ #endif #ifndef GL_VERSION_3_1 #define GL_VERSION_3_1 #define _ALLEGRO_GL_VERSION_3_1 #define GL_SAMPLER_2D_RECT 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 #define GL_SAMPLER_BUFFER 0x8DC2 #define GL_INT_SAMPLER_2D_RECT 0x8DCD #define GL_INT_SAMPLER_BUFFER 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 #define GL_TEXTURE_BUFFER 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B #define GL_TEXTURE_BINDING_BUFFER 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT 0x8C2E #define GL_TEXTURE_RECTANGLE 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 #define GL_RED_SNORM 0x8F90 #define GL_RG_SNORM 0x8F91 #define GL_RGB_SNORM 0x8F92 #define GL_RGBA_SNORM 0x8F93 #define GL_R8_SNORM 0x8F94 #define GL_RG8_SNORM 0x8F95 #define GL_RGB8_SNORM 0x8F96 #define GL_RGBA8_SNORM 0x8F97 #define GL_R16_SNORM 0x8F98 #define GL_RG16_SNORM 0x8F99 #define GL_RGB16_SNORM 0x8F9A #define GL_RGBA16_SNORM 0x8F9B #define GL_SIGNED_NORMALIZED 0x8F9C #define GL_PRIMITIVE_RESTART 0x8F9D #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E #endif #ifndef GL_VERSION_3_2 #define GL_VERSION_3_2 #define _ALLEGRO_GL_VERSION_3_2 #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #define GL_LINES_ADJACENCY 0x000A #define GL_LINE_STRIP_ADJACENCY 0x000B #define GL_TRIANGLES_ADJACENCY 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D #define GL_PROGRAM_POINT_SIZE 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 #define GL_GEOMETRY_SHADER 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT 0x8916 #define GL_GEOMETRY_INPUT_TYPE 0x8917 #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 #define GL_CONTEXT_PROFILE_MASK 0x9126 #endif #ifndef GL_VERSION_3_3 #define GL_VERSION_3_3 #define _ALLEGRO_GL_VERSION_3_3 #endif /* */ /* */ #ifndef GL_ARB_multitexture #define GL_ARB_multitexture #define _ALLEGRO_GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 #define GL_TEXTURE4_ARB 0x84C4 #define GL_TEXTURE5_ARB 0x84C5 #define GL_TEXTURE6_ARB 0x84C6 #define GL_TEXTURE7_ARB 0x84C7 #define GL_TEXTURE8_ARB 0x84C8 #define GL_TEXTURE9_ARB 0x84C9 #define GL_TEXTURE10_ARB 0x84CA #define GL_TEXTURE11_ARB 0x84CB #define GL_TEXTURE12_ARB 0x84CC #define GL_TEXTURE13_ARB 0x84CD #define GL_TEXTURE14_ARB 0x84CE #define GL_TEXTURE15_ARB 0x84CF #define GL_TEXTURE16_ARB 0x84D0 #define GL_TEXTURE17_ARB 0x84D1 #define GL_TEXTURE18_ARB 0x84D2 #define GL_TEXTURE19_ARB 0x84D3 #define GL_TEXTURE20_ARB 0x84D4 #define GL_TEXTURE21_ARB 0x84D5 #define GL_TEXTURE22_ARB 0x84D6 #define GL_TEXTURE23_ARB 0x84D7 #define GL_TEXTURE24_ARB 0x84D8 #define GL_TEXTURE25_ARB 0x84D9 #define GL_TEXTURE26_ARB 0x84DA #define GL_TEXTURE27_ARB 0x84DB #define GL_TEXTURE28_ARB 0x84DC #define GL_TEXTURE29_ARB 0x84DD #define GL_TEXTURE30_ARB 0x84DE #define GL_TEXTURE31_ARB 0x84DF #define GL_ACTIVE_TEXTURE_ARB 0x84E0 #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix #define _ALLEGRO_GL_ARB_transpose_matrix #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 #define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 #define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 #endif #ifndef GL_ARB_multisample #define GL_ARB_multisample #define _ALLEGRO_GL_ARB_multisample #define GL_MULTISAMPLE_ARB 0x809D #define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F #define GL_SAMPLE_COVERAGE_ARB 0x80A0 #define GL_SAMPLE_BUFFERS_ARB 0x80A8 #define GL_SAMPLES_ARB 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA #define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB #define GL_MULTISAMPLE_BIT_ARB 0x20000000 #endif #ifndef GL_ARB_texture_cube_map #define GL_ARB_texture_cube_map #define _ALLEGRO_GL_ARB_texture_cube_map #define GL_NORMAL_MAP_ARB 0x8511 #define GL_REFLECTION_MAP_ARB 0x8512 #define GL_TEXTURE_CUBE_MAP_ARB 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C #endif #ifndef GL_ARB_texture_compression #define GL_ARB_texture_compression #define _ALLEGRO_GL_ARB_texture_compression #define GL_COMPRESSED_ALPHA_ARB 0x84E9 #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA #define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB #define GL_COMPRESSED_INTENSITY_ARB 0x84EC #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE #define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 #define GL_TEXTURE_COMPRESSED_ARB 0x86A1 #define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 #endif #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp #define _ALLEGRO_GL_ARB_texture_border_clamp #define GL_CLAMP_TO_BORDER_ARB 0x812D #endif #ifndef GL_ARB_point_parameters #define GL_ARB_point_parameters #define _ALLEGRO_GL_ARB_point_parameters #define GL_POINT_SIZE_MIN_ARB 0x8126 #define GL_POINT_SIZE_MAX_ARB 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 #define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef GL_ARB_vertex_blend #define GL_ARB_vertex_blend #define _ALLEGRO_GL_ARB_vertex_blend #define GL_MAX_VERTEX_UNITS_ARB 0x86A4 #define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 #define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 #define GL_VERTEX_BLEND_ARB 0x86A7 #define GL_CURRENT_WEIGHT_ARB 0x86A8 #define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 #define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA #define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB #define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC #define GL_WEIGHT_ARRAY_ARB 0x86AD #define GL_MODELVIEW0_ARB 0x1700 #define GL_MODELVIEW1_ARB 0x850A #define GL_MODELVIEW2_ARB 0x8722 #define GL_MODELVIEW3_ARB 0x8723 #define GL_MODELVIEW4_ARB 0x8724 #define GL_MODELVIEW5_ARB 0x8725 #define GL_MODELVIEW6_ARB 0x8726 #define GL_MODELVIEW7_ARB 0x8727 #define GL_MODELVIEW8_ARB 0x8728 #define GL_MODELVIEW9_ARB 0x8729 #define GL_MODELVIEW10_ARB 0x872A #define GL_MODELVIEW11_ARB 0x872B #define GL_MODELVIEW12_ARB 0x872C #define GL_MODELVIEW13_ARB 0x872D #define GL_MODELVIEW14_ARB 0x872E #define GL_MODELVIEW15_ARB 0x872F #define GL_MODELVIEW16_ARB 0x8730 #define GL_MODELVIEW17_ARB 0x8731 #define GL_MODELVIEW18_ARB 0x8732 #define GL_MODELVIEW19_ARB 0x8733 #define GL_MODELVIEW20_ARB 0x8734 #define GL_MODELVIEW21_ARB 0x8735 #define GL_MODELVIEW22_ARB 0x8736 #define GL_MODELVIEW23_ARB 0x8737 #define GL_MODELVIEW24_ARB 0x8738 #define GL_MODELVIEW25_ARB 0x8739 #define GL_MODELVIEW26_ARB 0x873A #define GL_MODELVIEW27_ARB 0x873B #define GL_MODELVIEW28_ARB 0x873C #define GL_MODELVIEW29_ARB 0x873D #define GL_MODELVIEW30_ARB 0x873E #define GL_MODELVIEW31_ARB 0x873F #endif #ifndef GL_ARB_matrix_palette #define GL_ARB_matrix_palette #define _ALLEGRO_GL_ARB_matrix_palette #define GL_MATRIX_PALETTE_ARB 0x8840 #define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 #define GL_MAX_PALETTE_MATRICES_ARB 0x8842 #define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 #define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 #define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 #define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 #define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 #define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 #define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 #endif #ifndef GL_ARB_texture_env_combine #define GL_ARB_texture_env_combine #define _ALLEGRO_GL_ARB_texture_env_combine #define GL_COMBINE_ARB 0x8570 #define GL_COMBINE_RGB_ARB 0x8571 #define GL_COMBINE_ALPHA_ARB 0x8572 #define GL_SOURCE0_RGB_ARB 0x8580 #define GL_SOURCE1_RGB_ARB 0x8581 #define GL_SOURCE2_RGB_ARB 0x8582 #define GL_SOURCE0_ALPHA_ARB 0x8588 #define GL_SOURCE1_ALPHA_ARB 0x8589 #define GL_SOURCE2_ALPHA_ARB 0x858A #define GL_OPERAND0_RGB_ARB 0x8590 #define GL_OPERAND1_RGB_ARB 0x8591 #define GL_OPERAND2_RGB_ARB 0x8592 #define GL_OPERAND0_ALPHA_ARB 0x8598 #define GL_OPERAND1_ALPHA_ARB 0x8599 #define GL_OPERAND2_ALPHA_ARB 0x859A #define GL_RGB_SCALE_ARB 0x8573 #define GL_ADD_SIGNED_ARB 0x8574 #define GL_INTERPOLATE_ARB 0x8575 #define GL_SUBTRACT_ARB 0x84E7 #define GL_CONSTANT_ARB 0x8576 #define GL_PRIMARY_COLOR_ARB 0x8577 #define GL_PREVIOUS_ARB 0x8578 #endif #ifndef GL_ARB_texture_env_dot3 #define GL_ARB_texture_env_dot3 #define _ALLEGRO_GL_ARB_texture_env_dot3 #define GL_DOT3_RGB_ARB 0x86AE #define GL_DOT3_RGBA_ARB 0x86AF #endif #ifndef GL_ARB_texture_mirrored_repeat #define GL_ARB_texture_mirrored_repeat #define _ALLEGRO_GL_ARB_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_ARB 0x8370 #endif #ifndef GL_ARB_depth_texture #define GL_ARB_depth_texture #define _ALLEGRO_GL_ARB_depth_texture #define GL_DEPTH_COMPONENT16_ARB 0x81A5 #define GL_DEPTH_COMPONENT24_ARB 0x81A6 #define GL_DEPTH_COMPONENT32_ARB 0x81A7 #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif #ifndef GL_ARB_window_pos #define GL_ARB_window_pos #define _ALLEGRO_GL_ARB_window_pos #endif #ifndef GL_ARB_shadow #define GL_ARB_shadow #define _ALLEGRO_GL_ARB_shadow #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E #endif #ifndef GL_ARB_shadow_ambient #define GL_ARB_shadow_ambient #define _ALLEGRO_GL_ARB_shadow_ambient #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif #ifndef GL_ARB_vertex_program #define GL_ARB_vertex_program #define _ALLEGRO_GL_ARB_vertex_program #define GL_COLOR_SUM_ARB 0x8458 #define GL_VERTEX_PROGRAM_ARB 0x8620 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define GL_PROGRAM_LENGTH_ARB 0x8627 #define GL_PROGRAM_STRING_ARB 0x8628 #define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E #define GL_MAX_PROGRAM_MATRICES_ARB 0x862F #define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 #define GL_CURRENT_MATRIX_ARB 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #define GL_PROGRAM_ERROR_POSITION_ARB 0x864B #define GL_PROGRAM_BINDING_ARB 0x8677 #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define GL_PROGRAM_ERROR_STRING_ARB 0x8874 #define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define GL_PROGRAM_FORMAT_ARB 0x8876 #define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 #define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 #define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 #define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 #define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 #define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 #define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 #define GL_PROGRAM_PARAMETERS_ARB 0x88A8 #define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 #define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA #define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB #define GL_PROGRAM_ATTRIBS_ARB 0x88AC #define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD #define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE #define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF #define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 #define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 #define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 #define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 #define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 #define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 #define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 #define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 #define GL_MATRIX0_ARB 0x88C0 #define GL_MATRIX1_ARB 0x88C1 #define GL_MATRIX2_ARB 0x88C2 #define GL_MATRIX3_ARB 0x88C3 #define GL_MATRIX4_ARB 0x88C4 #define GL_MATRIX5_ARB 0x88C5 #define GL_MATRIX6_ARB 0x88C6 #define GL_MATRIX7_ARB 0x88C7 #define GL_MATRIX8_ARB 0x88C8 #define GL_MATRIX9_ARB 0x88C9 #define GL_MATRIX10_ARB 0x88CA #define GL_MATRIX11_ARB 0x88CB #define GL_MATRIX12_ARB 0x88CC #define GL_MATRIX13_ARB 0x88CD #define GL_MATRIX14_ARB 0x88CE #define GL_MATRIX15_ARB 0x88CF #define GL_MATRIX16_ARB 0x88D0 #define GL_MATRIX17_ARB 0x88D1 #define GL_MATRIX18_ARB 0x88D2 #define GL_MATRIX19_ARB 0x88D3 #define GL_MATRIX20_ARB 0x88D4 #define GL_MATRIX21_ARB 0x88D5 #define GL_MATRIX22_ARB 0x88D6 #define GL_MATRIX23_ARB 0x88D7 #define GL_MATRIX24_ARB 0x88D8 #define GL_MATRIX25_ARB 0x88D9 #define GL_MATRIX26_ARB 0x88DA #define GL_MATRIX27_ARB 0x88DB #define GL_MATRIX28_ARB 0x88DC #define GL_MATRIX29_ARB 0x88DD #define GL_MATRIX30_ARB 0x88DE #define GL_MATRIX31_ARB 0x88DF #endif #ifndef GL_ARB_fragment_program #define GL_ARB_fragment_program #define _ALLEGRO_GL_ARB_fragment_program #define GL_FRAGMENT_PROGRAM_ARB 0x8804 #define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 #define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 #define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 #define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 #define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A #define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B #define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C #define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D #define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E #define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F #define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #endif #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object #define _ALLEGRO_GL_ARB_vertex_buffer_object #include typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 #define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define GL_READ_ONLY_ARB 0x88B8 #define GL_WRITE_ONLY_ARB 0x88B9 #define GL_READ_WRITE_ARB 0x88BA #define GL_BUFFER_ACCESS_ARB 0x88BB #define GL_BUFFER_MAPPED_ARB 0x88BC #define GL_BUFFER_MAP_POINTER_ARB 0x88BD #define GL_STREAM_DRAW_ARB 0x88E0 #define GL_STREAM_READ_ARB 0x88E1 #define GL_STREAM_COPY_ARB 0x88E2 #define GL_STATIC_DRAW_ARB 0x88E4 #define GL_STATIC_READ_ARB 0x88E5 #define GL_STATIC_COPY_ARB 0x88E6 #define GL_DYNAMIC_DRAW_ARB 0x88E8 #define GL_DYNAMIC_READ_ARB 0x88E9 #define GL_DYNAMIC_COPY_ARB 0x88EA #endif #ifndef GL_ARB_occlusion_query #define GL_ARB_occlusion_query #define _ALLEGRO_GL_ARB_occlusion_query #define GL_SAMPLES_PASSED_ARB 0x8914 #define GL_QUERY_COUNTER_BITS_ARB 0x8864 #define GL_CURRENT_QUERY_ARB 0x8865 #define GL_QUERY_RESULT_ARB 0x8866 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #endif #ifndef GL_ARB_shader_objects #define GL_ARB_shader_objects #define _ALLEGRO_GL_ARB_shader_objects typedef char GLcharARB; typedef unsigned long GLhandleARB; #define GL_PROGRAM_OBJECT_ARB 0x8B40 #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 #define GL_SHADER_OBJECT_ARB 0x8B48 /* GL_FLOAT */ #define GL_FLOAT_VEC2_ARB 0x8B50 #define GL_FLOAT_VEC3_ARB 0x8B51 #define GL_FLOAT_VEC4_ARB 0x8B52 /* GL_INT */ #define GL_INT_VEC2_ARB 0x8B53 #define GL_INT_VEC3_ARB 0x8B54 #define GL_INT_VEC4_ARB 0x8B55 #define GL_BOOL_ARB 0x8B56 #define GL_BOOL_VEC2_ARB 0x8B57 #define GL_BOOL_VEC3_ARB 0x8B58 #define GL_BOOL_VEC4_ARB 0x8B59 #define GL_FLOAT_MAT2_ARB 0x8B5A #define GL_FLOAT_MAT3_ARB 0x8B5B #define GL_FLOAT_MAT4_ARB 0x8B5C #define GL_SAMPLER_1D_ARB 0x8B5D #define GL_SAMPLER_2D_ARB 0x8B5E #define GL_SAMPLER_3D_ARB 0x8B5F #define GL_SAMPLER_CUBE_ARB 0x8B60 #define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 #define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 #define GL_SAMPLER_2D_RECT_ARB 0x8B63 #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 #endif #ifndef GL_ARB_vertex_shader #define GL_ARB_vertex_shader #define _ALLEGRO_GL_ARB_vertex_shader #define GL_VERTEX_SHADER_ARB 0x8B31 #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A #define GL_MAX_VARYING_FLOATS_ARB 0x8B4B #define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #if !defined GL_ARB_shader_objects #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #endif #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #if !defined GL_ARB_shader_objects #define GL_SHADER_OBJECT_ARB 0x8B48 #endif #define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #if !defined GL_ARB_shader_objects /* GL_FLOAT */ #define GL_FLOAT_VEC2_ARB 0x8B50 #define GL_FLOAT_VEC3_ARB 0x8B51 #define GL_FLOAT_VEC4_ARB 0x8B52 #define GL_FLOAT_MAT2_ARB 0x8B5A #define GL_FLOAT_MAT3_ARB 0x8B5B #define GL_FLOAT_MAT4_ARB 0x8B5C #endif #endif #ifndef GL_ARB_fragment_shader #define GL_ARB_fragment_shader #define _ALLEGRO_GL_ARB_fragment_shader #define GL_FRAGMENT_SHADER_ARB 0x8B30 #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 #define GL_MAX_TEXTURE_COORDS_ARB 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #if !defined GL_ARB_shader_objects && !defined GL_ARB_vertex_shader #define GL_OBJECT_TYPE_ARB 0x8B4E #define GL_OBJECT_SUBTYPE_ARB 0x8B4F #define GL_SHADER_OBJECT_ARB 0x8B48 #endif #endif #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 #define _ALLEGRO_GL_ARB_shading_language_100 #endif #ifndef GL_ARB_texture_non_power_of_two #define GL_ARB_texture_non_power_of_two #define _ALLEGRO_GL_ARB_texture_non_power_of_two #endif #ifndef GL_ARB_point_sprite #define GL_ARB_point_sprite #define _ALLEGRO_GL_ARB_point_sprite #define GL_POINT_SPRITE_ARB 0x8861 #define GL_COORD_REPLACE_ARB 0x8862 /* GL_FALSE */ /* GL_TRUE */ #endif #ifndef GL_ARB_draw_buffers #define GL_ARB_draw_buffers #define _ALLEGRO_GL_ARB_draw_buffers #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 #define GL_DRAW_BUFFER0_ARB 0x8825 #define GL_DRAW_BUFFER1_ARB 0x8826 #define GL_DRAW_BUFFER2_ARB 0x8827 #define GL_DRAW_BUFFER3_ARB 0x8828 #define GL_DRAW_BUFFER4_ARB 0x8829 #define GL_DRAW_BUFFER5_ARB 0x882A #define GL_DRAW_BUFFER6_ARB 0x882B #define GL_DRAW_BUFFER7_ARB 0x882C #define GL_DRAW_BUFFER8_ARB 0x882D #define GL_DRAW_BUFFER9_ARB 0x882E #define GL_DRAW_BUFFER10_ARB 0x882F #define GL_DRAW_BUFFER11_ARB 0x8830 #define GL_DRAW_BUFFER12_ARB 0x8831 #define GL_DRAW_BUFFER13_ARB 0x8832 #define GL_DRAW_BUFFER14_ARB 0x8833 #define GL_DRAW_BUFFER15_ARB 0x8834 #endif #ifndef GL_ARB_texture_rectangle #define GL_ARB_texture_rectangle #define _ALLEGRO_GL_ARB_texture_rectangle #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 #endif #ifdef ALLEGRO_MACOSX #ifndef GL_EXT_texture_rectangle #define GL_EXT_texture_rectangle #define _ALLEGRO_GL_EXT_texture_rectangle #define GL_TEXTURE_RECTANGLE_EXT 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 #endif #endif #ifndef GL_ARB_color_buffer_float #define GL_ARB_color_buffer_float #define _ALLEGRO_GL_ARB_color_buffer_float #define GL_RGBA_FLOAT_MODE_ARB 0x8820 #define GL_CLAMP_VERTEX_COLOR_ARB 0x891A #define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B #define GL_CLAMP_READ_COLOR_ARB 0x891C #define GL_FIXED_ONLY_ARB 0x891D #endif #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel #define _ALLEGRO_GL_ARB_half_float_pixel #define GL_HALF_FLOAT_ARB 0x140B #endif #ifndef GL_ARB_texture_float #define GL_ARB_texture_float #define _ALLEGRO_GL_ARB_texture_float #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 #define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 #define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 #define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 #define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 #define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 #define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 #define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 #define GL_RGBA32F_ARB 0x8814 #define GL_RGB32F_ARB 0x8815 #define GL_ALPHA32F_ARB 0x8816 #define GL_INTENSITY32F_ARB 0x8817 #define GL_LUMINANCE32F_ARB 0x8818 #define GL_LUMINANCE_ALPHA32F_ARB 0x8819 #define GL_RGBA16F_ARB 0x881A #define GL_RGB16F_ARB 0x881B #define GL_ALPHA16F_ARB 0x881C #define GL_INTENSITY16F_ARB 0x881D #define GL_LUMINANCE16F_ARB 0x881E #define GL_LUMINANCE_ALPHA16F_ARB 0x881F #endif #ifndef GL_ARB_pixel_buffer_object #define GL_ARB_pixel_buffer_object #define _ALLEGRO_GL_ARB_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB #define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #endif #ifndef GL_ARB_depth_buffer_float #define GL_ARB_depth_buffer_float #define _ALLEGRO_GL_ARB_depth_buffer_float #define GL_DEPTH_COMPONENT32F 0x8CAC #define GL_DEPTH32F_STENCIL8 0x8CAD #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD #endif #ifndef GL_ARB_draw_instanced #define GL_ARB_draw_instanced #define _ALLEGRO_GL_ARB_draw_instanced #endif #ifndef GL_ARB_framebuffer_object #define GL_ARB_framebuffer_object #define _ALLEGRO_GL_ARB_framebuffer_object #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 #define GL_FRAMEBUFFER_DEFAULT 0x8218 #define GL_FRAMEBUFFER_UNDEFINED 0x8219 #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_INDEX 0x8222 #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 #define GL_DEPTH_STENCIL 0x84F9 #define GL_UNSIGNED_INT_24_8 0x84FA #define GL_DEPTH24_STENCIL8 0x88F0 #define GL_TEXTURE_STENCIL_SIZE 0x88F1 #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_READ_FRAMEBUFFER 0x8CA8 #define GL_DRAW_FRAMEBUFFER 0x8CA9 #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA #define GL_RENDERBUFFER_SAMPLES 0x8CAB #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT2 0x8CE2 #define GL_COLOR_ATTACHMENT3 0x8CE3 #define GL_COLOR_ATTACHMENT4 0x8CE4 #define GL_COLOR_ATTACHMENT5 0x8CE5 #define GL_COLOR_ATTACHMENT6 0x8CE6 #define GL_COLOR_ATTACHMENT7 0x8CE7 #define GL_COLOR_ATTACHMENT8 0x8CE8 #define GL_COLOR_ATTACHMENT9 0x8CE9 #define GL_COLOR_ATTACHMENT10 0x8CEA #define GL_COLOR_ATTACHMENT11 0x8CEB #define GL_COLOR_ATTACHMENT12 0x8CEC #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 #define GL_STENCIL_INDEX1 0x8D46 #define GL_STENCIL_INDEX4 0x8D47 #define GL_STENCIL_INDEX8 0x8D48 #define GL_STENCIL_INDEX16 0x8D49 #define GL_RENDERBUFFER_RED_SIZE 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define GL_MAX_SAMPLES 0x8D57 #endif #ifndef GL_ARB_framebuffer_sRGB #define GL_ARB_framebuffer_sRGB #define _ALLEGRO_GL_ARB_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB 0x8DB9 #endif #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 #define _ALLEGRO_GL_ARB_geometry_shader4 #define GL_LINES_ADJACENCY_ARB 0x000A #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B #define GL_TRIANGLES_ADJACENCY_ARB 0x000C #define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D #define GL_PROGRAM_POINT_SIZE_ARB 0x8642 #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 #define GL_GEOMETRY_SHADER_ARB 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 /* reuse GL_MAX_VARYING_COMPONENTS */ /* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ #endif #ifndef GL_ARB_half_float_vertex #define GL_ARB_half_float_vertex #define _ALLEGRO_GL_ARB_half_float_vertex #define GL_HALF_FLOAT 0x140B #endif #ifndef GL_ARB_instanced_arrays #define GL_ARB_instanced_arrays #define _ALLEGRO_GL_ARB_instanced_arrays #endif #ifndef GL_ARB_map_buffer_range #define GL_ARB_map_buffer_range #define _ALLEGRO_GL_ARB_map_buffer_range #define GL_MAP_READ_BIT 0x0001 #define GL_MAP_WRITE_BIT 0x0002 #define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 #define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 #define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #endif #ifndef GL_ARB_texture_buffer_object #define GL_ARB_texture_buffer_object #define _ALLEGRO_GL_ARB_texture_buffer_object #define GL_TEXTURE_BUFFER_ARB 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E #endif #ifndef GL_ARB_texture_compression_rgtc #define GL_ARB_texture_compression_rgtc #define _ALLEGRO_GL_ARB_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_RG_RGTC2 0x8DBD #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #endif #ifndef GL_ARB_texture_rg #define GL_ARB_texture_rg #define _ALLEGRO_GL_ARB_texture_rg #define GL_RG 0x8227 #define GL_RG_INTEGER 0x8228 #define GL_R8 0x8229 #define GL_R16 0x822A #define GL_RG8 0x822B #define GL_RG16 0x822C #define GL_R16F 0x822D #define GL_R32F 0x822E #define GL_RG16F 0x822F #define GL_RG32F 0x8230 #define GL_R8I 0x8231 #define GL_R8UI 0x8232 #define GL_R16I 0x8233 #define GL_R16UI 0x8234 #define GL_R32I 0x8235 #define GL_R32UI 0x8236 #define GL_RG8I 0x8237 #define GL_RG8UI 0x8238 #define GL_RG16I 0x8239 #define GL_RG16UI 0x823A #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #endif #ifndef GL_ARB_vertex_array_object #define GL_ARB_vertex_array_object #define _ALLEGRO_GL_ARB_vertex_array_object #define GL_VERTEX_ARRAY_BINDING 0x85B5 #endif #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object #define _ALLEGRO_GL_ARB_uniform_buffer_object #define GL_UNIFORM_BUFFER 0x8A11 #define GL_UNIFORM_BUFFER_BINDING 0x8A28 #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B #define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 #define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 #define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 #define GL_UNIFORM_TYPE 0x8A37 #define GL_UNIFORM_SIZE 0x8A38 #define GL_UNIFORM_NAME_LENGTH 0x8A39 #define GL_UNIFORM_BLOCK_INDEX 0x8A3A #define GL_UNIFORM_OFFSET 0x8A3B #define GL_UNIFORM_ARRAY_STRIDE 0x8A3C #define GL_UNIFORM_MATRIX_STRIDE 0x8A3D #define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E #define GL_UNIFORM_BLOCK_BINDING 0x8A3F #define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 #define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 #define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu #endif #ifndef GL_ARB_compatibility #define GL_ARB_compatibility #define _ALLEGRO_GL_ARB_compatibility /* ARB_compatibility just defines tokens from core 3.0 */ #endif #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer #define _ALLEGRO_GL_ARB_copy_buffer #define GL_COPY_READ_BUFFER 0x8F36 #define GL_COPY_WRITE_BUFFER 0x8F37 #endif #ifndef GL_ARB_shader_texture_lod #define GL_ARB_shader_texture_lod #define _ALLEGRO_GL_ARB_shader_texture_lod #endif #ifndef GL_ARB_depth_clamp #define GL_ARB_depth_clamp #define _ALLEGRO_GL_ARB_depth_clamp #define GL_DEPTH_CLAMP 0x864F #endif #ifndef GL_ARB_draw_elements_base_vertex #define GL_ARB_draw_elements_base_vertex #define _ALLEGRO_GL_ARB_draw_elements_base_vertex #endif #ifndef GL_ARB_fragment_coord_conventions #define GL_ARB_fragment_coord_conventions #define _ALLEGRO_GL_ARB_fragment_coord_conventions #endif #ifndef GL_ARB_provoking_vertex #define GL_ARB_provoking_vertex #define _ALLEGRO_GL_ARB_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C #define GL_FIRST_VERTEX_CONVENTION 0x8E4D #define GL_LAST_VERTEX_CONVENTION 0x8E4E #define GL_PROVOKING_VERTEX 0x8E4F #endif #ifndef GL_ARB_seamless_cube_map #define GL_ARB_seamless_cube_map #define _ALLEGRO_GL_ARB_seamless_cube_map #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F #endif #ifndef GL_ARB_sync #define GL_ARB_sync #define _ALLEGRO_GL_ARB_sync #if (defined _MSC_VER) && (_MSC_VER < 1400) typedef __int64 GLint64; typedef unsigned __int64 GLuint64; #else typedef int64_t GLint64; typedef uint64_t GLuint64; #endif typedef struct __GLsync *GLsync; #define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 #define GL_OBJECT_TYPE 0x9112 #define GL_SYNC_CONDITION 0x9113 #define GL_SYNC_STATUS 0x9114 #define GL_SYNC_FLAGS 0x9115 #define GL_SYNC_FENCE 0x9116 #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 #define GL_UNSIGNALED 0x9118 #define GL_SIGNALED 0x9119 #define GL_ALREADY_SIGNALED 0x911A #define GL_TIMEOUT_EXPIRED 0x911B #define GL_CONDITION_SATISFIED 0x911C #define GL_WAIT_FAILED 0x911D #define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 #define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull #endif #ifndef GL_ARB_texture_multisample #define GL_ARB_texture_multisample #define _ALLEGRO_GL_ARB_texture_multisample #define GL_SAMPLE_POSITION 0x8E50 #define GL_SAMPLE_MASK 0x8E51 #define GL_SAMPLE_MASK_VALUE 0x8E52 #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 #define GL_TEXTURE_SAMPLES 0x9106 #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F #define GL_MAX_INTEGER_SAMPLES 0x9110 #endif #ifndef GL_ARB_vertex_array_bgra #define GL_ARB_vertex_array_bgra #define _ALLEGRO_GL_ARB_vertex_array_bgra /* reuse GL_BGRA */ #endif #ifndef GL_ARB_draw_buffers_blend #define GL_ARB_draw_buffers_blend #define _ALLEGRO_GL_ARB_draw_buffers_blend #endif #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading #define _ALLEGRO_GL_ARB_sample_shading #define GL_SAMPLE_SHADING 0x8C36 #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 #endif #ifndef GL_ARB_texture_cube_map_array #define GL_ARB_texture_cube_map_array #define _ALLEGRO_GL_ARB_texture_cube_map_array #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F #endif #ifndef GL_ARB_texture_gather #define GL_ARB_texture_gather #define _ALLEGRO_GL_ARB_texture_gather #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F #endif #ifndef GL_ARB_texture_query_lod #define GL_ARB_texture_query_lod #define _ALLEGRO_GL_ARB_texture_query_lod #endif #ifndef GL_ARB_shading_language_include #define GL_ARB_shading_language_include #define _ALLEGRO_GL_ARB_shading_language_include #define GL_SHADER_INCLUDE_ARB 0x8DAE #define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 #define GL_NAMED_STRING_TYPE_ARB 0x8DEA #endif #ifndef GL_ARB_texture_compression_bptc #define GL_ARB_texture_compression_bptc #define _ALLEGRO_GL_ARB_texture_compression_bptc #define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F #endif #ifndef GL_ARB_blend_func_extended #define GL_ARB_blend_func_extended #define _ALLEGRO_GL_ARB_blend_func_extended #define GL_SRC1_COLOR 0x88F9 /* reuse GL_SRC1_ALPHA */ #define GL_ONE_MINUS_SRC1_COLOR 0x88FA #define GL_ONE_MINUS_SRC1_ALPHA 0x88FB #define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC #endif #ifndef GL_ARB_explicit_attrib_location #define GL_ARB_explicit_attrib_location #define _ALLEGRO_GL_ARB_explicit_attrib_location #endif #ifndef GL_ARB_occlusion_query2 #define GL_ARB_occlusion_query2 #define _ALLEGRO_GL_ARB_occlusion_query2 #define GL_ANY_SAMPLES_PASSED 0x8C2F #endif #ifndef GL_ARB_sampler_objects #define GL_ARB_sampler_objects #define _ALLEGRO_GL_ARB_sampler_objects #define GL_SAMPLER_BINDING 0x8919 #endif #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding #define _ALLEGRO_GL_ARB_shader_bit_encoding #endif #ifndef GL_ARB_texture_rgb10_a2ui #define GL_ARB_texture_rgb10_a2ui #define _ALLEGRO_GL_ARB_texture_rgb10_a2ui #define GL_RGB10_A2UI 0x906F #endif #ifndef GL_ARB_texture_swizzle #define GL_ARB_texture_swizzle #define _ALLEGRO_GL_ARB_texture_swizzle #define GL_TEXTURE_SWIZZLE_R 0x8E42 #define GL_TEXTURE_SWIZZLE_G 0x8E43 #define GL_TEXTURE_SWIZZLE_B 0x8E44 #define GL_TEXTURE_SWIZZLE_A 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 #endif #ifndef GL_ARB_timer_query #define GL_ARB_timer_query #define _ALLEGRO_GL_ARB_timer_query #define GL_TIME_ELAPSED 0x88BF #define GL_TIMESTAMP 0x8E28 #endif #ifndef GL_ARB_vertex_type_2_10_10_10_rev #define GL_ARB_vertex_type_2_10_10_10_rev #define _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev /* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ #define GL_INT_2_10_10_10_REV 0x8D9F #endif #ifndef GL_ARB_draw_indirect #define GL_ARB_draw_indirect #define _ALLEGRO_GL_ARB_draw_indirect #define GL_DRAW_INDIRECT_BUFFER 0x8F3F #define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 #endif #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 #define _ALLEGRO_GL_ARB_gpu_shader5 #define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F #define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A #define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B #define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C #define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D #define GL_MAX_VERTEX_STREAMS 0x8E71 #endif #ifndef GL_ARB_gpu_shader_fp64 #define GL_ARB_gpu_shader_fp64 #define _ALLEGRO_GL_ARB_gpu_shader_fp64 /* reuse GL_DOUBLE */ #define GL_DOUBLE_VEC2 0x8FFC #define GL_DOUBLE_VEC3 0x8FFD #define GL_DOUBLE_VEC4 0x8FFE #define GL_DOUBLE_MAT2 0x8F46 #define GL_DOUBLE_MAT3 0x8F47 #define GL_DOUBLE_MAT4 0x8F48 #define GL_DOUBLE_MAT2x3 0x8F49 #define GL_DOUBLE_MAT2x4 0x8F4A #define GL_DOUBLE_MAT3x2 0x8F4B #define GL_DOUBLE_MAT3x4 0x8F4C #define GL_DOUBLE_MAT4x2 0x8F4D #define GL_DOUBLE_MAT4x3 0x8F4E #endif #ifndef GL_ARB_shader_subroutine #define GL_ARB_shader_subroutine #define _ALLEGRO_GL_ARB_shader_subroutine #define GL_ACTIVE_SUBROUTINES 0x8DE5 #define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 #define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 #define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 #define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 #define GL_MAX_SUBROUTINES 0x8DE7 #define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 #define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A #define GL_COMPATIBLE_SUBROUTINES 0x8E4B /* reuse GL_UNIFORM_SIZE */ /* reuse GL_UNIFORM_NAME_LENGTH */ #endif #ifndef GL_ARB_tessellation_shader #define GL_ARB_tessellation_shader #define _ALLEGRO_GL_ARB_tessellation_shader #define GL_PATCHES 0x000E #define GL_PATCH_VERTICES 0x8E72 #define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 #define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 #define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 #define GL_TESS_GEN_MODE 0x8E76 #define GL_TESS_GEN_SPACING 0x8E77 #define GL_TESS_GEN_VERTEX_ORDER 0x8E78 #define GL_TESS_GEN_POINT_MODE 0x8E79 /* reuse GL_TRIANGLES */ /* reuse GL_QUADS */ #define GL_ISOLINES 0x8E7A /* reuse GL_EQUAL */ #define GL_FRACTIONAL_ODD 0x8E7B #define GL_FRACTIONAL_EVEN 0x8E7C /* reuse GL_CCW */ /* reuse GL_CW */ #define GL_MAX_PATCH_VERTICES 0x8E7D #define GL_MAX_TESS_GEN_LEVEL 0x8E7E #define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F #define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 #define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 #define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 #define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 #define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 #define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 #define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 #define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 #define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A #define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C #define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D #define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E #define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 #define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 #define GL_TESS_EVALUATION_SHADER 0x8E87 #define GL_TESS_CONTROL_SHADER 0x8E88 #endif #ifndef GL_ARB_texture_buffer_object_rgb32 #define GL_ARB_texture_buffer_object_rgb32 #define _ALLEGRO_GL_ARB_texture_buffer_object_rgb32 /* reuse GL_RGB32F */ /* reuse GL_RGB32UI */ /* reuse GL_RGB32I */ #endif #ifndef GL_ARB_transform_feedback2 #define GL_ARB_transform_feedback2 #define _ALLEGRO_GL_ARB_transform_feedback2 #define GL_TRANSFORM_FEEDBACK 0x8E22 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 #define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 #endif #ifndef GL_ARB_transform_feedback3 #define GL_ARB_transform_feedback3 #define _ALLEGRO_GL_ARB_transform_feedback3 #define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 #endif /* */ #ifndef GL_EXT_abgr #define GL_EXT_abgr #define _ALLEGRO_GL_EXT_abgr #define GL_ABGR_EXT 0x8000 #endif #ifndef GL_EXT_blend_color #define GL_EXT_blend_color #define _ALLEGRO_GL_EXT_blend_color #define GL_CONSTANT_COLOR_EXT 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define GL_CONSTANT_ALPHA_EXT 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define GL_BLEND_COLOR_EXT 0x8005 #endif #ifndef GL_EXT_polygon_offset #define GL_EXT_polygon_offset #define _ALLEGRO_GL_EXT_polygon_offset #define GL_POLYGON_OFFSET_EXT 0x8037 #define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 #define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 #endif #ifndef GL_EXT_texture #define GL_EXT_texture #define _ALLEGRO_GL_EXT_texture #define GL_ALPHA4_EXT 0x803B #define GL_ALPHA8_EXT 0x803C #define GL_ALPHA12_EXT 0x803D #define GL_ALPHA16_EXT 0x803E #define GL_LUMINANCE4_EXT 0x803F #define GL_LUMINANCE8_EXT 0x8040 #define GL_LUMINANCE12_EXT 0x8041 #define GL_LUMINANCE16_EXT 0x8042 #define GL_LUMINANCE4_ALPHA4_EXT 0x8043 #define GL_LUMINANCE6_ALPHA2_EXT 0x8044 #define GL_LUMINANCE8_ALPHA8_EXT 0x8045 #define GL_LUMINANCE12_ALPHA4_EXT 0x8046 #define GL_LUMINANCE12_ALPHA12_EXT 0x8047 #define GL_LUMINANCE16_ALPHA16_EXT 0x8048 #define GL_INTENSITY_EXT 0x8049 #define GL_INTENSITY4_EXT 0x804A #define GL_INTENSITY8_EXT 0x804B #define GL_INTENSITY12_EXT 0x804C #define GL_INTENSITY16_EXT 0x804D #define GL_RGB2_EXT 0x804E #define GL_RGB4_EXT 0x804F #define GL_RGB5_EXT 0x8050 #define GL_RGB8_EXT 0x8051 #define GL_RGB10_EXT 0x8052 #define GL_RGB12_EXT 0x8053 #define GL_RGB16_EXT 0x8054 #define GL_RGBA2_EXT 0x8055 #define GL_RGBA4_EXT 0x8056 #define GL_RGB5_A1_EXT 0x8057 #define GL_RGBA8_EXT 0x8058 #define GL_RGB10_A2_EXT 0x8059 #define GL_RGBA12_EXT 0x805A #define GL_RGBA16_EXT 0x805B #define GL_TEXTURE_RED_SIZE_EXT 0x805C #define GL_TEXTURE_GREEN_SIZE_EXT 0x805D #define GL_TEXTURE_BLUE_SIZE_EXT 0x805E #define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F #define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 #define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 #define GL_REPLACE_EXT 0x8062 #define GL_PROXY_TEXTURE_1D_EXT 0x8063 #define GL_PROXY_TEXTURE_2D_EXT 0x8064 #define GL_TEXTURE_TOO_LARGE_EXT 0x8065 #endif #ifndef GL_EXT_texture3D #define GL_EXT_texture3D #define _ALLEGRO_GL_EXT_texture3D #define GL_PACK_SKIP_IMAGES_EXT 0x806B #define GL_PACK_IMAGE_HEIGHT_EXT 0x806C #define GL_UNPACK_SKIP_IMAGES_EXT 0x806D #define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define GL_TEXTURE_3D_EXT 0x806F #define GL_PROXY_TEXTURE_3D_EXT 0x8070 #define GL_TEXTURE_DEPTH_EXT 0x8071 #define GL_TEXTURE_WRAP_R_EXT 0x8072 #define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 #endif #ifndef GL_SGIS_texture_filter4 #define GL_SGIS_texture_filter4 #define _ALLEGRO_GL_SGIS_texture_filter4 #define GL_FILTER4_SGIS 0x8146 #define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 #endif #ifndef GL_EXT_histogram #define GL_EXT_histogram #define _ALLEGRO_GL_EXT_histogram #define GL_HISTOGRAM_EXT 0x8024 #define GL_PROXY_HISTOGRAM_EXT 0x8025 #define GL_HISTOGRAM_WIDTH_EXT 0x8026 #define GL_HISTOGRAM_FORMAT_EXT 0x8027 #define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 #define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 #define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A #define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C #define GL_HISTOGRAM_SINK_EXT 0x802D #define GL_MINMAX_EXT 0x802E #define GL_MINMAX_FORMAT_EXT 0x802F #define GL_MINMAX_SINK_EXT 0x8030 #define GL_TABLE_TOO_LARGE_EXT 0x8031 #endif #ifndef GL_EXT_subtexture #define GL_EXT_subtexture #define _ALLEGRO_GL_EXT_subtexture #endif #ifndef GL_EXT_copy_texture #define GL_EXT_copy_texture /* NV's headers don't define EXT_copy_texture yet provide the API */ #ifndef ALLEGRO_GL_HEADER_NV #define _ALLEGRO_GL_EXT_copy_texture #endif #endif #ifndef GL_EXT_histogram #define GL_EXT_histogram #define _ALLEGRO_GL_EXT_histogram #endif #ifndef GL_EXT_convolution #define GL_EXT_convolution #define _ALLEGRO_GL_EXT_convolution #define GL_CONVOLUTION_1D_EXT 0x8010 #define GL_CONVOLUTION_2D_EXT 0x8011 #define GL_SEPARABLE_2D_EXT 0x8012 #define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 #define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 #define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 #define GL_REDUCE_EXT 0x8016 #define GL_CONVOLUTION_FORMAT_EXT 0x8017 #define GL_CONVOLUTION_WIDTH_EXT 0x8018 #define GL_CONVOLUTION_HEIGHT_EXT 0x8019 #define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A #define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B #define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C #define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D #define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E #define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F #define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 #define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 #endif #ifndef GL_SGI_color_matrix #define GL_SGI_color_matrix #define _ALLEGRO_GL_SGI_color_matrix #define GL_COLOR_MATRIX_SGI 0x80B1 #define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 #define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 #define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 #define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 #define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 #define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 #define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 #define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB #endif #ifndef GL_SGI_color_table #define GL_SGI_color_table #define _ALLEGRO_GL_SGI_color_table #define GL_COLOR_TABLE_SGI 0x80D0 #define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 #define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 #define GL_PROXY_COLOR_TABLE_SGI 0x80D3 #define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 #define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 #define GL_COLOR_TABLE_SCALE_SGI 0x80D6 #define GL_COLOR_TABLE_BIAS_SGI 0x80D7 #define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 #define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 #define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF #endif #ifndef GL_SGIS_pixel_texture #define GL_SGIS_pixel_texture #define _ALLEGRO_GL_SGIS_pixel_texture #define GL_PIXEL_TEXTURE_SGIS 0x8353 #define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 #define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 #define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 #endif #ifndef GL_SGIX_pixel_texture #define GL_SGIX_pixel_texture #define _ALLEGRO_GL_SGIX_pixel_texture #define GL_PIXEL_TEX_GEN_SGIX 0x8139 #define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B #endif #ifndef GL_SGIS_texture4D #define GL_SGIS_texture4D #define _ALLEGRO_GL_SGIS_texture4D #define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 #define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 #define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define GL_TEXTURE_4D_SGIS 0x8134 #define GL_PROXY_TEXTURE_4D_SGIS 0x8135 #define GL_TEXTURE_4DSIZE_SGIS 0x8136 #define GL_TEXTURE_WRAP_Q_SGIS 0x8137 #define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 #define GL_TEXTURE_4D_BINDING_SGIS 0x814F #endif #ifndef GL_SGI_texture_color_table #define GL_SGI_texture_color_table #define _ALLEGRO_GL_SGI_texture_color_table #define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC #define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD #endif #ifndef GL_EXT_cmyka #define GL_EXT_cmyka #define _ALLEGRO_GL_EXT_cmyka #define GL_CMYK_EXT 0x800C #define GL_CMYKA_EXT 0x800D #define GL_PACK_CMYK_HINT_EXT 0x800E #define GL_UNPACK_CMYK_HINT_EXT 0x800F #endif #ifndef GL_EXT_texture_object #define GL_EXT_texture_object #define _ALLEGRO_GL_EXT_texture_object #define GL_TEXTURE_PRIORITY_EXT 0x8066 #define GL_TEXTURE_RESIDENT_EXT 0x8067 #define GL_TEXTURE_1D_BINDING_EXT 0x8068 #define GL_TEXTURE_2D_BINDING_EXT 0x8069 #define GL_TEXTURE_3D_BINDING_EXT 0x806A #endif #ifndef GL_SGIS_detail_texture #define GL_SGIS_detail_texture #define _ALLEGRO_GL_SGIS_detail_texture #define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 #define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 #define GL_LINEAR_DETAIL_SGIS 0x8097 #define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 #define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 #define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B #define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #endif #ifndef GL_SGIS_sharpen_texture #define GL_SGIS_sharpen_texture #define _ALLEGRO_GL_SGIS_sharpen_texture #define GL_LINEAR_SHARPEN_SGIS 0x80AD #define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE #define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF #define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 #endif #ifndef GL_EXT_packed_pixels #define GL_EXT_packed_pixels #define _ALLEGRO_GL_EXT_packed_pixels #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 #endif #ifndef GL_SGIS_texture_lod #define GL_SGIS_texture_lod #define _ALLEGRO_GL_SGIS_texture_lod #define GL_TEXTURE_MIN_LOD_SGIS 0x813A #define GL_TEXTURE_MAX_LOD_SGIS 0x813B #define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C #define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D #endif #ifndef GL_SGIS_multisample #define GL_SGIS_multisample #define _ALLEGRO_GL_SGIS_multisample #define GL_MULTISAMPLE_SGIS 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F #define GL_SAMPLE_MASK_SGIS 0x80A0 #define GL_1PASS_SGIS 0x80A1 #define GL_2PASS_0_SGIS 0x80A2 #define GL_2PASS_1_SGIS 0x80A3 #define GL_4PASS_0_SGIS 0x80A4 #define GL_4PASS_1_SGIS 0x80A5 #define GL_4PASS_2_SGIS 0x80A6 #define GL_4PASS_3_SGIS 0x80A7 #define GL_SAMPLE_BUFFERS_SGIS 0x80A8 #define GL_SAMPLES_SGIS 0x80A9 #define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA #define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB #define GL_SAMPLE_PATTERN_SGIS 0x80AC #endif #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal #define _ALLEGRO_GL_EXT_rescale_normal #define GL_RESCALE_NORMAL_EXT 0x803A #endif #ifndef GL_EXT_vertex_array #define GL_EXT_vertex_array #define _ALLEGRO_GL_EXT_vertex_array #define GL_VERTEX_ARRAY_EXT 0x8074 #define GL_NORMAL_ARRAY_EXT 0x8075 #define GL_COLOR_ARRAY_EXT 0x8076 #define GL_INDEX_ARRAY_EXT 0x8077 #define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define GL_EDGE_FLAG_ARRAY_EXT 0x8079 #define GL_VERTEX_ARRAY_SIZE_EXT 0x807A #define GL_VERTEX_ARRAY_TYPE_EXT 0x807B #define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_NORMAL_ARRAY_TYPE_EXT 0x807E #define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define GL_COLOR_ARRAY_SIZE_EXT 0x8081 #define GL_COLOR_ARRAY_TYPE_EXT 0x8082 #define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define GL_COLOR_ARRAY_COUNT_EXT 0x8084 #define GL_INDEX_ARRAY_TYPE_EXT 0x8085 #define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define GL_INDEX_ARRAY_COUNT_EXT 0x8087 #define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define GL_VERTEX_ARRAY_POINTER_EXT 0x808E #define GL_NORMAL_ARRAY_POINTER_EXT 0x808F #define GL_COLOR_ARRAY_POINTER_EXT 0x8090 #define GL_INDEX_ARRAY_POINTER_EXT 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #endif #ifndef GL_SGIS_generate_mipmap #define GL_SGIS_generate_mipmap #define _ALLEGRO_GL_SGIS_generate_mipmap #define GL_GENERATE_MIPMAP_SGIS 0x8191 #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif #ifndef GL_SGIX_clipmap #define GL_SGIX_clipmap #define _ALLEGRO_GL_SGIX_clipmap #define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 #define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 #define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 #define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 #define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 #define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 #define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 #define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D #define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E #define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F #endif #ifndef GL_SGIX_shadow #define GL_SGIX_shadow #define _ALLEGRO_GL_SGIX_shadow #define GL_TEXTURE_COMPARE_SGIX 0x819A #define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B #define GL_TEXTURE_LEQUAL_R_SGIX 0x819C #define GL_TEXTURE_GEQUAL_R_SGIX 0x819D #endif #ifndef GL_SGIS_texture_edge_clamp #define GL_SGIS_texture_edge_clamp #define _ALLEGRO_GL_SGIS_texture_edge_clamp #define GL_CLAMP_TO_EDGE_SGIS 0x812F #endif #ifndef GL_EXT_blend_minmax #define GL_EXT_blend_minmax #define _ALLEGRO_GL_EXT_blend_minmax #define GL_FUNC_ADD_EXT 0x8006 #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 #define GL_BLEND_EQUATION_EXT 0x8009 #endif #ifndef GL_EXT_blend_subtract #define GL_EXT_blend_subtract #define _ALLEGRO_GL_EXT_blend_subtract #define GL_FUNC_SUBTRACT_EXT 0x800A #define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B #endif #ifndef GL_SGIX_interlace #define GL_SGIX_interlace #define _ALLEGRO_GL_SGIX_interlace #define GL_INTERLACE_SGIX 0x8094 #endif #ifndef GL_SGIX_pixel_tiles #define GL_SGIX_pixel_tiles #define _ALLEGRO_GL_SGIX_pixel_tiles #define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E #define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F #define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 #define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 #define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 #define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 #define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 #define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 #endif #ifndef GL_SGIS_texture_select #define GL_SGIS_texture_select #define _ALLEGRO_GL_SGIS_texture_select #define GL_DUAL_ALPHA4_SGIS 0x8110 #define GL_DUAL_ALPHA8_SGIS 0x8111 #define GL_DUAL_ALPHA12_SGIS 0x8112 #define GL_DUAL_ALPHA16_SGIS 0x8113 #define GL_DUAL_LUMINANCE4_SGIS 0x8114 #define GL_DUAL_LUMINANCE8_SGIS 0x8115 #define GL_DUAL_LUMINANCE12_SGIS 0x8116 #define GL_DUAL_LUMINANCE16_SGIS 0x8117 #define GL_DUAL_INTENSITY4_SGIS 0x8118 #define GL_DUAL_INTENSITY8_SGIS 0x8119 #define GL_DUAL_INTENSITY12_SGIS 0x811A #define GL_DUAL_INTENSITY16_SGIS 0x811B #define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C #define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D #define GL_QUAD_ALPHA4_SGIS 0x811E #define GL_QUAD_ALPHA8_SGIS 0x811F #define GL_QUAD_LUMINANCE4_SGIS 0x8120 #define GL_QUAD_LUMINANCE8_SGIS 0x8121 #define GL_QUAD_INTENSITY4_SGIS 0x8122 #define GL_QUAD_INTENSITY8_SGIS 0x8123 #define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 #define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #endif #ifndef GL_SGIX_sprite #define GL_SGIX_sprite #define _ALLEGRO_GL_SGIX_sprite #define GL_SPRITE_SGIX 0x8148 #define GL_SPRITE_MODE_SGIX 0x8149 #define GL_SPRITE_AXIS_SGIX 0x814A #define GL_SPRITE_TRANSLATION_SGIX 0x814B #define GL_SPRITE_AXIAL_SGIX 0x814C #define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D #define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E #endif #ifndef GL_SGIX_texture_multi_buffer #define GL_SGIX_texture_multi_buffer #define _ALLEGRO_GL_SGIX_texture_multi_buffer #define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E #endif #ifndef GL_EXT_point_parameters #define GL_EXT_point_parameters #define _ALLEGRO_GL_EXT_point_parameters #define GL_POINT_SIZE_MIN_EXT 0x8126 #define GL_POINT_SIZE_MAX_EXT 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define GL_DISTANCE_ATTENUATION_EXT 0x8129 #endif #ifndef GL_SGIS_point_parameters #define GL_SGIS_point_parameters #define _ALLEGRO_GL_SGIS_point_parameters #define GL_POINT_SIZE_MIN_SGIS 0x8126 #define GL_POINT_SIZE_MAX_SGIS 0x8127 #define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 #define GL_DISTANCE_ATTENUATION_SGIS 0x8129 #endif #ifndef GL_SGIX_instruments #define GL_SGIX_instruments #define _ALLEGRO_GL_SGIX_instruments #define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #endif #ifndef GL_SGIX_texture_scale_bias #define GL_SGIX_texture_scale_bias #define _ALLEGRO_GL_SGIX_texture_scale_bias #define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 #define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A #define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B #define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C #endif #ifndef GL_SGIX_framezoom #define GL_SGIX_framezoom #define _ALLEGRO_GL_SGIX_framezoom #define GL_FRAMEZOOM_SGIX 0x818B #define GL_FRAMEZOOM_FACTOR_SGIX 0x818C #define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D #endif #ifndef GL_FfdMaskSGIX #define GL_FfdMaskSGIX #define _ALLEGRO_GL_FfdMaskSGIX #define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 #define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 #endif #ifndef GL_SGIX_tag_sample_buffer #define GL_SGIX_tag_sample_buffer #define _ALLEGRO_GL_SGIX_tag_sample_buffer #endif #ifndef GL_SGIX_polynomial_ffd #define GL_SGIX_polynomial_ffd #define _ALLEGRO_GL_SGIX_polynomial_ffd #define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 #define GL_TEXTURE_DEFORMATION_SGIX 0x8195 #define GL_DEFORMATIONS_MASK_SGIX 0x8196 #define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #endif #ifndef GL_SGIX_reference_plane #define GL_SGIX_reference_plane #define _ALLEGRO_GL_SGIX_reference_plane #define GL_REFERENCE_PLANE_SGIX 0x817D #define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E #endif #ifndef GL_SGIX_depth_texture #define GL_SGIX_depth_texture #define _ALLEGRO_GL_SGIX_depth_texture #define GL_DEPTH_COMPONENT16_SGIX 0x81A5 #define GL_DEPTH_COMPONENT24_SGIX 0x81A6 #define GL_DEPTH_COMPONENT32_SGIX 0x81A7 #endif #ifndef GL_SGIX_flush_raster #define GL_SGIX_flush_raster #define _ALLEGRO_GL_SGIX_flush_raster #endif #ifndef GL_SGIS_fog_function #define GL_SGIS_fog_function #define _ALLEGRO_GL_SGIS_fog_function #define GL_FOG_FUNC_SGIS 0x812A #define GL_FOG_FUNC_POINTS_SGIS 0x812B #define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C #endif #ifndef GL_SGIX_fog_offset #define GL_SGIX_fog_offset #define _ALLEGRO_GL_SGIX_fog_offset #define GL_FOG_OFFSET_SGIX 0x8198 #define GL_FOG_OFFSET_VALUE_SGIX 0x8199 #endif #ifndef GL_HP_image_transform #define GL_HP_image_transform #define _ALLEGRO_GL_HP_image_transform #define GL_IMAGE_SCALE_X_HP 0x8155 #define GL_IMAGE_SCALE_Y_HP 0x8156 #define GL_IMAGE_TRANSLATE_X_HP 0x8157 #define GL_IMAGE_TRANSLATE_Y_HP 0x8158 #define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 #define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A #define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B #define GL_IMAGE_MAG_FILTER_HP 0x815C #define GL_IMAGE_MIN_FILTER_HP 0x815D #define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E #define GL_CUBIC_HP 0x815F #define GL_AVERAGE_HP 0x8160 #define GL_IMAGE_TRANSFORM_2D_HP 0x8161 #define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 #define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 #endif #ifndef GL_HP_convolution_border_modes #define GL_HP_convolution_border_modes #define _ALLEGRO_GL_HP_convolution_border_modes #define GL_IGNORE_BORDER_HP 0x8150 #define GL_CONSTANT_BORDER_HP 0x8151 #define GL_REPLICATE_BORDER_HP 0x8153 #define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 #endif #ifndef GL_SGIX_texture_add_env #define GL_SGIX_texture_add_env #define _ALLEGRO_GL_SGIX_texture_add_env #define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE #endif #ifndef GL_EXT_color_subtable #define GL_EXT_color_subtable #define _ALLEGRO_GL_EXT_color_subtable #endif #ifndef GL_PGI_vertex_hints #define GL_PGI_vertex_hints #define _ALLEGRO_GL_PGI_vertex_hints #define GL_VERTEX_DATA_HINT_PGI 0x1A22A #define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C #define GL_MAX_VERTEX_HINT_PGI 0x1A22D #define GL_COLOR3_BIT_PGI 0x00010000 #define GL_COLOR4_BIT_PGI 0x00020000 #define GL_EDGEFLAG_BIT_PGI 0x00040000 #define GL_INDEX_BIT_PGI 0x00080000 #define GL_MAT_AMBIENT_BIT_PGI 0x00100000 #define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 #define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 #define GL_MAT_EMISSION_BIT_PGI 0x00800000 #define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 #define GL_MAT_SHININESS_BIT_PGI 0x02000000 #define GL_MAT_SPECULAR_BIT_PGI 0x04000000 #define GL_NORMAL_BIT_PGI 0x08000000 #define GL_TEXCOORD1_BIT_PGI 0x10000000 #define GL_TEXCOORD2_BIT_PGI 0x20000000 #define GL_TEXCOORD3_BIT_PGI 0x40000000 #define GL_TEXCOORD4_BIT_PGI 0x80000000 #define GL_VERTEX23_BIT_PGI 0x00000004 #define GL_VERTEX4_BIT_PGI 0x00000008 #endif #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints #define _ALLEGRO_GL_PGI_misc_hints #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 #define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE #define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 #define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 #define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 #define GL_ALWAYS_FAST_HINT_PGI 0x1A20C #define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D #define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E #define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F #define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 #define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 #define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 #define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 #define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 #define GL_FULL_STIPPLE_HINT_PGI 0x1A219 #define GL_CLIP_NEAR_HINT_PGI 0x1A220 #define GL_CLIP_FAR_HINT_PGI 0x1A221 #define GL_WIDE_LINE_HINT_PGI 0x1A222 #define GL_BACK_NORMALS_HINT_PGI 0x1A223 #endif #ifndef GL_EXT_paletted_texture #define GL_EXT_paletted_texture #define _ALLEGRO_GL_EXT_paletted_texture #define GL_COLOR_INDEX1_EXT 0x80E2 #define GL_COLOR_INDEX2_EXT 0x80E3 #define GL_COLOR_INDEX4_EXT 0x80E4 #define GL_COLOR_INDEX8_EXT 0x80E5 #define GL_COLOR_INDEX12_EXT 0x80E6 #define GL_COLOR_INDEX16_EXT 0x80E7 #define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif #ifndef GL_EXT_clip_volume_hint #define GL_EXT_clip_volume_hint #define _ALLEGRO_GL_EXT_clip_volume_hint #define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #endif #ifndef GL_SGIX_list_priority #define GL_SGIX_list_priority #define _ALLEGRO_GL_SGIX_list_priority #define GL_LIST_PRIORITY_SGIX 0x8182 #endif #ifndef GL_SGIX_ir_instrument1 #define GL_SGIX_ir_instrument1 #define _ALLEGRO_GL_SGIX_ir_instrument1 #define GL_IR_INSTRUMENT1_SGIX 0x817F #endif #ifndef GL_SGIX_calligraphic_fragment #define GL_SGIX_calligraphic_fragment #define _ALLEGRO_GL_SGIX_calligraphic_fragment #define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 #endif #ifndef GL_SGIX_texture_lod_bias #define GL_SGIX_texture_lod_bias #define _ALLEGRO_GL_SGIX_texture_lod_bias #define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E #define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F #define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 #endif #ifndef GL_SGIX_shadow_ambient #define GL_SGIX_shadow_ambient #define _ALLEGRO_GL_SGIX_shadow_ambient #define GL_SHADOW_AMBIENT_SGIX 0x80BF #endif #ifndef GL_EXT_index_material #define GL_EXT_index_material #define _ALLEGRO_GL_EXT_index_material #define GL_INDEX_MATERIAL_EXT 0x81B8 #define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 #define GL_INDEX_MATERIAL_FACE_EXT 0x81BA #endif #ifndef GL_EXT_index_func #define GL_EXT_index_func #define _ALLEGRO_GL_EXT_index_func #define GL_INDEX_TEST_EXT 0x81B5 #define GL_INDEX_TEST_FUNC_EXT 0x81B6 #define GL_INDEX_TEST_REF_EXT 0x81B7 #endif #ifndef GL_EXT_index_array_formats #define GL_EXT_index_array_formats #define _ALLEGRO_GL_EXT_index_array_formats #define GL_IUI_V2F_EXT 0x81AD #define GL_IUI_V3F_EXT 0x81AE #define GL_IUI_N3F_V2F_EXT 0x81AF #define GL_IUI_N3F_V3F_EXT 0x81B0 #define GL_T2F_IUI_V2F_EXT 0x81B1 #define GL_T2F_IUI_V3F_EXT 0x81B2 #define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 #define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 #endif #ifndef GL_EXT_compiled_vertex_array #define GL_EXT_compiled_vertex_array #define _ALLEGRO_GL_EXT_compiled_vertex_array #define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 #define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 #endif #ifndef GL_EXT_cull_vertex #define GL_EXT_cull_vertex #define _ALLEGRO_GL_EXT_cull_vertex #define GL_CULL_VERTEX_EXT 0x81AA #define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB #define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC #endif #ifndef GL_SGIX_ycrcb #define GL_SGIX_ycrcb #define _ALLEGRO_GL_SGIX_ycrcb #define GL_YCRCB_422_SGIX 0x81BB #define GL_YCRCB_444_SGIX 0x81BC #endif #ifndef GL_SGIX_fragment_lighting #define GL_SGIX_fragment_lighting #define _ALLEGRO_GL_SGIX_fragment_lighting #define GL_FRAGMENT_LIGHTING_SGIX 0x8400 #define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 #define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 #define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 #define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 #define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 #define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 #define GL_LIGHT_ENV_MODE_SGIX 0x8407 #define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define GL_FRAGMENT_LIGHT0_SGIX 0x840C #define GL_FRAGMENT_LIGHT1_SGIX 0x840D #define GL_FRAGMENT_LIGHT2_SGIX 0x840E #define GL_FRAGMENT_LIGHT3_SGIX 0x840F #define GL_FRAGMENT_LIGHT4_SGIX 0x8410 #define GL_FRAGMENT_LIGHT5_SGIX 0x8411 #define GL_FRAGMENT_LIGHT6_SGIX 0x8412 #define GL_FRAGMENT_LIGHT7_SGIX 0x8413 #endif #ifndef GL_IBM_rasterpos_clip #define GL_IBM_rasterpos_clip #define _ALLEGRO_GL_IBM_rasterpos_clip #define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 #endif #ifndef GL_HP_texture_lighting #define GL_HP_texture_lighting #define _ALLEGRO_GL_HP_texture_lighting #define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 #define GL_TEXTURE_POST_SPECULAR_HP 0x8168 #define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 #endif #ifndef GL_EXT_draw_range_elements #define GL_EXT_draw_range_elements #define _ALLEGRO_GL_EXT_draw_range_elements #define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 #define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 #endif #ifndef GL_WIN_phong_shading #define GL_WIN_phong_shading #define _ALLEGRO_GL_WIN_phong_shading #define GL_PHONG_WIN 0x80EA #define GL_PHONG_HINT_WIN 0x80EB #endif #ifndef GL_WIN_specular_fog #define GL_WIN_specular_fog #define _ALLEGRO_GL_WIN_specular_fog #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #endif #ifndef GL_EXT_light_texture #define GL_EXT_light_texture #define _ALLEGRO_GL_EXT_light_texture #define GL_FRAGMENT_MATERIAL_EXT 0x8349 #define GL_FRAGMENT_NORMAL_EXT 0x834A #define GL_FRAGMENT_COLOR_EXT 0x834C #define GL_ATTENUATION_EXT 0x834D #define GL_SHADOW_ATTENUATION_EXT 0x834E #define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F #define GL_TEXTURE_LIGHT_EXT 0x8350 #define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 #define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 #ifndef GL_FRAGMENT_DEPTH_EXT #define GL_FRAGMENT_DEPTH_EXT 0x8452 #endif #endif #ifndef GL_SGIX_blend_alpha_minmax #define GL_SGIX_blend_alpha_minmax #define _ALLEGRO_GL_SGIX_blend_alpha_minmax #define GL_ALPHA_MIN_SGIX 0x8320 #define GL_ALPHA_MAX_SGIX 0x8321 #endif #ifndef GL_SGIX_impact_pixel_texture #define GL_SGIX_impact_pixel_texture #define _ALLEGRO_GL_SGIX_impact_pixel_texture #define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 #define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 #define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 #define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 #define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 #define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 #define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A #endif #ifndef GL_EXT_bgra #define GL_EXT_bgra #define _ALLEGRO_GL_EXT_bgra #define GL_BGR_EXT 0x80E0 #define GL_BGRA_EXT 0x80E1 #endif #ifndef GL_SGIX_async #define GL_SGIX_async #define _ALLEGRO_GL_SGIX_async #define GL_ASYNC_MARKER_SGIX 0x8329 #endif #ifndef GL_SGIX_async_pixel #define GL_SGIX_async_pixel #define _ALLEGRO_GL_SGIX_async_pixel #define GL_ASYNC_TEX_IMAGE_SGIX 0x835C #define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D #define GL_ASYNC_READ_PIXELS_SGIX 0x835E #define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F #define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 #define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 #endif #ifndef GL_SGIX_async_histogram #define GL_SGIX_async_histogram #define _ALLEGRO_GL_SGIX_async_histogram #define GL_ASYNC_HISTOGRAM_SGIX 0x832C #define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D #endif #ifndef GL_INTEL_parallel_arrays #define GL_INTEL_parallel_arrays #define _ALLEGRO_GL_INTEL_parallel_arrays #define GL_PARALLEL_ARRAYS_INTEL 0x83F4 #define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 #define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 #define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 #define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 #endif #ifndef GL_HP_occlusion_test #define GL_HP_occlusion_test #define _ALLEGRO_GL_HP_occlusion_test #define GL_OCCLUSION_TEST_HP 0x8165 #define GL_OCCLUSION_TEST_RESULT_HP 0x8166 #endif #ifndef GL_EXT_pixel_transform #define GL_EXT_pixel_transform #define _ALLEGRO_GL_EXT_pixel_transform #define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 #define GL_PIXEL_MAG_FILTER_EXT 0x8331 #define GL_PIXEL_MIN_FILTER_EXT 0x8332 #define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 #define GL_CUBIC_EXT 0x8334 #define GL_AVERAGE_EXT 0x8335 #define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 #define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 #define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 #endif #ifndef GL_EXT_shared_texture_palette #define GL_EXT_shared_texture_palette #define _ALLEGRO_GL_EXT_shared_texture_palette #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #ifndef GL_EXT_separate_specular_color #define GL_EXT_separate_specular_color #define _ALLEGRO_GL_EXT_separate_specular_color #define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 #define GL_SINGLE_COLOR_EXT 0x81F9 #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif #ifndef GL_EXT_secondary_color #define GL_EXT_secondary_color #define _ALLEGRO_GL_EXT_secondary_color #define GL_COLOR_SUM_EXT 0x8458 #define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D #define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E #endif #ifndef GL_EXT_texture_perturb_normal #define GL_EXT_texture_perturb_normal #define _ALLEGRO_GL_EXT_texture_perturb_normal #define GL_PERTURB_EXT 0x85AE #define GL_TEXTURE_NORMAL_EXT 0x85AF #endif #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays #define _ALLEGRO_GL_EXT_multi_draw_arrays #endif #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord #define _ALLEGRO_GL_EXT_fog_coord #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 #define GL_FOG_COORDINATE_EXT 0x8451 #define GL_FRAGMENT_DEPTH_EXT 0x8452 #define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 #define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 #define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 #define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 #endif #ifndef GL_REND_screen_coordinates #define GL_REND_screen_coordinates #define _ALLEGRO_GL_REND_screen_coordinates #define GL_SCREEN_COORDINATES_REND 0x8490 #define GL_INVERTED_SCREEN_W_REND 0x8491 #endif #ifndef GL_EXT_coordinate_frame #define GL_EXT_coordinate_frame #define _ALLEGRO_GL_EXT_coordinate_frame #define GL_TANGENT_ARRAY_EXT 0x8439 #define GL_BINORMAL_ARRAY_EXT 0x843A #define GL_CURRENT_TANGENT_EXT 0x843B #define GL_CURRENT_BINORMAL_EXT 0x843C #define GL_TANGENT_ARRAY_TYPE_EXT 0x843E #define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F #define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 #define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 #define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 #define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 #define GL_MAP1_TANGENT_EXT 0x8444 #define GL_MAP2_TANGENT_EXT 0x8445 #define GL_MAP1_BINORMAL_EXT 0x8446 #define GL_MAP2_BINORMAL_EXT 0x8447 #endif #ifndef GL_EXT_texture_env_combine #define GL_EXT_texture_env_combine #define _ALLEGRO_GL_EXT_texture_env_combine #define GL_COMBINE_EXT 0x8570 #define GL_COMBINE_RGB_EXT 0x8571 #define GL_COMBINE_ALPHA_EXT 0x8572 #define GL_RGB_SCALE_EXT 0x8573 #define GL_ADD_SIGNED_EXT 0x8574 #define GL_INTERPOLATE_EXT 0x8575 #define GL_CONSTANT_EXT 0x8576 #define GL_PRIMARY_COLOR_EXT 0x8577 #define GL_PREVIOUS_EXT 0x8578 #define GL_SOURCE0_RGB_EXT 0x8580 #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE2_RGB_EXT 0x8582 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 #define GL_SOURCE2_ALPHA_EXT 0x858A #define GL_OPERAND0_RGB_EXT 0x8590 #define GL_OPERAND1_RGB_EXT 0x8591 #define GL_OPERAND2_RGB_EXT 0x8592 #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A #endif #ifndef GL_APPLE_specular_vector #define GL_APPLE_specular_vector #define _ALLEGRO_GL_APPLE_specular_vector #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 #endif #ifndef GL_APPLE_transform_hint #define GL_APPLE_transform_hint #define _ALLEGRO_GL_APPLE_transform_hint #define GL_TRANSFORM_HINT_APPLE 0x85B1 #endif #ifndef GL_SGIX_fog_scale #define GL_SGIX_fog_scale #define _ALLEGRO_GL_SGIX_fog_scale #define GL_FOG_SCALE_SGIX 0x81FC #define GL_FOG_SCALE_VALUE_SGIX 0x81FD #endif #ifndef GL_SUNX_constant_data #define GL_SUNX_constant_data #define _ALLEGRO_GL_SUNX_constant_data #define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 #define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 #endif #ifndef GL_SUN_global_alpha #define GL_SUN_global_alpha #define _ALLEGRO_GL_SUN_global_alpha #define GL_GLOBAL_ALPHA_SUN 0x81D9 #define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #endif #ifndef GL_SUN_triangle_list #define GL_SUN_triangle_list #define _ALLEGRO_GL_SUN_triangle_list #define GL_RESTART_SUN 0x0001 #define GL_REPLACE_MIDDLE_SUN 0x0002 #define GL_REPLACE_OLDEST_SUN 0x0003 #define GL_TRIANGLE_LIST_SUN 0x81D7 #define GL_REPLACEMENT_CODE_SUN 0x81D8 #define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 #define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 #define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 #define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 #define GL_R1UI_V3F_SUN 0x85C4 #define GL_R1UI_C4UB_V3F_SUN 0x85C5 #define GL_R1UI_C3F_V3F_SUN 0x85C6 #define GL_R1UI_N3F_V3F_SUN 0x85C7 #define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 #define GL_R1UI_T2F_V3F_SUN 0x85C9 #define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA #define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB #endif #ifndef GL_SUN_vertex #define GL_SUN_vertex #define _ALLEGRO_GL_SUN_vertex #endif #ifndef GL_EXT_blend_func_separate #define GL_EXT_blend_func_separate #define _ALLEGRO_GL_EXT_blend_func_separate #define GL_BLEND_DST_RGB_EXT 0x80C8 #define GL_BLEND_SRC_RGB_EXT 0x80C9 #define GL_BLEND_DST_ALPHA_EXT 0x80CA #define GL_BLEND_SRC_ALPHA_EXT 0x80CB #endif #ifndef GL_INGR_color_clamp #define GL_INGR_color_clamp #define _ALLEGRO_GL_INGR_color_clamp #define GL_RED_MIN_CLAMP_INGR 0x8560 #define GL_GREEN_MIN_CLAMP_INGR 0x8561 #define GL_BLUE_MIN_CLAMP_INGR 0x8562 #define GL_ALPHA_MIN_CLAMP_INGR 0x8563 #define GL_RED_MAX_CLAMP_INGR 0x8564 #define GL_GREEN_MAX_CLAMP_INGR 0x8565 #define GL_BLUE_MAX_CLAMP_INGR 0x8566 #define GL_ALPHA_MAX_CLAMP_INGR 0x8567 #endif #ifndef GL_INGR_blend_func_separate #define GL_INGR_blend_func_separate #define _ALLEGRO_GL_INGR_blend_func_separate #endif #ifndef GL_INGR_interlace_read #define GL_INGR_interlace_read #define _ALLEGRO_GL_INGR_interlace_read #define GL_INTERLACE_READ_INGR 0x8568 #endif #ifndef GL_EXT_stencil_wrap #define GL_EXT_stencil_wrap #define _ALLEGRO_GL_EXT_stencil_wrap #define GL_INCR_WRAP_EXT 0x8507 #define GL_DECR_WRAP_EXT 0x8508 #endif #ifndef GL_EXT_422_pixels #define GL_EXT_422_pixels #define _ALLEGRO_GL_EXT_422_pixels #define GL_422_EXT 0x80CC #define GL_422_REV_EXT 0x80CD #define GL_422_AVERAGE_EXT 0x80CE #define GL_422_REV_AVERAGE_EXT 0x80CF #endif #ifndef GL_NV_texgen_reflection #define GL_NV_texgen_reflection #define _ALLEGRO_GL_NV_texgen_reflection #define GL_NORMAL_MAP_NV 0x8511 #define GL_REFLECTION_MAP_NV 0x8512 #endif #ifndef GL_EXT_texture_cube_map #define GL_EXT_texture_cube_map #define _ALLEGRO_GL_EXT_texture_cube_map #define GL_NORMAL_MAP_EXT 0x8511 #define GL_REFLECTION_MAP_EXT 0x8512 #define GL_TEXTURE_CUBE_MAP_EXT 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A #define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #endif #ifndef GL_SUN_convolution_border_modes #define GL_SUN_convolution_border_modes #define _ALLEGRO_GL_SUN_convolution_border_modes #define GL_WRAP_BORDER_SUN 0x81D4 #endif #ifndef GL_EXT_texture_lod_bias #define GL_EXT_texture_lod_bias #define _ALLEGRO_GL_EXT_texture_lod_bias #define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD #define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 #define GL_TEXTURE_LOD_BIAS_EXT 0x8501 #endif #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic #define _ALLEGRO_GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef GL_EXT_vertex_weighting #define GL_EXT_vertex_weighting #define _ALLEGRO_GL_EXT_vertex_weighting #define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH #define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 #define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX #define GL_MODELVIEW1_MATRIX_EXT 0x8506 #define GL_VERTEX_WEIGHTING_EXT 0x8509 #define GL_MODELVIEW0_EXT GL_MODELVIEW #define GL_MODELVIEW1_EXT 0x850A #define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C #define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D #define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E #define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F #define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 #endif #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent #define _ALLEGRO_GL_NV_light_max_exponent #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #endif #ifndef GL_NV_vertex_array_range #define GL_NV_vertex_array_range #define _ALLEGRO_GL_NV_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_NV 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E #define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 #define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 #endif #ifndef GL_NV_register_combiners #define GL_NV_register_combiners #define _ALLEGRO_GL_NV_register_combiners #define GL_REGISTER_COMBINERS_NV 0x8522 #define GL_VARIABLE_A_NV 0x8523 #define GL_VARIABLE_B_NV 0x8524 #define GL_VARIABLE_C_NV 0x8525 #define GL_VARIABLE_D_NV 0x8526 #define GL_VARIABLE_E_NV 0x8527 #define GL_VARIABLE_F_NV 0x8528 #define GL_VARIABLE_G_NV 0x8529 #define GL_CONSTANT_COLOR0_NV 0x852A #define GL_CONSTANT_COLOR1_NV 0x852B #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D #define GL_SPARE0_NV 0x852E #define GL_SPARE1_NV 0x852F #define GL_DISCARD_NV 0x8530 #define GL_E_TIMES_F_NV 0x8531 #define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define GL_UNSIGNED_IDENTITY_NV 0x8536 #define GL_UNSIGNED_INVERT_NV 0x8537 #define GL_EXPAND_NORMAL_NV 0x8538 #define GL_EXPAND_NEGATE_NV 0x8539 #define GL_HALF_BIAS_NORMAL_NV 0x853A #define GL_HALF_BIAS_NEGATE_NV 0x853B #define GL_SIGNED_IDENTITY_NV 0x853C #define GL_SIGNED_NEGATE_NV 0x853D #define GL_SCALE_BY_TWO_NV 0x853E #define GL_SCALE_BY_FOUR_NV 0x853F #define GL_SCALE_BY_ONE_HALF_NV 0x8540 #define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 #define GL_COMBINER_INPUT_NV 0x8542 #define GL_COMBINER_MAPPING_NV 0x8543 #define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 #define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 #define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 #define GL_COMBINER_MUX_SUM_NV 0x8547 #define GL_COMBINER_SCALE_NV 0x8548 #define GL_COMBINER_BIAS_NV 0x8549 #define GL_COMBINER_AB_OUTPUT_NV 0x854A #define GL_COMBINER_CD_OUTPUT_NV 0x854B #define GL_COMBINER_SUM_OUTPUT_NV 0x854C #define GL_MAX_GENERAL_COMBINERS_NV 0x854D #define GL_NUM_GENERAL_COMBINERS_NV 0x854E #define GL_COLOR_SUM_CLAMP_NV 0x854F #define GL_COMBINER0_NV 0x8550 #define GL_COMBINER1_NV 0x8551 #define GL_COMBINER2_NV 0x8552 #define GL_COMBINER3_NV 0x8553 #define GL_COMBINER4_NV 0x8554 #define GL_COMBINER5_NV 0x8555 #define GL_COMBINER6_NV 0x8556 #define GL_COMBINER7_NV 0x8557 /* GL_TEXTURE0_ARB */ /* GL_TEXTURE1_ARB */ /* GL_ZERO */ /* GL_NONE */ /* GL_FOG */ #endif #ifndef GL_NV_fog_distance #define GL_NV_fog_distance #define _ALLEGRO_GL_NV_fog_distance #define GL_FOG_DISTANCE_MODE_NV 0x855A #define GL_EYE_RADIAL_NV 0x855B #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C /* GL_EYE_PLANE */ #endif #ifndef GL_NV_texgen_emboss #define GL_NV_texgen_emboss #define _ALLEGRO_GL_NV_texgen_emboss #define GL_EMBOSS_LIGHT_NV 0x855D #define GL_EMBOSS_CONSTANT_NV 0x855E #define GL_EMBOSS_MAP_NV 0x855F #endif #ifndef GL_NV_texture_env_combine4 #define GL_NV_texture_env_combine4 #define _ALLEGRO_GL_NV_texture_env_combine4 #define GL_COMBINE4_NV 0x8503 #define GL_SOURCE3_RGB_NV 0x8583 #define GL_SOURCE3_ALPHA_NV 0x858B #define GL_OPERAND3_RGB_NV 0x8593 #define GL_OPERAND3_ALPHA_NV 0x859B #endif #ifndef GL_EXT_texture_compression_s3tc #define GL_EXT_texture_compression_s3tc #define _ALLEGRO_GL_EXT_texture_compression_s3tc #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers #define _ALLEGRO_GL_MESA_resize_buffers #endif #ifndef GL_MESA_window_pos #define GL_MESA_window_pos #define _ALLEGRO_GL_MESA_window_pos #endif #ifndef GL_IBM_cull_vertex #define GL_IBM_cull_vertex #define _ALLEGRO_GL_IBM_cull_vertex #define GL_CULL_VERTEX_IBM 103050 #endif #ifndef GL_IBM_multimode_draw_arrays #define GL_IBM_multimode_draw_arrays #define _ALLEGRO_GL_IBM_multimode_draw_arrays #endif #ifndef GL_IBM_vertex_array_lists #define GL_IBM_vertex_array_lists #define _ALLEGRO_GL_IBM_vertex_array_lists #define GL_VERTEX_ARRAY_LIST_IBM 103070 #define GL_NORMAL_ARRAY_LIST_IBM 103071 #define GL_COLOR_ARRAY_LIST_IBM 103072 #define GL_INDEX_ARRAY_LIST_IBM 103073 #define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 #define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 #define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 #define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 #define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 #define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 #define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 #define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 #define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 #define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 #define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 #define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 #endif #ifndef GL_SGIX_subsample #define GL_SGIX_subsample #define _ALLEGRO_GL_SGIX_subsample #define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 #define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 #define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 #define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 #endif #ifndef GL_SGIX_ycrcba #define GL_SGIX_ycrcba #define _ALLEGRO_GL_SGIX_ycrcba #define GL_YCRCB_SGIX 0x8318 #define GL_YCRCBA_SGIX 0x8319 #endif #ifndef GL_SGI_depth_pass_instrument #define GL_SGI_depth_pass_instrument #define _ALLEGRO_GL_SGI_depth_pass_instrument #define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 #define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 #define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 #endif #ifndef GL_3DFX_texture_compression_FXT1 #define GL_3DFX_texture_compression_FXT1 #define _ALLEGRO_GL_3DFX_texture_compression_FXT1 #define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #endif #ifndef GL_3DFX_multisample #define GL_3DFX_multisample #define _ALLEGRO_GL_3DFX_multisample #define GL_MULTISAMPLE_3DFX 0x86B2 #define GL_SAMPLE_BUFFERS_3DFX 0x86B3 #define GL_SAMPLES_3DFX 0x86B4 #define GL_MULTISAMPLE_BIT_3DFX 0x20000000 #endif #ifndef GL_3DFX_tbuffer #define GL_3DFX_tbuffer #ifndef ALLEGRO_GL_HEADER_NV #define _ALLEGRO_GL_3DFX_tbuffer #endif #endif #ifndef GL_EXT_multisample #define GL_EXT_multisample #define _ALLEGRO_GL_EXT_multisample #define GL_MULTISAMPLE_EXT 0x809D #define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E #define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #define GL_SAMPLE_MASK_EXT 0x80A0 #define GL_1PASS_EXT 0x80A1 #define GL_2PASS_0_EXT 0x80A2 #define GL_2PASS_1_EXT 0x80A3 #define GL_4PASS_0_EXT 0x80A4 #define GL_4PASS_1_EXT 0x80A5 #define GL_4PASS_2_EXT 0x80A6 #define GL_4PASS_3_EXT 0x80A7 #define GL_SAMPLE_BUFFERS_EXT 0x80A8 #define GL_SAMPLES_EXT 0x80A9 #define GL_SAMPLE_MASK_VALUE_EXT 0x80AA #define GL_SAMPLE_MASK_INVERT_EXT 0x80AB #define GL_SAMPLE_PATTERN_EXT 0x80AC #define GL_MULTISAMPLE_BIT_EXT 0x20000000 #endif #ifndef GL_SGIX_vertex_preclip #define GL_SGIX_vertex_preclip #define _ALLEGRO_GL_SGIX_vertex_preclip #define GL_VERTEX_PRECLIP_SGIX 0x83EE #define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #endif #ifndef GL_SGIX_convolution_accuracy #define GL_SGIX_convolution_accuracy #define _ALLEGRO_GL_SGIX_convolution_accuracy #define GL_CONVOLUTION_HINT_SGIX 0x8316 #endif #ifndef GL_SGIX_resample #define GL_SGIX_resample #define _ALLEGRO_GL_SGIX_resample #define GL_PACK_RESAMPLE_SGIX 0x842C #define GL_UNPACK_RESAMPLE_SGIX 0x842D #define GL_RESAMPLE_REPLICATE_SGIX 0x842E #define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif #ifndef GL_SGIS_point_line_texgen #define GL_SGIS_point_line_texgen #define _ALLEGRO_GL_SGIS_point_line_texgen #define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 #define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 #define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 #define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 #define GL_EYE_POINT_SGIS 0x81F4 #define GL_OBJECT_POINT_SGIS 0x81F5 #define GL_EYE_LINE_SGIS 0x81F6 #define GL_OBJECT_LINE_SGIS 0x81F7 #endif #ifndef GL_SGIS_texture_color_mask #define GL_SGIS_texture_color_mask #ifndef ALLEGRO_GL_HEADER_NV #define _ALLEGRO_GL_SGIS_texture_color_mask #define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif #endif #ifndef GL_SGIX_igloo_interface #define GL_SGIX_igloo_interface #define _ALLEGRO_GL_SGIX_igloo_interface #endif #ifndef GL_EXT_texture_env_dot3 #define GL_EXT_texture_env_dot3 #define _ALLEGRO_GL_EXT_texture_env_dot3 /* GL_DOT3_RGB_EXT */ /* GL_DOT3_RGBA_EXT */ #endif #ifndef GL_ATI_texture_mirror_once #define GL_ATI_texture_mirror_once #define _ALLEGRO_GL_ATI_texture_mirror_once #define GL_MIRROR_CLAMP_ATI 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #endif #ifndef GL_NV_fence #define GL_NV_fence #define _ALLEGRO_GL_NV_fence #define GL_ALL_COMPLETED_NV 0x84F2 #define GL_FENCE_STATUS_NV 0x84F3 #define GL_FENCE_CONDITION_NV 0x84F4 #endif #ifndef GL_IBM_texture_mirrored_repeat #define GL_IBM_texture_mirrored_repeat #define _ALLEGRO_GL_IBM_texture_mirrored_repeat #define GL_MIRRORED_REPEAT_IBM 0x8370 #endif #ifndef GL_NV_evaluators #define GL_NV_evaluators #define _ALLEGRO_GL_NV_evaluators #define GL_EVAL_2D_NV 0x86C0 #define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 #define GL_MAP_TESSELLATION_NV 0x86C2 #define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 #define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 #define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 #define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 #define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA #define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB #define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC #define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF #define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 #define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 #define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 #define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 #define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 #define GL_MAX_MAP_TESSELLATION_NV 0x86D6 #define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 #endif #ifndef GL_NV_packed_depth_stencil #define GL_NV_packed_depth_stencil #define _ALLEGRO_GL_NV_packed_depth_stencil #define GL_DEPTH_STENCIL_NV 0x84F9 #define GL_UNSIGNED_INT_24_8_NV 0x84FA #endif #ifndef GL_NV_register_combiners2 #define GL_NV_register_combiners2 #define _ALLEGRO_GL_NV_register_combiners2 #define GL_PER_STAGE_CONSTANTS_NV 0x8535 #endif #ifndef GL_NV_texture_rectangle #define GL_NV_texture_rectangle #define _ALLEGRO_GL_NV_texture_rectangle #define GL_TEXTURE_RECTANGLE_NV 0x84F5 #define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 #define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif #ifndef GL_NV_texture_shader #define GL_NV_texture_shader #define _ALLEGRO_GL_NV_texture_shader #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C #define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D #define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E #define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 #define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA #define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB #define GL_DSDT_MAG_INTENSITY_NV 0x86DC #define GL_SHADER_CONSISTENT_NV 0x86DD #define GL_TEXTURE_SHADER_NV 0x86DE #define GL_SHADER_OPERATION_NV 0x86DF #define GL_CULL_MODES_NV 0x86E0 #define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 #define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV #define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV #define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV #define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 #define GL_CONST_EYE_NV 0x86E5 #define GL_PASS_THROUGH_NV 0x86E6 #define GL_CULL_FRAGMENT_NV 0x86E7 #define GL_OFFSET_TEXTURE_2D_NV 0x86E8 #define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 #define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA #define GL_DOT_PRODUCT_NV 0x86EC #define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED #define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE #define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 #define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 #define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 #define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 #define GL_HILO_NV 0x86F4 #define GL_DSDT_NV 0x86F5 #define GL_DSDT_MAG_NV 0x86F6 #define GL_DSDT_MAG_VIB_NV 0x86F7 #define GL_HILO16_NV 0x86F8 #define GL_SIGNED_HILO_NV 0x86F9 #define GL_SIGNED_HILO16_NV 0x86FA #define GL_SIGNED_RGBA_NV 0x86FB #define GL_SIGNED_RGBA8_NV 0x86FC #define GL_SIGNED_RGB_NV 0x86FE #define GL_SIGNED_RGB8_NV 0x86FF #define GL_SIGNED_LUMINANCE_NV 0x8701 #define GL_SIGNED_LUMINANCE8_NV 0x8702 #define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 #define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 #define GL_SIGNED_ALPHA_NV 0x8705 #define GL_SIGNED_ALPHA8_NV 0x8706 #define GL_SIGNED_INTENSITY_NV 0x8707 #define GL_SIGNED_INTENSITY8_NV 0x8708 #define GL_DSDT8_NV 0x8709 #define GL_DSDT8_MAG8_NV 0x870A #define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B #define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C #define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D #define GL_HI_SCALE_NV 0x870E #define GL_LO_SCALE_NV 0x870F #define GL_DS_SCALE_NV 0x8710 #define GL_DT_SCALE_NV 0x8711 #define GL_MAGNITUDE_SCALE_NV 0x8712 #define GL_VIBRANCE_SCALE_NV 0x8713 #define GL_HI_BIAS_NV 0x8714 #define GL_LO_BIAS_NV 0x8715 #define GL_DS_BIAS_NV 0x8716 #define GL_DT_BIAS_NV 0x8717 #define GL_MAGNITUDE_BIAS_NV 0x8718 #define GL_VIBRANCE_BIAS_NV 0x8719 #define GL_TEXTURE_BORDER_VALUES_NV 0x871A #define GL_TEXTURE_HI_SIZE_NV 0x871B #define GL_TEXTURE_LO_SIZE_NV 0x871C #define GL_TEXTURE_DS_SIZE_NV 0x871D #define GL_TEXTURE_DT_SIZE_NV 0x871E #define GL_TEXTURE_MAG_SIZE_NV 0x871F #endif #ifndef GL_NV_texture_shader2 #define GL_NV_texture_shader2 #define _ALLEGRO_GL_NV_texture_shader2 #define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF #endif #ifndef GL_NV_vertex_array_range2 #define GL_NV_vertex_array_range2 #define _ALLEGRO_GL_NV_vertex_array_range2 #define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 #endif #ifndef GL_NV_vertex_program #define GL_NV_vertex_program #define _ALLEGRO_GL_NV_vertex_program #define GL_VERTEX_PROGRAM_NV 0x8620 #define GL_VERTEX_STATE_PROGRAM_NV 0x8621 #define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 #define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 #define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 #define GL_CURRENT_ATTRIB_NV 0x8626 #define GL_PROGRAM_LENGTH_NV 0x8627 #define GL_PROGRAM_STRING_NV 0x8628 #define GL_MODELVIEW_PROJECTION_NV 0x8629 #define GL_IDENTITY_NV 0x862A #define GL_INVERSE_NV 0x862B #define GL_TRANSPOSE_NV 0x862C #define GL_INVERSE_TRANSPOSE_NV 0x862D #define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define GL_MAX_TRACK_MATRICES_NV 0x862F #define GL_MATRIX0_NV 0x8630 #define GL_MATRIX1_NV 0x8631 #define GL_MATRIX2_NV 0x8632 #define GL_MATRIX3_NV 0x8633 #define GL_MATRIX4_NV 0x8634 #define GL_MATRIX5_NV 0x8635 #define GL_MATRIX6_NV 0x8636 #define GL_MATRIX7_NV 0x8637 #define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 #define GL_CURRENT_MATRIX_NV 0x8641 #define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 #define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 #define GL_PROGRAM_PARAMETER_NV 0x8644 #define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 #define GL_PROGRAM_TARGET_NV 0x8646 #define GL_PROGRAM_RESIDENT_NV 0x8647 #define GL_TRACK_MATRIX_NV 0x8648 #define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 #define GL_VERTEX_PROGRAM_BINDING_NV 0x864A #define GL_PROGRAM_ERROR_POSITION_NV 0x864B #define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 #define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 #define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 #define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 #define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 #define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 #define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 #define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 #define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 #define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 #define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A #define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B #define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C #define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D #define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E #define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F #define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 #define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 #define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 #define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 #define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 #define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 #define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 #define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 #define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 #define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 #define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A #define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B #define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C #define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D #define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E #define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F #define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 #define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 #define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 #define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 #define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 #define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 #define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 #define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 #define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 #define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A #define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B #define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C #define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D #define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E #define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F #endif #ifndef GL_SGIX_texture_coordinate_clamp #define GL_SGIX_texture_coordinate_clamp #define _ALLEGRO_GL_SGIX_texture_coordinate_clamp #define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B #endif #ifndef GL_SGIX_scalebias_hint #define GL_SGIX_scalebias_hint #define _ALLEGRO_GL_SGIX_scalebias_hint #define GL_SCALEBIAS_HINT_SGIX 0x8322 #endif #ifndef GL_OML_interlace #define GL_OML_interlace #define _ALLEGRO_GL_OML_interlace #define GL_INTERLACE_OML 0x8980 #define GL_INTERLACE_READ_OML 0x8981 #endif #ifndef GL_OML_subsample #define GL_OML_subsample #define _ALLEGRO_GL_OML_subsample #define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif #ifndef GL_OML_resample #define GL_OML_resample #define _ALLEGRO_GL_OML_resample #define GL_PACK_RESAMPLE_OML 0x8984 #define GL_UNPACK_RESAMPLE_OML 0x8985 #define GL_RESAMPLE_REPLICATE_OML 0x8986 #define GL_RESAMPLE_ZERO_FILL_OML 0x8987 #define GL_RESAMPLE_AVERAGE_OML 0x8988 #define GL_RESAMPLE_DECIMATE_OML 0x8989 #endif #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color #define _ALLEGRO_GL_NV_copy_depth_to_color #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E #define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F #endif #ifndef GL_ATI_envmap_bumpmap #define GL_ATI_envmap_bumpmap #define _ALLEGRO_GL_ATI_envmap_bumpmap #define GL_BUMP_ROT_MATRIX_ATI 0x8775 #define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 #define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 #define GL_BUMP_TEX_UNITS_ATI 0x8778 #define GL_DUDV_ATI 0x8779 #define GL_DU8DV8_ATI 0x877A #define GL_BUMP_ENVMAP_ATI 0x877B #define GL_BUMP_TARGET_ATI 0x877C #endif #ifndef GL_ATI_fragment_shader #define GL_ATI_fragment_shader #define _ALLEGRO_GL_ATI_fragment_shader #define GL_FRAGMENT_SHADER_ATI 0x8920 #define GL_REG_0_ATI 0x8921 #define GL_REG_1_ATI 0x8922 #define GL_REG_2_ATI 0x8923 #define GL_REG_3_ATI 0x8924 #define GL_REG_4_ATI 0x8925 #define GL_REG_5_ATI 0x8926 #define GL_REG_6_ATI 0x8927 #define GL_REG_7_ATI 0x8928 #define GL_REG_8_ATI 0x8929 #define GL_REG_9_ATI 0x892A #define GL_REG_10_ATI 0x892B #define GL_REG_11_ATI 0x892C #define GL_REG_12_ATI 0x892D #define GL_REG_13_ATI 0x892E #define GL_REG_14_ATI 0x892F #define GL_REG_15_ATI 0x8930 #define GL_REG_16_ATI 0x8931 #define GL_REG_17_ATI 0x8932 #define GL_REG_18_ATI 0x8933 #define GL_REG_19_ATI 0x8934 #define GL_REG_20_ATI 0x8935 #define GL_REG_21_ATI 0x8936 #define GL_REG_22_ATI 0x8937 #define GL_REG_23_ATI 0x8938 #define GL_REG_24_ATI 0x8939 #define GL_REG_25_ATI 0x893A #define GL_REG_26_ATI 0x893B #define GL_REG_27_ATI 0x893C #define GL_REG_28_ATI 0x893D #define GL_REG_29_ATI 0x893E #define GL_REG_30_ATI 0x893F #define GL_REG_31_ATI 0x8940 #define GL_CON_0_ATI 0x8941 #define GL_CON_1_ATI 0x8942 #define GL_CON_2_ATI 0x8943 #define GL_CON_3_ATI 0x8944 #define GL_CON_4_ATI 0x8945 #define GL_CON_5_ATI 0x8946 #define GL_CON_6_ATI 0x8947 #define GL_CON_7_ATI 0x8948 #define GL_CON_8_ATI 0x8949 #define GL_CON_9_ATI 0x894A #define GL_CON_10_ATI 0x894B #define GL_CON_11_ATI 0x894C #define GL_CON_12_ATI 0x894D #define GL_CON_13_ATI 0x894E #define GL_CON_14_ATI 0x894F #define GL_CON_15_ATI 0x8950 #define GL_CON_16_ATI 0x8951 #define GL_CON_17_ATI 0x8952 #define GL_CON_18_ATI 0x8953 #define GL_CON_19_ATI 0x8954 #define GL_CON_20_ATI 0x8955 #define GL_CON_21_ATI 0x8956 #define GL_CON_22_ATI 0x8957 #define GL_CON_23_ATI 0x8958 #define GL_CON_24_ATI 0x8959 #define GL_CON_25_ATI 0x895A #define GL_CON_26_ATI 0x895B #define GL_CON_27_ATI 0x895C #define GL_CON_28_ATI 0x895D #define GL_CON_29_ATI 0x895E #define GL_CON_30_ATI 0x895F #define GL_CON_31_ATI 0x8960 #define GL_MOV_ATI 0x8961 #define GL_ADD_ATI 0x8963 #define GL_MUL_ATI 0x8964 #define GL_SUB_ATI 0x8965 #define GL_DOT3_ATI 0x8966 #define GL_DOT4_ATI 0x8967 #define GL_MAD_ATI 0x8968 #define GL_LERP_ATI 0x8969 #define GL_CND_ATI 0x896A #define GL_CND0_ATI 0x896B #define GL_DOT2_ADD_ATI 0x896C #define GL_SECONDARY_INTERPOLATOR_ATI 0x896D #define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E #define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F #define GL_NUM_PASSES_ATI 0x8970 #define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 #define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 #define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 #define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 #define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define GL_SWIZZLE_STR_ATI 0x8976 #define GL_SWIZZLE_STQ_ATI 0x8977 #define GL_SWIZZLE_STR_DR_ATI 0x8978 #define GL_SWIZZLE_STQ_DQ_ATI 0x8979 #define GL_SWIZZLE_STRQ_ATI 0x897A #define GL_SWIZZLE_STRQ_DQ_ATI 0x897B #define GL_RED_BIT_ATI 0x00000001 #define GL_GREEN_BIT_ATI 0x00000002 #define GL_BLUE_BIT_ATI 0x00000004 #define GL_2X_BIT_ATI 0x00000001 #define GL_4X_BIT_ATI 0x00000002 #define GL_8X_BIT_ATI 0x00000004 #define GL_HALF_BIT_ATI 0x00000008 #define GL_QUARTER_BIT_ATI 0x00000010 #define GL_EIGHTH_BIT_ATI 0x00000020 #define GL_SATURATE_BIT_ATI 0x00000040 #define GL_COMP_BIT_ATI 0x00000002 #define GL_NEGATE_BIT_ATI 0x00000004 #define GL_BIAS_BIT_ATI 0x00000008 #endif #ifndef GL_ATI_pn_triangles #define GL_ATI_pn_triangles #define _ALLEGRO_GL_ATI_pn_triangles #define GL_PN_TRIANGLES_ATI 0x87F0 #define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 #define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 #define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 #define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 #define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 #define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 #define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 #endif #ifndef GL_ATI_vertex_array_object #define GL_ATI_vertex_array_object #define _ALLEGRO_GL_ATI_vertex_array_object #define GL_STATIC_ATI 0x8760 #define GL_DYNAMIC_ATI 0x8761 #define GL_PRESERVE_ATI 0x8762 #define GL_DISCARD_ATI 0x8763 #define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 #define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 #define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 #define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 #endif #ifndef GL_EXT_vertex_shader #define GL_EXT_vertex_shader #define _ALLEGRO_GL_EXT_vertex_shader #define GL_VERTEX_SHADER_EXT 0x8780 #define GL_VERTEX_SHADER_BINDING_EXT 0x8781 #define GL_OP_INDEX_EXT 0x8782 #define GL_OP_NEGATE_EXT 0x8783 #define GL_OP_DOT3_EXT 0x8784 #define GL_OP_DOT4_EXT 0x8785 #define GL_OP_MUL_EXT 0x8786 #define GL_OP_ADD_EXT 0x8787 #define GL_OP_MADD_EXT 0x8788 #define GL_OP_FRAC_EXT 0x8789 #define GL_OP_MAX_EXT 0x878A #define GL_OP_MIN_EXT 0x878B #define GL_OP_SET_GE_EXT 0x878C #define GL_OP_SET_LT_EXT 0x878D #define GL_OP_CLAMP_EXT 0x878E #define GL_OP_FLOOR_EXT 0x878F #define GL_OP_ROUND_EXT 0x8790 #define GL_OP_EXP_BASE_2_EXT 0x8791 #define GL_OP_LOG_BASE_2_EXT 0x8792 #define GL_OP_POWER_EXT 0x8793 #define GL_OP_RECIP_EXT 0x8794 #define GL_OP_RECIP_SQRT_EXT 0x8795 #define GL_OP_SUB_EXT 0x8796 #define GL_OP_CROSS_PRODUCT_EXT 0x8797 #define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 #define GL_OP_MOV_EXT 0x8799 #define GL_OUTPUT_VERTEX_EXT 0x879A #define GL_OUTPUT_COLOR0_EXT 0x879B #define GL_OUTPUT_COLOR1_EXT 0x879C #define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D #define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E #define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F #define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 #define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 #define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 #define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 #define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 #define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 #define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 #define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 #define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 #define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA #define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB #define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC #define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD #define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE #define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF #define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 #define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 #define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 #define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 #define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 #define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 #define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 #define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 #define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 #define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 #define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA #define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB #define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC #define GL_OUTPUT_FOG_EXT 0x87BD #define GL_SCALAR_EXT 0x87BE #define GL_VECTOR_EXT 0x87BF #define GL_MATRIX_EXT 0x87C0 #define GL_VARIANT_EXT 0x87C1 #define GL_INVARIANT_EXT 0x87C2 #define GL_LOCAL_CONSTANT_EXT 0x87C3 #define GL_LOCAL_EXT 0x87C4 #define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 #define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 #define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 #define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 #define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF #define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 #define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 #define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 #define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 #define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 #define GL_X_EXT 0x87D5 #define GL_Y_EXT 0x87D6 #define GL_Z_EXT 0x87D7 #define GL_W_EXT 0x87D8 #define GL_NEGATIVE_X_EXT 0x87D9 #define GL_NEGATIVE_Y_EXT 0x87DA #define GL_NEGATIVE_Z_EXT 0x87DB #define GL_NEGATIVE_W_EXT 0x87DC #define GL_ZERO_EXT 0x87DD #define GL_ONE_EXT 0x87DE #define GL_NEGATIVE_ONE_EXT 0x87DF #define GL_NORMALIZED_RANGE_EXT 0x87E0 #define GL_FULL_RANGE_EXT 0x87E1 #define GL_CURRENT_VERTEX_EXT 0x87E2 #define GL_MVP_MATRIX_EXT 0x87E3 #define GL_VARIANT_VALUE_EXT 0x87E4 #define GL_VARIANT_DATATYPE_EXT 0x87E5 #define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 #define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 #define GL_VARIANT_ARRAY_EXT 0x87E8 #define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 #define GL_INVARIANT_VALUE_EXT 0x87EA #define GL_INVARIANT_DATATYPE_EXT 0x87EB #define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED #endif #ifndef GL_ATI_vertex_streams #define GL_ATI_vertex_streams #define _ALLEGRO_GL_ATI_vertex_streams #define GL_MAX_VERTEX_STREAMS_ATI 0x876B #define GL_VERTEX_STREAM0_ATI 0x876C #define GL_VERTEX_STREAM1_ATI 0x876D #define GL_VERTEX_STREAM2_ATI 0x876E #define GL_VERTEX_STREAM3_ATI 0x876F #define GL_VERTEX_STREAM4_ATI 0x8770 #define GL_VERTEX_STREAM5_ATI 0x8771 #define GL_VERTEX_STREAM6_ATI 0x8772 #define GL_VERTEX_STREAM7_ATI 0x8773 #define GL_VERTEX_SOURCE_ATI 0x8774 #endif #ifndef GL_ATI_element_array #define GL_ATI_element_array #define _ALLEGRO_GL_ATI_element_array #define GL_ELEMENT_ARRAY_ATI 0x8768 #define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 #define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A #endif #ifndef GL_SUN_mesh_array #define GL_SUN_mesh_array #define _ALLEGRO_GL_SUN_mesh_array #define GL_QUAD_MESH_SUN 0x8614 #define GL_TRIANGLE_MESH_SUN 0x8615 #endif #ifndef GL_SUN_slice_accum #define GL_SUN_slice_accum #define _ALLEGRO_GL_SUN_slice_accum #define GL_SLICE_ACCUM_SUN 0x85CC #endif #ifndef GL_NV_multisample_filter_hint #define GL_NV_multisample_filter_hint #define _ALLEGRO_GL_NV_multisample_filter_hint #define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #endif #ifndef GL_NV_depth_clamp #define GL_NV_depth_clamp #define _ALLEGRO_GL_NV_depth_clamp #define GL_DEPTH_CLAMP_NV 0x864F #endif #ifndef GL_NV_occlusion_query #define GL_NV_occlusion_query #define _ALLEGRO_GL_NV_occlusion_query #define GL_PIXEL_COUNTER_BITS_NV 0x8864 #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 #define GL_PIXEL_COUNT_NV 0x8866 #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 #endif #ifndef GL_NV_point_sprite #define GL_NV_point_sprite #define _ALLEGRO_GL_NV_point_sprite #define GL_POINT_SPRITE_NV 0x8861 #define GL_COORD_REPLACE_NV 0x8862 #define GL_POINT_SPRITE_R_MODE_NV 0x8863 #endif #ifndef GL_NV_texture_shader3 #define GL_NV_texture_shader3 #define _ALLEGRO_GL_NV_texture_shader3 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 #define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 #define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 #define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 #define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 #define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A #define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B #define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C #define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D #define GL_HILO8_NV 0x885E #define GL_SIGNED_HILO8_NV 0x885F #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif #ifndef GL_EXT_stencil_two_side #define GL_EXT_stencil_two_side #define _ALLEGRO_GL_EXT_stencil_two_side #define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 #define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 #endif #ifndef GL_ATI_text_fragment_shader #define GL_ATI_text_fragment_shader #define _ALLEGRO_GL_ATI_text_fragment_shader #define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #endif #ifndef GL_APPLE_client_storage #define GL_APPLE_client_storage #define _ALLEGRO_GL_APPLE_client_storage #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #endif #ifndef GL_APPLE_element_array #define GL_APPLE_element_array #define _ALLEGRO_GL_APPLE_element_array #define GL_ELEMENT_ARRAY_APPLE 0x8768 #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A #endif #ifndef GL_APPLE_fence #define GL_APPLE_fence #define _ALLEGRO_GL_APPLE_fence #define GL_DRAW_PIXELS_APPLE 0x8A0A #define GL_FENCE_APPLE 0x8A0B #endif #ifndef GL_APPLE_vertex_array_object #define GL_APPLE_vertex_array_object #define _ALLEGRO_GL_APPLE_vertex_array_object #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 #endif #ifndef GL_APPLE_vertex_array_range #define GL_APPLE_vertex_array_range #define _ALLEGRO_GL_APPLE_vertex_array_range #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 #define GL_STORAGE_CACHED_APPLE 0x85BE #define GL_STORAGE_SHARED_APPLE 0x85BF #endif #ifndef GL_APPLE_ycbcr_422 #define GL_APPLE_ycbcr_422 #define _ALLEGRO_GL_APPLE_ycbcr_422 #define GL_YCBCR_422_APPLE 0x85B9 #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif #ifndef GL_S3_s3tc #define GL_S3_s3tc #define _ALLEGRO_GL_S3_s3tc #define GL_RGB_S3TC 0x83A0 #define GL_RGB4_S3TC 0x83A1 #define GL_RGBA_S3TC 0x83A2 #define GL_RGBA4_S3TC 0x83A3 #endif #ifndef GL_ATI_draw_buffers #define GL_ATI_draw_buffers #define _ALLEGRO_GL_ATI_draw_buffers #define GL_MAX_DRAW_BUFFERS_ATI 0x8824 #define GL_DRAW_BUFFER0_ATI 0x8825 #define GL_DRAW_BUFFER1_ATI 0x8826 #define GL_DRAW_BUFFER2_ATI 0x8827 #define GL_DRAW_BUFFER3_ATI 0x8828 #define GL_DRAW_BUFFER4_ATI 0x8829 #define GL_DRAW_BUFFER5_ATI 0x882A #define GL_DRAW_BUFFER6_ATI 0x882B #define GL_DRAW_BUFFER7_ATI 0x882C #define GL_DRAW_BUFFER8_ATI 0x882D #define GL_DRAW_BUFFER9_ATI 0x882E #define GL_DRAW_BUFFER10_ATI 0x882F #define GL_DRAW_BUFFER11_ATI 0x8830 #define GL_DRAW_BUFFER12_ATI 0x8831 #define GL_DRAW_BUFFER13_ATI 0x8832 #define GL_DRAW_BUFFER14_ATI 0x8833 #define GL_DRAW_BUFFER15_ATI 0x8834 #endif #ifndef GL_ATI_texture_env_combine3 #define GL_ATI_texture_env_combine3 #define _ALLEGRO_GL_ATI_texture_env_combine3 #define GL_MODULATE_ADD_ATI 0x8744 #define GL_MODULATE_SIGNED_ADD_ATI 0x8745 #define GL_MODULATE_SUBTRACT_ATI 0x8746 #endif #ifndef GL_ATI_texture_float #define GL_ATI_texture_float #define _ALLEGRO_GL_ATI_texture_float #define GL_RGBA_FLOAT32_ATI 0x8814 #define GL_RGB_FLOAT32_ATI 0x8815 #define GL_ALPHA_FLOAT32_ATI 0x8816 #define GL_INTENSITY_FLOAT32_ATI 0x8817 #define GL_LUMINANCE_FLOAT32_ATI 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 #define GL_RGBA_FLOAT16_ATI 0x881A #define GL_RGB_FLOAT16_ATI 0x881B #define GL_ALPHA_FLOAT16_ATI 0x881C #define GL_INTENSITY_FLOAT16_ATI 0x881D #define GL_LUMINANCE_FLOAT16_ATI 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif #ifndef GL_NV_float_buffer #define GL_NV_float_buffer #define _ALLEGRO_GL_NV_float_buffer #define GL_FLOAT_R_NV 0x8880 #define GL_FLOAT_RG_NV 0x8881 #define GL_FLOAT_RGB_NV 0x8882 #define GL_FLOAT_RGBA_NV 0x8883 #define GL_FLOAT_R16_NV 0x8884 #define GL_FLOAT_R32_NV 0x8885 #define GL_FLOAT_RG16_NV 0x8886 #define GL_FLOAT_RG32_NV 0x8887 #define GL_FLOAT_RGB16_NV 0x8888 #define GL_FLOAT_RGB32_NV 0x8889 #define GL_FLOAT_RGBA16_NV 0x888A #define GL_FLOAT_RGBA32_NV 0x888B #define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C #define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define GL_FLOAT_RGBA_MODE_NV 0x888E #endif #ifndef GL_NV_fragment_program #define GL_NV_fragment_program #define _ALLEGRO_GL_NV_fragment_program #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 #define GL_FRAGMENT_PROGRAM_NV 0x8870 #define GL_MAX_TEXTURE_COORDS_NV 0x8871 #define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 #define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 #define GL_PROGRAM_ERROR_STRING_NV 0x8874 #endif #ifndef GL_NV_half_float #define GL_NV_half_float #define _ALLEGRO_GL_NV_half_float typedef short GLhalfNV; #define GL_HALF_FLOAT_NV 0x140B #endif #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range #define _ALLEGRO_GL_NV_pixel_data_range #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 #define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 #define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A #define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B #define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #endif #ifndef GL_NV_primitive_restart #define GL_NV_primitive_restart #define _ALLEGRO_GL_NV_primitive_restart #define GL_PRIMITIVE_RESTART_NV 0x8558 #define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #endif #ifndef GL_NV_texture_expand_normal #define GL_NV_texture_expand_normal #define _ALLEGRO_GL_NV_texture_expand_normal #define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F #endif #ifndef GL_ATI_map_object_buffer #define GL_ATI_map_object_buffer #define _ALLEGRO_GL_ATI_map_object_buffer #endif #ifndef GL_ATI_separate_stencil #define GL_ATI_separate_stencil #define GL_STENCIL_BACK_FUNC_ATI 0x8800 #define GL_STENCIL_BACK_FAIL_ATI 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 #endif #ifndef GL_ATI_vertex_attrib_array_object #define GL_ATI_vertex_attrib_array_object #define _ALLEGRO_GL_ATI_vertex_attrib_array_object #endif #ifndef GL_OES_byte_coordinates #define GL_OES_byte_coordinates #define _ALLEGRO_GL_OES_byte_coordinates /* GL_BYTE */ #endif #ifndef GL_OES_fixed_point #define GL_OES_fixed_point #define _ALLEGRO_GL_OES_fixed_point typedef int GLfixed; typedef int GLclampx; #define GL_FIXED_OES 0x140C #endif #ifndef GL_OES_single_precision #define GL_OES_single_precision #define _ALLEGRO_GL_OES_single_precision #endif #ifndef GL_OES_compressed_paletted_texture #define GL_OES_compressed_paletted_texture #define _ALLEGRO_GL_OES_compressed_paletted_texture #define GL_PALETTE4_RGB8_OES 0x8B90 #define GL_PALETTE4_RGBA8_OES 0x8B91 #define GL_PALETTE4_R5_G6_B5_OES 0x8B92 #define GL_PALETTE4_RGBA4_OES 0x8B93 #define GL_PALETTE4_RGB5_A1_OES 0x8B94 #define GL_PALETTE8_RGB8_OES 0x8B95 #define GL_PALETTE8_RGBA8_OES 0x8B96 #define GL_PALETTE8_R5_G6_B5_OES 0x8B97 #define GL_PALETTE8_RGBA4_OES 0x8B98 #define GL_PALETTE8_RGB5_A1_OES 0x8B99 #endif #ifndef GL_OES_read_format #define GL_OES_read_format #define _ALLEGRO_GL_OES_read_format #define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B #endif #ifndef GL_OES_query_matrix #define GL_OES_query_matrix #define _ALLEGRO_GL_OES_query_matrix #endif #ifndef GL_EXT_depth_bounds_test #define GL_EXT_depth_bounds_test #define _ALLEGRO_GL_EXT_depth_bounds_test #define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define GL_DEPTH_BOUNDS_EXT 0x8891 #endif #ifndef GL_EXT_texture_mirror_clamp #define GL_EXT_texture_mirror_clamp #define _ALLEGRO_GL_EXT_texture_mirror_clamp #define GL_MIRROR_CLAMP_EXT 0x8742 #define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 #endif #ifndef GL_EXT_blend_equation_separate #define GL_EXT_blend_equation_separate #define _ALLEGRO_GL_EXT_blend_equation_separate #define GL_BLEND_EQUATION_RGB_EXT 0x8009 /* Same as GL_BLEND_EQUATION */ #define GL_BLEND_EQUATION_ALPHA_EXT 0x883D #endif #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert #define _ALLEGRO_GL_MESA_pack_invert #define GL_PACK_INVERT_MESA 0x8758 #endif #ifndef GL_MESA_ycbcr_texture #define GL_MESA_ycbcr_texture #define _ALLEGRO_GL_MESA_ycbcr_texture #define GL_YCBCR_MESA 0x8757 /* Same as GL_UNSIGNED_SHORT_8_8_APPLE and GL_UNSIGNED_SHORT_8_8_REV_APPLE */ #define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA #define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB #endif #ifndef GL_EXT_pixel_buffer_object #define GL_EXT_pixel_buffer_object #define _ALLEGRO_GL_EXT_pixel_buffer_object #define GL_PIXEL_PACK_BUFFER_EXT 0x88EB #define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC #define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED #define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF #endif #ifndef GL_NV_fragment_program_option #define GL_NV_fragment_program_option #define _ALLEGRO_GL_NV_fragment_program_option #endif #ifndef GL_NV_fragment_program2 #define GL_NV_fragment_program2 #define _ALLEGRO_GL_NV_fragment_program2 #define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 #define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 #define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 #define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 #define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 #endif #ifndef GL_NV_vertex_program2_option #define GL_NV_vertex_program2_option #define _ALLEGRO_GL_NV_vertex_program2_option #define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 #define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 #endif #ifndef GL_NV_vertex_program3 #define GL_NV_vertex_program3 #define _ALLEGRO_GL_NV_vertex_program3 #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #endif #ifndef GL_EXT_texture_compression_dxt1 #define GL_EXT_texture_compression_dxt1 #define _ALLEGRO_GL_EXT_texture_compression_dxt1 #ifndef ALLEGRO_GL_EXT_texture_compression_s3tc #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #endif #endif #ifndef GL_EXT_framebuffer_object #define GL_EXT_framebuffer_object #define _ALLEGRO_GL_EXT_framebuffer_object #define GL_FRAMEBUFFER_EXT 0x8D40 #define GL_RENDERBUFFER_EXT 0x8D41 #define GL_STENCIL_INDEX_EXT 0x8D45 #define GL_STENCIL_INDEX1_EXT 0x8D46 #define GL_STENCIL_INDEX4_EXT 0x8D47 #define GL_STENCIL_INDEX8_EXT 0x8D48 #define GL_STENCIL_INDEX16_EXT 0x8D49 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC #define GL_COLOR_ATTACHMENT13_EXT 0x8CED #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD #define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #endif #ifndef GL_GREMEDY_string_marker #define GL_GREMEDY_string_marker #define _ALLEGRO_GL_GREMEDY_string_marker #endif #ifndef GL_EXT_packed_depth_stencil #define GL_EXT_packed_depth_stencil #define _ALLEGRO_GL_EXT_packed_depth_stencil #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA #define GL_DEPTH24_STENCIL8_EXT 0x88F0 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif #ifndef GL_EXT_stencil_clear_tag #define GL_EXT_stencil_clear_tag #define _ALLEGRO_GL_EXT_stencil_clear_tag #define GL_STENCIL_TAG_BITS_EXT 0x88F2 #define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 #endif #ifndef GL_EXT_texture_sRGB #define GL_EXT_texture_sRGB #define _ALLEGRO_GL_EXT_texture_sRGB #define GL_SRGB_EXT 0x8C40 #define GL_SRGB8_EXT 0x8C41 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB8_ALPHA8_EXT 0x8C43 #define GL_SLUMINANCE_ALPHA_EXT 0x8C44 #define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 #define GL_SLUMINANCE_EXT 0x8C46 #define GL_SLUMINANCE8_EXT 0x8C47 #define GL_COMPRESSED_SRGB_EXT 0x8C48 #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F #endif #ifndef GL_EXT_framebuffer_blit #define GL_EXT_framebuffer_blit #define _ALLEGRO_GL_EXT_framebuffer_blit #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 #define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT #define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif #ifndef GL_EXT_framebuffer_multisample #define GL_EXT_framebuffer_multisample #define _ALLEGRO_GL_EXT_framebuffer_multisample #define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 #define GL_MAX_SAMPLES_EXT 0x8D57 #endif #ifndef GL_MESAX_texture_stack #define GL_MESAX_texture_stack #define _ALLEGRO_GL_MESAX_texture_stack #define GL_TEXTURE_1D_STACK_MESAX 0x8759 #define GL_TEXTURE_2D_STACK_MESAX 0x875A #define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B #define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C #define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D #define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E #endif #ifndef GL_EXT_timer_query #define GL_EXT_timer_query #define _ALLEGRO_GL_EXT_timer_query #if (defined _MSC_VER) && (_MSC_VER < 1400) typedef __int64 GLint64EXT; typedef unsigned __int64 GLuint64EXT; #else typedef int64_t GLint64EXT; typedef uint64_t GLuint64EXT; #endif #define GL_TIME_ELAPSED_EXT 0x88BF #endif #ifndef GL_EXT_gpu_program_parameters #define GL_EXT_gpu_program_parameters #define _ALLEGRO_GL_EXT_gpu_program_parameters #endif #ifndef GL_APPLE_flush_buffer_range #define GL_APPLE_flush_buffer_range #define _ALLEGRO_GL_APPLE_flush_buffer_range #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 #endif #ifndef GL_EXT_bindable_uniform #define GL_EXT_bindable_uniform #define _ALLEGRO_GL_EXT_bindable_uniform #define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 #define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 #define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 #define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED #define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF #define GL_UNIFORM_BUFFER_EXT 0x8DEE #endif #ifndef GL_EXT_draw_buffers2 #define GL_EXT_draw_buffers2 #define _ALLEGRO_GL_EXT_draw_buffers2 #endif #ifndef GL_EXT_draw_instanced #define GL_EXT_draw_instanced #define _ALLEGRO_GL_EXT_draw_instanced #endif #ifndef GL_EXT_framebuffer_sRGB #define GL_EXT_framebuffer_sRGB #define _ALLEGRO_GL_EXT_framebuffer_sRGB #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA #endif #ifndef GL_EXT_geometry_shader4 #define GL_EXT_geometry_shader4 #define _ALLEGRO_GL_EXT_geometry_shader4 #define GL_GEOMETRY_SHADER_EXT 0x8DD9 #define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 #define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD #define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE #define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF #define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 #define GL_LINES_ADJACENCY_EXT 0xA #define GL_LINE_STRIP_ADJACENCY_EXT 0xB #define GL_TRIANGLES_ADJACENCY_EXT 0xC #define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define GL_PROGRAM_POINT_SIZE_EXT 0x8642 #endif #ifndef GL_EXT_gpu_shader4 #define GL_EXT_gpu_shader4 #define _ALLEGRO_GL_EXT_gpu_shader4 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_BUFFER_EXT 0x8DC2 #define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 #define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 #define GL_UNSIGNED_INT 0x1405 #define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 #define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 #define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 #define GL_INT_SAMPLER_1D_EXT 0x8DC9 #define GL_INT_SAMPLER_2D_EXT 0x8DCA #define GL_INT_SAMPLER_3D_EXT 0x8DCB #define GL_INT_SAMPLER_CUBE_EXT 0x8DCC #define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD #define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE #define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF #define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 #define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 #define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 #define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 #define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 #define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 #define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 #endif #ifndef GL_EXT_packed_float #define GL_EXT_packed_float #define _ALLEGRO_GL_EXT_packed_float #define GL_R11F_G11F_B10F_EXT 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B #define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C #endif #ifndef GL_EXT_texture_array #define GL_EXT_texture_array #define _ALLEGRO_GL_EXT_texture_array #define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 #define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A #define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B #define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 #define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C #define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D #define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF #define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 #define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 #endif #ifndef GL_EXT_texture_buffer_object #define GL_EXT_texture_buffer_object #define _ALLEGRO_GL_EXT_texture_buffer_object #define GL_TEXTURE_BUFFER_EXT 0x8C2A #define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B #define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D #define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E #endif #ifndef GL_EXT_texture_compression_latc #define GL_EXT_texture_compression_latc #define _ALLEGRO_GL_EXT_texture_compression_latc #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 #endif #ifndef GL_EXT_texture_compression_rgtc #define GL_EXT_texture_compression_rgtc #define _ALLEGRO_GL_EXT_texture_compression_rgtc #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE #endif #ifndef GL_EXT_texture_integer #define GL_EXT_texture_integer #define _ALLEGRO_GL_EXT_texture_integer #define GL_RGBA_INTEGER_MODE_EXT 0x8D9E #define GL_RGBA32UI_EXT 0x8D70 #define GL_RGB32UI_EXT 0x8D71 #define GL_ALPHA32UI_EXT 0x8D72 #define GL_INTENSITY32UI_EXT 0x8D73 #define GL_LUMINANCE32UI_EXT 0x8D74 #define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 #define GL_RGBA16UI_EXT 0x8D76 #define GL_RGB16UI_EXT 0x8D77 #define GL_ALPHA16UI_EXT 0x8D78 #define GL_INTENSITY16UI_EXT 0x8D79 #define GL_LUMINANCE16UI_EXT 0x8D7A #define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B #define GL_RGBA8UI_EXT 0x8D7C #define GL_RGB8UI_EXT 0x8D7D #define GL_ALPHA8UI_EXT 0x8D7E #define GL_INTENSITY8UI_EXT 0x8D7F #define GL_LUMINANCE8UI_EXT 0x8D80 #define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 #define GL_RGBA32I_EXT 0x8D82 #define GL_RGB32I_EXT 0x8D83 #define GL_ALPHA32I_EXT 0x8D84 #define GL_INTENSITY32I_EXT 0x8D85 #define GL_LUMINANCE32I_EXT 0x8D86 #define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 #define GL_RGBA16I_EXT 0x8D88 #define GL_RGB16I_EXT 0x8D89 #define GL_ALPHA16I_EXT 0x8D8A #define GL_INTENSITY16I_EXT 0x8D8B #define GL_LUMINANCE16I_EXT 0x8D8C #define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D #define GL_RGBA8I_EXT 0x8D8E #define GL_RGB8I_EXT 0x8D8F #define GL_ALPHA8I_EXT 0x8D90 #define GL_INTENSITY8I_EXT 0x8D91 #define GL_LUMINANCE8I_EXT 0x8D92 #define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 #define GL_RED_INTEGER_EXT 0x8D94 #define GL_GREEN_INTEGER_EXT 0x8D95 #define GL_BLUE_INTEGER_EXT 0x8D96 #define GL_ALPHA_INTEGER_EXT 0x8D97 #define GL_RGB_INTEGER_EXT 0x8D98 #define GL_RGBA_INTEGER_EXT 0x8D99 #define GL_BGR_INTEGER_EXT 0x8D9A #define GL_BGRA_INTEGER_EXT 0x8D9B #define GL_LUMINANCE_INTEGER_EXT 0x8D9C #define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D #endif #ifndef GL_EXT_texture_shared_exponent #define GL_EXT_texture_shared_exponent #define _ALLEGRO_GL_EXT_texture_shared_exponent #define GL_RGB9_E5_EXT 0x8C3D #define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E #define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F #endif #ifndef GL_NV_depth_buffer_float #define GL_NV_depth_buffer_float #define _ALLEGRO_GL_NV_depth_buffer_float #define GL_DEPTH_COMPONENT32F_NV 0x8DAB #define GL_DEPTH32F_STENCIL8_NV 0x8DAC #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD #define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF #endif #ifndef GL_NV_fragment_program4 #define GL_NV_fragment_program4 #define _ALLEGRO_GL_NV_fragment_program4 #endif #ifndef GL_NV_framebuffer_multisample_coverage #define GL_NV_framebuffer_multisample_coverage #define _ALLEGRO_GL_NV_framebuffer_multisample_coverage #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB #define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 #endif #ifndef GL_NV_geometry_program4 #define GL_NV_geometry_program4 #define _ALLEGRO_GL_NV_geometry_program4 #define GL_GEOMETRY_PROGRAM_NV 0x8C26 #define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 #define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 #if !defined GL_EXT_geometry_shader4 #define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA #define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB #define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 #define GL_LINES_ADJACENCY_EXT 0xA #define GL_LINE_STRIP_ADJACENCY_EXT 0xB #define GL_TRIANGLES_ADJACENCY_EXT 0xC #define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define GL_PROGRAM_POINT_SIZE_EXT 0x8642 #endif #endif #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 #define _ALLEGRO_GL_NV_gpu_program4 #define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 #define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 #define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 #define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 #define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 #define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 #define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 #endif #ifndef GL_NV_parameter_buffer_object #define GL_NV_parameter_buffer_object #define _ALLEGRO_GL_NV_parameter_buffer_object #define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 #define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 #define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 #define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 #define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 #endif #ifndef GL_NV_transform_feedback #define GL_NV_transform_feedback #define _ALLEGRO_GL_NV_transform_feedback #define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 #define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F #define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C #define GL_SEPARATE_ATTRIBS_NV 0x8C8D #define GL_PRIMITIVES_GENERATED_NV 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 #define GL_RASTERIZER_DISCARD_NV 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 #define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E #define GL_ACTIVE_VARYINGS_NV 0x8C81 #define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 #define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F #define GL_BACK_PRIMARY_COLOR_NV 0x8C77 #define GL_BACK_SECONDARY_COLOR_NV 0x8C78 #define GL_TEXTURE_COORD_NV 0x8C79 #define GL_CLIP_DISTANCE_NV 0x8C7A #define GL_VERTEX_ID_NV 0x8C7B #define GL_PRIMITIVE_ID_NV 0x8C7C #define GL_GENERIC_ATTRIB_NV 0x8C7D #if !defined GL_NV_register_combiners #define GL_SECONDARY_COLOR_NV 0x852D #endif #if !defined GL_EXT_gpu_shader4 #define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 #define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 #define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 #endif #endif #ifndef GL_NV_vertex_program4 #define GL_NV_vertex_program4 #define _ALLEGRO_GL_NV_vertex_program4 #if !defined GL_EXT_vertex_shader4 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD #endif #endif #ifndef GL_GREMEDY_frame_terminator #define GL_GREMEDY_frame_terminator #define _ALLEGRO_GL_GREMEDY_frame_terminator #endif #ifndef GL_NV_conditional_render #define GL_NV_conditional_render #define _ALLEGRO_GL_NV_conditional_render #define GL_QUERY_WAIT_NV 0x8E13 #define GL_QUERY_NO_WAIT_NV 0x8E14 #define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 #define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 #endif #ifndef GL_NV_present_video #define GL_NV_present_video #define _ALLEGRO_GL_NV_present_video #define GL_FRAME_NV 0x8E26 #define GL_FIELDS_NV 0x8E27 #define GL_CURRENT_TIME_NV 0x8E28 #define GL_NUM_FILL_STREAMS_NV 0x8E29 #define GL_PRESENT_TIME_NV 0x8E2A #define GL_PRESENT_DURATION_NV 0x8E2B #endif #ifndef GL_EXT_transform_feedback #define GL_EXT_transform_feedback #define _ALLEGRO_GL_EXT_transform_feedback #define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E #define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F #define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C #define GL_SEPARATE_ATTRIBS_EXT 0x8C8D #define GL_PRIMITIVES_GENERATED_EXT 0x8C87 #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 #define GL_RASTERIZER_DISCARD_EXT 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 #define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 #endif #ifndef GL_EXT_direct_state_access #define GL_EXT_direct_state_access #define _ALLEGRO_GL_EXT_direct_state_access #define GL_PROGRAM_MATRIX_EXT 0x8E2D #define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E #define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F #endif #ifndef GL_EXT_texture_swizzle #define GL_EXT_texture_swizzle #define _ALLEGRO_GL_EXT_texture_swizzle #define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 #define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 #define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 #define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 #define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 #endif #ifndef GL_NV_explicit_multisample #define GL_NV_explicit_multisample #define _ALLEGRO_GL_NV_explicit_multisample #define GL_SAMPLE_POSITION_NV 0x8E50 #define GL_SAMPLE_MASK_NV 0x8E51 #define GL_SAMPLE_MASK_VALUE_NV 0x8E52 #define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 #define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 #define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 #define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 #define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 #define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 #define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 #endif #ifndef GL_NV_transform_feedback2 #define GL_NV_transform_feedback2 #define _ALLEGRO_GL_NV_transform_feedback2 #define GL_TRANSFORM_FEEDBACK_NV 0x8E22 #define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 #define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 #define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 #endif #ifndef GL_ATI_meminfo #define GL_ATI_meminfo #define _ALLEGRO_GL_ATI_meminfo #define GL_VBO_FREE_MEMORY_ATI 0x87FB #define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD #endif #ifndef GL_AMD_performance_monitor #define GL_AMD_performance_monitor #define _ALLEGRO_GL_AMD_performance_monitor #define GL_COUNTER_TYPE_AMD 0x8BC0 #define GL_COUNTER_RANGE_AMD 0x8BC1 #define GL_UNSIGNED_INT64_AMD 0x8BC2 #define GL_PERCENTAGE_AMD 0x8BC3 #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 #define GL_PERFMON_RESULT_AMD 0x8BC6 #endif #ifndef GL_AMD_texture_texture4 #define GL_AMD_texture_texture4 #define _ALLEGRO_GL_AMD_texture_texture4 #endif #ifndef GL_AMD_vertex_shader_tesselator #define GL_AMD_vertex_shader_tesselator #define _ALLEGRO_GL_AMD_vertex_shader_tesselator #define GL_SAMPLER_BUFFER_AMD 0x9001 #define GL_INT_SAMPLER_BUFFER_AMD 0x9002 #define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 #define GL_TESSELLATION_MODE_AMD 0x9004 #define GL_TESSELLATION_FACTOR_AMD 0x9005 #define GL_DISCRETE_AMD 0x9006 #define GL_CONTINUOUS_AMD 0x9007 #endif #ifndef GL_EXT_provoking_vertex #define GL_EXT_provoking_vertex #define _ALLEGRO_GL_EXT_provoking_vertex #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C #define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D #define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E #define GL_PROVOKING_VERTEX_EXT 0x8E4F #endif #ifndef GL_EXT_texture_snorm #define GL_EXT_texture_snorm #define _ALLEGRO_GL_EXT_texture_snorm #define GL_ALPHA_SNORM 0x9010 #define GL_LUMINANCE_SNORM 0x9011 #define GL_LUMINANCE_ALPHA_SNORM 0x9012 #define GL_INTENSITY_SNORM 0x9013 #define GL_ALPHA8_SNORM 0x9014 #define GL_LUMINANCE8_SNORM 0x9015 #define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 #define GL_INTENSITY8_SNORM 0x9017 #define GL_ALPHA16_SNORM 0x9018 #define GL_LUMINANCE16_SNORM 0x9019 #define GL_LUMINANCE16_ALPHA16_SNORM 0x901A #define GL_INTENSITY16_SNORM 0x901B /* reuse GL_RED_SNORM */ /* reuse GL_RG_SNORM */ /* reuse GL_RGB_SNORM */ /* reuse GL_RGBA_SNORM */ /* reuse GL_R8_SNORM */ /* reuse GL_RG8_SNORM */ /* reuse GL_RGB8_SNORM */ /* reuse GL_RGBA8_SNORM */ /* reuse GL_R16_SNORM */ /* reuse GL_RG16_SNORM */ /* reuse GL_RGB16_SNORM */ /* reuse GL_RGBA16_SNORM */ /* reuse GL_SIGNED_NORMALIZED */ #endif #ifndef GL_AMD_draw_buffers_blend #define GL_AMD_draw_buffers_blend #define _ALLEGRO_GL_AMD_draw_buffers_blend #endif #ifndef GL_APPLE_texture_range #define GL_APPLE_texture_range #define _ALLEGRO_GL_APPLE_texture_range #define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 #define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #define GL_STORAGE_PRIVATE_APPLE 0x85BD /* reuse GL_STORAGE_CACHED_APPLE */ /* reuse GL_STORAGE_SHARED_APPLE */ #endif #ifndef GL_APPLE_float_pixels #define GL_APPLE_float_pixels #define _ALLEGRO_GL_APPLE_float_pixels #define GL_HALF_APPLE 0x140B #define GL_RGBA_FLOAT32_APPLE 0x8814 #define GL_RGB_FLOAT32_APPLE 0x8815 #define GL_ALPHA_FLOAT32_APPLE 0x8816 #define GL_INTENSITY_FLOAT32_APPLE 0x8817 #define GL_LUMINANCE_FLOAT32_APPLE 0x8818 #define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 #define GL_RGBA_FLOAT16_APPLE 0x881A #define GL_RGB_FLOAT16_APPLE 0x881B #define GL_ALPHA_FLOAT16_APPLE 0x881C #define GL_INTENSITY_FLOAT16_APPLE 0x881D #define GL_LUMINANCE_FLOAT16_APPLE 0x881E #define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F #define GL_COLOR_FLOAT_APPLE 0x8A0F #endif #ifndef GL_APPLE_vertex_program_evaluators #define GL_APPLE_vertex_program_evaluators #define _ALLEGRO_GL_APPLE_vertex_program_evaluators #define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 #define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 #define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 #define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 #define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 #define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 #define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 #define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 #define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 #define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 #endif #ifndef GL_APPLE_aux_depth_stencil #define GL_APPLE_aux_depth_stencil #define _ALLEGRO_GL_APPLE_aux_depth_stencil #define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 #endif #ifndef GL_APPLE_object_purgeable #define GL_APPLE_object_purgeable #define _ALLEGRO_GL_APPLE_object_purgeable #define GL_BUFFER_OBJECT_APPLE 0x85B3 #define GL_RELEASED_APPLE 0x8A19 #define GL_VOLATILE_APPLE 0x8A1A #define GL_RETAINED_APPLE 0x8A1B #define GL_UNDEFINED_APPLE 0x8A1C #define GL_PURGEABLE_APPLE 0x8A1D #endif #ifndef GL_APPLE_row_bytes #define GL_APPLE_row_bytes #define _ALLEGRO_GL_APPLE_row_bytes #define GL_PACK_ROW_BYTES_APPLE 0x8A15 #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 #endif #ifndef GL_APPLE_rgb_422 #define GL_APPLE_rgb_422 #define _ALLEGRO_GL_APPLE_rgb_422 #define GL_RGB_422_APPLE 0x8A1F /* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ /* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ #endif #ifndef GL_NV_video_capture #define GL_NV_video_capture #define _ALLEGRO_GL_NV_video_capture #define GL_VIDEO_BUFFER_NV 0x9020 #define GL_VIDEO_BUFFER_BINDING_NV 0x9021 #define GL_FIELD_UPPER_NV 0x9022 #define GL_FIELD_LOWER_NV 0x9023 #define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 #define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 #define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 #define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 #define GL_VIDEO_BUFFER_PITCH_NV 0x9028 #define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 #define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A #define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B #define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C #define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D #define GL_PARTIAL_SUCCESS_NV 0x902E #define GL_SUCCESS_NV 0x902F #define GL_FAILURE_NV 0x9030 #define GL_YCBYCR8_422_NV 0x9031 #define GL_YCBAYCR8A_4224_NV 0x9032 #define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 #define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 #define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 #define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 #define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 #define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 #define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 #define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A #define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B #define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C #endif #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects #define _ALLEGRO_GL_EXT_separate_shader_objects #define GL_ACTIVE_PROGRAM_EXT 0x8B8D #endif #ifndef GL_NV_parameter_buffer_object2 #define GL_NV_parameter_buffer_object2 #define _ALLEGRO_GL_NV_parameter_buffer_object2 #endif #ifndef GL_NV_shader_buffer_load #define GL_NV_shader_buffer_load #define _ALLEGRO_GL_NV_shader_buffer_load #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D #define GL_GPU_ADDRESS_NV 0x8F34 #define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 #endif #ifndef GL_NV_vertex_buffer_unified_memory #define GL_NV_vertex_buffer_unified_memory #define _ALLEGRO_GL_NV_vertex_buffer_unified_memory #define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E #define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F #define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 #define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 #define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 #define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 #define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 #define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 #define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 #define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 #define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 #define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 #define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A #define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B #define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C #define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D #define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E #define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F #define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 #define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 #define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 #define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 #endif #ifndef GL_NV_texture_barrier #define GL_NV_texture_barrier #define _ALLEGRO_GL_NV_texture_barrier #endif #ifndef GL_AMD_shader_stencil_export #define GL_AMD_shader_stencil_export #define _ALLEGRO_GL_AMD_shader_stencil_export #endif #ifndef GL_AMD_seamless_cubemap_per_texture #define GL_AMD_seamless_cubemap_per_texture #define _ALLEGRO_GL_AMD_seamless_cubemap_per_texture /* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB */ #endif #ifndef GL_AMD_conservative_depth #define GL_AMD_conservative_depth #define _ALLEGRO_GL_AMD_conservative_depth #endif allegro-5.0.10/include/allegro5/opengl/GLext/glx_ext_api.h0000644000175000001440000002332711364043251022534 0ustar tjadenusers#ifdef _ALLEGRO_GLX_VERSION_1_3 /* GLX 1.3 */ AGL_API(GLXFBConfig *, GetFBConfigs, (Display *, int, int *)) AGL_API(GLXFBConfig *, ChooseFBConfig, (Display *, int, const int *, int *)) AGL_API(int, GetFBConfigAttrib, (Display *, GLXFBConfig, int, int *)) AGL_API(XVisualInfo *, GetVisualFromFBConfig, (Display *, GLXFBConfig)) AGL_API(GLXWindow, CreateWindow, (Display *, GLXFBConfig, Window, const int *)) AGL_API(void, DestroyWindow, (Display *, GLXWindow)) AGL_API(GLXPixmap, CreatePixmap, (Display *, GLXFBConfig, Pixmap, const int *)) AGL_API(void, DestroyPixmap, (Display *, GLXPixmap)) AGL_API(GLXPbuffer, CreatePbuffer, (Display *, GLXFBConfig, const int *)) AGL_API(void, DestroyPbuffer, (Display *, GLXPbuffer)) AGL_API(void, QueryDrawable, (Display *, GLXDrawable, int, unsigned int *)) AGL_API(GLXContext, CreateNewContext, (Display *, GLXFBConfig, int, GLXContext, Bool)) AGL_API(Bool, MakeContextCurrent, (Display *, GLXDrawable, GLXDrawable, GLXContext)) AGL_API(GLXDrawable, GetCurrentReadDrawable, (void)) AGL_API(Display *, GetCurrentDisplay, (void)) AGL_API(int, QueryContext, (Display *, GLXContext, int, int *)) AGL_API(void, SelectEvent, (Display *, GLXDrawable, unsigned long)) AGL_API(void, GetSelectedEvent, (Display *, GLXDrawable, unsigned long *)) #endif #ifdef _ALLEGRO_GLX_VERSION_1_4 /* GLX 1.4 */ AGL_API(__GLXextFuncPtr, GetProcAddress, (const GLubyte *)) #endif #ifdef _ALLEGRO_GLX_ARB_get_proc_address /* GLX_ARB_get_proc_address */ AGL_API(__GLXextFuncPtr, GetProcAddressARB, (const GLubyte *)) #endif #ifdef _ALLEGRO_GLX_ARB_create_context AGL_API(GLXContext, CreateContextAttribsARB, (Display *, GLXFBConfig, GLXContext, Bool, const int *)) #endif #ifdef _ALLEGRO_GLX_SGI_swap_control /* GLX_SGI_swap_control */ AGL_API(int, SwapIntervalSGI, (int)) #endif #ifdef _ALLEGRO_GLX_SGI_video_sync /* GLX_SGI_video_sync */ AGL_API(int, GetVideoSyncSGI, (unsigned int *)) AGL_API(int, WaitVideoSyncSGI, (int, int, unsigned int *)) #endif #ifdef _ALLEGRO_GLX_SGI_make_current_read /* GLX_SGI_make_current_read */ AGL_API(Bool, MakeCurrentReadSGI, (Display *, GLXDrawable, GLXDrawable, GLXContext)) AGL_API(GLXDrawable, GetCurrentReadDrawableSGI, (void)) #endif #ifdef _ALLEGRO_GLX_SGIX_video_source /* GLX_SGIX_video_source */ /* This one needs SGI's header file to be included first */ #ifdef _VL_H_ AGL_API(GLXVideoSourceSGIX, CreateGLXVideoSourceSGIX, (Display *, int, VLServer, VLPath, int, VLNode)) AGL_API(void, DestroyGLXVideoSourceSGIX, (Display *, GLXVideoSourceSGIX)) #endif #endif #ifdef _ALLEGRO_GLX_EXT_import_context /* GLX_EXT_import_context */ AGL_API(Display *, GetCurrentDisplayEXT, (void)) AGL_API(int, QueryContextInfoEXT, (Display *, GLXContext, int, int *)) AGL_API(GLXContextID, GetContextIDEXT, (const GLXContext)) AGL_API(GLXContext, ImportContextEXT, (Display *, GLXContextID)) AGL_API(void, FreeContextEXT, (Display *, GLXContext)) #endif #ifdef _ALLEGRO_GLX_SGIX_fbconfig /* GLX_SGIX_fbconfig */ AGL_API(int, GetFBConfigAttribSGIX, (Display *, GLXFBConfigSGIX, int, int *)) AGL_API(GLXFBConfigSGIX *, ChooseFBConfigSGIX, (Display *, int, int *, int *)) AGL_API(GLXPixmap, CreateGLXPixmapWithConfigSGIX, (Display *, GLXFBConfigSGIX, Pixmap)) AGL_API(GLXContext, CreateContextWithConfigSGIX, (Display *, GLXFBConfigSGIX, int, GLXContext, Bool)) AGL_API(XVisualInfo *, GetVisualFromFBConfigSGIX, (Display *, GLXFBConfigSGIX)) AGL_API(GLXFBConfigSGIX, GetFBConfigFromVisualSGIX, (Display *, XVisualInfo *)) #endif #ifdef _ALLEGRO_GLX_SGIX_pbuffer /* GLX_SGIX_pbuffer */ AGL_API(GLXPbufferSGIX, CreateGLXPbufferSGIX, (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *)) AGL_API(void, DestroyGLXPbufferSGIX, (Display *, GLXPbufferSGIX)) AGL_API(int, QueryGLXPbufferSGIX, (Display *, GLXPbufferSGIX, int, unsigned int *)) AGL_API(void, SelectEventSGIX, (Display *, GLXDrawable, unsigned long)) AGL_API(void, GetSelectedEventSGIX, (Display *, GLXDrawable, unsigned long *)) #endif #ifdef _ALLEGRO_GLX_SGI_cushion /* GLX_SGI_cushion */ AGL_API(void, CushionSGI, (Display *, Window, float)) #endif #ifdef _ALLEGRO_GLX_SGIX_video_resize /* GLX_SGIX_video_resize */ AGL_API(int, BindChannelToWindowSGIX, (Display *, int, int, Window)) AGL_API(int, ChannelRectSGIX, (Display *, int, int, int, int, int, int)) AGL_API(int, QueryChannelRectSGIX, (Display *, int, int, int *, int *, int *, int *)) AGL_API(int, QueryChannelDeltasSGIX, (Display *, int, int, int *, int *, int *, int *)) AGL_API(int, ChannelRectSyncSGIX, (Display *, int, int, GLenum)) #endif #ifdef _ALLEGRO_GLX_SGIX_dmbuffer /* GLX_SGIX_dmbuffer */ /* This one needs SGI's header file to be included first */ #ifdef _DM_BUFFER_H_ AGL_API(Bool, AssociateDMPbufferSGIX, (Display *, GLXPbufferSGIX, DMparams *, DMbuffer)) #endif #endif #ifdef _ALLEGRO_GLX_SGIX_swap_group /* GLX_SGIX_swap_group */ AGL_API(void, JoinSwapGroupSGIX, (Display *, GLXDrawable, GLXDrawable)) #endif #ifdef _ALLEGRO_GLX_SGIX_swap_barrier /* GLX_SGIX_swap_barrier */ AGL_API(void, BindSwapBarrierSGIX, (Display *, GLXDrawable, int)) AGL_API(Bool, QueryMaxSwapBarriersSGIX, (Display *, int, int *)) #endif #ifdef _ALLEGRO_GLX_SUN_get_transparent_index /* GLX_SUN_get_transparent_index */ AGL_API(Status, GetTransparentIndexSUN, (Display *, Window, Window, long *)) #endif #ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer /* GLX_MESA_copy_sub_buffer */ AGL_API(void, CopySubBufferMESA, (Display *, GLXDrawable, int, int, int, int)) #endif #ifdef _ALLEGRO_GLX_MESA_pixmap_colormap /* GLX_MESA_pixmap_colormap */ AGL_API(GLXPixmap, CreateGLXPixmapMESA, (Display *, XVisualInfo *, Pixmap, Colormap)) #endif #ifdef _ALLEGRO_GLX_MESA_release_buffers /* GLX_MESA_release_buffers */ AGL_API(Bool, ReleaseBuffersMESA, (Display *, GLXDrawable)) #endif #ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode /* GLX_MESA_set_3dfx_mode */ AGL_API(Bool, Set3DfxModeMESA, (int)) #endif #ifdef _ALLEGRO_GLX_OML_sync_control /* GLX_OML_sync_control */ AGL_API(Bool, GetSyncValuesOML, (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *)) AGL_API(Bool, GetMscRateOML, (Display *, GLXDrawable, int32_t *, int32_t *)) AGL_API(int64_t, SwapBuffersMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t)) AGL_API(Bool, WaitForMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *)) AGL_API(Bool, WaitForSbcOML, (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *)) #endif #ifdef _ALLEGRO_GLX_SGIX_hyperpipe AGL_API(GLXHyperpipeNetworkSGIX *, QueryHyperpipeNetworkSGIX, (Display *dpy, int *npipes)) AGL_API(int, HyperpipeConfigSGIX, (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId)) AGL_API(GLXHyperpipeConfigSGIX *, QueryHyperpipeConfigSGIX, (Display *dpy, int hpId, int *npipes)) AGL_API(int, DestroyHyperpipeConfigSGIX, (Display * dpy, int hpId)) AGL_API(int, BindHyperpipeSGIX, (Display *dpy, int hpId)) AGL_API(int, QueryHyperpipeBestAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList)) AGL_API(int, HyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList)) AGL_API(int, QueryHyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList)) #endif #ifdef _ALLEGRO_GLX_MESA_agp_offset AGL_API(unsigned int, GetAGPOffsetMESA, (const void *pointer)) #endif #ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap AGL_API(void, BindTexImageEXT, (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list)) AGL_API(void, ReleaseTextImageEXT, (Display *dpy, GLXDrawable drawable, int buffer)) #endif #ifdef _ALLEGRO_GLX_NV_video_output AGL_API(int, GetVideoDeviceNV, (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice)) AGL_API(int, ReleaseVideoDeviceNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice)) AGL_API(int, BindVideoImageNV, (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer)) AGL_API(int, ReleaseVideoImageNV, (Display *dpy, GLXPbuffer pbuf)) AGL_API(int, SendPbufferToVideoNV, (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock)) AGL_API(int, GetVideoInfoNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputVideo, unsigned long *pulCounterOutputPbuffer)) #endif #ifdef _ALLEGRO_GLX_NV_swap_group AGL_API(Bool, JoinSwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint group)) AGL_API(Bool, BindSwapBarrierNV, (Display *dpy, GLuint group, GLuint barrier)) AGL_API(Bool, QuerySwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier)) AGL_API(Bool, QueryMaxSwapGroupsNV, (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers)) AGL_API(Bool, QueryFrameCountNV, (Display *dpy, int screen, GLuint *count)) AGL_API(Bool, ResetFrameCountNV, (Display *dpy, int screen)) #endif #ifdef _ALLEGRO_GLX_NV_video_capture AGL_API(int, BindVideoCaptureDeviceNV, (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device)) AGL_API(GLXVideoCaptureDeviceNV *, EnumerateVideoCaptureDevicesNV, (Display *dpy, int screen, int *nelements)) AGL_API(void, LockVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) AGL_API(int, QueryVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value)) AGL_API(void, ReleaseVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) #endif #ifdef _ALLEGRO_GLX_EXT_swap_control AGL_API(int, SwapIntervalEXT, (Display *dpy, GLXDrawable drawable, int interval)) #endif #ifdef _ALLEGRO_GLX_NV_copy_image AGL_API(void, CopyImageSubDataNV, (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) #endif allegro-5.0.10/include/allegro5/opengl/GLext/glx_ext_list.h0000644000175000001440000000315011364043251022726 0ustar tjadenusersAGL_EXT(ARB_get_proc_address, 0) AGL_EXT(ARB_multisample, 0) AGL_EXT(ARB_fbconfig_float, 0) AGL_EXT(ARB_create_context, 0) AGL_EXT(ARB_vertex_buffer_object, 0) AGL_EXT(EXT_visual_info, 0) AGL_EXT(SGI_swap_control, 0) AGL_EXT(SGI_video_sync, 0) AGL_EXT(SGI_make_current_read, 0) AGL_EXT(SGIX_video_source, 0) AGL_EXT(EXT_visual_rating, 0) AGL_EXT(EXT_import_context, 0) AGL_EXT(SGIX_fbconfig, 0) AGL_EXT(SGIX_pbuffer, 0) AGL_EXT(SGI_cushion, 0) AGL_EXT(SGIX_video_resize, 0) AGL_EXT(SGIX_dm_buffer, 0) AGL_EXT(SGIX_swap_group, 0) AGL_EXT(SGIX_swap_barrier, 0) AGL_EXT(SGIS_color_range, 0) AGL_EXT(SGIS_blended_overlay, 0) AGL_EXT(SUN_get_transparent_index, 0) AGL_EXT(MESA_copy_sub_buffer, 0) AGL_EXT(MESA_pixmap_colormap, 0) AGL_EXT(MESA_release_buffers, 0) AGL_EXT(MESA_set_3dfx_mode, 0) AGL_EXT(SGIX_visual_select_group, 0) AGL_EXT(OML_swap_method, 0) AGL_EXT(OML_sync_control, 0) AGL_EXT(SGIX_hyperpipe, 0) AGL_EXT(MESA_agp_offset, 0) AGL_EXT(EXT_framebuffer_sRGB, 0) AGL_EXT(EXT_packed_float, 0) AGL_EXT(EXT_texture_from_pixmap, 0) AGL_EXT(NV_video_output, 0) AGL_EXT(NV_swap_group, 0) AGL_EXT(NV_video_capture, 0) AGL_EXT(EXT_swap_control, 0) AGL_EXT(NV_copy_image, 0) AGL_EXT(INTEL_swap_event, 0) allegro-5.0.10/include/allegro5/opengl/GLext/glx_ext_alias.h0000644000175000001440000001645511364043251023060 0ustar tjadenusers/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ #ifdef _ALLEGRO_GLX_VERSION_1_3 /*GLX1.3*/ #define glXGetFBConfigs _al_glXGetFBConfigs #define glXChooseFBConfig _al_glXChooseFBConfig #define glXGetFBConfigAttrib _al_glXGetFBConfigAttrib #define glXGetVisualFromFBConfig _al_glXGetVisualFromFBConfig #define glXCreateWindow _al_glXCreateWindow #define glXDestroyWindow _al_glXDestroyWindow #define glXCreatePixmap _al_glXCreatePixmap #define glXDestroyPixmap _al_glXDestroyPixmap #define glXCreatePbuffer _al_glXCreatePbuffer #define glXDestroyPbuffer _al_glXDestroyPbuffer #define glXQueryDrawable _al_glXQueryDrawable #define glXCreateNewContext _al_glXCreateNewContext #define glXMakeContextCurrent _al_glXMakeContextCurrent #define glXGetCurrentReadDrawable _al_glXGetCurrentReadDrawable #define glXGetCurrentDisplay _al_glXGetCurrentDisplay #define glXQueryContext _al_glXQueryContext #define glXSelectEvent _al_glXSelectEvent #define glXGetSelectedEvent _al_glXGetSelectedEvent #endif #ifdef _ALLEGRO_GLX_VERSION_1_4 /*GLX1.4*/ #define glXGetProcAddress _al_glXGetProcAddress #endif #ifdef _ALLEGRO_GLX_ARB_get_proc_address /*GLX_ARB_get_proc_address*/ #define glXGetProcAddressARB _al_glXGetProcAddressARB #endif #ifdef _ALLEGRO_GLX_ARB_create_context #define glXCreateContextAttribsARB _al_glXCreateContextAttribsARB #endif #ifdef _ALLEGRO_GLX_SGI_swap_control /*GLX_SGI_swap_control*/ #define glXSwapIntervalSGI _al_glXSwapIntervalSGI #endif #ifdef _ALLEGRO_GLX_SGI_video_sync /*GLX_SGI_video_sync*/ #define glXGetVideoSyncSGI _al_glXGetVideoSyncSGI #define glXWaitVideoSyncSGI _al_glXWaitVideoSyncSGI #endif #ifdef _ALLEGRO_GLX_SGI_make_current_read /*GLX_SGI_make_current_read*/ #define glXMakeCurrentReadSGI _al_glXMakeCurrentReadSGI #define glXGetCurrentReadDrawableSGI _al_glXGetCurrentReadDrawableSGI #endif #ifdef _ALLEGRO_GLX_SGIX_video_source /*GLX_SGIX_video_source*/ /*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ #ifdef _VL_H_ #define glXCreateGLXVideoSourceSGIX _al_glXCreateGLXVideoSourceSGIX #define glXDestroyGLXVideoSourceSGIX _al_glXDestroyGLXVideoSourceSGIX #endif #endif #ifdef _ALLEGRO_GLX_EXT_import_context /*GLX_EXT_import_context*/ #define glXGetCurrentDisplayEXT _al_glXGetCurrentDisplayEXT #define glXQueryContextInfoEXT _al_glXQueryContextInfoEXT #define glXGetContextIDEXT _al_glXGetContextIDEXT #define glXImportContextEXT _al_glXImportContextEXT #define glXFreeContextEXT _al_glXFreeContextEXT #endif #ifdef _ALLEGRO_GLX_SGIX_fbconfig /*GLX_SGIX_fbconfig*/ #define glXGetFBConfigAttribSGIX _al_glXGetFBConfigAttribSGIX #define glXChooseFBConfigSGIX _al_glXChooseFBConfigSGIX #define glXCreateGLXPixmapWithConfigSGIX _al_glXCreateGLXPixmapWithConfigSGIX #define glXCreateContextWithConfigSGIX _al_glXCreateContextWithConfigSGIX #define glXGetVisualFromFBConfigSGIX _al_glXGetVisualFromFBConfigSGIX #define glXGetFBConfigFromVisualSGIX _al_glXGetFBConfigFromVisualSGIX #endif #ifdef _ALLEGRO_GLX_SGIX_pbuffer /*GLX_SGIX_pbuffer*/ #define glXCreateGLXPbufferSGIX _al_glXCreateGLXPbufferSGIX #define glXDestroyGLXPbufferSGIX _al_glXDestroyGLXPbufferSGIX #define glXQueryGLXPbufferSGIX _al_glXQueryGLXPbufferSGIX #define glXSelectEventSGIX _al_glXSelectEventSGIX #define glXGetSelectedEventSGIX _al_glXGetSelectedEventSGIX #endif #ifdef _ALLEGRO_GLX_SGI_cushion /*GLX_SGI_cushion*/ #define glXCushionSGI _al_glXCushionSGI #endif #ifdef _ALLEGRO_GLX_SGIX_video_resize /*GLX_SGIX_video_resize*/ #define glXBindChannelToWindowSGIX _al_glXBindChannelToWindowSGIX #define glXChannelRectSGIX _al_glXChannelRectSGIX #define glXQueryChannelRectSGIX _al_glXQueryChannelRectSGIX #define glXQueryChannelDeltasSGIX _al_glXQueryChannelDeltasSGIX #define glXChannelRectSyncSGIX _al_glXChannelRectSyncSGIX #endif #ifdef _ALLEGRO_GLX_SGIX_dmbuffer /*GLX_SGIX_dmbuffer*/ /*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ #ifdef _DM_BUFFER_H_ #define glXAssociateDMPbufferSGIX _al_glXAssociateDMPbufferSGIX #endif #endif #ifdef _ALLEGRO_GLX_SGIX_swap_group /*GLX_SGIX_swap_group*/ #define glXJoinSwapGroupSGIX _al_glXJoinSwapGroupSGIX #endif #ifdef _ALLEGRO_GLX_SGIX_swap_barrier /*GLX_SGIX_swap_barrier*/ #define glXBindSwapBarrierSGIX _al_glXBindSwapBarrierSGIX #define glXQueryMaxSwapBarriersSGIX _al_glXQueryMaxSwapBarriersSGIX #endif #ifdef _ALLEGRO_GLX_SUN_get_transparent_index /*GLX_SUN_get_transparent_index*/ #define glXGetTransparentIndexSUN _al_glXGetTransparentIndexSUN #endif #ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer /*GLX_MESA_copy_sub_buffer*/ #define glXCopySubBufferMESA _al_glXCopySubBufferMESA #endif #ifdef _ALLEGRO_GLX_MESA_pixmap_colormap /*GLX_MESA_pixmap_colormap*/ #define glXCreateGLXPixmapMESA _al_glXCreateGLXPixmapMESA #endif #ifdef _ALLEGRO_GLX_MESA_release_buffers /*GLX_MESA_release_buffers*/ #define glXReleaseBuffersMESA _al_glXReleaseBuffersMESA #endif #ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode /*GLX_MESA_set_3dfx_mode*/ #define glXSet3DfxModeMESA _al_glXSet3DfxModeMESA #endif #ifdef _ALLEGRO_GLX_OML_sync_control /*GLX_OML_sync_control*/ #define glXGetSyncValuesOML _al_glXGetSyncValuesOML #define glXGetMscRateOML _al_glXGetMscRateOML #define glXSwapBuffersMscOML _al_glXSwapBuffersMscOML #define glXWaitForMscOML _al_glXWaitForMscOML #define glXWaitForSbcOML _al_glXWaitForSbcOML #endif #ifdef _ALLEGRO_GLX_SGIX_hyperpipe #define glXQueryHyperpipeNetworkSGIX _al_glXQueryHyperpipeNetworkSGIX #define glXHyperpipeConfigSGIX _al_glXHyperpipeConfigSGIX #define glXQueryHyperpipeConfigSGIX _al_glXQueryHyperpipeConfigSGIX #define glXDestroyHyperpipeConfigSGIX _al_glXDestroyHyperpipeConfigSGIX #define glXBindHyperpipeSGIX _al_glXBindHyperpipeSGIX #define glXQueryHyperpipeBestAttribSGIX _al_glXQueryHyperpipeBestAttribSGIX #define glXHyperpipeAttribSGIX _al_glXHyperpipeAttribSGIX #define glXQueryHyperpipeAttribSGIX _al_glXQueryHyperpipeAttribSGIX #endif #ifdef _ALLEGRO_GLX_MESA_agp_offset #define glXGetAGPOffsetMESA _al_glXGetAGPOffsetMESA #endif #ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap #define glXBindTexImageEXT _al_glXBindTexImageEXT #define glXReleaseTextImageEXT _al_glXReleaseTextImageEXT #endif #ifdef _ALLEGRO_GLX_NV_video_output #define glXGetVideoDeviceNV _al_glXGetVideoDeviceNV #define glXReleaseVideoDeviceNV _al_glXReleaseVideoDeviceNV #define glXBindVideoImageNV _al_glXBindVideoImageNV #define glXReleaseVideoImageNV _al_glXReleaseVideoImageNV #define glXSendPbufferToVideoNV _al_glXSendPbufferToVideoNV #define glXGetVideoInfoNV _al_glXGetVideoInfoNV #endif #ifdef _ALLEGRO_GLX_NV_swap_group #define glXJoinSwapGroupNV _al_glXJoinSwapGroupNV #define glXBindSwapBarrierNV _al_glXBindSwapBarrierNV #define glXQuerySwapGroupNV _al_glXQuerySwapGroupNV #define glXQueryMaxSwapGroupsNV _al_glXQueryMaxSwapGroupsNV #define glXQueryFrameCountNV _al_glXQueryFrameCountNV #define glXResetFrameCountNV _al_glXResetFrameCountNV #endif #ifdef _ALLEGRO_GLX_NV_video_capture #define glXBindVideoCaptureDeviceNV _al_glXBindVideoCaptureDeviceNV #define glXEnumerateVideoCaptureDevicesNV _al_glXEnumerateVideoCaptureDevicesNV #define glXLockVideoCaptureDeviceNV _al_glXLockVideoCaptureDeviceNV #define glXQueryVideoCaptureDeviceNV _al_glXQueryVideoCaptureDeviceNV #define glXReleaseVideoCaptureDeviceNV _al_glXReleaseVideoCaptureDeviceNV #endif #ifdef _ALLEGRO_GLX_EXT_swap_control #define glXSwapIntervalEXT _al_glXSwapIntervalEXT #endif #ifdef _ALLEGRO_GLX_NV_copy_image #define glXCopyImageSubDataNV _al_glXCopyImageSubDataNV #endif allegro-5.0.10/include/allegro5/opengl/GLext/gl_ext_alias.h0000644000175000001440000034547611771523645022714 0ustar tjadenusers/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ /**/ #ifdef _ALLEGRO_GL_VERSION_1_2 #define glBlendColor _al_glBlendColor #define glBlendEquation _al_glBlendEquation #define glDrawRangeElements _al_glDrawRangeElements #define glColorTable _al_glColorTable #define glColorTableParameterfv _al_glColorTableParameterfv #define glColorTableParameteriv _al_glColorTableParameteriv #define glCopyColorTable _al_glCopyColorTable #define glGetColorTable _al_glGetColorTable #define glGetColorTableParameterfv _al_glGetColorTableParameterfv #define glGetColorTableParameteriv _al_glGetColorTableParameteriv #define glColorSubTable _al_glColorSubTable #define glCopyColorSubTable _al_glCopyColorSubTable #define glTexImage3D _al_glTexImage3D #define glTexSubImage3D _al_glTexSubImage3D #define glCopyTexSubImage3D _al_glCopyTexSubImage3D #endif #if defined _ALLEGRO_GL_ARB_imaging #define glConvolutionFilter1D _al_glConvolutionFilter1D #define glConvolutionFilter2D _al_glConvolutionFilter2D #define glConvolutionParameterf _al_glConvolutionParameterf #define glConvolutionParameterfv _al_glConvolutionParameterfv #define glConvolutionParameteri _al_glConvolutionParameteri #define glConvolutionParameteriv _al_glConvolutionParameteriv #define glCopyConvolutionFilter1D _al_glCopyConvolutionFilter1D #define glCopyConvolutionFilter2D _al_glCopyConvolutionFilter2D #define glGetConvolutionFilter _al_glGetConvolutionFilter #define glGetConvolutionParameterfv _al_glGetConvolutionParameterfv #define glGetConvolutionParameteriv _al_glGetConvolutionParameteriv #define glGetSeparableFilter _al_glGetSeparableFilter #define glSeparableFilter2D _al_glSeparableFilter2D #define glGetHistogram _al_glGetHistogram #define glGetHistogramParameterfv _al_glGetHistogramParameterfv #define glGetHistogramParameteriv _al_glGetHistogramParameteriv #define glGetMinmax _al_glGetMinmax #define glGetMinmaxParameterfv _al_glGetMinmaxParameterfv #define glGetMinmaxParameteriv _al_glGetMinmaxParameteriv #define glHistogram _al_glHistogram #define glMinmax _al_glMinmax #define glResetHistogram _al_glResetHistogram #define glResetMinmax _al_glResetMinmax #endif #if defined _ALLEGRO_GL_VERSION_1_3 #define glActiveTexture _al_glActiveTexture #define glClientActiveTexture _al_glClientActiveTexture #define glMultiTexCoord1d _al_glMultiTexCoord1d #define glMultiTexCoord1dv _al_glMultiTexCoord1dv #define glMultiTexCoord1f _al_glMultiTexCoord1f #define glMultiTexCoord1fv _al_glMultiTexCoord1fv #define glMultiTexCoord1i _al_glMultiTexCoord1i #define glMultiTexCoord1iv _al_glMultiTexCoord1iv #define glMultiTexCoord1s _al_glMultiTexCoord1s #define glMultiTexCoord1sv _al_glMultiTexCoord1sv #define glMultiTexCoord2d _al_glMultiTexCoord2d #define glMultiTexCoord2dv _al_glMultiTexCoord2dv #define glMultiTexCoord2f _al_glMultiTexCoord2f #define glMultiTexCoord2fv _al_glMultiTexCoord2fv #define glMultiTexCoord2i _al_glMultiTexCoord2i #define glMultiTexCoord2iv _al_glMultiTexCoord2iv #define glMultiTexCoord2s _al_glMultiTexCoord2s #define glMultiTexCoord2sv _al_glMultiTexCoord2sv #define glMultiTexCoord3d _al_glMultiTexCoord3d #define glMultiTexCoord3dv _al_glMultiTexCoord3dv #define glMultiTexCoord3f _al_glMultiTexCoord3f #define glMultiTexCoord3fv _al_glMultiTexCoord3fv #define glMultiTexCoord3i _al_glMultiTexCoord3i #define glMultiTexCoord3iv _al_glMultiTexCoord3iv #define glMultiTexCoord3s _al_glMultiTexCoord3s #define glMultiTexCoord3sv _al_glMultiTexCoord3sv #define glMultiTexCoord4d _al_glMultiTexCoord4d #define glMultiTexCoord4dv _al_glMultiTexCoord4dv #define glMultiTexCoord4f _al_glMultiTexCoord4f #define glMultiTexCoord4fv _al_glMultiTexCoord4fv #define glMultiTexCoord4i _al_glMultiTexCoord4i #define glMultiTexCoord4iv _al_glMultiTexCoord4iv #define glMultiTexCoord4s _al_glMultiTexCoord4s #define glMultiTexCoord4sv _al_glMultiTexCoord4sv #define glLoadTransposeMatrixf _al_glLoadTransposeMatrixf #define glLoadTransposeMatrixd _al_glLoadTransposeMatrixd #define glMultTransposeMatrixf _al_glMultTransposeMatrixf #define glMultTransposeMatrixd _al_glMultTransposeMatrixd #define glSampleCoverage _al_glSampleCoverage #define glCompressedTexImage3D _al_glCompressedTexImage3D #define glCompressedTexImage2D _al_glCompressedTexImage2D #define glCompressedTexImage1D _al_glCompressedTexImage1D #define glCompressedTexSubImage3D _al_glCompressedTexSubImage3D #define glCompressedTexSubImage2D _al_glCompressedTexSubImage2D #define glCompressedTexSubImage1D _al_glCompressedTexSubImage1D #define glGetCompressedTexImage _al_glGetCompressedTexImage #endif #if defined _ALLEGRO_GL_VERSION_1_4 #define glBlendFuncSeparate _al_glBlendFuncSeparate #define glFogCoordf _al_glFogCoordf #define glFogCoordfv _al_glFogCoordfv #define glFogCoordd _al_glFogCoordd #define glFogCoorddv _al_glFogCoorddv #define glFogCoordPointer _al_glFogCoordPointer #define glMultiDrawArrays _al_glMultiDrawArrays #define glMultiDrawElements _al_glMultiDrawElements #define glPointParameterf _al_glPointParameterf #define glPointParameterfv _al_glPointParameterfv #define glPointParameteri _al_glPointParameteri #define glPointParameteriv _al_glPointParameteriv #define glSecondaryColor3b _al_glSecondaryColor3b #define glSecondaryColor3bv _al_glSecondaryColor3bv #define glSecondaryColor3d _al_glSecondaryColor3d #define glSecondaryColor3dv _al_glSecondaryColor3dv #define glSecondaryColor3f _al_glSecondaryColor3f #define glSecondaryColor3fv _al_glSecondaryColor3fv #define glSecondaryColor3i _al_glSecondaryColor3i #define glSecondaryColor3iv _al_glSecondaryColor3iv #define glSecondaryColor3s _al_glSecondaryColor3s #define glSecondaryColor3sv _al_glSecondaryColor3sv #define glSecondaryColor3ub _al_glSecondaryColor3ub #define glSecondaryColor3ubv _al_glSecondaryColor3ubv #define glSecondaryColor3ui _al_glSecondaryColor3ui #define glSecondaryColor3uiv _al_glSecondaryColor3uiv #define glSecondaryColor3us _al_glSecondaryColor3us #define glSecondaryColor3usv _al_glSecondaryColor3usv #define glSecondaryColorPointer _al_glSecondaryColorPointer #define glWindowPos2d _al_glWindowPos2d #define glWindowPos2dv _al_glWindowPos2dv #define glWindowPos2f _al_glWindowPos2f #define glWindowPos2fv _al_glWindowPos2fv #define glWindowPos2i _al_glWindowPos2i #define glWindowPos2iv _al_glWindowPos2iv #define glWindowPos2s _al_glWindowPos2s #define glWindowPos2sv _al_glWindowPos2sv #define glWindowPos3d _al_glWindowPos3d #define glWindowPos3dv _al_glWindowPos3dv #define glWindowPos3f _al_glWindowPos3f #define glWindowPos3fv _al_glWindowPos3fv #define glWindowPos3i _al_glWindowPos3i #define glWindowPos3iv _al_glWindowPos3iv #define glWindowPos3s _al_glWindowPos3s #define glWindowPos3sv _al_glWindowPos3sv #endif #if defined _ALLEGRO_GL_VERSION_1_5 #define glBindBuffer _al_glBindBuffer #define glDeleteBuffers _al_glDeleteBuffers #define glGenBuffers _al_glGenBuffers #define glIsBuffer _al_glIsBuffer #define glBufferData _al_glBufferData #define glBufferSubData _al_glBufferSubData #define glGetBufferSubData _al_glGetBufferSubData #define glMapBuffer _al_glMapBuffer #define glUnmapBuffer _al_glUnmapBuffer #define glGetBufferParameteriv _al_glGetBufferParameteriv #define glGetBufferPointerv _al_glGetBufferPointerv #define glGenQueries _al_glGenQueries #define glDeleteQueries _al_glDeleteQueries #define glIsQuery _al_glIsQuery #define glBeginQuery _al_glBeginQuery #define glEndQuery _al_glEndQuery #define glGetQueryiv _al_glGetQueryiv #define glGetQueryObjectiv _al_glGetQueryObjectiv #define glGetQueryObjectuiv _al_glGetQueryObjectuiv #endif #if defined _ALLEGRO_GL_VERSION_2_0 #define glBlendEquationSeparate _al_glBlendEquationSeparate #define glCreateProgram _al_glCreateProgram #define glCreateShader _al_glCreateShader #define glDeleteProgram _al_glDeleteProgram #define glDeleteShader _al_glDeleteShader #define glAttachShader _al_glAttachShader #define glDetachShader _al_glDetachShader #define glShaderSource _al_glShaderSource #define glCompileShader _al_glCompileShader #define glIsProgram _al_glIsProgram #define glIsShader _al_glIsShader #define glLinkProgram _al_glLinkProgram #define glUseProgram _al_glUseProgram #define glValidateProgram _al_glValidateProgram #define glUniform1f _al_glUniform1f #define glUniform2f _al_glUniform2f #define glUniform3f _al_glUniform3f #define glUniform4f _al_glUniform4f #define glUniform1i _al_glUniform1i #define glUniform2i _al_glUniform2i #define glUniform3i _al_glUniform3i #define glUniform4i _al_glUniform4i #define glUniform1fv _al_glUniform1fv #define glUniform2fv _al_glUniform2fv #define glUniform3fv _al_glUniform3fv #define glUniform4fv _al_glUniform4fv #define glUniform1iv _al_glUniform1iv #define glUniform2iv _al_glUniform2iv #define glUniform3iv _al_glUniform3iv #define glUniform4iv _al_glUniform4iv #define glUniformMatrix2fv _al_glUniformMatrix2fv #define glUniformMatrix3fv _al_glUniformMatrix3fv #define glUniformMatrix4fv _al_glUniformMatrix4fv #define glGetShaderfv _al_glGetShaderfv #define glGetShaderiv _al_glGetShaderiv #define glGetProgramfv _al_glGetProgramfv #define glGetProgramiv _al_glGetProgramiv #define glGetShaderInfoLog _al_glGetShaderInfoLog #define glGetProgramInfoLog _al_glGetProgramInfoLog #define glGetAttachedShaders _al_glGetAttachedShaders #define glGetUniformLocation _al_glGetUniformLocation #define glGetActiveUniform _al_glGetActiveUniform #define glGetUniformfv _al_glGetUniformfv #define glGetUniformiv _al_glGetUniformiv #define glGetShaderSource _al_glGetShaderSource #define glVertexAttrib1f _al_glVertexAttrib1f #define glVertexAttrib1s _al_glVertexAttrib1s #define glVertexAttrib1d _al_glVertexAttrib1d #define glVertexAttrib2f _al_glVertexAttrib2f #define glVertexAttrib2s _al_glVertexAttrib2s #define glVertexAttrib2d _al_glVertexAttrib2d #define glVertexAttrib3f _al_glVertexAttrib3f #define glVertexAttrib3s _al_glVertexAttrib3s #define glVertexAttrib3d _al_glVertexAttrib3d #define glVertexAttrib4f _al_glVertexAttrib4f #define glVertexAttrib4s _al_glVertexAttrib4s #define glVertexAttrib4d _al_glVertexAttrib4d #define glVertexAttrib4Nub _al_glVertexAttrib4Nub #define glVertexAttrib1fv _al_glVertexAttrib1fv #define glVertexAttrib1sv _al_glVertexAttrib1sv #define glVertexAttrib1dv _al_glVertexAttrib1dv #define glVertexAttrib2fv _al_glVertexAttrib2fv #define glVertexAttrib2sv _al_glVertexAttrib2sv #define glVertexAttrib2dv _al_glVertexAttrib2dv #define glVertexAttrib3fv _al_glVertexAttrib3fv #define glVertexAttrib3sv _al_glVertexAttrib3sv #define glVertexAttrib3dv _al_glVertexAttrib3dv #define glVertexAttrib4fv _al_glVertexAttrib4fv #define glVertexAttrib4sv _al_glVertexAttrib4sv #define glVertexAttrib4dv _al_glVertexAttrib4dv #define glVertexAttrib4iv _al_glVertexAttrib4iv #define glVertexAttrib4bv _al_glVertexAttrib4bv #define glVertexAttrib4ubv _al_glVertexAttrib4ubv #define glVertexAttrib4usv _al_glVertexAttrib4usv #define glVertexAttrib4uiv _al_glVertexAttrib4uiv #define glVertexAttrib4Nbv _al_glVertexAttrib4Nbv #define glVertexAttrib4Nsv _al_glVertexAttrib4Nsv #define glVertexAttrib4Niv _al_glVertexAttrib4Niv #define glVertexAttrib4Nubv _al_glVertexAttrib4Nubv #define glVertexAttrib4Nusv _al_glVertexAttrib4Nusv #define glVertexAttrib4Nuiv _al_glVertexAttrib4Nuiv #define glVertexAttribPointer _al_glVertexAttribPointer #define glEnableVertexAttribArray _al_glEnableVertexAttribArray #define glDisableVertexAttribArray _al_glDisableVertexAttribArray #define glBindAttribLocation _al_glBindAttribLocation #define glGetActiveAttrib _al_glGetActiveAttrib #define glGetAttribLocation _al_glGetAttribLocation #define glGetVertexAttribdv _al_glGetVertexAttribdv #define glGetVertexAttribfv _al_glGetVertexAttribfv #define glGetVertexAttribiv _al_glGetVertexAttribiv #define glGetVertexAttribPointerv _al_glGetVertexAttribPointerv #define glDrawBuffers _al_glDrawBuffers #define glStencilOpSeparate _al_glStencilOpSeparate #define glStencilFuncSeparate _al_glStencilFuncSeparate #endif #if defined _ALLEGRO_GL_VERSION_2_1 #define glUniformMatrix2x3fv _al_glUniformMatrix2x3fv #define glUniformMatrix3x2fv _al_glUniformMatrix3x2fv #define glUniformMatrix2x4fv _al_glUniformMatrix2x4fv #define glUniformMatrix4x2fv _al_glUniformMatrix4x2fv #define glUniformMatrix3x4fv _al_glUniformMatrix3x4fv #define glUniformMatrix4x3fv _al_glUniformMatrix4x3fv #endif #if defined _ALLEGRO_GL_VERSION_3_0 /*OpenGL3.0alsoreusesentrypointsfromtheseextensions:*/ /*ARB_framebuffer_object*/ /*ARB_map_buffer_range*/ /*ARB_vertex_array_object*/ #define glColorMaski _al_glColorMaski #define glGetBooleani_v _al_glGetBooleani_v #define glGetIntegeri_v _al_glGetIntegeri_v #define glEnablei _al_glEnablei #define glDisablei _al_glDisablei #define glIsEnabledi _al_glIsEnabledi #define glBeginTransformFeedback _al_glBeginTransformFeedback #define glEndTransformFeedback _al_glEndTransformFeedback #define glBindBufferRange _al_glBindBufferRange #define glBindBufferBase _al_glBindBufferBase #define glTransformFeedbackVaryings _al_glTransformFeedbackVaryings #define glGetTransformFeedbackVarying _al_glGetTransformFeedbackVarying #define glClampColor _al_glClampColor #define glBeginConditionalRender _al_glBeginConditionalRender #define glEndConditionalRender _al_glEndConditionalRender #define glVertexAttribI1i _al_glVertexAttribI1i #define glVertexAttribI2i _al_glVertexAttribI2i #define glVertexAttribI3i _al_glVertexAttribI3i #define glVertexAttribI4i _al_glVertexAttribI4i #define glVertexAttribI1ui _al_glVertexAttribI1ui #define glVertexAttribI2ui _al_glVertexAttribI2ui #define glVertexAttribI3ui _al_glVertexAttribI3ui #define glVertexAttribI4ui _al_glVertexAttribI4ui #define glVertexAttribI1iv _al_glVertexAttribI1iv #define glVertexAttribI2iv _al_glVertexAttribI2iv #define glVertexAttribI3iv _al_glVertexAttribI3iv #define glVertexAttribI4iv _al_glVertexAttribI4iv #define glVertexAttribI1uiv _al_glVertexAttribI1uiv #define glVertexAttribI2uiv _al_glVertexAttribI2uiv #define glVertexAttribI3uiv _al_glVertexAttribI3uiv #define glVertexAttribI4uiv _al_glVertexAttribI4uiv #define glVertexAttribI4bv _al_glVertexAttribI4bv #define glVertexAttribI4sv _al_glVertexAttribI4sv #define glVertexAttribI4ubv _al_glVertexAttribI4ubv #define glVertexAttribI4usv _al_glVertexAttribI4usv #define glVertexAttribIPointer _al_glVertexAttribIPointer #define glGetVertexAttribIiv _al_glGetVertexAttribIiv #define glGetVertexAttribIuiv _al_glGetVertexAttribIuiv #define glGetUniformuiv _al_glGetUniformuiv #define glBindFragDataLocation _al_glBindFragDataLocation #define glGetFragDataLocation _al_glGetFragDataLocation #define glUniform1ui _al_glUniform1ui #define glUniform2ui _al_glUniform2ui #define glUniform3ui _al_glUniform3ui #define glUniform4ui _al_glUniform4ui #define glUniform1uiv _al_glUniform1uiv #define glUniform2uiv _al_glUniform2uiv #define glUniform3uiv _al_glUniform3uiv #define glUniform4uiv _al_glUniform4uiv #define glTexParameterIiv _al_glTexParameterIiv #define glTexParameterIuiv _al_glTexParameterIuiv #define glGetTexParameterIiv _al_glGetTexParameterIiv #define glGetTexParameterIuiv _al_glGetTexParameterIuiv #define glClearBufferiv _al_glClearBufferiv #define glClearBufferuiv _al_glClearBufferuiv #define glClearBufferfv _al_glClearBufferfv #define glClearBufferfi _al_glClearBufferfi #define glGetStringi _al_glGetStringi #endif #if defined _ALLEGRO_GL_VERSION_3_1 /*OpenGL3.1alsoreusesentrypointsfromtheseextensions:*/ /*ARB_copy_buffer*/ /*ARB_uniform_buffer_object*/ #define glDrawArraysInstanced _al_glDrawArraysInstanced #define glDrawElementsInstanced _al_glDrawElementsInstanced #define glTexBuffer _al_glTexBuffer #define glPrimitiveRestartIndex _al_glPrimitiveRestartIndex #endif #if defined _ALLEGRO_GL_VERSION_3_2 /*OpenGL3.2alsoreusesentrypointsfromtheseextensions:*/ /*ARB_draw_elements_base_vertex*/ /*ARB_provoking_vertex*/ /*ARB_sync*/ /*ARB_texture_multisample*/ #define glGetInteger64i_v _al_glGetInteger64i_v #define glGetBufferParameteri64v _al_glGetBufferParameteri64v #define glProgramParameteri _al_glProgramParameteri #define glFramebufferTexture _al_glFramebufferTexture #endif #if defined _ALLEGRO_GL_VERSION_3_3 /*OpenGL3.3alsoreusesentrypointsfromtheseextensions:*/ /*ARB_blend_func_extended*/ /*ARB_sampler_objects*/ /*ARB_explicit_attrib_location,butithasnone*/ /*ARB_occlusion_query2(noentrypoints)*/ /*ARB_shader_bit_encoding(noentrypoints)*/ /*ARB_texture_rgb10_a2ui(noentrypoints)*/ /*ARB_texture_swizzle(noentrypoints)*/ /*ARB_timer_query*/ /*ARB_vertex_type_2_10_10_10_rev*/ #endif /**/ /**/ #ifdef _ALLEGRO_GL_ARB_multitexture #define glActiveTextureARB _al_glActiveTextureARB #define glClientActiveTextureARB _al_glClientActiveTextureARB #define glMultiTexCoord1dARB _al_glMultiTexCoord1dARB #define glMultiTexCoord1dvARB _al_glMultiTexCoord1dvARB #define glMultiTexCoord1fARB _al_glMultiTexCoord1fARB #define glMultiTexCoord1fvARB _al_glMultiTexCoord1fvARB #define glMultiTexCoord1iARB _al_glMultiTexCoord1iARB #define glMultiTexCoord1ivARB _al_glMultiTexCoord1ivARB #define glMultiTexCoord1sARB _al_glMultiTexCoord1sARB #define glMultiTexCoord1svARB _al_glMultiTexCoord1svARB #define glMultiTexCoord2dARB _al_glMultiTexCoord2dARB #define glMultiTexCoord2dvARB _al_glMultiTexCoord2dvARB #define glMultiTexCoord2fARB _al_glMultiTexCoord2fARB #define glMultiTexCoord2fvARB _al_glMultiTexCoord2fvARB #define glMultiTexCoord2iARB _al_glMultiTexCoord2iARB #define glMultiTexCoord2ivARB _al_glMultiTexCoord2ivARB #define glMultiTexCoord2sARB _al_glMultiTexCoord2sARB #define glMultiTexCoord2svARB _al_glMultiTexCoord2svARB #define glMultiTexCoord3dARB _al_glMultiTexCoord3dARB #define glMultiTexCoord3dvARB _al_glMultiTexCoord3dvARB #define glMultiTexCoord3fARB _al_glMultiTexCoord3fARB #define glMultiTexCoord3fvARB _al_glMultiTexCoord3fvARB #define glMultiTexCoord3iARB _al_glMultiTexCoord3iARB #define glMultiTexCoord3ivARB _al_glMultiTexCoord3ivARB #define glMultiTexCoord3sARB _al_glMultiTexCoord3sARB #define glMultiTexCoord3svARB _al_glMultiTexCoord3svARB #define glMultiTexCoord4dARB _al_glMultiTexCoord4dARB #define glMultiTexCoord4dvARB _al_glMultiTexCoord4dvARB #define glMultiTexCoord4fARB _al_glMultiTexCoord4fARB #define glMultiTexCoord4fvARB _al_glMultiTexCoord4fvARB #define glMultiTexCoord4iARB _al_glMultiTexCoord4iARB #define glMultiTexCoord4ivARB _al_glMultiTexCoord4ivARB #define glMultiTexCoord4sARB _al_glMultiTexCoord4sARB #define glMultiTexCoord4svARB _al_glMultiTexCoord4svARB #endif #if defined _ALLEGRO_GL_ARB_transpose_matrix #define glLoadTransposeMatrixfARB _al_glLoadTransposeMatrixfARB #define glLoadTransposeMatrixdARB _al_glLoadTransposeMatrixdARB #define glMultTransposeMatrixfARB _al_glMultTransposeMatrixfARB #define glMultTransposeMatrixdARB _al_glMultTransposeMatrixdARB #endif #if defined _ALLEGRO_GL_ARB_multisample #define glSampleCoverageARB _al_glSampleCoverageARB #endif #if defined _ALLEGRO_GL_ARB_texture_compression #define glCompressedTexImage3DARB _al_glCompressedTexImage3DARB #define glCompressedTexImage2DARB _al_glCompressedTexImage2DARB #define glCompressedTexImage1DARB _al_glCompressedTexImage1DARB #define glCompressedTexSubImage3DARB _al_glCompressedTexSubImage3DARB #define glCompressedTexSubImage2DARB _al_glCompressedTexSubImage2DARB #define glCompressedTexSubImage1DARB _al_glCompressedTexSubImage1DARB #define glGetCompressedTexImageARB _al_glGetCompressedTexImageARB #endif #if defined _ALLEGRO_GL_ARB_point_parameters #define glPointParameterfARB _al_glPointParameterfARB #define glPointParameterfvARB _al_glPointParameterfvARB #endif #if defined _ALLEGRO_GL_ARB_vertex_blend #define glWeightbvARB _al_glWeightbvARB #define glWeightsvARB _al_glWeightsvARB #define glWeightivARB _al_glWeightivARB #define glWeightfvARB _al_glWeightfvARB #define glWeightdvARB _al_glWeightdvARB #define glWeightubvARB _al_glWeightubvARB #define glWeightusvARB _al_glWeightusvARB #define glWeightuivARB _al_glWeightuivARB #define glWeightPointerARB _al_glWeightPointerARB #define glVertexBlendARB _al_glVertexBlendARB #endif #if defined _ALLEGRO_GL_ARB_matrix_palette #define glCurrentPaletteMatrixARB _al_glCurrentPaletteMatrixARB #define glMatrixIndexubvARB _al_glMatrixIndexubvARB #define glMatrixIndexusvARB _al_glMatrixIndexusvARB #define glMatrixIndexuivARB _al_glMatrixIndexuivARB #define glMatrixIndexPointerARB _al_glMatrixIndexPointerARB #endif #if defined _ALLEGRO_GL_ARB_window_pos #define glWindowPos2dARB _al_glWindowPos2dARB #define glWindowPos2dvARB _al_glWindowPos2dvARB #define glWindowPos2fARB _al_glWindowPos2fARB #define glWindowPos2fvARB _al_glWindowPos2fvARB #define glWindowPos2iARB _al_glWindowPos2iARB #define glWindowPos2ivARB _al_glWindowPos2ivARB #define glWindowPos2sARB _al_glWindowPos2sARB #define glWindowPos2svARB _al_glWindowPos2svARB #define glWindowPos3dARB _al_glWindowPos3dARB #define glWindowPos3dvARB _al_glWindowPos3dvARB #define glWindowPos3fARB _al_glWindowPos3fARB #define glWindowPos3fvARB _al_glWindowPos3fvARB #define glWindowPos3iARB _al_glWindowPos3iARB #define glWindowPos3ivARB _al_glWindowPos3ivARB #define glWindowPos3sARB _al_glWindowPos3sARB #define glWindowPos3svARB _al_glWindowPos3svARB #endif #if defined _ALLEGRO_GL_ARB_vertex_program #define glVertexAttrib1dARB _al_glVertexAttrib1dARB #define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB #define glVertexAttrib1fARB _al_glVertexAttrib1fARB #define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB #define glVertexAttrib1sARB _al_glVertexAttrib1sARB #define glVertexAttrib1svARB _al_glVertexAttrib1svARB #define glVertexAttrib2dARB _al_glVertexAttrib2dARB #define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB #define glVertexAttrib2fARB _al_glVertexAttrib2fARB #define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB #define glVertexAttrib2sARB _al_glVertexAttrib2sARB #define glVertexAttrib2svARB _al_glVertexAttrib2svARB #define glVertexAttrib3dARB _al_glVertexAttrib3dARB #define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB #define glVertexAttrib3fARB _al_glVertexAttrib3fARB #define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB #define glVertexAttrib3sARB _al_glVertexAttrib3sARB #define glVertexAttrib3svARB _al_glVertexAttrib3svARB #define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB #define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB #define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB #define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB #define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB #define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB #define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB #define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB #define glVertexAttrib4dARB _al_glVertexAttrib4dARB #define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB #define glVertexAttrib4fARB _al_glVertexAttrib4fARB #define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB #define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB #define glVertexAttrib4sARB _al_glVertexAttrib4sARB #define glVertexAttrib4svARB _al_glVertexAttrib4svARB #define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB #define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB #define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB #define glVertexAttribPointerARB _al_glVertexAttribPointerARB #define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB #define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB #define glProgramStringARB _al_glProgramStringARB #define glBindProgramARB _al_glBindProgramARB #define glDeleteProgramsARB _al_glDeleteProgramsARB #define glGenProgramsARB _al_glGenProgramsARB #define glProgramEnvParameter4dARB _al_glProgramEnvParameter4dARB #define glProgramEnvParameter4dvARB _al_glProgramEnvParameter4dvARB #define glProgramEnvParameter4fARB _al_glProgramEnvParameter4fARB #define glProgramEnvParameter4fvARB _al_glProgramEnvParameter4fvARB #define glProgramLocalParameter4dARB _al_glProgramLocalParameter4dARB #define glProgramLocalParameter4dvARB _al_glProgramLocalParameter4dvARB #define glProgramLocalParameter4fARB _al_glProgramLocalParameter4fARB #define glProgramLocalParameter4fvARB _al_glProgramLocalParameter4fvARB #define glGetProgramEnvParameterdvARB _al_glGetProgramEnvParameterdvARB #define glGetProgramEnvParameterfvARB _al_glGetProgramEnvParameterfvARB #define glGetProgramLocalParameterdvARB _al_glGetProgramLocalParameterdvARB #define glGetProgramLocalParameterfvARB _al_glGetProgramLocalParameterfvARB #define glGetProgramivARB _al_glGetProgramivARB #define glGetProgramStringARB _al_glGetProgramStringARB #define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB #define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB #define glGetVertexAttribivARB _al_glGetVertexAttribivARB #define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB #define glIsProgramARB _al_glIsProgramARB #endif #if defined _ALLEGRO_GL_ARB_vertex_buffer_object #define glBindBufferARB _al_glBindBufferARB #define glDeleteBuffersARB _al_glDeleteBuffersARB #define glGenBuffersARB _al_glGenBuffersARB #define glIsBufferARB _al_glIsBufferARB #define glBufferDataARB _al_glBufferDataARB #define glBufferSubDataARB _al_glBufferSubDataARB #define glGetBufferSubDataARB _al_glGetBufferSubDataARB #define glMapBufferARB _al_glMapBufferARB #define glUnmapBufferARB _al_glUnmapBufferARB #define glGetBufferParameterivARB _al_glGetBufferParameterivARB #define glGetBufferPointervARB _al_glGetBufferPointervARB #endif #if defined _ALLEGRO_GL_ARB_occlusion_query #define glGenQueriesARB _al_glGenQueriesARB #define glDeleteQueriesARB _al_glDeleteQueriesARB #define glIsQueryARB _al_glIsQueryARB #define glBeginQueryARB _al_glBeginQueryARB #define glEndQueryARB _al_glEndQueryARB #define glGetQueryivARB _al_glGetQueryivARB #define glGetQueryObjectivARB _al_glGetQueryObjectivARB #define glGetQueryObjectuivARB _al_glGetQueryObjectuivARB #endif #if defined _ALLEGRO_GL_ARB_shader_objects #define glDeleteObjectARB _al_glDeleteObjectARB #define glGetHandleARB _al_glGetHandleARB #define glDetachObjectARB _al_glDetachObjectARB #define glCreateShaderObjectARB _al_glCreateShaderObjectARB #define glShaderSourceARB _al_glShaderSourceARB #define glCompileShaderARB _al_glCompileShaderARB #define glCreateProgramObjectARB _al_glCreateProgramObjectARB #define glAttachObjectARB _al_glAttachObjectARB #define glLinkProgramARB _al_glLinkProgramARB #define glUseProgramObjectARB _al_glUseProgramObjectARB #define glValidateProgramARB _al_glValidateProgramARB #define glUniform1fARB _al_glUniform1fARB #define glUniform2fARB _al_glUniform2fARB #define glUniform3fARB _al_glUniform3fARB #define glUniform4fARB _al_glUniform4fARB #define glUniform1iARB _al_glUniform1iARB #define glUniform2iARB _al_glUniform2iARB #define glUniform3iARB _al_glUniform3iARB #define glUniform4iARB _al_glUniform4iARB #define glUniform1fvARB _al_glUniform1fvARB #define glUniform2fvARB _al_glUniform2fvARB #define glUniform3fvARB _al_glUniform3fvARB #define glUniform4fvARB _al_glUniform4fvARB #define glUniform1ivARB _al_glUniform1ivARB #define glUniform2ivARB _al_glUniform2ivARB #define glUniform3ivARB _al_glUniform3ivARB #define glUniform4ivARB _al_glUniform4ivARB #define glUniformMatrix2fvARB _al_glUniformMatrix2fvARB #define glUniformMatrix3fvARB _al_glUniformMatrix3fvARB #define glUniformMatrix4fvARB _al_glUniformMatrix4fvARB #define glGetObjectParameterfvARB _al_glGetObjectParameterfvARB #define glGetObjectParameterivARB _al_glGetObjectParameterivARB #define glGetInfoLogARB _al_glGetInfoLogARB #define glGetAttachedObjectsARB _al_glGetAttachedObjectsARB #define glGetUniformLocationARB _al_glGetUniformLocationARB #define glGetActiveUniformARB _al_glGetActiveUniformARB #define glGetUniformfvARB _al_glGetUniformfvARB #define glGetUniformivARB _al_glGetUniformivARB #define glGetShaderSourceARB _al_glGetShaderSourceARB #endif #ifdef _ALLEGRO_GL_ARB_vertex_shader #ifndef GL_ARB_vertex_program #define glVertexAttrib1fARB _al_glVertexAttrib1fARB #define glVertexAttrib1sARB _al_glVertexAttrib1sARB #define glVertexAttrib1dARB _al_glVertexAttrib1dARB #define glVertexAttrib2fARB _al_glVertexAttrib2fARB #define glVertexAttrib2sARB _al_glVertexAttrib2sARB #define glVertexAttrib2dARB _al_glVertexAttrib2dARB #define glVertexAttrib3fARB _al_glVertexAttrib3fARB #define glVertexAttrib3sARB _al_glVertexAttrib3sARB #define glVertexAttrib3dARB _al_glVertexAttrib3dARB #define glVertexAttrib4fARB _al_glVertexAttrib4fARB #define glVertexAttrib4sARB _al_glVertexAttrib4sARB #define glVertexAttrib4dARB _al_glVertexAttrib4dARB #define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB #define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB #define glVertexAttrib1svARB _al_glVertexAttrib1svARB #define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB #define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB #define glVertexAttrib2svARB _al_glVertexAttrib2svARB #define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB #define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB #define glVertexAttrib3svARB _al_glVertexAttrib3svARB #define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB #define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB #define glVertexAttrib4svARB _al_glVertexAttrib4svARB #define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB #define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB #define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB #define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB #define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB #define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB #define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB #define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB #define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB #define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB #define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB #define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB #define glVertexAttribPointerARB _al_glVertexAttribPointerARB #define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB #define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB #endif #define glBindAttribLocationARB _al_glBindAttribLocationARB #define glGetActiveAttribARB _al_glGetActiveAttribARB #define glGetAttribLocationARB _al_glGetAttribLocationARB #ifndef GL_ARB_vertex_program #define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB #define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB #define glGetVertexAttribivARB _al_glGetVertexAttribivARB #define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB #endif #endif #if defined _ALLEGRO_GL_ARB_draw_buffers #define glDrawBuffersARB _al_glDrawBuffersARB #endif #if defined _ALLEGRO_GL_ARB_color_buffer_float #define glClampColorARB _al_glClampColorARB #endif #if defined _ALLEGRO_GL_ARB_draw_instanced #define glDrawArraysInstancedARB _al_glDrawArraysInstancedARB #define glDrawElementsInstancedARB _al_glDrawElementsInstancedARB #endif #if defined _ALLEGRO_GL_ARB_framebuffer_object #define glIsRenderbuffer _al_glIsRenderbuffer #define glBindRenderbuffer _al_glBindRenderbuffer #define glDeleteRenderbuffers _al_glDeleteRenderbuffers #define glGenRenderbuffers _al_glGenRenderbuffers #define glRenderbufferStorage _al_glRenderbufferStorage #define glGetRenderbufferParameteriv _al_glGetRenderbufferParameteriv #define glIsFramebuffer _al_glIsFramebuffer #define glBindFramebuffer _al_glBindFramebuffer #define glDeleteFramebuffers _al_glDeleteFramebuffers #define glGenFramebuffers _al_glGenFramebuffers #define glCheckFramebufferStatus _al_glCheckFramebufferStatus #define glFramebufferTexture1D _al_glFramebufferTexture1D #define glFramebufferTexture2D _al_glFramebufferTexture2D #define glFramebufferTexture3D _al_glFramebufferTexture3D #define glFramebufferRenderbuffer _al_glFramebufferRenderbuffer #define glGetFramebufferAttachmentParameteriv _al_glGetFramebufferAttachmentParameteriv #define glGenerateMipmap _al_glGenerateMipmap #define glBlitFramebuffer _al_glBlitFramebuffer #define glRenderbufferStorageMultisample _al_glRenderbufferStorageMultisample #define glFramebufferTextureLayer _al_glFramebufferTextureLayer #endif #if defined _ALLEGRO_GL_ARB_geometry_shader4 #define glProgramParameteriARB _al_glProgramParameteriARB #define glFramebufferTextureARB _al_glFramebufferTextureARB #define glFramebufferTextureLayerARB _al_glFramebufferTextureLayerARB #define glFramebufferTextureFaceARB _al_glFramebufferTextureFaceARB #endif #if defined _ALLEGRO_GL_ARB_instanced_arrays #define glVertexAttribDivisor _al_glVertexAttribDivisor #endif #if defined _ALLEGRO_GL_ARB_map_buffer_range #define glMapBufferRange _al_glMapBufferRange #define glFlushMappedBufferRange _al_glFlushMappedBufferRange #endif #if defined _ALLEGRO_GL_ARB_texture_buffer_object #define glTexBufferARB _al_glTexBufferARB #endif #if defined _ALLEGRO_GL_ARB_vertex_array_object #define glBindVertexArray _al_glBindVertexArray #define glDeleteVertexArrays _al_glDeleteVertexArrays #define glGenVertexArrays _al_glGenVertexArrays #define glIsVertexArray _al_glIsVertexArray #endif #if defined _ALLEGRO_GL_ARB_uniform_buffer_object #define glGetUniformIndices _al_glGetUniformIndices #define glGetActiveUniformsiv _al_glGetActiveUniformsiv #define glGetActiveUniformName _al_glGetActiveUniformName #define glGetUniformBlockIndex _al_glGetUniformBlockIndex #define glGetActiveUniformBlockiv _al_glGetActiveUniformBlockiv #define glGetActiveUniformBlockName _al_glGetActiveUniformBlockName #define glUniformBlockBinding _al_glUniformBlockBinding #endif #if defined _ALLEGRO_GL_ARB_copy_buffer #define glCopyBufferSubData _al_glCopyBufferSubData #endif #if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex #define glDrawElementsBaseVertex _al_glDrawElementsBaseVertex #define glDrawRangeElementsBaseVertex _al_glDrawRangeElementsBaseVertex #define glDrawElementsInstancedBaseVertex _al_glDrawElementsInstancedBaseVertex #define glMultiDrawElementsBaseVertex _al_glMultiDrawElementsBaseVertex #endif #if defined _ALLEGRO_GL_ARB_provoking_vertex #define glProvokingVertex _al_glProvokingVertex #endif #if defined _ALLEGRO_GL_ARB_sync #define glFenceSync _al_glFenceSync #define glIsSync _al_glIsSync #define glDeleteSync _al_glDeleteSync #define glClientWaitSync _al_glClientWaitSync #define glWaitSync _al_glWaitSync #define glGetInteger64v _al_glGetInteger64v #define glGetSynciv _al_glGetSynciv #endif #if defined _ALLEGRO_GL_ARB_texture_multisample #define glTexImage2DMultisample _al_glTexImage2DMultisample #define glTexImage3DMultisample _al_glTexImage3DMultisample #define glGetMultisamplefv _al_glGetMultisamplefv #define glSampleMaski _al_glSampleMaski #endif #if defined _ALLEGRO_GL_ARB_draw_buffers_blend #define glBlendEquationi _al_glBlendEquationi #define glBlendEquationSeparatei _al_glBlendEquationSeparatei #define glBlendFunci _al_glBlendFunci #define glBlendFuncSeparatei _al_glBlendFuncSeparatei #endif #if defined _ALLEGRO_GL_ARB_sample_shading #define glMinSampleShading _al_glMinSampleShading #endif #if defined _ALLEGRO_GL_ARB_shading_language_include #define glNamedStringARB _al_glNamedStringARB #define glDeleteNamedStringARB _al_glDeleteNamedStringARB #define glCompileShaderIncludeARB _al_glCompileShaderIncludeARB #define glIsNamedStringARB _al_glIsNamedStringARB #define glGetNamedStringARB _al_glGetNamedStringARB #define glGetNamedStringivARB _al_glGetNamedStringivARB #endif #if defined _ALLEGRO_GL_ARB_blend_func_extended #define glBindFragDataLocationIndexed _al_glBindFragDataLocationIndexed #define glGetFragDataIndex _al_glGetFragDataIndex #endif #if defined _ALLEGRO_GL_ARB_sampler_objects #define glGenSamplers _al_glGenSamplers #define glDeleteSamplers _al_glDeleteSamplers #define glIsSampler _al_glIsSampler #define glBindSampler _al_glBindSampler #define glSamplerParameteri _al_glSamplerParameteri #define glSamplerParameteriv _al_glSamplerParameteriv #define glSamplerParameterf _al_glSamplerParameterf #define glSamplerParameterfv _al_glSamplerParameterfv #define glSamplerParameterIiv _al_glSamplerParameterIiv #define glSamplerParameterIuiv _al_glSamplerParameterIuiv #define glGetSamplerParameteriv _al_glGetSamplerParameteriv #define glGetSamplerParameterIiv _al_glGetSamplerParameterIiv #define glGetSamplerParameterfv _al_glGetSamplerParameterfv #define glGetSamplerParameterIfv _al_glGetSamplerParameterIfv #endif #if defined _ALLEGRO_GL_ARB_timer_query #define glQueryCounter _al_glQueryCounter #define glGetQueryObjecti64v _al_glGetQueryObjecti64v #define glGetQueryObjectui64v _al_glGetQueryObjectui64v #endif #if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev #define glVertexP2ui _al_glVertexP2ui #define glVertexP2uiv _al_glVertexP2uiv #define glVertexP3ui _al_glVertexP3ui #define glVertexP3uiv _al_glVertexP3uiv #define glVertexP4ui _al_glVertexP4ui #define glVertexP4uiv _al_glVertexP4uiv #define glTexCoordP1ui _al_glTexCoordP1ui #define glTexCoordP1uiv _al_glTexCoordP1uiv #define glTexCoordP2ui _al_glTexCoordP2ui #define glTexCoordP2uiv _al_glTexCoordP2uiv #define glTexCoordP3ui _al_glTexCoordP3ui #define glTexCoordP3uiv _al_glTexCoordP3uiv #define glTexCoordP4ui _al_glTexCoordP4ui #define glTexCoordP4uiv _al_glTexCoordP4uiv #define glMultiTexCoordP1ui _al_glMultiTexCoordP1ui #define glMultiTexCoordP1uiv _al_glMultiTexCoordP1uiv #define glMultiTexCoordP2ui _al_glMultiTexCoordP2ui #define glMultiTexCoordP2uiv _al_glMultiTexCoordP2uiv #define glMultiTexCoordP3ui _al_glMultiTexCoordP3ui #define glMultiTexCoordP3uiv _al_glMultiTexCoordP3uiv #define glMultiTexCoordP4ui _al_glMultiTexCoordP4ui #define glMultiTexCoordP4uiv _al_glMultiTexCoordP4uiv #define glNormalP3ui _al_glNormalP3ui #define glNormalP3uiv _al_glNormalP3uiv #define glColorP3ui _al_glColorP3ui #define glColorP3uiv _al_glColorP3uiv #define glColorP4ui _al_glColorP4ui #define glColorP4uiv _al_glColorP4uiv #define glSecondaryColorP3ui _al_glSecondaryColorP3ui #define glSecondaryColorP3uiv _al_glSecondaryColorP3uiv #define glVertexAttribP1ui _al_glVertexAttribP1ui #define glVertexAttribP1uiv _al_glVertexAttribP1uiv #define glVertexAttribP2ui _al_glVertexAttribP2ui #define glVertexAttribP2uiv _al_glVertexAttribP2uiv #define glVertexAttribP3ui _al_glVertexAttribP3ui #define glVertexAttribP3uiv _al_glVertexAttribP3uiv #define glVertexAttribP4ui _al_glVertexAttribP4ui #define glVertexAttribP4uiv _al_glVertexAttribP4uiv #endif #if defined _ALLEGRO_GL_ARB_draw_indirect #define glDrawArraysIndirect _al_glDrawArraysIndirect #define glDrawElementsIndirect _al_glDrawElementsIndirect #endif #if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 #define glUniform1d _al_glUniform1d #define glUniform2d _al_glUniform2d #define glUniform3d _al_glUniform3d #define glUniform4d _al_glUniform4d #define glUniform1dv _al_glUniform1dv #define glUniform2dv _al_glUniform2dv #define glUniform3dv _al_glUniform3dv #define glUniform4dv _al_glUniform4dv #define glUniformMatrix2dv _al_glUniformMatrix2dv #define glUniformMatrix3dv _al_glUniformMatrix3dv #define glUniformMatrix4dv _al_glUniformMatrix4dv #define glUniformMatrix2x3dv _al_glUniformMatrix2x3dv #define glUniformMatrix2x4dv _al_glUniformMatrix2x4dv #define glUniformMatrix3x2dv _al_glUniformMatrix3x2dv #define glUniformMatrix3x4dv _al_glUniformMatrix3x4dv #define glUniformMatrix4x2dv _al_glUniformMatrix4x2dv #define glUniformMatrix4x3dv _al_glUniformMatrix4x3dv #define glGetUniformdv _al_glGetUniformdv #define glProgramUniform1dEXT _al_glProgramUniform1dEXT #define glProgramUniform2dEXT _al_glProgramUniform2dEXT #define glProgramUniform3dEXT _al_glProgramUniform3dEXT #define glProgramUniform4dEXT _al_glProgramUniform4dEXT #define glProgramUniform1dvEXT _al_glProgramUniform1dvEXT #define glProgramUniform2dvEXT _al_glProgramUniform2dvEXT #define glProgramUniform3dvEXT _al_glProgramUniform3dvEXT #define glProgramUniform4dvEXT _al_glProgramUniform4dvEXT #define glProgramUniformMatrix2dvEXT _al_glProgramUniformMatrix2dvEXT #define glProgramUniformMatrix3dvEXT _al_glProgramUniformMatrix3dvEXT #define glProgramUniformMatrix4dvEXT _al_glProgramUniformMatrix4dvEXT #define glProgramUniformMatrix2x3dvEXT _al_glProgramUniformMatrix2x3dvEXT #define glProgramUniformMatrix2x4dvEXT _al_glProgramUniformMatrix2x4dvEXT #define glProgramUniformMatrix3x2dvEXT _al_glProgramUniformMatrix3x2dvEXT #define glProgramUniformMatrix3x4dvEXT _al_glProgramUniformMatrix3x4dvEXT #define glProgramUniformMatrix4x2dvEXT _al_glProgramUniformMatrix4x2dvEXT #define glProgramUniformMatrix4x3dvEXT _al_glProgramUniformMatrix4x3dvEXT #endif #if defined _ALLEGRO_GL_ARB_shader_subroutine #define glGetSubroutineUniformLocation _al_glGetSubroutineUniformLocation #define glGetSubroutineIndex _al_glGetSubroutineIndex #define glGetActiveSubroutineUniformiv _al_glGetActiveSubroutineUniformiv #define glGetActiveSubroutineUniformName _al_glGetActiveSubroutineUniformName #define glGetActiveSubroutineName _al_glGetActiveSubroutineName #define glUniformSubroutinesuiv _al_glUniformSubroutinesuiv #define glGetUniformSubroutineuiv _al_glGetUniformSubroutineuiv #define glGetProgramStageiv _al_glGetProgramStageiv #endif #if defined _ALLEGRO_GL_ARB_tessellation_shader #define glPatchParameteri _al_glPatchParameteri #define glPatchParameterfv _al_glPatchParameterfv #endif #if defined _ALLEGRO_GL_ARB_transform_feedback2 #define glBindTransformFeedback _al_glBindTransformFeedback #define glDeleteTransformFeedbacks _al_glDeleteTransformFeedbacks #define glGenTransformFeedbacks _al_glGenTransformFeedbacks #define glIsTransformFeedback _al_glIsTransformFeedback #define glPauseTransformFeedback _al_glPauseTransformFeedback #define glResumeTransformFeedback _al_glResumeTransformFeedback #define glDrawTransformFeedback _al_glDrawTransformFeedback #endif #if defined _ALLEGRO_GL_ARB_transform_feedback3 #define glDrawTransformFeedbackStream _al_glDrawTransformFeedbackStream #define glBeginQueryIndexed _al_glBeginQueryIndexed #define glEndQueryIndexed _al_glEndQueryIndexed #define glGetQueryIndexediv _al_glGetQueryIndexediv #endif /**/ #if defined _ALLEGRO_GL_EXT_blend_color #define glBlendColorEXT _al_glBlendColorEXT #endif #if defined _ALLEGRO_GL_EXT_polygon_offset #define glPolygonOffsetEXT _al_glPolygonOffsetEXT #endif #if defined _ALLEGRO_GL_EXT_texture3D #define glTexImage3DEXT _al_glTexImage3DEXT #define glTexSubImage3DEXT _al_glTexSubImage3DEXT #endif #if defined _ALLEGRO_GL_SGIS_texture_filter4 #define glGetTexFilterFuncSGIS _al_glGetTexFilterFuncSGIS #define glTexFilterFuncSGIS _al_glTexFilterFuncSGIS #endif #if defined _ALLEGRO_GL_EXT_subtexture #define glTexSubImage1DEXT _al_glTexSubImage1DEXT #define glTexSubImage2DEXT _al_glTexSubImage2DEXT #endif #if defined _ALLEGRO_GL_EXT_copy_texture #define glCopyTexImage1DEXT _al_glCopyTexImage1DEXT #define glCopyTexImage2DEXT _al_glCopyTexImage2DEXT #define glCopyTexSubImage1DEXT _al_glCopyTexSubImage1DEXT #define glCopyTexSubImage2DEXT _al_glCopyTexSubImage2DEXT #define glCopyTexSubImage3DEXT _al_glCopyTexSubImage3DEXT #endif #if defined _ALLEGRO_GL_EXT_histogram #define glGetHistogramEXT _al_glGetHistogramEXT #define glGetHistogramParameterfvEXT _al_glGetHistogramParameterfvEXT #define glGetHistogramParameterivEXT _al_glGetHistogramParameterivEXT #define glGetMinmaxEXT _al_glGetMinmaxEXT #define glGetMinmaxParameterfvEXT _al_glGetMinmaxParameterfvEXT #define glGetMinmaxParameterivEXT _al_glGetMinmaxParameterivEXT #define glHistogramEXT _al_glHistogramEXT #define glMinmaxEXT _al_glMinmaxEXT #define glResetHistogramEXT _al_glResetHistogramEXT #define glResetMinmaxEXT _al_glResetMinmaxEXT #endif #if defined _ALLEGRO_GL_EXT_convolution #define glConvolutionFilter1DEXT _al_glConvolutionFilter1DEXT #define glConvolutionFilter2DEXT _al_glConvolutionFilter2DEXT #define glConvolutionParameterfEXT _al_glConvolutionParameterfEXT #define glConvolutionParameterfvEXT _al_glConvolutionParameterfvEXT #define glConvolutionParameteriEXT _al_glConvolutionParameteriEXT #define glConvolutionParameterivEXT _al_glConvolutionParameterivEXT #define glCopyConvolutionFilter1DEXT _al_glCopyConvolutionFilter1DEXT #define glCopyConvolutionFilter2DEXT _al_glCopyConvolutionFilter2DEXT #define glGetConvolutionFilterEXT _al_glGetConvolutionFilterEXT #define glGetConvolutionParameterfvEXT _al_glGetConvolutionParameterfvEXT #define glGetConvolutionParameterivEXT _al_glGetConvolutionParameterivEXT #define glGetSeparableFilterEXT _al_glGetSeparableFilterEXT #define glSeparableFilter2DEXT _al_glSeparableFilter2DEXT #endif #if defined _ALLEGRO_GL_SGI_color_table #define glColorTableSGI _al_glColorTableSGI #define glColorTableParameterfvSGI _al_glColorTableParameterfvSGI #define glColorTableParameterivSGI _al_glColorTableParameterivSGI #define glCopyColorTableSGI _al_glCopyColorTableSGI #define glGetColorTableSGI _al_glGetColorTableSGI #define glGetColorTableParameterfvSGI _al_glGetColorTableParameterfvSGI #define glGetColorTableParameterivSGI _al_glGetColorTableParameterivSGI #endif #if defined _ALLEGRO_GL_SGIX_pixel_texture #define glPixelTexGenSGIX _al_glPixelTexGenSGIX #endif #if defined _ALLEGRO_GL_SGIS_pixel_texture #define glPixelTexGenParameteriSGIS _al_glPixelTexGenParameteriSGIS #define glPixelTexGenParameterivSGIS _al_glPixelTexGenParameterivSGIS #define glPixelTexGenParameterfSGIS _al_glPixelTexGenParameterfSGIS #define glPixelTexGenParameterfvSGIS _al_glPixelTexGenParameterfvSGIS #define glGetPixelTexGenParameterivSGIS _al_glGetPixelTexGenParameterivSGIS #define glGetPixelTexGenParameterfvSGIS _al_glGetPixelTexGenParameterfvSGIS #endif #if defined _ALLEGRO_GL_SGIS_texture4D #define glTexImage4DSGIS _al_glTexImage4DSGIS #define glTexSubImage4DSGIS _al_glTexSubImage4DSGIS #endif #if defined _ALLEGRO_GL_EXT_texture_object #define glAreTexturesResidentEXT _al_glAreTexturesResidentEXT #define glBindTextureEXT _al_glBindTextureEXT #define glDeleteTexturesEXT _al_glDeleteTexturesEXT #define glGenTexturesEXT _al_glGenTexturesEXT #define glIsTextureEXT _al_glIsTextureEXT #define glPrioritizeTexturesEXT _al_glPrioritizeTexturesEXT #endif #if defined _ALLEGRO_GL_SGIS_detail_texture #define glDetailTexFuncSGIS _al_glDetailTexFuncSGIS #define glGetDetailTexFuncSGIS _al_glGetDetailTexFuncSGIS #endif #if defined _ALLEGRO_GL_SGIS_sharpen_texture #define glSharpenTexFuncSGIS _al_glSharpenTexFuncSGIS #define glGetSharpenTexFuncSGIS _al_glGetSharpenTexFuncSGIS #endif #if defined _ALLEGRO_GL_SGIS_multisample #define glSampleMaskSGIS _al_glSampleMaskSGIS #define glSamplePatternSGIS _al_glSamplePatternSGIS #endif #if defined _ALLEGRO_GL_EXT_vertex_array #define glArrayElementEXT _al_glArrayElementEXT #define glColorPointerEXT _al_glColorPointerEXT #define glDrawArraysEXT _al_glDrawArraysEXT #define glEdgeFlagPointerEXT _al_glEdgeFlagPointerEXT #define glGetPointervEXT _al_glGetPointervEXT #define glIndexPointerEXT _al_glIndexPointerEXT #define glNormalPointerEXT _al_glNormalPointerEXT #define glTexCoordPointerEXT _al_glTexCoordPointerEXT #define glVertexPointerEXT _al_glVertexPointerEXT #endif #if defined _ALLEGRO_GL_EXT_blend_minmax #define glBlendEquationEXT _al_glBlendEquationEXT #endif #if defined _ALLEGRO_GL_SGIX_sprite #define glSpriteParameterfSGIX _al_glSpriteParameterfSGIX #define glSpriteParameterfvSGIX _al_glSpriteParameterfvSGIX #define glSpriteParameteriSGIX _al_glSpriteParameteriSGIX #define glSpriteParameterivSGIX _al_glSpriteParameterivSGIX #endif #if defined _ALLEGRO_GL_EXT_point_parameters #define glPointParameterfEXT _al_glPointParameterfEXT #define glPointParameterfvEXT _al_glPointParameterfvEXT #endif #if defined _ALLEGRO_GL_SGIS_point_parameters #define glPointParameterfSGIS _al_glPointParameterfSGIS #define glPointParameterfvSGIS _al_glPointParameterfvSGIS #endif #if defined _ALLEGRO_GL_SGIX_instruments #define glGetInstrumentsSGIX _al_glGetInstrumentsSGIX #define glInstrumentsBufferSGIX _al_glInstrumentsBufferSGIX #define glPollInstrumentsSGIX _al_glPollInstrumentsSGIX #define glReadInstrumentsSGIX _al_glReadInstrumentsSGIX #define glStartInstrumentsSGIX _al_glStartInstrumentsSGIX #define glStopInstrumentsSGIX _al_glStopInstrumentsSGIX #endif #if defined _ALLEGRO_GL_SGIX_framezoom #define glFrameZoomSGIX _al_glFrameZoomSGIX #endif #if defined _ALLEGRO_GL_SGIX_tag_sample_buffer #define glTagSampleBufferSGIX _al_glTagSampleBufferSGIX #endif #if defined _ALLEGRO_GL_SGIX_polynomial_ffd #define glDeformationMap3dSGIX _al_glDeformationMap3dSGIX #define glDeformationMap3fSGIX _al_glDeformationMap3fSGIX #define glDeformSGIX _al_glDeformSGIX #define glLoadIdentityDeformationMapSGIX _al_glLoadIdentityDeformationMapSGIX #endif #if defined _ALLEGRO_GL_SGIX_reference_plane #define glReferencePlaneSGIX _al_glReferencePlaneSGIX #endif #if defined _ALLEGRO_GL_SGIX_flush_raster #define glFlushRasterSGIX _al_glFlushRasterSGIX #endif #if defined _ALLEGRO_GL_SGIS_fog_function #define glFogFuncSGIS _al_glFogFuncSGIS #define glGetFogFuncSGIS _al_glGetFogFuncSGIS #endif #if defined _ALLEGRO_GL_HP_image_transform #define glImageTransformParameteriHP _al_glImageTransformParameteriHP #define glImageTransformParameterfHP _al_glImageTransformParameterfHP #define glImageTransformParameterivHP _al_glImageTransformParameterivHP #define glImageTransformParameterfvHP _al_glImageTransformParameterfvHP #define glGetImageTransformParameterivHP _al_glGetImageTransformParameterivHP #define glGetImageTransformParameterfvHP _al_glGetImageTransformParameterfvHP #endif #if defined _ALLEGRO_GL_EXT_color_subtable #ifndef GL_EXT_paletted_texture #define glColorSubTableEXT _al_glColorSubTableEXT #endif #define glCopyColorSubTableEXT _al_glCopyColorSubTableEXT #endif #if defined _ALLEGRO_GL_PGI_misc_hints #define glHintPGI _al_glHintPGI #endif #if defined _ALLEGRO_GL_EXT_paletted_texture #define glColorTableEXT _al_glColorTableEXT #define glGetColorTableEXT _al_glGetColorTableEXT #define glGetColorTableParameterivEXT _al_glGetColorTableParameterivEXT #define glGetColorTableParameterfvEXT _al_glGetColorTableParameterfvEXT #endif #if defined _ALLEGRO_GL_SGIX_list_priority #define glGetListParameterfvSGIX _al_glGetListParameterfvSGIX #define glGetListParameterivSGIX _al_glGetListParameterivSGIX #define glListParameterfSGIX _al_glListParameterfSGIX #define glListParameterfvSGIX _al_glListParameterfvSGIX #define glListParameteriSGIX _al_glListParameteriSGIX #define glListParameterivSGIX _al_glListParameterivSGIX #endif #if defined _ALLEGRO_GL_EXT_index_material #define glIndexMaterialEXT _al_glIndexMaterialEXT #endif #if defined _ALLEGRO_GL_EXT_index_func #define glIndexFuncEXT _al_glIndexFuncEXT #endif #if defined _ALLEGRO_GL_EXT_compiled_vertex_array #define glLockArraysEXT _al_glLockArraysEXT #define glUnlockArraysEXT _al_glUnlockArraysEXT #endif #if defined _ALLEGRO_GL_EXT_cull_vertex #define glCullParameterdvEXT _al_glCullParameterdvEXT #define glCullParameterfvEXT _al_glCullParameterfvEXT #endif #if defined _ALLEGRO_GL_SGIX_fragment_lighting #define glFragmentColorMaterialSGIX _al_glFragmentColorMaterialSGIX #define glFragmentLightfSGIX _al_glFragmentLightfSGIX #define glFragmentLightfvSGIX _al_glFragmentLightfvSGIX #define glFragmentLightiSGIX _al_glFragmentLightiSGIX #define glFragmentLightivSGIX _al_glFragmentLightivSGIX #define glFragmentLightModelfSGIX _al_glFragmentLightModelfSGIX #define glFragmentLightModelfvSGIX _al_glFragmentLightModelfvSGIX #define glFragmentLightModeliSGIX _al_glFragmentLightModeliSGIX #define glFragmentLightModelivSGIX _al_glFragmentLightModelivSGIX #define glFragmentMaterialfSGIX _al_glFragmentMaterialfSGIX #define glFragmentMaterialfvSGIX _al_glFragmentMaterialfvSGIX #define glFragmentMaterialiSGIX _al_glFragmentMaterialiSGIX #define glFragmentMaterialivSGIX _al_glFragmentMaterialivSGIX #define glGetFragmentLightfvSGIX _al_glGetFragmentLightfvSGIX #define glGetFragmentLightivSGIX _al_glGetFragmentLightivSGIX #define glGetFragmentMaterialfvSGIX _al_glGetFragmentMaterialfvSGIX #define glGetFragmentMaterialivSGIX _al_glGetFragmentMaterialivSGIX #define glLightEnviSGIX _al_glLightEnviSGIX #endif #if defined _ALLEGRO_GL_EXT_draw_range_elements #define glDrawRangeElementsEXT _al_glDrawRangeElementsEXT #endif #if defined _ALLEGRO_GL_EXT_light_texture #define glApplyTextureEXT _al_glApplyTextureEXT #define glTextureLightEXT _al_glTextureLightEXT #define glTextureMaterialEXT _al_glTextureMaterialEXT #endif #if defined _ALLEGRO_GL_SGIX_async #define glAsyncMarkerSGIX _al_glAsyncMarkerSGIX #define glFinishAsyncSGIX _al_glFinishAsyncSGIX #define glPollAsyncSGIX _al_glPollAsyncSGIX #define glGenAsyncMarkersSGIX _al_glGenAsyncMarkersSGIX #define glDeleteAsyncMarkersSGIX _al_glDeleteAsyncMarkersSGIX #define glIsAsyncMarkerSGIX _al_glIsAsyncMarkerSGIX #endif #if defined _ALLEGRO_GL_INTEL_parallel_arrays #define glVertexPointervINTEL _al_glVertexPointervINTEL #define glNormalPointervINTEL _al_glNormalPointervINTEL #define glColorPointervINTEL _al_glColorPointervINTEL #define glTexCoordPointervINTEL _al_glTexCoordPointervINTEL #endif #if defined _ALLEGRO_GL_EXT_pixel_transform #define glPixelTransformParameteriEXT _al_glPixelTransformParameteriEXT #define glPixelTransformParameterfEXT _al_glPixelTransformParameterfEXT #define glPixelTransformParameterivEXT _al_glPixelTransformParameterivEXT #define glPixelTransformParameterfvEXT _al_glPixelTransformParameterfvEXT #endif #if defined _ALLEGRO_GL_EXT_secondary_color #define glSecondaryColor3bEXT _al_glSecondaryColor3bEXT #define glSecondaryColor3bvEXT _al_glSecondaryColor3bvEXT #define glSecondaryColor3dEXT _al_glSecondaryColor3dEXT #define glSecondaryColor3dvEXT _al_glSecondaryColor3dvEXT #define glSecondaryColor3fEXT _al_glSecondaryColor3fEXT #define glSecondaryColor3fvEXT _al_glSecondaryColor3fvEXT #define glSecondaryColor3iEXT _al_glSecondaryColor3iEXT #define glSecondaryColor3ivEXT _al_glSecondaryColor3ivEXT #define glSecondaryColor3sEXT _al_glSecondaryColor3sEXT #define glSecondaryColor3svEXT _al_glSecondaryColor3svEXT #define glSecondaryColor3ubEXT _al_glSecondaryColor3ubEXT #define glSecondaryColor3ubvEXT _al_glSecondaryColor3ubvEXT #define glSecondaryColor3uiEXT _al_glSecondaryColor3uiEXT #define glSecondaryColor3uivEXT _al_glSecondaryColor3uivEXT #define glSecondaryColor3usEXT _al_glSecondaryColor3usEXT #define glSecondaryColor3usvEXT _al_glSecondaryColor3usvEXT #define glSecondaryColorPointerEXT _al_glSecondaryColorPointerEXT #endif #if defined _ALLEGRO_GL_EXT_texture_perturb_normal #define glTextureNormalEXT _al_glTextureNormalEXT #endif #if defined _ALLEGRO_GL_EXT_multi_draw_arrays #define glMultiDrawArraysEXT _al_glMultiDrawArraysEXT #define glMultiDrawElementsEXT _al_glMultiDrawElementsEXT #endif #if defined _ALLEGRO_GL_EXT_fog_coord #define glFogCoordfEXT _al_glFogCoordfEXT #define glFogCoordfvEXT _al_glFogCoordfvEXT #define glFogCoorddEXT _al_glFogCoorddEXT #define glFogCoorddvEXT _al_glFogCoorddvEXT #define glFogCoordPointerEXT _al_glFogCoordPointerEXT #endif #if defined _ALLEGRO_GL_EXT_coordinate_frame #define glTangent3bEXT _al_glTangent3bEXT #define glTangent3bvEXT _al_glTangent3bvEXT #define glTangent3dEXT _al_glTangent3dEXT #define glTangent3dvEXT _al_glTangent3dvEXT #define glTangent3fEXT _al_glTangent3fEXT #define glTangent3fvEXT _al_glTangent3fvEXT #define glTangent3iEXT _al_glTangent3iEXT #define glTangent3ivEXT _al_glTangent3ivEXT #define glTangent3sEXT _al_glTangent3sEXT #define glTangent3svEXT _al_glTangent3svEXT #define glBinormal3bEXT _al_glBinormal3bEXT #define glBinormal3bvEXT _al_glBinormal3bvEXT #define glBinormal3dEXT _al_glBinormal3dEXT #define glBinormal3dvEXT _al_glBinormal3dvEXT #define glBinormal3fEXT _al_glBinormal3fEXT #define glBinormal3fvEXT _al_glBinormal3fvEXT #define glBinormal3iEXT _al_glBinormal3iEXT #define glBinormal3ivEXT _al_glBinormal3ivEXT #define glBinormal3sEXT _al_glBinormal3sEXT #define glBinormal3svEXT _al_glBinormal3svEXT #define glTangentPointerEXT _al_glTangentPointerEXT #define glBinormalPointerEXT _al_glBinormalPointerEXT #endif #if defined _ALLEGRO_GL_SUNX_constant_data #define glFinishTextureSUNX _al_glFinishTextureSUNX #endif #if defined _ALLEGRO_GL_SUN_global_alpha #define glGlobalAlphaFactorbSUN _al_glGlobalAlphaFactorbSUN #define glGlobalAlphaFactorsSUN _al_glGlobalAlphaFactorsSUN #define glGlobalAlphaFactoriSUN _al_glGlobalAlphaFactoriSUN #define glGlobalAlphaFactorfSUN _al_glGlobalAlphaFactorfSUN #define glGlobalAlphaFactordSUN _al_glGlobalAlphaFactordSUN #define glGlobalAlphaFactorubSUN _al_glGlobalAlphaFactorubSUN #define glGlobalAlphaFactorusSUN _al_glGlobalAlphaFactorusSUN #define glGlobalAlphaFactoruiSUN _al_glGlobalAlphaFactoruiSUN #endif #if defined _ALLEGRO_GL_SUN_triangle_list #define glReplacementCodeuiSUN _al_glReplacementCodeuiSUN #define glReplacementCodeusSUN _al_glReplacementCodeusSUN #define glReplacementCodeubSUN _al_glReplacementCodeubSUN #define glReplacementCodeuivSUN _al_glReplacementCodeuivSUN #define glReplacementCodeusvSUN _al_glReplacementCodeusvSUN #define glReplacementCodeubvSUN _al_glReplacementCodeubvSUN #define glReplacementCodePointerSUN _al_glReplacementCodePointerSUN #endif #if defined _ALLEGRO_GL_SUN_vertex #define glColor4ubVertex2fSUN _al_glColor4ubVertex2fSUN #define glColor4ubVertex2fvSUN _al_glColor4ubVertex2fvSUN #define glColor4ubVertex3fSUN _al_glColor4ubVertex3fSUN #define glColor4ubVertex3fvSUN _al_glColor4ubVertex3fvSUN #define glColor3fVertex3fSUN _al_glColor3fVertex3fSUN #define glColor3fVertex3fvSUN _al_glColor3fVertex3fvSUN #define glNormal3fVertex3fSUN _al_glNormal3fVertex3fSUN #define glNormal3fVertex3fvSUN _al_glNormal3fVertex3fvSUN #define glColor4fNormal3fVertex3fSUN _al_glColor4fNormal3fVertex3fSUN #define glColor4fNormal3fVertex3fvSUN _al_glColor4fNormal3fVertex3fvSUN #define glTexCoord2fVertex3fSUN _al_glTexCoord2fVertex3fSUN #define glTexCoord2fVertex3fvSUN _al_glTexCoord2fVertex3fvSUN #define glTexCoord4fVertex4fSUN _al_glTexCoord4fVertex4fSUN #define glTexCoord4fVertex4fvSUN _al_glTexCoord4fVertex4fvSUN #define glTexCoord2fColor4ubVertex3fSUN _al_glTexCoord2fColor4ubVertex3fSUN #define glTexCoord2fColor4ubVertex3fvSUN _al_glTexCoord2fColor4ubVertex3fvSUN #define glTexCoord2fColor3fVertex3fSUN _al_glTexCoord2fColor3fVertex3fSUN #define glTexCoord2fColor3fVertex3fvSUN _al_glTexCoord2fColor3fVertex3fvSUN #define glTexCoord2fNormal3fVertex3fSUN _al_glTexCoord2fNormal3fVertex3fSUN #define glTexCoord2fNormal3fVertex3fvSUN _al_glTexCoord2fNormal3fVertex3fvSUN #define glTexCoord2fColor4fNormal3fVertex3fSUN _al_glTexCoord2fColor4fNormal3fVertex3fSUN #define glTexCoord2fColor4fNormal3fVertex3fvSUN _al_glTexCoord2fColor4fNormal3fVertex3fvSUN #define glTexCoord4fColor4fNormal3fVertex4fSUN _al_glTexCoord4fColor4fNormal3fVertex4fSUN #define glTexCoord4fColor4fNormal3fVertex4fvSUN _al_glTexCoord4fColor4fNormal3fVertex4fvSUN #define glReplacementCodeuiVertex3fSUN _al_glReplacementCodeuiVertex3fSUN #define glReplacementCodeuiVertex3fvSUN _al_glReplacementCodeuiVertex3fvSUN #define glReplacementCodeuiColor4ubVertex3fSUN _al_glReplacementCodeuiColor4ubVertex3fSUN #define glReplacementCodeuiColor4ubVertex3fvSUN _al_glReplacementCodeuiColor4ubVertex3fvSUN #define glReplacementCodeuiColor3fVertex3fSUN _al_glReplacementCodeuiColor3fVertex3fSUN #define glReplacementCodeuiColor3fVertex3fvSUN _al_glReplacementCodeuiColor3fVertex3fvSUN #define glReplacementCodeuiNormal3fVertex3fSUN _al_glReplacementCodeuiNormal3fVertex3fSUN #define glReplacementCodeuiNormal3fVertex3fvSUN _al_glReplacementCodeuiNormal3fVertex3fvSUN #define glReplacementCodeuiColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fSUN #define glReplacementCodeuiColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fvSUN #define glReplacementCodeuiTexCoord2fVertex3fSUN _al_glReplacementCodeuiTexCoord2fVertex3fSUN #define glReplacementCodeuiTexCoord2fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fVertex3fvSUN #define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN #define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN #define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN #endif #if defined _ALLEGRO_GL_EXT_blend_func_separate #define glBlendFuncSeparateEXT _al_glBlendFuncSeparateEXT #endif #if defined _ALLEGRO_GL_INGR_blend_func_separate #define glBlendFuncSeparateINGR _al_glBlendFuncSeparateINGR #endif #if defined _ALLEGRO_GL_EXT_vertex_weighting #define glVertexWeightfEXT _al_glVertexWeightfEXT #define glVertexWeightfvEXT _al_glVertexWeightfvEXT #define glVertexWeightPointerEXT _al_glVertexWeightPointerEXT #endif #if defined _ALLEGRO_GL_NV_vertex_array_range #define glFlushVertexArrayRangeNV _al_glFlushVertexArrayRangeNV #define glVertexArrayRangeNV _al_glVertexArrayRangeNV #endif #if defined _ALLEGRO_GL_NV_register_combiners #define glCombinerParameterfvNV _al_glCombinerParameterfvNV #define glCombinerParameterfNV _al_glCombinerParameterfNV #define glCombinerParameterivNV _al_glCombinerParameterivNV #define glCombinerParameteriNV _al_glCombinerParameteriNV #define glCombinerInputNV _al_glCombinerInputNV #define glCombinerOutputNV _al_glCombinerOutputNV #define glFinalCombinerInputNV _al_glFinalCombinerInputNV #define glGetCombinerInputParameterfvNV _al_glGetCombinerInputParameterfvNV #define glGetCombinerInputParameterivNV _al_glGetCombinerInputParameterivNV #define glGetCombinerOutputParameterfvNV _al_glGetCombinerOutputParameterfvNV #define glGetCombinerOutputParameterivNV _al_glGetCombinerOutputParameterivNV #define glGetFinalCombinerInputParameterfvNV _al_glGetFinalCombinerInputParameterfvNV #define glGetFinalCombinerInputParameterivNV _al_glGetFinalCombinerInputParameterivNV #endif #if defined _ALLEGRO_GL_MESA_resize_buffers #define glResizeBuffersMESA _al_glResizeBuffersMESA #endif #if defined _ALLEGRO_GL_MESA_window_pos #define glWindowPos2dMESA _al_glWindowPos2dMESA #define glWindowPos2dvMESA _al_glWindowPos2dvMESA #define glWindowPos2fMESA _al_glWindowPos2fMESA #define glWindowPos2fvMESA _al_glWindowPos2fvMESA #define glWindowPos2iMESA _al_glWindowPos2iMESA #define glWindowPos2ivMESA _al_glWindowPos2ivMESA #define glWindowPos2sMESA _al_glWindowPos2sMESA #define glWindowPos2svMESA _al_glWindowPos2svMESA #define glWindowPos3dMESA _al_glWindowPos3dMESA #define glWindowPos3dvMESA _al_glWindowPos3dvMESA #define glWindowPos3fMESA _al_glWindowPos3fMESA #define glWindowPos3fvMESA _al_glWindowPos3fvMESA #define glWindowPos3iMESA _al_glWindowPos3iMESA #define glWindowPos3ivMESA _al_glWindowPos3ivMESA #define glWindowPos3sMESA _al_glWindowPos3sMESA #define glWindowPos3svMESA _al_glWindowPos3svMESA #define glWindowPos4dMESA _al_glWindowPos4dMESA #define glWindowPos4dvMESA _al_glWindowPos4dvMESA #define glWindowPos4fMESA _al_glWindowPos4fMESA #define glWindowPos4fvMESA _al_glWindowPos4fvMESA #define glWindowPos4iMESA _al_glWindowPos4iMESA #define glWindowPos4ivMESA _al_glWindowPos4ivMESA #define glWindowPos4sMESA _al_glWindowPos4sMESA #define glWindowPos4svMESA _al_glWindowPos4svMESA #endif #if defined _ALLEGRO_GL_IBM_multimode_draw_arrays #define glMultiModeDrawArraysIBM _al_glMultiModeDrawArraysIBM #define glMultiModeDrawElementsIBM _al_glMultiModeDrawElementsIBM #endif #ifdef AGK_IBM_vertex_array_lists #define glColorPointerListIBM _al_glColorPointerListIBM #define glSecondaryColorPointerListIBM _al_glSecondaryColorPointerListIBM #define glEdgeFlagPointerListIBM _al_glEdgeFlagPointerListIBM #define glFogCoordPointerListIBM _al_glFogCoordPointerListIBM #define glIndexPointerListIBM _al_glIndexPointerListIBM #define glNormalPointerListIBM _al_glNormalPointerListIBM #define glTexCoordPointerListIBM _al_glTexCoordPointerListIBM #define glVertexPointerListIBM _al_glVertexPointerListIBM #endif #if defined _ALLEGRO_GL_3DFX_tbuffer #define glTbufferMask3DFX _al_glTbufferMask3DFX #endif #if defined _ALLEGRO_GL_EXT_multisample #define glSampleMaskEXT _al_glSampleMaskEXT #define glSamplePatternEXT _al_glSamplePatternEXT #endif #if defined _ALLEGRO_GL_SGIS_texture_color_mask #define glTextureColorMaskSGIS _al_glTextureColorMaskSGIS #endif #if defined _ALLEGRO_GL_SGIX_igloo_interface #define glIglooInterfaceSGIX _al_glIglooInterfaceSGIX #endif #if defined _ALLEGRO_GL_NV_fence #define glDeleteFencesNV _al_glDeleteFencesNV #define glGenFencesNV _al_glGenFencesNV #define glIsFenceNV _al_glIsFenceNV #define glTestFenceNV _al_glTestFenceNV #define glGetFenceivNV _al_glGetFenceivNV #define glFinishFenceNV _al_glFinishFenceNV #define glSetFenceNV _al_glSetFenceNV #endif #if defined _ALLEGRO_GL_NV_evaluators #define glMapControlPointsNV _al_glMapControlPointsNV #define glMapParameterivNV _al_glMapParameterivNV #define glMapParameterfvNV _al_glMapParameterfvNV #define glGetMapControlPointsNV _al_glGetMapControlPointsNV #define glGetMapParameterivNV _al_glGetMapParameterivNV #define glGetMapParameterfvNV _al_glGetMapParameterfvNV #define glGetMapAttribParameterivNV _al_glGetMapAttribParameterivNV #define glGetMapAttribParameterfvNV _al_glGetMapAttribParameterfvNV #define glEvalMapsNV _al_glEvalMapsNV #endif #if defined _ALLEGRO_GL_NV_register_combiners2 #define glCombinerStageParameterfvNV _al_glCombinerStageParameterfvNV #define glGetCombinerStageParameterfvNV _al_glGetCombinerStageParameterfvNV #endif #if defined _ALLEGRO_GL_NV_vertex_program #define glAreProgramsResidentNV _al_glAreProgramsResidentNV #define glBindProgramNV _al_glBindProgramNV #define glDeleteProgramsNV _al_glDeleteProgramsNV #define glExecuteProgramNV _al_glExecuteProgramNV #define glGenProgramsNV _al_glGenProgramsNV #define glGetProgramParameterdvNV _al_glGetProgramParameterdvNV #define glGetProgramParameterfvNV _al_glGetProgramParameterfvNV #define glGetProgramivNV _al_glGetProgramivNV #define glGetProgramStringNV _al_glGetProgramStringNV #define glGetTrackMatrixivNV _al_glGetTrackMatrixivNV #define glGetVertexAttribdvNV _al_glGetVertexAttribdvNV #define glGetVertexAttribfvNV _al_glGetVertexAttribfvNV #define glGetVertexAttribivNV _al_glGetVertexAttribivNV #define glGetVertexAttribPointervNV _al_glGetVertexAttribPointervNV #define glIsProgramNV _al_glIsProgramNV #define glLoadProgramNV _al_glLoadProgramNV #define glProgramParameter4dNV _al_glProgramParameter4dNV #define glProgramParameter4dvNV _al_glProgramParameter4dvNV #define glProgramParameter4fNV _al_glProgramParameter4fNV #define glProgramParameter4fvNV _al_glProgramParameter4fvNV #define glProgramParameters4dvNV _al_glProgramParameters4dvNV #define glProgramParameters4fvNV _al_glProgramParameters4fvNV #define glRequestResidentProgramsNV _al_glRequestResidentProgramsNV #define glTrackMatrixNV _al_glTrackMatrixNV #define glVertexAttribPointerNV _al_glVertexAttribPointerNV #define glVertexAttrib1dNV _al_glVertexAttrib1dNV #define glVertexAttrib1dvNV _al_glVertexAttrib1dvNV #define glVertexAttrib1fNV _al_glVertexAttrib1fNV #define glVertexAttrib1fvNV _al_glVertexAttrib1fvNV #define glVertexAttrib1sNV _al_glVertexAttrib1sNV #define glVertexAttrib1svNV _al_glVertexAttrib1svNV #define glVertexAttrib2dNV _al_glVertexAttrib2dNV #define glVertexAttrib2dvNV _al_glVertexAttrib2dvNV #define glVertexAttrib2fNV _al_glVertexAttrib2fNV #define glVertexAttrib2fvNV _al_glVertexAttrib2fvNV #define glVertexAttrib2sNV _al_glVertexAttrib2sNV #define glVertexAttrib2svNV _al_glVertexAttrib2svNV #define glVertexAttrib3dNV _al_glVertexAttrib3dNV #define glVertexAttrib3dvNV _al_glVertexAttrib3dvNV #define glVertexAttrib3fNV _al_glVertexAttrib3fNV #define glVertexAttrib3fvNV _al_glVertexAttrib3fvNV #define glVertexAttrib3sNV _al_glVertexAttrib3sNV #define glVertexAttrib3svNV _al_glVertexAttrib3svNV #define glVertexAttrib4dNV _al_glVertexAttrib4dNV #define glVertexAttrib4dvNV _al_glVertexAttrib4dvNV #define glVertexAttrib4fNV _al_glVertexAttrib4fNV #define glVertexAttrib4fvNV _al_glVertexAttrib4fvNV #define glVertexAttrib4sNV _al_glVertexAttrib4sNV #define glVertexAttrib4svNV _al_glVertexAttrib4svNV #define glVertexAttrib4ubNV _al_glVertexAttrib4ubNV #define glVertexAttrib4ubvNV _al_glVertexAttrib4ubvNV #define glVertexAttribs1dvNV _al_glVertexAttribs1dvNV #define glVertexAttribs1fvNV _al_glVertexAttribs1fvNV #define glVertexAttribs1svNV _al_glVertexAttribs1svNV #define glVertexAttribs2dvNV _al_glVertexAttribs2dvNV #define glVertexAttribs2fvNV _al_glVertexAttribs2fvNV #define glVertexAttribs2svNV _al_glVertexAttribs2svNV #define glVertexAttribs3dvNV _al_glVertexAttribs3dvNV #define glVertexAttribs3fvNV _al_glVertexAttribs3fvNV #define glVertexAttribs3svNV _al_glVertexAttribs3svNV #define glVertexAttribs4dvNV _al_glVertexAttribs4dvNV #define glVertexAttribs4fvNV _al_glVertexAttribs4fvNV #define glVertexAttribs4svNV _al_glVertexAttribs4svNV #define glVertexAttribs4ubvNV _al_glVertexAttribs4ubvNV #endif #if defined _ALLEGRO_GL_ATI_envmap_bumpmap #define glTexBumpParameterivATI _al_glTexBumpParameterivATI #define glTexBumpParameterfvATI _al_glTexBumpParameterfvATI #define glGetTexBumpParameterivATI _al_glGetTexBumpParameterivATI #define glGetTexBumpParameterfvATI _al_glGetTexBumpParameterfvATI #endif #if defined _ALLEGRO_GL_ATI_fragment_shader #define glGenFragmentShadersATI _al_glGenFragmentShadersATI #define glBindFragmentShaderATI _al_glBindFragmentShaderATI #define glDeleteFragmentShaderATI _al_glDeleteFragmentShaderATI #define glBeginFragmentShaderATI _al_glBeginFragmentShaderATI #define glEndFragmentShaderATI _al_glEndFragmentShaderATI #define glPassTexCoordATI _al_glPassTexCoordATI #define glSampleMapATI _al_glSampleMapATI #define glColorFragmentOp1ATI _al_glColorFragmentOp1ATI #define glColorFragmentOp2ATI _al_glColorFragmentOp2ATI #define glColorFragmentOp3ATI _al_glColorFragmentOp3ATI #define glAlphaFragmentOp1ATI _al_glAlphaFragmentOp1ATI #define glAlphaFragmentOp2ATI _al_glAlphaFragmentOp2ATI #define glAlphaFragmentOp3ATI _al_glAlphaFragmentOp3ATI #define glSetFragmentShaderConstantATI _al_glSetFragmentShaderConstantATI #endif #if defined _ALLEGRO_GL_ATI_pn_triangles #define glPNTrianglesiATI _al_glPNTrianglesiATI #define glPNTrianglesfATI _al_glPNTrianglesfATI #endif #if defined _ALLEGRO_GL_ATI_vertex_array_object #define glNewObjectBufferATI _al_glNewObjectBufferATI #define glIsObjectBufferATI _al_glIsObjectBufferATI #define glUpdateObjectBufferATI _al_glUpdateObjectBufferATI #define glGetObjectBufferfvATI _al_glGetObjectBufferfvATI #define glGetObjectBufferivATI _al_glGetObjectBufferivATI #define glFreeObjectBufferATI _al_glFreeObjectBufferATI #define glArrayObjectATI _al_glArrayObjectATI #define glGetArrayObjectfvATI _al_glGetArrayObjectfvATI #define glGetArrayObjectivATI _al_glGetArrayObjectivATI #define glVariantArrayObjectATI _al_glVariantArrayObjectATI #define glGetVariantArrayObjectfvATI _al_glGetVariantArrayObjectfvATI #define glGetVariantArrayObjectivATI _al_glGetVariantArrayObjectivATI #endif #if defined _ALLEGRO_GL_EXT_vertex_shader #define glBeginVertexShaderEXT _al_glBeginVertexShaderEXT #define glEndVertexShaderEXT _al_glEndVertexShaderEXT #define glBindVertexShaderEXT _al_glBindVertexShaderEXT #define glGenVertexShadersEXT _al_glGenVertexShadersEXT #define glDeleteVertexShaderEXT _al_glDeleteVertexShaderEXT #define glShaderOp1EXT _al_glShaderOp1EXT #define glShaderOp2EXT _al_glShaderOp2EXT #define glShaderOp3EXT _al_glShaderOp3EXT #define glSwizzleEXT _al_glSwizzleEXT #define glWriteMaskEXT _al_glWriteMaskEXT #define glInsertComponentEXT _al_glInsertComponentEXT #define glExtractComponentEXT _al_glExtractComponentEXT #define glGenSymbolsEXT _al_glGenSymbolsEXT #define glSetInvariantEXT _al_glSetInvariantEXT #define glSetLocalConstantEXT _al_glSetLocalConstantEXT #define glVariantbvEXT _al_glVariantbvEXT #define glVariantsvEXT _al_glVariantsvEXT #define glVariantivEXT _al_glVariantivEXT #define glVariantfvEXT _al_glVariantfvEXT #define glVariantdvEXT _al_glVariantdvEXT #define glVariantubvEXT _al_glVariantubvEXT #define glVariantusvEXT _al_glVariantusvEXT #define glVariantuivEXT _al_glVariantuivEXT #define glVariantPointerEXT _al_glVariantPointerEXT #define glEnableVariantClientStateEXT _al_glEnableVariantClientStateEXT #define glDisableVariantClientStateEXT _al_glDisableVariantClientStateEXT #define glBindLightParameterEXT _al_glBindLightParameterEXT #define glBindMaterialParameterEXT _al_glBindMaterialParameterEXT #define glBindTexGenParameterEXT _al_glBindTexGenParameterEXT #define glBindTextureUnitParameterEXT _al_glBindTextureUnitParameterEXT #define glBindParameterEXT _al_glBindParameterEXT #define glIsVariantEnabledEXT _al_glIsVariantEnabledEXT #define glGetVariantBooleanvEXT _al_glGetVariantBooleanvEXT #define glGetVariantIntegervEXT _al_glGetVariantIntegervEXT #define glGetVariantFloatvEXT _al_glGetVariantFloatvEXT #define glGetVariantPointervEXT _al_glGetVariantPointervEXT #define glGetInvariantBooleanvEXT _al_glGetInvariantBooleanvEXT #define glGetInvariantIntegervEXT _al_glGetInvariantIntegervEXT #define glGetInvariantFloatvEXT _al_glGetInvariantFloatvEXT #define glGetLocalConstantBooleanvEXT _al_glGetLocalConstantBooleanvEXT #define glGetLocalConstantIntegervEXT _al_glGetLocalConstantIntegervEXT #define glGetLocalConstantFloatvEXT _al_glGetLocalConstantFloatvEXT #endif #if defined _ALLEGRO_GL_ATI_vertex_streams #define glVertexStream1sATI _al_glVertexStream1sATI #define glVertexStream1svATI _al_glVertexStream1svATI #define glVertexStream1iATI _al_glVertexStream1iATI #define glVertexStream1ivATI _al_glVertexStream1ivATI #define glVertexStream1fATI _al_glVertexStream1fATI #define glVertexStream1fvATI _al_glVertexStream1fvATI #define glVertexStream1dATI _al_glVertexStream1dATI #define glVertexStream1dvATI _al_glVertexStream1dvATI #define glVertexStream2sATI _al_glVertexStream2sATI #define glVertexStream2svATI _al_glVertexStream2svATI #define glVertexStream2iATI _al_glVertexStream2iATI #define glVertexStream2ivATI _al_glVertexStream2ivATI #define glVertexStream2fATI _al_glVertexStream2fATI #define glVertexStream2fvATI _al_glVertexStream2fvATI #define glVertexStream2dATI _al_glVertexStream2dATI #define glVertexStream2dvATI _al_glVertexStream2dvATI #define glVertexStream3sATI _al_glVertexStream3sATI #define glVertexStream3svATI _al_glVertexStream3svATI #define glVertexStream3iATI _al_glVertexStream3iATI #define glVertexStream3ivATI _al_glVertexStream3ivATI #define glVertexStream3fATI _al_glVertexStream3fATI #define glVertexStream3fvATI _al_glVertexStream3fvATI #define glVertexStream3dATI _al_glVertexStream3dATI #define glVertexStream3dvATI _al_glVertexStream3dvATI #define glVertexStream4sATI _al_glVertexStream4sATI #define glVertexStream4svATI _al_glVertexStream4svATI #define glVertexStream4iATI _al_glVertexStream4iATI #define glVertexStream4ivATI _al_glVertexStream4ivATI #define glVertexStream4fATI _al_glVertexStream4fATI #define glVertexStream4fvATI _al_glVertexStream4fvATI #define glVertexStream4dATI _al_glVertexStream4dATI #define glVertexStream4dvATI _al_glVertexStream4dvATI #define glNormalStream3bATI _al_glNormalStream3bATI #define glNormalStream3bvATI _al_glNormalStream3bvATI #define glNormalStream3sATI _al_glNormalStream3sATI #define glNormalStream3svATI _al_glNormalStream3svATI #define glNormalStream3iATI _al_glNormalStream3iATI #define glNormalStream3ivATI _al_glNormalStream3ivATI #define glNormalStream3fATI _al_glNormalStream3fATI #define glNormalStream3fvATI _al_glNormalStream3fvATI #define glNormalStream3dATI _al_glNormalStream3dATI #define glNormalStream3dvATI _al_glNormalStream3dvATI #define glClientActiveVertexStreamATI _al_glClientActiveVertexStreamATI #define glVertexBlendEnviATI _al_glVertexBlendEnviATI #define glVertexBlendEnvfATI _al_glVertexBlendEnvfATI #endif #if defined _ALLEGRO_GL_ATI_element_array #define glElementPointerATI _al_glElementPointerATI #define glDrawElementArrayATI _al_glDrawElementArrayATI #define glDrawRangeElementArrayATI _al_glDrawRangeElementArrayATI #endif #if defined _ALLEGRO_GL_SUN_mesh_array #define glDrawMeshArraysSUN _al_glDrawMeshArraysSUN #endif #if defined _ALLEGRO_GL_NV_occlusion_query #define glGenOcclusionQueriesNV _al_glGenOcclusionQueriesNV #define glDeleteOcclusionQueriesNV _al_glDeleteOcclusionQueriesNV #define glIsOcclusionQueryNV _al_glIsOcclusionQueryNV #define glBeginOcclusionQueryNV _al_glBeginOcclusionQueryNV #define glEndOcclusionQueryNV _al_glEndOcclusionQueryNV #define glGetOcclusionQueryivNV _al_glGetOcclusionQueryivNV #define glGetOcclusionQueryuivNV _al_glGetOcclusionQueryuivNV #endif #if defined _ALLEGRO_GL_NV_point_sprite #define glPointParameteriNV _al_glPointParameteriNV #define glPointParameterivNV _al_glPointParameterivNV #endif #if defined _ALLEGRO_GL_EXT_stencil_two_side #define glActiveStencilFaceEXT _al_glActiveStencilFaceEXT #endif #if defined _ALLEGRO_GL_APPLE_element_array #define glElementPointerAPPLE _al_glElementPointerAPPLE #define glDrawElementArrayAPPLE _al_glDrawElementArrayAPPLE #define glDrawRangeElementArrayAPPLE _al_glDrawRangeElementArrayAPPLE #define glMultiDrawElementArrayAPPLE _al_glMultiDrawElementArrayAPPLE #define glMultiDrawRangeElementArrayAPPLE _al_glMultiDrawRangeElementArrayAPPLE #endif #if defined _ALLEGRO_GL_APPLE_fence #define glGenFencesAPPLE _al_glGenFencesAPPLE #define glDeleteFencesAPPLE _al_glDeleteFencesAPPLE #define glSetFenceAPPLE _al_glSetFenceAPPLE #define glIsFenceAPPLE _al_glIsFenceAPPLE #define glTestFenceAPPLE _al_glTestFenceAPPLE #define glFinishFenceAPPLE _al_glFinishFenceAPPLE #define glTestObjectAPPLE _al_glTestObjectAPPLE #define glFinishObjectAPPLE _al_glFinishObjectAPPLE #endif #if defined _ALLEGRO_GL_APPLE_vertex_array_object #define glBindVertexArrayAPPLE _al_glBindVertexArrayAPPLE #define glDeleteVertexArraysAPPLE _al_glDeleteVertexArraysAPPLE #define glGenVertexArraysAPPLE _al_glGenVertexArraysAPPLE #define glIsVertexArrayAPPLE _al_glIsVertexArrayAPPLE #endif #if defined _ALLEGRO_GL_APPLE_vertex_array_range #define glVertexArrayRangeAPPLE _al_glVertexArrayRangeAPPLE #define glFlushVertexArrayRangeAPPLE _al_glFlushVertexArrayRangeAPPLE #define glVertexArrayParameteriAPPLE _al_glVertexArrayParameteriAPPLE #endif #if defined _ALLEGRO_GL_ATI_draw_buffers #define glDrawBuffersATI _al_glDrawBuffersATI #endif #if defined _ALLEGRO_GL_NV_fragment_program #define glProgramNamedParameter4fNV _al_glProgramNamedParameter4fNV #define glProgramNamedParameter4dNV _al_glProgramNamedParameter4dNV #define glProgramNamedParameter4fvNV _al_glProgramNamedParameter4fvNV #define glProgramNamedParameter4dvNV _al_glProgramNamedParameter4dvNV #define glGetProgramNamedParameterfvNV _al_glGetProgramNamedParameterfvNV #define glGetProgramNamedParameterdvNV _al_glGetProgramNamedParameterdvNV #endif #if defined _ALLEGRO_GL_NV_half_float #define glVertex2hNV _al_glVertex2hNV #define glVertex2hvNV _al_glVertex2hvNV #define glVertex3hNV _al_glVertex3hNV #define glVertex3hvNV _al_glVertex3hvNV #define glVertex4hNV _al_glVertex4hNV #define glVertex4hvNV _al_glVertex4hvNV #define glNormal3hNV _al_glNormal3hNV #define glNormal3hvNV _al_glNormal3hvNV #define glColor3hNV _al_glColor3hNV #define glColor3hvNV _al_glColor3hvNV #define glColor4hNV _al_glColor4hNV #define glColor4hvNV _al_glColor4hvNV #define glTexCoord1hNV _al_glTexCoord1hNV #define glTexCoord1hvNV _al_glTexCoord1hvNV #define glTexCoord2hNV _al_glTexCoord2hNV #define glTexCoord2hvNV _al_glTexCoord2hvNV #define glTexCoord3hNV _al_glTexCoord3hNV #define glTexCoord3hvNV _al_glTexCoord3hvNV #define glTexCoord4hNV _al_glTexCoord4hNV #define glTexCoord4hvNV _al_glTexCoord4hvNV #define glMultiTexCoord1hNV _al_glMultiTexCoord1hNV #define glMultiTexCoord1hvNV _al_glMultiTexCoord1hvNV #define glMultiTexCoord2hNV _al_glMultiTexCoord2hNV #define glMultiTexCoord2hvNV _al_glMultiTexCoord2hvNV #define glMultiTexCoord3hNV _al_glMultiTexCoord3hNV #define glMultiTexCoord3hvNV _al_glMultiTexCoord3hvNV #define glMultiTexCoord4hNV _al_glMultiTexCoord4hNV #define glMultiTexCoord4hvNV _al_glMultiTexCoord4hvNV #define glFogCoordhNV _al_glFogCoordhNV #define glFogCoordhvNV _al_glFogCoordhvNV #define glSecondaryColor3hNV _al_glSecondaryColor3hNV #define glSecondaryColor3hvNV _al_glSecondaryColor3hvNV #define glVertexWeighthNV _al_glVertexWeighthNV #define glVertexWeighthvNV _al_glVertexWeighthvNV #define glVertexAttrib1hNV _al_glVertexAttrib1hNV #define glVertexAttrib1hvNV _al_glVertexAttrib1hvNV #define glVertexAttrib2hNV _al_glVertexAttrib2hNV #define glVertexAttrib2hvNV _al_glVertexAttrib2hvNV #define glVertexAttrib3hNV _al_glVertexAttrib3hNV #define glVertexAttrib3hvNV _al_glVertexAttrib3hvNV #define glVertexAttrib4hNV _al_glVertexAttrib4hNV #define glVertexAttrib4hvNV _al_glVertexAttrib4hvNV #define glVertexAttribs1hvNV _al_glVertexAttribs1hvNV #define glVertexAttribs2hvNV _al_glVertexAttribs2hvNV #define glVertexAttribs3hvNV _al_glVertexAttribs3hvNV #define glVertexAttribs4hvNV _al_glVertexAttribs4hvNV #endif #if defined _ALLEGRO_GL_NV_pixel_data_range #define glPixelDataRangeNV _al_glPixelDataRangeNV #define glFlushPixelDataRangeNV _al_glFlushPixelDataRangeNV #endif #if defined _ALLEGRO_GL_NV_primitive_restart #define glPrimitiveRestartNV _al_glPrimitiveRestartNV #define glPrimitiveRestartIndexNV _al_glPrimitiveRestartIndexNV #endif #if defined _ALLEGRO_GL_ATI_map_object_buffer #define glMapObjectBufferATI _al_glMapObjectBufferATI #define glUnmapObjectBufferATI _al_glUnmapObjectBufferATI #endif #if defined _ALLEGRO_GL_ATI_separate_stencil #define glStencilOpSeparateATI _al_glStencilOpSeparateATI #define glStencilFuncSeparateATI _al_glStencilFuncSeparateATI #endif #if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object #define glVertexAttribArrayObjectATI _al_glVertexAttribArrayObjectATI #define glGetVertexAttribArrayObjectfvATI _al_glGetVertexAttribArrayObjectfvATI #define glGetVertexAttribArrayObjectivATI _al_glGetVertexAttribArrayObjectivATI #endif #if defined _ALLEGRO_GL_OES_byte_coordinates #define glVertex2bOES _al_glVertex2bOES #define glVertex3bOES _al_glVertex3bOES #define glVertex4bOES _al_glVertex4bOES #define glVertex2bvOES _al_glVertex2bvOES #define glVertex3bvOES _al_glVertex3bvOES #define glVertex4bvOES _al_glVertex4bvOES #define glTexCoord1bOES _al_glTexCoord1bOES #define glTexCoord2bOES _al_glTexCoord2bOES #define glTexCoord3bOES _al_glTexCoord3bOES #define glTexCoord4bOES _al_glTexCoord4bOES #define glTexCoord1bvOES _al_glTexCoord1bvOES #define glTexCoord2bvOES _al_glTexCoord2bvOES #define glTexCoord3bvOES _al_glTexCoord3bvOES #define glTexCoord4bvOES _al_glTexCoord4bvOES #define glMultiTexCoord1bOES _al_glMultiTexCoord1bOES #define glMultiTexCoord2bOES _al_glMultiTexCoord2bOES #define glMultiTexCoord3bOES _al_glMultiTexCoord3bOES #define glMultiTexCoord4bOES _al_glMultiTexCoord4bOES #define glMultiTexCoord1bvOES _al_glMultiTexCoord1bvOES #define glMultiTexCoord2bvOES _al_glMultiTexCoord2bvOES #define glMultiTexCoord3bvOES _al_glMultiTexCoord3bvOES #define glMultiTexCoord4bvOES _al_glMultiTexCoord4bvOES #endif #if defined _ALLEGRO_GL_OES_fixed_point #define glVertex2xOES _al_glVertex2xOES #define glVertex3xOES _al_glVertex3xOES #define glVertex4xOES _al_glVertex4xOES #define glVertex2xvOES _al_glVertex2xvOES #define glVertex3xvOES _al_glVertex3xvOES #define glVertex4xvOES _al_glVertex4xvOES #define glNormal3xOES _al_glNormal3xOES #define glNormal3xvOES _al_glNormal3xvOES #define glTexCoord1xOES _al_glTexCoord1xOES #define glTexCoord2xOES _al_glTexCoord2xOES #define glTexCoord3xOES _al_glTexCoord3xOES #define glTexCoord4xOES _al_glTexCoord4xOES #define glTexCoord1xvOES _al_glTexCoord1xvOES #define glTexCoord2xvOES _al_glTexCoord2xvOES #define glTexCoord3xvOES _al_glTexCoord3xvOES #define glTexCoord4xvOES _al_glTexCoord4xvOES #define glMultiTexCoord1xOES _al_glMultiTexCoord1xOES #define glMultiTexCoord2xOES _al_glMultiTexCoord2xOES #define glMultiTexCoord3xOES _al_glMultiTexCoord3xOES #define glMultiTexCoord4xOES _al_glMultiTexCoord4xOES #define glMultiTexCoord1xvOES _al_glMultiTexCoord1xvOES #define glMultiTexCoord2xvOES _al_glMultiTexCoord2xvOES #define glMultiTexCoord3xvOES _al_glMultiTexCoord3xvOES #define glMultiTexCoord4xvOES _al_glMultiTexCoord4xvOES #define glColor3xOES _al_glColor3xOES #define glColor4xOES _al_glColor4xOES #define glColor3xvOES _al_glColor3xvOES #define glColor4xvOES _al_glColor4xvOES #define glIndexxOES _al_glIndexxOES #define glIndexxvOES _al_glIndexxvOES #define glRectxOES _al_glRectxOES #define glRectxvOES _al_glRectxvOES #define glDepthRangexOES _al_glDepthRangexOES #define glLoadMatrixxOES _al_glLoadMatrixxOES #define glMultMatrixxOES _al_glMultMatrixxOES #define glLoadTransposeMatrixxOES _al_glLoadTransposeMatrixxOES #define glMultTransposeMatrixxOES _al_glMultTransposeMatrixxOES #define glRotatexOES _al_glRotatexOES #define glScalexOES _al_glScalexOES #define glTranslatexOES _al_glTranslatexOES #define glFrustumxOES _al_glFrustumxOES #define glOrthoxOES _al_glOrthoxOES #define glTexGenxOES _al_glTexGenxOES #define glTexGenxvOES _al_glTexGenxvOES #define glGetTexGenxvOES _al_glGetTexGenxvOES #define glClipPlanexOES _al_glClipPlanexOES #define glGetClipPlanexOES _al_glGetClipPlanexOES #define glRasterPos2xOES _al_glRasterPos2xOES #define glRasterPos3xOES _al_glRasterPos3xOES #define glRasterPos4xOES _al_glRasterPos4xOES #define glRasterPos2xvOES _al_glRasterPos2xvOES #define glRasterPos3xvOES _al_glRasterPos3xvOES #define glRasterPos4xvOES _al_glRasterPos4xvOES #define glMaterialxOES _al_glMaterialxOES #define glMaterialxvOES _al_glMaterialxvOES #define glGetMaterialxOES _al_glGetMaterialxOES #define glLightxOES _al_glLightxOES #define glLightxvOES _al_glLightxvOES #define glGetLightxOES _al_glGetLightxOES #define glLightModelxOES _al_glLightModelxOES #define glLightModelxvOES _al_glLightModelxvOES #define glPointSizexOES _al_glPointSizexOES #define glLineWidthxOES _al_glLineWidthxOES #define glPolygonOffsetxOES _al_glPolygonOffsetxOES #define glPixelStorex _al_glPixelStorex #define glPixelTransferxOES _al_glPixelTransferxOES #define glPixelMapx _al_glPixelMapx #define glGetPixelMapxv _al_glGetPixelMapxv #define glConvolutionParameterxOES _al_glConvolutionParameterxOES #define glConvolutionParameterxvOES _al_glConvolutionParameterxvOES #define glGetConvolutionParameterxvOES _al_glGetConvolutionParameterxvOES #define glGetHistogramParameterxvOES _al_glGetHistogramParameterxvOES #define glPixelZoomxOES _al_glPixelZoomxOES #define glBitmapxOES _al_glBitmapxOES #define glTexParameterxOES _al_glTexParameterxOES #define glTexParameterxvOES _al_glTexParameterxvOES #define glGetTexParameterxvOES _al_glGetTexParameterxvOES #define glGetTexLevelParameterxvOES _al_glGetTexLevelParameterxvOES #define glPrioritizeTexturesxOES _al_glPrioritizeTexturesxOES #define glTexEnvxOES _al_glTexEnvxOES #define glTexEnvxvOES _al_glTexEnvxvOES #define glGetTexEnvxvOES _al_glGetTexEnvxvOES #define glFogxOES _al_glFogxOES #define glFogxvOES _al_glFogxvOES #define glSampleCoverageOES _al_glSampleCoverageOES #define glAlphaFuncxOES _al_glAlphaFuncxOES #define glBlendColorxOES _al_glBlendColorxOES #define glClearColorxOES _al_glClearColorxOES #define glClearDepthxOES _al_glClearDepthxOES #define glClearAccumxOES _al_glClearAccumxOES #define glAccumxOES _al_glAccumxOES #define glMap1xOES _al_glMap1xOES #define glMap2xOES _al_glMap2xOES #define glMapGrid1xOES _al_glMapGrid1xOES #define glMapGrid2xOES _al_glMapGrid2xOES #define glGetMapxvOES _al_glGetMapxvOES #define glEvalCoord1xOES _al_glEvalCoord1xOES #define glEvalCoord2xOES _al_glEvalCoord2xOES #define glEvalCoord1xvOES _al_glEvalCoord1xvOES #define glEvalCoord2xvOES _al_glEvalCoord2xvOES #define glFeedbackBufferxOES _al_glFeedbackBufferxOES #define glPassThroughxOES _al_glPassThroughxOES #define glGetFixedvOES _al_glGetFixedvOES #endif #if defined _ALLEGRO_GL_OES_single_precision #define glDepthRangefOES _al_glDepthRangefOES #define glFrustumfOES _al_glFrustumfOES #define glOrthofOES _al_glOrthofOES #define glClipPlanefOES _al_glClipPlanefOES #define glGetClipPlanefOES _al_glGetClipPlanefOES #define glClearDepthfOES _al_glClearDepthfOES #endif #if defined _ALLEGRO_GL_OES_query_matrix #define glQueryMatrixxOES _al_glQueryMatrixxOES #endif #if defined _ALLEGRO_GL_EXT_depth_bounds_test #define glDepthBoundsEXT _al_glDepthBoundsEXT #endif #if defined _ALLEGRO_GL_EXT_blend_equation_separate #define glBlendEquationSeparateEXT _al_glBlendEquationSeparateEXT #endif #if defined _ALLEGRO_GL_EXT_framebuffer_object #define glIsRenderbufferEXT _al_glIsRenderbufferEXT #define glBindRenderbufferEXT _al_glBindRenderbufferEXT #define glDeleteRenderbuffersEXT _al_glDeleteRenderbuffersEXT #define glGenRenderbuffersEXT _al_glGenRenderbuffersEXT #define glRenderbufferStorageEXT _al_glRenderbufferStorageEXT #define glGetRenderbufferParameterivEXT _al_glGetRenderbufferParameterivEXT #define glIsFramebufferEXT _al_glIsFramebufferEXT #define glBindFramebufferEXT _al_glBindFramebufferEXT #define glDeleteFramebuffersEXT _al_glDeleteFramebuffersEXT #define glGenFramebuffersEXT _al_glGenFramebuffersEXT #define glCheckFramebufferStatusEXT _al_glCheckFramebufferStatusEXT #define glFramebufferTexture1DEXT _al_glFramebufferTexture1DEXT #define glFramebufferTexture2DEXT _al_glFramebufferTexture2DEXT #define glFramebufferTexture3DEXT _al_glFramebufferTexture3DEXT #define glFramebufferRenderbufferEXT _al_glFramebufferRenderbufferEXT #define glGetFramebufferAttachmentParameterivEXT _al_glGetFramebufferAttachmentParameterivEXT #define glGenerateMipmapEXT _al_glGenerateMipmapEXT #endif #if defined _ALLEGRO_GL_GREMEDY_string_marker #define glStringMarkerGREMEDY _al_glStringMarkerGREMEDY #endif #if defined _ALLEGRO_GL_EXT_stencil_clear_tag #define glStencilClearTagEXT _al_glStencilClearTagEXT #endif #if defined _ALLEGRO_GL_EXT_framebuffer_blit #define glBlitFramebufferEXT _al_glBlitFramebufferEXT #endif #if defined _ALLEGRO_GL_EXT_framebuffer_multisample #define glRenderbufferStorageMultisampleEXT _al_glRenderbufferStorageMultisampleEXT #endif #if defined _ALLEGRO_GL_EXT_timer_query #define glGetQueryObjecti64vEXT _al_glGetQueryObjecti64vEXT #define glGetQueryObjectui64vEXT _al_glGetQueryObjectui64vEXT #endif #if defined _ALLEGRO_GL_EXT_gpu_program_parameters #define glProgramEnvParameters4fvEXT _al_glProgramEnvParameters4fvEXT #define glProgramLocalParameters4fvEXT _al_glProgramLocalParameters4fvEXT #endif #if defined _ALLEGRO_GL_APPLE_flush_buffer_range #define glBufferParameteriAPPLE _al_glBufferParameteriAPPLE #define glFlushMappedBufferRangeAPPLE _al_glFlushMappedBufferRangeAPPLE #endif #if defined _ALLEGRO_GL_EXT_bindable_uniform #define glUniformBufferEXT _al_glUniformBufferEXT #define glGetUniformBufferSizeEXT _al_glGetUniformBufferSizeEXT #define glGetUniformOffsetEXT _al_glGetUniformOffsetEXT #endif #if defined _ALLEGRO_GL_EXT_draw_buffers2 #define glColorMaskIndexedEXT _al_glColorMaskIndexedEXT #define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT #define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT #define glEnableIndexedEXT _al_glEnableIndexedEXT #define glDisableIndexedEXT _al_glDisableIndexedEXT #define glIsEnabledIndexedEXT _al_glIsEnabledIndexedEXT #endif #if defined _ALLEGRO_GL_EXT_draw_instanced #define glDrawArraysInstancedEXT _al_glDrawArraysInstancedEXT #define glDrawElementsInstancedEXT _al_glDrawElementsInstancedEXT #endif #if defined _ALLEGRO_GL_EXT_geometry_shader4 #define glProgramParameteriEXT _al_glProgramParameteriEXT #define glFramebufferTextureEXT _al_glFramebufferTextureEXT #if !defined _ALLEGRO_GL_EXT_texture_array #define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT #endif #define glFramebufferTextureFaceEXT _al_glFramebufferTextureFaceEXT #endif #if defined _ALLEGRO_GL_EXT_gpu_shader4 #define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT #define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT #define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT #define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT #define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT #define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT #define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT #define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT #define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT #define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT #define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT #define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT #define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT #define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT #define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT #define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT #define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT #define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT #define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT #define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT #define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT #define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT #define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT #define glUniform1uiEXT _al_glUniform1uiEXT #define glUniform2uiEXT _al_glUniform2uiEXT #define glUniform3uiEXT _al_glUniform3uiEXT #define glUniform4uiEXT _al_glUniform4uiEXT #define glUniform1uivEXT _al_glUniform1uivEXT #define glUniform2uivEXT _al_glUniform2uivEXT #define glUniform3uivEXT _al_glUniform3uivEXT #define glUniform4uivEXT _al_glUniform4uivEXT #define glGetUniformuivEXT _al_glGetUniformuivEXT #define glBindFragDataLocationEXT _al_glBindFragDataLocationEXT #define glGetFragDataLocationEXT _al_glGetFragDataLocationEXT #endif #if defined _ALLEGRO_GL_EXT_texture_array #define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT #endif #if defined _ALLEGRO_GL_EXT_texture_buffer_object #define glTexBufferEXT _al_glTexBufferEXT #endif #if defined _ALLEGRO_GL_texture_integer #define glClearColorIiEXT _al_glClearColorIiEXT #define glClearColorIuiEXT _al_glClearColorIuiEXT #define glTexParameterIivEXT _al_glTexParameterIivEXT #define glTexParameterIuivEXT _al_glTexParameterIuivEXT #define glGetTexParameterIivEXT _al_glGetTexParameterIivEXT #define glGetTexParameterIiuvEXT _al_glGetTexParameterIiuvEXT #endif #if defined _ALLEGRO_GL_NV_depth_buffer_float #define glDepthRangedNV _al_glDepthRangedNV #define glClearDepthdNV _al_glClearDepthdNV #define glDepthBoundsdNV _al_glDepthBoundsdNV #endif #if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage #define glRenderbufferStorageMultsampleCoverageNV _al_glRenderbufferStorageMultsampleCoverageNV #endif #if defined _ALLEGRO_GL_NV_geometry_program4 #define glProgramVertexLimitNV _al_glProgramVertexLimitNV #if !defined _ALLEGRO_GL_EXT_geometry_shader4 #define glFramebufferTextureEXT _al_glFramebufferTextureEXT #if !defined _ALLEGRO_GL_EXT_texture_array #define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT #endif #endif #endif #if defined _ALLEGRO_GL_NV_gpu_program4 #define glProgramLocalParameterI4iNV _al_glProgramLocalParameterI4iNV #define glProgramLocalParameterI4ivNV _al_glProgramLocalParameterI4ivNV #define glProgramLocalParametersI4ivNV _al_glProgramLocalParametersI4ivNV #define glProgramLocalParameterI4uiNV _al_glProgramLocalParameterI4uiNV #define glProgramLocalParameterI4uivNV _al_glProgramLocalParameterI4uivNV #define glProgramLocalParametersI4uivNV _al_glProgramLocalParametersI4uivNV #define glProgramEnvParameterI4iNV _al_glProgramEnvParameterI4iNV #define glProgramEnvParameterI4ivNV _al_glProgramEnvParameterI4ivNV #define glProgramEnvParametersI4ivNV _al_glProgramEnvParametersI4ivNV #define glProgramEnvParameterI4uiNV _al_glProgramEnvParameterI4uiNV #define glProgramEnvParameterI4uivNV _al_glProgramEnvParameterI4uivNV #define glProgramEnvParametersI4uivNV _al_glProgramEnvParametersI4uivNV #define glGetProgramLocalParameterIivNV _al_glGetProgramLocalParameterIivNV #define glGetProgramLocalParameterIuivNV _al_glGetProgramLocalParameterIuivNV #define glGetProgramEnvParameterIivNV _al_glGetProgramEnvParameterIivNV #define glGetProgramEnvParameterIuivNV _al_glGetProgramEnvParameterIuivNV #endif #if defined _ALLEGRO_GL_NV_parameter_buffer_object #if !defined _ALLEGRO_GL_NV_transform_feedback #define glBindBufferRangeNV _al_glBindBufferRangeNV #define glBindBufferOffsetNV _al_glBindBufferOffsetNV #define glBindBufferBaseNV _al_glBindBufferBaseNV #endif #define glProgramBufferParametersfvNV _al_glProgramBufferParametersfvNV #define glProgramBufferParametersIivNV _al_glProgramBufferParametersIivNV #define glProgramBufferParametersIuivNV _al_glProgramBufferParametersIuivNV #if !defined _ALLEGRO_GL_EXT_draw_buffers2 #define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT #endif #endif #if defined _ALLEGRO_GL_NV_transform_feedback #define glBindBufferRangeNV _al_glBindBufferRangeNV #define glBindBufferOffsetNV _al_glBindBufferOffsetNV #define glBindBufferBaseNV _al_glBindBufferBaseNV #define glTransformFeedbackAttribsNV _al_glTransformFeedbackAttribsNV #define glTransformFeedbackVaryingsNV _al_glTransformFeedbackVaryingsNV #define glBeginTransformFeedbackNV _al_glBeginTransformFeedbackNV #define glEndTransformFeedbackNV _al_glEndTransformFeedbackNV #define glGetVaryingLocationNV _al_glGetVaryingLocationNV #define glGetActiveVaryingNV _al_glGetActiveVaryingNV #define glActiveVaryingNV _al_glActiveVaryingNV #define glGetTransformFeedbackVaryingNV _al_glGetTransformFeedbackVaryingNV #if !defined _ALLEGRO_GL_EXT_draw_buffers2 #define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT /*AGL_API(void,GetIntegerIndexedvEXT,(GLenum,GLuint,GLint*))*/ #endif #endif #if defined _ALLEGRO_GL_NV_vertex_program4 #ifndef _ALLEGRO_GL_EXT_gpu_shader4 #define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT #define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT #define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT #define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT #define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT #define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT #define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT #define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT #define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT #define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT #define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT #define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT #define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT #define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT #define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT #define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT #define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT #define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT #define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT #define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT #define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT #define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT #define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT #endif #endif #if defined _ALLEGRO_GL_GREMEDY_frame_terminator #define glFrameTerminatorGREMEDY _al_glFrameTerminatorGREMEDY #endif #if defined _ALLEGRO_GL_NV_conditional_render #define glBeginConditionalRenderNV _al_glBeginConditionalRenderNV #define glEndConditionalRenderNV _al_glEndConditionalRenderNV #endif #if defined _ALLEGRO_GL_EXT_transform_feedback #define glBeginTransformFeedbackEXT _al_glBeginTransformFeedbackEXT #define glEndTransformFeedbackEXT _al_glEndTransformFeedbackEXT #define glBindBufferRangeEXT _al_glBindBufferRangeEXT #define glBindBufferOffsetEXT _al_glBindBufferOffsetEXT #define glBindBufferBaseEXT _al_glBindBufferBaseEXT #define glTransformFeedbackVaryingsEXT _al_glTransformFeedbackVaryingsEXT #define glGetTransformFeedbackVaryingEXT _al_glGetTransformFeedbackVaryingEXT #endif #if defined _ALLEGRO_GL_EXT_direct_state_access #define glClientAttribDefaultEXT _al_glClientAttribDefaultEXT #define glPushClientAttribDefaultEXT _al_glPushClientAttribDefaultEXT #define glMatrixLoadfEXT _al_glMatrixLoadfEXT #define glMatrixLoaddEXT _al_glMatrixLoaddEXT #define glMatrixMultfEXT _al_glMatrixMultfEXT #define glMatrixMultdEXT _al_glMatrixMultdEXT #define glMatrixLoadIdentityEXT _al_glMatrixLoadIdentityEXT #define glMatrixRotatefEXT _al_glMatrixRotatefEXT #define glMatrixRotatedEXT _al_glMatrixRotatedEXT #define glMatrixScalefEXT _al_glMatrixScalefEXT #define glMatrixScaledEXT _al_glMatrixScaledEXT #define glMatrixTranslatefEXT _al_glMatrixTranslatefEXT #define glMatrixTranslatedEXT _al_glMatrixTranslatedEXT #define glMatrixFrustumEXT _al_glMatrixFrustumEXT #define glMatrixOrthoEXT _al_glMatrixOrthoEXT #define glMatrixPopEXT _al_glMatrixPopEXT #define glMatrixPushEXT _al_glMatrixPushEXT #define glMatrixLoadTransposefEXT _al_glMatrixLoadTransposefEXT #define glMatrixLoadTransposedEXT _al_glMatrixLoadTransposedEXT #define glMatrixMultTransposefEXT _al_glMatrixMultTransposefEXT #define glMatrixMultTransposedEXT _al_glMatrixMultTransposedEXT #define glTextureParameterfEXT _al_glTextureParameterfEXT #define glTextureParameterfvEXT _al_glTextureParameterfvEXT #define glTextureParameteriEXT _al_glTextureParameteriEXT #define glTextureParameterivEXT _al_glTextureParameterivEXT #define glTextureImage1DEXT _al_glTextureImage1DEXT #define glTextureImage2DEXT _al_glTextureImage2DEXT #define glTextureSubImage1DEXT _al_glTextureSubImage1DEXT #define glTextureSubImage2DEXT _al_glTextureSubImage2DEXT #define glCopyTextureImage1DEXT _al_glCopyTextureImage1DEXT #define glCopyTextureImage2DEXT _al_glCopyTextureImage2DEXT #define glCopyTextureSubImage1DEXT _al_glCopyTextureSubImage1DEXT #define glCopyTextureSubImage2DEXT _al_glCopyTextureSubImage2DEXT #define glGetTextureImageEXT _al_glGetTextureImageEXT #define glGetTextureParameterfvEXT _al_glGetTextureParameterfvEXT #define glGetTextureParameterivEXT _al_glGetTextureParameterivEXT #define glGetTextureLevelParameterfvEXT _al_glGetTextureLevelParameterfvEXT #define glGetTextureLevelParameterivEXT _al_glGetTextureLevelParameterivEXT #define glTextureImage3DEXT _al_glTextureImage3DEXT #define glTextureSubImage3DEXT _al_glTextureSubImage3DEXT #define glCopyTextureSubImage3DEXT _al_glCopyTextureSubImage3DEXT #define glMultiTexParameterfEXT _al_glMultiTexParameterfEXT #define glMultiTexParameterfvEXT _al_glMultiTexParameterfvEXT #define glMultiTexParameteriEXT _al_glMultiTexParameteriEXT #define glMultiTexParameterivEXT _al_glMultiTexParameterivEXT #define glMultiTexImage1DEXT _al_glMultiTexImage1DEXT #define glMultiTexImage2DEXT _al_glMultiTexImage2DEXT #define glMultiTexSubImage1DEXT _al_glMultiTexSubImage1DEXT #define glMultiTexSubImage2DEXT _al_glMultiTexSubImage2DEXT #define glCopyMultiTexImage1DEXT _al_glCopyMultiTexImage1DEXT #define glCopyMultiTexImage2DEXT _al_glCopyMultiTexImage2DEXT #define glCopyMultiTexSubImage1DEXT _al_glCopyMultiTexSubImage1DEXT #define glCopyMultiTexSubImage2DEXT _al_glCopyMultiTexSubImage2DEXT #define glGetMultiTexImageEXT _al_glGetMultiTexImageEXT #define glGetMultiTexParameterfvEXT _al_glGetMultiTexParameterfvEXT #define glGetMultiTexParameterivEXT _al_glGetMultiTexParameterivEXT #define glGetMultiTexLevelParameterfvEXT _al_glGetMultiTexLevelParameterfvEXT #define glGetMultiTexLevelParameterivEXT _al_glGetMultiTexLevelParameterivEXT #define glMultiTexImage3DEXT _al_glMultiTexImage3DEXT #define glMultiTexSubImage3DEXT _al_glMultiTexSubImage3DEXT #define glCopyMultiTexSubImage3DEXT _al_glCopyMultiTexSubImage3DEXT #define glBindMultiTextureEXT _al_glBindMultiTextureEXT #define glEnableClientStateIndexedEXT _al_glEnableClientStateIndexedEXT #define glDisableClientStateIndexedEXT _al_glDisableClientStateIndexedEXT #define glMultiTexCoordPointerEXT _al_glMultiTexCoordPointerEXT #define glMultiTexEnvfEXT _al_glMultiTexEnvfEXT #define glMultiTexEnvfvEXT _al_glMultiTexEnvfvEXT #define glMultiTexEnviEXT _al_glMultiTexEnviEXT #define glMultiTexEnvivEXT _al_glMultiTexEnvivEXT #define glMultiTexGendEXT _al_glMultiTexGendEXT #define glMultiTexGendvEXT _al_glMultiTexGendvEXT #define glMultiTexGenfEXT _al_glMultiTexGenfEXT #define glMultiTexGenfvEXT _al_glMultiTexGenfvEXT #define glMultiTexGeniEXT _al_glMultiTexGeniEXT #define glMultiTexGenivEXT _al_glMultiTexGenivEXT #define glGetMultiTexEnvfvEXT _al_glGetMultiTexEnvfvEXT #define glGetMultiTexEnvivEXT _al_glGetMultiTexEnvivEXT #define glGetMultiTexGendvEXT _al_glGetMultiTexGendvEXT #define glGetMultiTexGenfvEXT _al_glGetMultiTexGenfvEXT #define glGetMultiTexGenivEXT _al_glGetMultiTexGenivEXT #define glGetFloatIndexedvEXT _al_glGetFloatIndexedvEXT #define glGetDoubleIndexedvEXT _al_glGetDoubleIndexedvEXT #define glGetPointerIndexedvEXT _al_glGetPointerIndexedvEXT #define glCompressedTextureImage3DEXT _al_glCompressedTextureImage3DEXT #define glCompressedTextureImage2DEXT _al_glCompressedTextureImage2DEXT #define glCompressedTextureImage1DEXT _al_glCompressedTextureImage1DEXT #define glCompressedTextureSubImage3DEXT _al_glCompressedTextureSubImage3DEXT #define glCompressedTextureSubImage2DEXT _al_glCompressedTextureSubImage2DEXT #define glCompressedTextureSubImage1DEXT _al_glCompressedTextureSubImage1DEXT #define glGetCompressedTextureImageEXT _al_glGetCompressedTextureImageEXT #define glCompressedMultiTexImage3DEXT _al_glCompressedMultiTexImage3DEXT #define glCompressedMultiTexImage2DEXT _al_glCompressedMultiTexImage2DEXT #define glCompressedMultiTexImage1DEXT _al_glCompressedMultiTexImage1DEXT #define glCompressedMultiTexSubImage3DEXT _al_glCompressedMultiTexSubImage3DEXT #define glCompressedMultiTexSubImage2DEXT _al_glCompressedMultiTexSubImage2DEXT #define glCompressedMultiTexSubImage1DEXT _al_glCompressedMultiTexSubImage1DEXT #define glGetCompressedMultiTexImageEXT _al_glGetCompressedMultiTexImageEXT #define glNamedProgramStringEXT _al_glNamedProgramStringEXT #define glNamedProgramLocalParameter4dEXT _al_glNamedProgramLocalParameter4dEXT #define glNamedProgramLocalParameter4dvEXT _al_glNamedProgramLocalParameter4dvEXT #define glNamedProgramLocalParameter4fEXT _al_glNamedProgramLocalParameter4fEXT #define glNamedProgramLocalParameter4fvEXT _al_glNamedProgramLocalParameter4fvEXT #define glGetNamedProgramLocalParameterdvEXT _al_glGetNamedProgramLocalParameterdvEXT #define glGetNamedProgramLocalParameterfvEXT _al_glGetNamedProgramLocalParameterfvEXT #define glGetNamedProgramivEXT _al_glGetNamedProgramivEXT #define glGetNamedProgramStringEXT _al_glGetNamedProgramStringEXT #define glNamedProgramLocalParameters4fvEXT _al_glNamedProgramLocalParameters4fvEXT #define glNamedProgramLocalParameterI4iEXT _al_glNamedProgramLocalParameterI4iEXT #define glNamedProgramLocalParameterI4ivEXT _al_glNamedProgramLocalParameterI4ivEXT #define glNamedProgramLocalParametersI4ivEXT _al_glNamedProgramLocalParametersI4ivEXT #define glNamedProgramLocalParameterI4uiEXT _al_glNamedProgramLocalParameterI4uiEXT #define glNamedProgramLocalParameterI4uivEXT _al_glNamedProgramLocalParameterI4uivEXT #define glNamedProgramLocalParametersI4uivEXT _al_glNamedProgramLocalParametersI4uivEXT #define glGetNamedProgramLocalParameterIivEXT _al_glGetNamedProgramLocalParameterIivEXT #define glGetNamedProgramLocalParameterIuivEXT _al_glGetNamedProgramLocalParameterIuivEXT #define glTextureParameterIivEXT _al_glTextureParameterIivEXT #define glTextureParameterIuivEXT _al_glTextureParameterIuivEXT #define glGetTextureParameterIivEXT _al_glGetTextureParameterIivEXT #define glGetTextureParameterIuivEXT _al_glGetTextureParameterIuivEXT #define glMultiTexParameterIivEXT _al_glMultiTexParameterIivEXT #define glMultiTexParameterIuivEXT _al_glMultiTexParameterIuivEXT #define glGetMultiTexParameterIivEXT _al_glGetMultiTexParameterIivEXT #define glGetMultiTexParameterIuivEXT _al_glGetMultiTexParameterIuivEXT #define glProgramUniform1fEXT _al_glProgramUniform1fEXT #define glProgramUniform2fEXT _al_glProgramUniform2fEXT #define glProgramUniform3fEXT _al_glProgramUniform3fEXT #define glProgramUniform4fEXT _al_glProgramUniform4fEXT #define glProgramUniform1iEXT _al_glProgramUniform1iEXT #define glProgramUniform2iEXT _al_glProgramUniform2iEXT #define glProgramUniform3iEXT _al_glProgramUniform3iEXT #define glProgramUniform4iEXT _al_glProgramUniform4iEXT #define glProgramUniform1fvEXT _al_glProgramUniform1fvEXT #define glProgramUniform2fvEXT _al_glProgramUniform2fvEXT #define glProgramUniform3fvEXT _al_glProgramUniform3fvEXT #define glProgramUniform4fvEXT _al_glProgramUniform4fvEXT #define glProgramUniform1ivEXT _al_glProgramUniform1ivEXT #define glProgramUniform2ivEXT _al_glProgramUniform2ivEXT #define glProgramUniform3ivEXT _al_glProgramUniform3ivEXT #define glProgramUniform4ivEXT _al_glProgramUniform4ivEXT #define glProgramUniformMatrix2fvEXT _al_glProgramUniformMatrix2fvEXT #define glProgramUniformMatrix3fvEXT _al_glProgramUniformMatrix3fvEXT #define glProgramUniformMatrix4fvEXT _al_glProgramUniformMatrix4fvEXT #define glProgramUniformMatrix2x3fvEXT _al_glProgramUniformMatrix2x3fvEXT #define glProgramUniformMatrix3x2fvEXT _al_glProgramUniformMatrix3x2fvEXT #define glProgramUniformMatrix2x4fvEXT _al_glProgramUniformMatrix2x4fvEXT #define glProgramUniformMatrix4x2fvEXT _al_glProgramUniformMatrix4x2fvEXT #define glProgramUniformMatrix3x4fvEXT _al_glProgramUniformMatrix3x4fvEXT #define glProgramUniformMatrix4x3fvEXT _al_glProgramUniformMatrix4x3fvEXT #define glProgramUniform1uiEXT _al_glProgramUniform1uiEXT #define glProgramUniform2uiEXT _al_glProgramUniform2uiEXT #define glProgramUniform3uiEXT _al_glProgramUniform3uiEXT #define glProgramUniform4uiEXT _al_glProgramUniform4uiEXT #define glProgramUniform1uivEXT _al_glProgramUniform1uivEXT #define glProgramUniform2uivEXT _al_glProgramUniform2uivEXT #define glProgramUniform3uivEXT _al_glProgramUniform3uivEXT #define glProgramUniform4uivEXT _al_glProgramUniform4uivEXT #define glNamedBufferDataEXT _al_glNamedBufferDataEXT #define glNamedBufferSubDataEXT _al_glNamedBufferSubDataEXT #define glMapNamedBufferEXT _al_glMapNamedBufferEXT #define glUnmapNamedBufferEXT _al_glUnmapNamedBufferEXT #define glGetNamedBufferParameterivEXT _al_glGetNamedBufferParameterivEXT #define glGetNamedBufferPointervEXT _al_glGetNamedBufferPointervEXT #define glGetNamedBufferSubDataEXT _al_glGetNamedBufferSubDataEXT #define glTextureBufferEXT _al_glTextureBufferEXT #define glMultiTexBufferEXT _al_glMultiTexBufferEXT #define glNamedRenderbufferStorageEXT _al_glNamedRenderbufferStorageEXT #define glGetNamedRenderbufferParameterivEXT _al_glGetNamedRenderbufferParameterivEXT #define glCheckNamedFramebufferStatusEXT _al_glCheckNamedFramebufferStatusEXT #define glNamedFramebufferTexture1DEXT _al_glNamedFramebufferTexture1DEXT #define glNamedFramebufferTexture2DEXT _al_glNamedFramebufferTexture2DEXT #define glNamedFramebufferTexture3DEXT _al_glNamedFramebufferTexture3DEXT #define glNamedFramebufferRenderbufferEXT _al_glNamedFramebufferRenderbufferEXT #define glGetNamedFramebufferAttachmentParameterivEXT _al_glGetNamedFramebufferAttachmentParameterivEXT #define glGenerateTextureMipmapEXT _al_glGenerateTextureMipmapEXT #define glGenerateMultiTexMipmapEXT _al_glGenerateMultiTexMipmapEXT #define glFramebufferDrawBufferEXT _al_glFramebufferDrawBufferEXT #define glFramebufferDrawBuffersEXT _al_glFramebufferDrawBuffersEXT #define glFramebufferReadBufferEXT _al_glFramebufferReadBufferEXT #define glGetFramebufferParameterivEXT _al_glGetFramebufferParameterivEXT #define glNamedRenderbufferStorageMultisampleEXT _al_glNamedRenderbufferStorageMultisampleEXT #define glNamedRenderbufferStorageMultisampleCoverageEXT _al_glNamedRenderbufferStorageMultisampleCoverageEXT #define glNamedFramebufferTextureEXT _al_glNamedFramebufferTextureEXT #define glNamedFramebufferTextureLayerEXT _al_glNamedFramebufferTextureLayerEXT #define glNamedFramebufferTextureFaceEXT _al_glNamedFramebufferTextureFaceEXT #define glTextureRenderbufferEXT _al_glTextureRenderbufferEXT #define glMultiTexRenderbufferEXT _al_glMultiTexRenderbufferEXT #endif #if defined _ALLEGRO_GL_NV_explicit_multisample #define glGetMultisamplefvNV _al_glGetMultisamplefvNV #define glSampleMaskIndexedNV _al_glSampleMaskIndexedNV #define glTexRenderbufferNV _al_glTexRenderbufferNV #endif #if defined _ALLEGRO_GL_NV_transform_feedback2 #define glBindTransformFeedbackNV _al_glBindTransformFeedbackNV #define glDeleteTransformFeedbacksNV _al_glDeleteTransformFeedbacksNV #define glGenTransformFeedbacksNV _al_glGenTransformFeedbacksNV #define glIsTransformFeedbackNV _al_glIsTransformFeedbackNV #define glPauseTransformFeedbackNV _al_glPauseTransformFeedbackNV #define glResumeTransformFeedbackNV _al_glResumeTransformFeedbackNV #define glDrawTransformFeedbackNV _al_glDrawTransformFeedbackNV #endif #if defined _ALLEGRO_GL_AMD_performance_monitor #define glGetPerfMonitorGroupsAMD _al_glGetPerfMonitorGroupsAMD #define glGetPerfMonitorCountersAMD _al_glGetPerfMonitorCountersAMD #define glGetPerfMonitorGroupStringAMD _al_glGetPerfMonitorGroupStringAMD #define glGetPerfMonitorCounterStringAMD _al_glGetPerfMonitorCounterStringAMD #define glGetPerfMonitorCounterInfoAMD _al_glGetPerfMonitorCounterInfoAMD #define glGenPerfMonitorsAMD _al_glGenPerfMonitorsAMD #define glDeletePerfMonitorsAMD _al_glDeletePerfMonitorsAMD #define glSelectPerfMonitorCountersAMD _al_glSelectPerfMonitorCountersAMD #define glBeginPerfMonitorAMD _al_glBeginPerfMonitorAMD #define glEndPerfMonitorAMD _al_glEndPerfMonitorAMD #define glGetPerfMonitorCounterDataAMD _al_glGetPerfMonitorCounterDataAMD #endif #if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator #define glTessellationFactorAMD _al_glTessellationFactorAMD #define glTessellationModeAMD _al_glTessellationModeAMD #endif #if defined _ALLEGRO_GL_EXT_provoking_vertex #define glProvokingVertexEXT _al_glProvokingVertexEXT #endif #if defined _ALLEGRO_GL_AMD_draw_buffers_blend #define glBlendFuncIndexedAMD _al_glBlendFuncIndexedAMD #define glBlendFuncSeparateIndexedAMD _al_glBlendFuncSeparateIndexedAMD #define glBlendEquationIndexedAMD _al_glBlendEquationIndexedAMD #define glBlendEquationSeparateIndexedAMD _al_glBlendEquationSeparateIndexedAMD #endif #if defined _ALLEGRO_GL_APPLE_texture_range #define glTextureRangeAPPLE _al_glTextureRangeAPPLE #define glGetTexParameterPointervAPPLE _al_glGetTexParameterPointervAPPLE #endif #if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators #define glEnableVertexAttribAPPLE _al_glEnableVertexAttribAPPLE #define glDisableVertexAttribAPPLE _al_glDisableVertexAttribAPPLE #define glIsVertexAttribEnabledAPPLE _al_glIsVertexAttribEnabledAPPLE #define glMapVertexAttrib1dAPPLE _al_glMapVertexAttrib1dAPPLE #define glMapVertexAttrib1fAPPLE _al_glMapVertexAttrib1fAPPLE #define glMapVertexAttrib2dAPPLE _al_glMapVertexAttrib2dAPPLE #define glMapVertexAttrib2fAPPLE _al_glMapVertexAttrib2fAPPLE #endif #if defined _ALLEGRO_GL_APPLE_object_purgeable #define glObjectPurgeableAPPLE _al_glObjectPurgeableAPPLE #define glObjectUnpurgeableAPPLE _al_glObjectUnpurgeableAPPLE #define glGetObjectParameterivAPPLE _al_glGetObjectParameterivAPPLE #endif #if defined _ALLEGRO_GL_NV_video_capture #define glBeginVideoCaptureNV _al_glBeginVideoCaptureNV #define glBindVideoCaptureStreamBufferNV _al_glBindVideoCaptureStreamBufferNV #define glBindVideoCaptureStreamTextureNV _al_glBindVideoCaptureStreamTextureNV #define glEndVideoCaptureNV _al_glEndVideoCaptureNV #define glGetVideoCaptureivNV _al_glGetVideoCaptureivNV #define glGetVideoCaptureStreamivNV _al_glGetVideoCaptureStreamivNV #define glGetVideoCaptureStreamfvNV _al_glGetVideoCaptureStreamfvNV #define glGetVideoCaptureStreamdvNV _al_glGetVideoCaptureStreamdvNV #define glVideoCaptureNV _al_glVideoCaptureNV #define glVideoCaptureStreamParameterivNV _al_glVideoCaptureStreamParameterivNV #define glVideoCaptureStreamParameterfvNV _al_glVideoCaptureStreamParameterfvNV #define glVideoCaptureStreamParameterdvNV _al_glVideoCaptureStreamParameterdvNV #endif #if defined _ALLEGRO_GL_EXT_separate_shader_objects #define glUseShaderProgramEXT _al_glUseShaderProgramEXT #define glActiveProgramEXT _al_glActiveProgramEXT #define glCreateShaderProgramEXT _al_glCreateShaderProgramEXT #endif #if defined _ALLEGRO_GL_NV_shader_buffer_load #define glMakeBufferResidentNV _al_glMakeBufferResidentNV #define glMakeBufferNonResidentNV _al_glMakeBufferNonResidentNV #define glIsBufferResidentNV _al_glIsBufferResidentNV #define glMakeNamedBufferResidentNV _al_glMakeNamedBufferResidentNV #define glMakeNamedBufferNonResidentNV _al_glMakeNamedBufferNonResidentNV #define glIsNamedBufferResidentNV _al_glIsNamedBufferResidentNV #define glGetBufferParameterui64vNV _al_glGetBufferParameterui64vNV #define glGetNamedBufferParameterui64vNV _al_glGetNamedBufferParameterui64vNV #define glGetIntegerui64vNV _al_glGetIntegerui64vNV #define glUniformui64NV _al_glUniformui64NV #define glUniformui64vNV _al_glUniformui64vNV #define glGetUniformui64vNV _al_glGetUniformui64vNV #define glProgramUniformui64NV _al_glProgramUniformui64NV #define glProgramUniformui64vNV _al_glProgramUniformui64vNV #endif #if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory #define glBufferAddressRangeNV _al_glBufferAddressRangeNV #define glVertexFormatNV _al_glVertexFormatNV #define glNormalFormatNV _al_glNormalFormatNV #define glColorFormatNV _al_glColorFormatNV #define glIndexFormatNV _al_glIndexFormatNV #define glTexCoordFormatNV _al_glTexCoordFormatNV #define glEdgeFlagFormatNV _al_glEdgeFlagFormatNV #define glSecondaryColorFormatNV _al_glSecondaryColorFormatNV #define glFogCoordFormatNV _al_glFogCoordFormatNV #define glVertexAttribFormatNV _al_glVertexAttribFormatNV #define glVertexAttribIFormatNV _al_glVertexAttribIFormatNV #define glGetIntegerui64i_vNV _al_glGetIntegerui64i_vNV #endif #if defined _ALLEGRO_GL_NV_texture_barrier #define glTextureBarrierNV _al_glTextureBarrierNV #endif allegro-5.0.10/include/allegro5/opengl/GLext/wgl_ext_list.h0000644000175000001440000000302611364043251022727 0ustar tjadenusersAGL_EXT(ARB_buffer_region, 0) AGL_EXT(ARB_multisample, 0) AGL_EXT(ARB_extensions_string, 0) AGL_EXT(ARB_pixel_format, 0) AGL_EXT(ARB_make_current_read, 0) AGL_EXT(ARB_pbuffer, 0) AGL_EXT(ARB_render_texture, 0) AGL_EXT(ARB_pixel_format_float, 0) AGL_EXT(EXT_display_color_table, 0) AGL_EXT(EXT_extensions_string, 0) AGL_EXT(EXT_make_current_read, 0) AGL_EXT(EXT_pixel_format, 0) AGL_EXT(EXT_pbuffer, 0) AGL_EXT(EXT_swap_control, 0) AGL_EXT(EXT_depth_float, 0) AGL_EXT(EXT_multisample, 0) AGL_EXT(OML_sync_control, 0) AGL_EXT(I3D_digital_video_control, 0) AGL_EXT(I3D_gamma, 0) AGL_EXT(I3D_genlock, 0) AGL_EXT(I3D_image_buffer, 0) AGL_EXT(I3D_swap_frame_lock, 0) AGL_EXT(I3D_swap_frame_usage, 0) AGL_EXT(NV_render_depth_texture, 0) AGL_EXT(NV_render_texture_rectangle, 0) AGL_EXT(ATI_pixel_format_float, 0) AGL_EXT(EXT_framebuffer_sRGB, 0) AGL_EXT(EXT_pixel_format_packed_float,0) AGL_EXT(WIN_swap_hint, 0) AGL_EXT(3DL_stereo_control, 0) AGL_EXT(NV_swap_group, 0) AGL_EXT(NV_gpu_affinity, 0) AGL_EXT(NV_video_out, 0) AGL_EXT(NV_present_video, 0) AGL_EXT(ARB_create_context, 0) AGL_EXT(AMD_gpu_association, 0) AGL_EXT(NV_copy_image, 0) AGL_EXT(NV_video_capture, 0) allegro-5.0.10/include/allegro5/opengl/GLext/gl_ext_list.h0000644000175000001440000003547611476663766022605 0ustar tjadenusersAGL_EXT(ARB_imaging, 0) AGL_EXT(ARB_multitexture, 1_2_1) AGL_EXT(ARB_transpose_matrix, 1_3) AGL_EXT(ARB_multisample, 1_3) AGL_EXT(ARB_texture_env_add, 1_3) AGL_EXT(ARB_texture_cube_map, 1_3) AGL_EXT(ARB_texture_compression, 1_3) AGL_EXT(ARB_texture_border_clamp, 1_3) AGL_EXT(ARB_point_parameters, 1_4) AGL_EXT(ARB_vertex_blend, 0) AGL_EXT(ARB_texture_env_combine, 1_3) AGL_EXT(ARB_texture_env_crossbar, 1_4) AGL_EXT(ARB_texture_env_dot3, 1_3) AGL_EXT(ARB_texture_mirrored_repeat, 1_4) AGL_EXT(ARB_depth_texture, 1_4) AGL_EXT(ARB_shadow, 1_4) AGL_EXT(ARB_shadow_ambient, 0) AGL_EXT(ARB_window_pos, 1_4) AGL_EXT(ARB_vertex_program, 0) AGL_EXT(ARB_fragment_program, 0) AGL_EXT(ARB_vertex_buffer_object, 1_5) AGL_EXT(ARB_occlusion_query, 1_5) AGL_EXT(ARB_shader_objects, 0) /* Those were promoted to Core in */ AGL_EXT(ARB_vertex_shader, 0) /* 2.0 with modifications. */ AGL_EXT(ARB_fragment_shader, 0) /* */ AGL_EXT(ARB_shading_language_100, 0) /* */ AGL_EXT(ARB_texture_non_power_of_two,2_0) AGL_EXT(ARB_point_sprite, 2_0) AGL_EXT(ARB_fragment_program_shadow, 0) AGL_EXT(ARB_draw_buffers, 2_0) AGL_EXT(ARB_texture_rectangle, 3_1) AGL_EXT(ARB_color_buffer_float, 3_0) AGL_EXT(ARB_half_float_pixel, 3_0) AGL_EXT(ARB_texture_float, 3_0) AGL_EXT(ARB_pixel_buffer_object, 2_1) AGL_EXT(ARB_instanced_arrays, 0) AGL_EXT(ARB_draw_instanced, 3_1) AGL_EXT(ARB_geometry_shader4, 0) AGL_EXT(ARB_texture_buffer_object, 3_1) AGL_EXT(ARB_depth_buffer_float, 3_0) AGL_EXT(ARB_framebuffer_object, 3_0) AGL_EXT(ARB_framebuffer_sRGB, 3_0) AGL_EXT(ARB_half_float_vertex, 3_0) AGL_EXT(ARB_map_buffer_range, 3_0) AGL_EXT(ARB_texture_compression_rgtc,3_0) AGL_EXT(ARB_texture_rg, 3_0) AGL_EXT(ARB_vertex_array_object, 3_0) AGL_EXT(ARB_copy_buffer, 3_1) AGL_EXT(ARB_compatibility, 0) AGL_EXT(ARB_uniform_buffer_object, 3_1) AGL_EXT(ARB_shader_texture_lod, 0) AGL_EXT(ARB_depth_clamp, 3_2) AGL_EXT(ARB_draw_elements_base_vertex, 3_2) AGL_EXT(ARB_fragment_coord_conventions, 3_2) AGL_EXT(ARB_provoking_vertex, 3_2) AGL_EXT(ARB_seamless_cube_map, 3_2) AGL_EXT(ARB_sync, 3_2) AGL_EXT(ARB_texture_multisample, 3_2) AGL_EXT(ARB_vertex_array_bgra, 0) AGL_EXT(ARB_draw_buffers_blend, 0) AGL_EXT(ARB_sample_shading, 0) AGL_EXT(ARB_texture_cube_map_array, 0) AGL_EXT(ARB_texture_gather, 0) AGL_EXT(ARB_texture_query_lod, 0) AGL_EXT(ARB_shading_language_include, 0) AGL_EXT(ARB_texture_compression_bptc, 0) AGL_EXT(ARB_blend_func_extended, 3_3) AGL_EXT(ARB_explicit_attrib_location, 3_3) AGL_EXT(ARB_occlusion_query2, 3_3) AGL_EXT(ARB_sampler_objects, 3_3) AGL_EXT(ARB_shader_bit_encoding, 3_3) AGL_EXT(ARB_texture_rgb10_a2ui, 3_3) AGL_EXT(ARB_texture_swizzle, 3_3) AGL_EXT(ARB_timer_query, 3_3) AGL_EXT(ARB_vertex_type_2_10_10_10_rev, 3_3) AGL_EXT(ARB_draw_indirect, 4_0) AGL_EXT(ARB_gpu_shader5, 4_0) AGL_EXT(ARB_gpu_shader_fp64, 4_0) AGL_EXT(ARB_shader_subroutine, 4_0) AGL_EXT(ARB_tessellation_shader, 4_0) AGL_EXT(ARB_texture_buffer_object_rgb32, 4_0) AGL_EXT(ARB_transform_feedback2, 4_0) AGL_EXT(ARB_transform_feedback3, 4_0) AGL_EXT(EXT_abgr, 0) AGL_EXT(EXT_blend_color, 1_1) AGL_EXT(EXT_polygon_offset, 1_1) AGL_EXT(EXT_texture, 1_1) AGL_EXT(EXT_texture3D, 1_2) AGL_EXT(SGIS_texture_filter4, 0) AGL_EXT(EXT_subtexture, 1_1) AGL_EXT(EXT_copy_texture, 1_1) AGL_EXT(EXT_histogram, 0) AGL_EXT(EXT_convolution, 0) AGL_EXT(SGI_color_matrix, 0) AGL_EXT(SGI_color_table, 0) AGL_EXT(SGIS_pixel_texture, 0) AGL_EXT(SGIX_pixel_texture, 0) AGL_EXT(SGIS_texture4D, 0) AGL_EXT(SGI_texture_color_table, 0) AGL_EXT(EXT_cmyka, 0) AGL_EXT(EXT_texture_object, 1_1) AGL_EXT(SGIS_detail_texture, 0) AGL_EXT(SGIS_sharpen_texture, 0) AGL_EXT(EXT_packed_pixels, 1_2) AGL_EXT(SGIS_texture_lod, 1_2) AGL_EXT(SGIS_multisample, 1_3) AGL_EXT(EXT_rescale_normal, 1_2) AGL_EXT(EXT_vertex_array, 1_1) AGL_EXT(EXT_misc_attribute, 0) AGL_EXT(SGIS_generate_mipmap, 1_4) AGL_EXT(SGIX_clipmap, 0) AGL_EXT(SGIX_shadow, 0) AGL_EXT(SGIS_texture_edge_clamp, 1_2) AGL_EXT(SGIS_texture_border_clamp, 0) AGL_EXT(EXT_blend_minmax, 0) AGL_EXT(EXT_blend_subtract, 0) AGL_EXT(EXT_blend_logic_op, 1_1) AGL_EXT(SGIX_interlace, 0) AGL_EXT(SGIS_texture_select, 0) AGL_EXT(SGIX_sprite, 0) AGL_EXT(SGIX_texture_multi_buffer, 0) AGL_EXT(EXT_point_parameters, 0) AGL_EXT(SGIX_instruments, 0) AGL_EXT(SGIX_texture_scale_bias, 0) AGL_EXT(SGIX_framezoom, 0) AGL_EXT(SGIX_tag_sample_buffer, 0) AGL_EXT(SGIX_reference_plane, 0) AGL_EXT(SGIX_flush_raster, 0) AGL_EXT(SGIX_depth_texture, 0) AGL_EXT(SGIS_fog_function, 0) AGL_EXT(SGIX_fog_offset, 0) AGL_EXT(HP_image_transform, 0) AGL_EXT(HP_convolution_border_modes, 0) AGL_EXT(SGIX_texture_add_env, 0) AGL_EXT(EXT_color_subtable, 0) AGL_EXT(PGI_vertex_hints, 0) AGL_EXT(PGI_misc_hints, 0) AGL_EXT(EXT_paletted_texture, 0) AGL_EXT(EXT_clip_volume_hint, 0) AGL_EXT(SGIX_list_priority, 0) AGL_EXT(SGIX_ir_instrument1, 0) AGL_EXT(SGIX_texture_lod_bias, 0) AGL_EXT(SGIX_shadow_ambient, 0) AGL_EXT(EXT_index_texture, 0) AGL_EXT(EXT_index_material, 0) AGL_EXT(EXT_index_func, 0) AGL_EXT(EXT_index_array_formats, 0) AGL_EXT(EXT_compiled_vertex_array, 0) AGL_EXT(EXT_cull_vertex, 0) AGL_EXT(SGIX_ycrcb, 0) AGL_EXT(EXT_fragment_lighting, 0) AGL_EXT(IBM_rasterpos_clip, 0) AGL_EXT(HP_texture_lighting, 0) AGL_EXT(EXT_draw_range_elements, 0) AGL_EXT(WIN_phong_shading, 0) AGL_EXT(WIN_specular_fog, 0) AGL_EXT(EXT_light_texture, 0) AGL_EXT(SGIX_blend_alpha_minmax, 0) AGL_EXT(EXT_scene_marker, 0) AGL_EXT(SGIX_pixel_texture_bits, 0) AGL_EXT(EXT_bgra, 1_2) AGL_EXT(SGIX_async, 0) AGL_EXT(SGIX_async_pixel, 0) AGL_EXT(SGIX_async_histogram, 0) AGL_EXT(INTEL_texture_scissor, 0) AGL_EXT(INTEL_parallel_arrays, 0) AGL_EXT(HP_occlusion_test, 0) AGL_EXT(EXT_pixel_transform, 0) AGL_EXT(EXT_pixel_transform_color_table, 0) AGL_EXT(EXT_shared_texture_palette, 0) AGL_EXT(EXT_separate_specular_color, 1_2) AGL_EXT(EXT_secondary_color, 1_4) AGL_EXT(EXT_texture_env, 0) AGL_EXT(EXT_texture_perturb_normal, 0) AGL_EXT(EXT_multi_draw_arrays, 1_4) AGL_EXT(EXT_fog_coord, 1_4) AGL_EXT(REND_screen_coordinates, 0) AGL_EXT(EXT_coordinate_frame, 0) AGL_EXT(EXT_texture_env_combine, 0) AGL_EXT(APPLE_specular_vector, 0) AGL_EXT(APPLE_transform_hint, 0) AGL_EXT(SUNX_constant_data, 0) AGL_EXT(SUN_global_alpha, 0) AGL_EXT(SUN_triangle_list, 0) AGL_EXT(SUN_vertex, 0) AGL_EXT(EXT_blend_func_separate, 1_4) AGL_EXT(INGR_color_clamp, 0) AGL_EXT(INGR_interlace_read, 0) AGL_EXT(EXT_stencil_wrap, 1_4) AGL_EXT(EXT_422_pixels, 0) AGL_EXT(NV_texgen_reflection, 0) AGL_EXT(SGIX_texture_range, 0) AGL_EXT(SUN_convolution_border_modes, 0) AGL_EXT(EXT_texture_env_add, 0) AGL_EXT(EXT_texture_lod_bias, 1_4) AGL_EXT(EXT_texture_filter_anisotropic, 0) AGL_EXT(EXT_vertex_weighting, 0) AGL_EXT(NV_light_max_exponent, 0) AGL_EXT(NV_vertex_array_range, 0) AGL_EXT(NV_register_combiners, 0) AGL_EXT(NV_fog_distance, 0) AGL_EXT(NV_texgen_emboss, 0) AGL_EXT(NV_blend_square, 1_4) AGL_EXT(NV_texture_env_combine4, 0) AGL_EXT(MESA_resize_buffers, 0) AGL_EXT(MESA_window_pos, 0) AGL_EXT(EXT_texture_compression_s3tc, 0) AGL_EXT(IBM_cull_vertex, 0) AGL_EXT(IBM_multimode_draw_arrays, 0) AGL_EXT(IBM_vertex_array_lists, 0) AGL_EXT(3DFX_texture_compression_FXT1, 0) AGL_EXT(3DFX_multisample, 0) AGL_EXT(3DFX_tbuffer, 0) AGL_EXT(SGIX_vertex_preclip, 0) AGL_EXT(SGIX_resample, 0) AGL_EXT(SGIS_texture_color_mask, 0) AGL_EXT(EXT_texture_env_dot3, 0) AGL_EXT(ATI_texture_mirror_once, 0) AGL_EXT(NV_fence, 0) AGL_EXT(IBM_static_data, 0) AGL_EXT(IBM_texture_mirrored_repeat, 0) AGL_EXT(NV_evaluators, 0) AGL_EXT(NV_packed_depth_stencil, 3_0) AGL_EXT(NV_register_combiners2, 0) AGL_EXT(NV_texture_compression_vtc, 0) AGL_EXT(NV_texture_rectangle, 0) AGL_EXT(NV_texture_shader, 0) AGL_EXT(NV_texture_shader2, 0) AGL_EXT(NV_vertex_array_range2, 0) AGL_EXT(NV_vertex_program, 0) AGL_EXT(SGIX_texture_coordinate_clamp, 0) AGL_EXT(OML_interlace, 0) AGL_EXT(OML_subsample, 0) AGL_EXT(OML_resample, 0) AGL_EXT(NV_copy_depth_to_color, 0) AGL_EXT(ATI_envmap_bumpmap, 0) AGL_EXT(ATI_fragment_shader, 0) AGL_EXT(ATI_pn_triangles, 0) AGL_EXT(ATI_vertex_array_object, 0) AGL_EXT(EXT_vertex_shader, 0) AGL_EXT(ATI_vertex_streams, 0) AGL_EXT(ATI_element_array, 0) AGL_EXT(SUN_mesh_array, 0) AGL_EXT(SUN_slice_accum, 0) AGL_EXT(NV_multisample_filter_hint, 0) AGL_EXT(NV_depth_clamp, 0) AGL_EXT(NV_occlusion_query, 0) AGL_EXT(NV_point_sprite, 0) AGL_EXT(NV_texture_shader3, 0) AGL_EXT(NV_vertex_program1_1, 0) AGL_EXT(EXT_shadow_funcs, 1_5) AGL_EXT(EXT_stencil_two_side, 0) AGL_EXT(ATI_text_fragment_shader, 0) AGL_EXT(APPLE_client_storage, 0) AGL_EXT(APPLE_element_array, 0) AGL_EXT(APPLE_fence, 0) AGL_EXT(APPLE_vertex_array_object, 3_0) AGL_EXT(APPLE_vertex_array_range, 0) AGL_EXT(APPLE_ycbcr_422, 0) AGL_EXT(S3_s3tc, 0) AGL_EXT(ATI_draw_buffers, 0) AGL_EXT(ATI_texture_env_combine3, 0) AGL_EXT(ATI_texture_float, 0) AGL_EXT(NV_float_buffer, 0) AGL_EXT(NV_fragment_program, 0) AGL_EXT(NV_half_float, 3_0) AGL_EXT(NV_pixel_data_range, 0) AGL_EXT(NV_primitive_restart, 3_1) AGL_EXT(NV_texture_expand_normal, 0) AGL_EXT(NV_vertex_program2, 0) AGL_EXT(ATI_map_object_buffer, 0) AGL_EXT(ATI_separate_stencil, 2_0) AGL_EXT(ATI_vertex_attrib_array_object, 0) AGL_EXT(OES_byte_coordinates, 0) AGL_EXT(OES_fixed_point, 0) AGL_EXT(OES_single_precision, 0) AGL_EXT(OES_compressed_paletted_texture, 0) AGL_EXT(OES_read_format, 0) AGL_EXT(OES_query_matrix, 0) AGL_EXT(OES_framebuffer_object, 0) AGL_EXT(EXT_depth_bounds_test, 0) AGL_EXT(EXT_texture_mirror_clamp, 0) AGL_EXT(EXT_blend_equation_separate, 0) AGL_EXT(MESA_pack_invert, 0) AGL_EXT(MESA_ycbcr_texture, 0) AGL_EXT(EXT_pixel_buffer_object, 0) AGL_EXT(NV_fragment_program_option, 0) AGL_EXT(NV_fragment_program2, 0) AGL_EXT(NV_vertex_program2_option, 0) AGL_EXT(NV_vertex_program3, 0) AGL_EXT(EXT_texture_compression_dxt1, 0) AGL_EXT(EXT_framebuffer_object, 3_0) AGL_EXT(GREMEDY_string_marker, 0) AGL_EXT(EXT_packed_depth_stencil, 0) AGL_EXT(EXT_stencil_clear_tag, 0) AGL_EXT(EXT_texture_sRGB, 2_1) AGL_EXT(EXT_framebuffer_blit, 3_0) AGL_EXT(EXT_framebuffer_multisample, 3_0) AGL_EXT(MESAX_texture_stack, 0) AGL_EXT(EXT_timer_query, 0) AGL_EXT(EXT_gpu_program_parameters, 0) AGL_EXT(APPLE_flush_buffer_range, 0) #ifdef ALLEGRO_MACOSX AGL_EXT(EXT_texture_rectangle, 0) #endif AGL_EXT(EXT_bindable_uniform, 0) AGL_EXT(EXT_draw_buffers2, 3_0) AGL_EXT(EXT_draw_instanced, 0) AGL_EXT(EXT_framebuffer_sRGB, 3_0) AGL_EXT(EXT_geometry_shader4, 0) AGL_EXT(EXT_gpu_shader4, 3_0) AGL_EXT(EXT_packed_float, 3_0) AGL_EXT(EXT_texture_array, 3_0) AGL_EXT(EXT_texture_buffer_object, 0) AGL_EXT(EXT_texture_compression_latc, 0) AGL_EXT(EXT_texture_compression_rgtc,3_0) AGL_EXT(EXT_texture_integer, 3_0) AGL_EXT(EXT_texture_shared_exponent, 3_0) AGL_EXT(NV_depth_buffer_float, 3_0) AGL_EXT(NV_fragment_program4, 0) AGL_EXT(NV_framebuffer_multisample_coverage, 0) AGL_EXT(NV_geometry_program4, 0) AGL_EXT(NV_gpu_program4, 0) AGL_EXT(NV_parameter_buffer_object, 0) AGL_EXT(NV_transform_feedback, 0) AGL_EXT(NV_vertex_program4, 0) AGL_EXT(GREMEDY_frame_terminator, 0) AGL_EXT(NV_conditional_render, 3_0) AGL_EXT(NV_present_video, 0) AGL_EXT(EXT_direct_state_access, 0) AGL_EXT(EXT_transform_feedback, 3_0) AGL_EXT(EXT_texture_swizzle, 0) AGL_EXT(NV_explicit_multisample, 0) AGL_EXT(NV_transform_feedback2, 0) AGL_EXT(ATI_meminfo, 0) AGL_EXT(AMD_performance_monitor, 0) AGL_EXT(AMD_texture_texture4, 0) AGL_EXT(AMD_vertex_shader_tesselator, 0) AGL_EXT(EXT_provoking_vertex, 0) AGL_EXT(EXT_texture_snorm, 0) AGL_EXT(AMD_draw_buffers_blend, 0) AGL_EXT(APPLE_texture_range, 0) AGL_EXT(APPLE_float_pixels, 0) AGL_EXT(APPLE_vertex_program_evaluators, 0) AGL_EXT(APPLE_aux_depth_stencil, 0) AGL_EXT(APPLE_object_purgeable, 0) AGL_EXT(APPLE_row_bytes, 0) AGL_EXT(APPLE_rgb_422, 0) AGL_EXT(NV_video_capture, 0) AGL_EXT(EXT_separate_shader_objects, 0) AGL_EXT(NV_parameter_buffer_object2, 0) AGL_EXT(NV_shader_buffer_load, 0) AGL_EXT(NV_vertex_buffer_unified_memory, 0) AGL_EXT(NV_texture_barrier, 0) AGL_EXT(AMD_shader_stencil_export, 0) AGL_EXT(AMD_seamless_cubemap_per_texture, 0) AGL_EXT(AMD_conservative_depth, 0) allegro-5.0.10/include/allegro5/opengl/GLext/wgl_ext_api.h0000644000175000001440000001720711364043251022533 0ustar tjadenusers/* WGL_ARB_buffer_region */ AGL_API(HANDLE, CreateBufferRegionARB, (HDC, int, UINT)) AGL_API(VOID, DeleteBufferRegionARB, (HANDLE)) AGL_API(BOOL, SaveBufferRegionARB, (HANDLE, int, int, int, int)) AGL_API(BOOL, RestoreBufferRegionARB, (HANDLE, int, int, int, int, int, int)) /* WGL_ARB_extensions_string */ AGL_API(const char *, GetExtensionsStringARB, (HDC)) /* WGL_ARB_pixel_format */ AGL_API(BOOL, GetPixelFormatAttribivARB, (HDC, int, int, UINT, const int *, int *)) AGL_API(BOOL, GetPixelFormatAttribfvARB, (HDC, int, int, UINT, const int *, FLOAT *)) AGL_API(BOOL, ChoosePixelFormatARB, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) /* WGL_ARB_make_current_read */ AGL_API(BOOL, MakeContextCurrentARB, (HDC, HDC, HGLRC)) AGL_API(HDC, GetCurrentReadDCARB, (void)) /* WGL_ARB_pbuffer */ AGL_API(HPBUFFERARB, CreatePbufferARB, (HDC, int, int, int, const int *)) AGL_API(HDC, GetPbufferDCARB, (HPBUFFERARB)) AGL_API(int, ReleasePbufferDCARB, (HPBUFFERARB, HDC)) AGL_API(BOOL, DestroyPbufferARB, (HPBUFFERARB)) AGL_API(BOOL, QueryPbufferARB, (HPBUFFERARB, int, int *)) /* WGL_ARB_render_texture */ AGL_API(BOOL, BindTexImageARB, (HPBUFFERARB, int)) AGL_API(BOOL, ReleaseTexImageARB, (HPBUFFERARB, int)) AGL_API(BOOL, SetPbufferAttribARB, (HPBUFFERARB, const int *)) /* WGL_ARB_create_context */ AGL_API(HGLRC, CreateContextAttribsARB, (HDC, HGLRC, const int *)) /* WGL_EXT_display_color_table */ AGL_API(GLboolean, CreateDisplayColorTableEXT, (GLushort)) AGL_API(GLboolean, LoadDisplayColorTableEXT, (const GLushort *, GLuint)) AGL_API(GLboolean, BindDisplayColorTableEXT, (GLushort)) AGL_API(VOID, DestroyDisplayColorTableEXT, (GLushort)) /* WGL_EXT_extensions_string */ AGL_API(const char *, GetExtensionsStringEXT, (void)) /* WGL_EXT_make_current_read */ AGL_API(BOOL, MakeContextCurrentEXT, (HDC, HDC, HGLRC)) AGL_API(HDC, GetCurrentReadDCEXT, (void)) /* WGL_EXT_pbuffer */ AGL_API(HPBUFFEREXT, CreatePbufferEXT, (HDC, int, int, int, const int *)) AGL_API(HDC, GetPbufferDCEXT, (HPBUFFEREXT)) AGL_API(int, ReleasePbufferDCEXT, (HPBUFFEREXT, HDC)) AGL_API(BOOL, DestroyPbufferEXT, (HPBUFFEREXT)) AGL_API(BOOL, QueryPbufferEXT, (HPBUFFEREXT, int, int *)) /* WGL_EXT_pixel_format */ AGL_API(BOOL, GetPixelFormatAttribivEXT, (HDC, int, int, UINT, int *, int *)) AGL_API(BOOL, GetPixelFormatAttribfvEXT, (HDC, int, int, UINT, int *, FLOAT *)) AGL_API(BOOL, ChoosePixelFormatEXT, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) /* WGL_EXT_swap_control */ AGL_API(BOOL, SwapIntervalEXT, (int)) AGL_API(int, GetSwapIntervalEXT, (void)) /* WGL_NV_vertex_array_range */ AGL_API(void*, AllocateMemoryNV, (GLsizei, GLfloat, GLfloat, GLfloat)) AGL_API(void, FreeMemoryNV, (void *)) /* WGL_OML_sync_control */ AGL_API(BOOL, GetSyncValuesOML, (HDC, INT64 *, INT64 *, INT64 *)) AGL_API(BOOL, GetMscRateOML, (HDC, INT32 *, INT32 *)) AGL_API(INT64, SwapBuffersMscOML, (HDC, INT64, INT64, INT64)) AGL_API(INT64, SwapLayerBuffersMscOML, (HDC, int, INT64, INT64, INT64)) AGL_API(BOOL, WaitForMscOML, (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *)) AGL_API(BOOL, WaitForSbcOML, (HDC, INT64, INT64 *, INT64 *, INT64 *)) /* WGL_I3D_digital_video_control */ AGL_API(BOOL, GetDigitalVideoParametersI3D, (HDC, int, int *)) AGL_API(BOOL, SetDigitalVideoParametersI3D, (HDC, int, const int *)) /* WGL_I3D_gamma */ AGL_API(BOOL, GetGammaTableParametersI3D, (HDC, int, int *)) AGL_API(BOOL, SetGammaTableParametersI3D, (HDC, int, const int *)) AGL_API(BOOL, GetGammaTableI3D, (HDC, int, USHORT *, USHORT *, USHORT *)) AGL_API(BOOL, SetGammaTableI3D, (HDC, int, const USHORT *, const USHORT *, const USHORT *)) /* WGL_I3D_genlock */ AGL_API(BOOL, EnableGenlockI3D, (HDC)) AGL_API(BOOL, DisableGenlockI3D, (HDC)) AGL_API(BOOL, IsEnabledGenlockI3D, (HDC, BOOL *)) AGL_API(BOOL, GenlockSourceI3D, (HDC, UINT)) AGL_API(BOOL, GetGenlockSourceI3D, (HDC, UINT *)) AGL_API(BOOL, GenlockSourceEdgeI3D, (HDC, UINT)) AGL_API(BOOL, GetGenlockSourceEdgeI3D, (HDC, UINT *)) AGL_API(BOOL, GenlockSampleRateI3D, (HDC, UINT)) AGL_API(BOOL, GetGenlockSampleRateI3D, (HDC, UINT *)) AGL_API(BOOL, GenlockSourceDelayI3D, (HDC, UINT)) AGL_API(BOOL, GetGenlockSourceDelayI3D, (HDC, UINT *)) AGL_API(BOOL, QueryGenlockMaxSourceDelayI3D, (HDC, UINT *, UINT *)) /* WGL_I3D_image_buffer */ AGL_API(LPVOID, CreateImageBufferI3D, (HDC, DWORD, UINT)) AGL_API(BOOL, DestroyImageBufferI3D, (HDC, LPVOID)) AGL_API(BOOL, AssociateImageBufferEventsI3D, (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT)) AGL_API(BOOL, ReleaseImageBufferEventsI3D, (HDC, const LPVOID *, UINT)) /* WGL_I3D_swap_frame_lock */ AGL_API(BOOL, EnableFrameLockI3D, (void)) AGL_API(BOOL, DisableFrameLockI3D, (void)) AGL_API(BOOL, IsEnabledFrameLockI3D, (BOOL *)) AGL_API(BOOL, QueryFrameLockMasterI3D, (BOOL *)) /* WGL_I3D_swap_frame_usage */ AGL_API(BOOL, GetFrameUsageI3D, (float *)) AGL_API(BOOL, BeginFrameTrackingI3D, (void)) AGL_API(BOOL, EndFrameTrackingI3D, (void)) AGL_API(BOOL, QueryFrameTrackingI3D, (DWORD *, DWORD *, float *)) /* glAddSwapHintRectWIN */ AGL_API(void, AddSwapHintRectWIN, (int, int, int, int)) /* WGL_NV_present_video */ AGL_API(int, EnumerateVideoDevicesNV, (HDC, HVIDEOOUTPUTDEVICENV *)) AGL_API(BOOL, BindVideoDeviceNV, (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *)) AGL_API(BOOL, QueryCurrentContextNV, (int, int *)) /* WGL_NV_video_out */ AGL_API(BOOL, GetVideoDeviceNV, (HDC, int, HPVIDEODEV *)) AGL_API(BOOL, ReleaseVideoDeviceNV, (HPVIDEODEV)) AGL_API(BOOL, BindVideoImageNV, (HPVIDEODEV, HPBUFFERARB, int)) AGL_API(BOOL, ReleaseVideoImageNV, (HPBUFFERARB, int)) AGL_API(BOOL, SendPbufferToVideoNV, (HPBUFFERARB, int, unsigned long *, BOOL)) AGL_API(BOOL, GetVideoInfoNV, (HPVIDEODEV, unsigned long *, unsigned long *)) /* WGL_NV_swap_group */ AGL_API(BOOL, JoinSwapGroupNV, (HDC hDC, GLuint group)) AGL_API(BOOL, BindSwapBarrierNV, (GLuint group, GLuint barrier)) AGL_API(BOOL, QuerySwapGroupNV, (HDC hDC, GLuint *group, GLuint *barrier)) AGL_API(BOOL, QueryMaxSwapGroupsNV, (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers)) AGL_API(BOOL, QueryFrameCountNV, (HDC hDC, GLuint *count)) AGL_API(BOOL, ResetFrameCountNV, (HDC hDC)) /* WGL_NV_gpu_affinity */ AGL_API(BOOL, EnumGpusNV, (UINT, HGPUNV *)) AGL_API(BOOL, EnumGpuDevicesNV, (HGPUNV, UINT, PGPU_DEVICE)) AGL_API(HDC, CreateAffinityDCNV, (const HGPUNV *)) AGL_API(BOOL, EnumGpusFromAffinityDCNV, (HDC, UINT, HGPUNV *)) AGL_API(BOOL, DeleteDCNV, (HDC)) /* WGL_AMD_gpu_association */ AGL_API(UINT, GetGPUIDsAMD, (UINT, UINT *)) AGL_API(INT, GetGPUInfoAMD, (UINT, int, GLenum, UINT, void *)) AGL_API(UINT, GetContextGPUIDAMD, (HGLRC)) AGL_API(HGLRC, CreateAssociatedContextAMD, (UINT)) AGL_API(HGLRC, CreateAssociatedContextAttribsAMD, (UINT, HGLRC, const int *)) AGL_API(BOOL, DeleteAssociatedContextAMD, (HGLRC)) AGL_API(BOOL, MakeAssociatedContextCurrentAMD, (HGLRC)) AGL_API(HGLRC, GetCurrentAssociatedContextAMD, (void)) AGL_API(VOID, BlitContextFramebufferAMD, (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) /* WGL_NV_video_capture */ AGL_API(BOOL, BindVideoCaptureDeviceNV, (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice)) AGL_API(UINT, EnumerateVideoCaptureDevicesNV, (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList)) AGL_API(BOOL, LockVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) AGL_API(BOOL, QueryVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue)) AGL_API(BOOL, ReleaseVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) /* WGL_NV_copy_image */ AGL_API(BOOL, CopyImageSubDataNV, (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) allegro-5.0.10/include/allegro5/opengl/GLext/wgl_ext_alias.h0000644000175000001440000001643611364043251023056 0ustar tjadenusers/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ /*WGL_ARB_buffer_region*/ #define wglCreateBufferRegionARB _al_wglCreateBufferRegionARB #define wglDeleteBufferRegionARB _al_wglDeleteBufferRegionARB #define wglSaveBufferRegionARB _al_wglSaveBufferRegionARB #define wglRestoreBufferRegionARB _al_wglRestoreBufferRegionARB /*WGL_ARB_extensions_string*/ #define wglGetExtensionsStringARB _al_wglGetExtensionsStringARB /*WGL_ARB_pixel_format*/ #define wglGetPixelFormatAttribivARB _al_wglGetPixelFormatAttribivARB #define wglGetPixelFormatAttribfvARB _al_wglGetPixelFormatAttribfvARB #define wglChoosePixelFormatARB _al_wglChoosePixelFormatARB /*WGL_ARB_make_current_read*/ #define wglMakeContextCurrentARB _al_wglMakeContextCurrentARB #define wglGetCurrentReadDCARB _al_wglGetCurrentReadDCARB /*WGL_ARB_pbuffer*/ #define wglCreatePbufferARB _al_wglCreatePbufferARB #define wglGetPbufferDCARB _al_wglGetPbufferDCARB #define wglReleasePbufferDCARB _al_wglReleasePbufferDCARB #define wglDestroyPbufferARB _al_wglDestroyPbufferARB #define wglQueryPbufferARB _al_wglQueryPbufferARB /*WGL_ARB_render_texture*/ #define wglBindTexImageARB _al_wglBindTexImageARB #define wglReleaseTexImageARB _al_wglReleaseTexImageARB #define wglSetPbufferAttribARB _al_wglSetPbufferAttribARB /*WGL_ARB_create_context*/ #define wglCreateContextAttribsARB _al_wglCreateContextAttribsARB /*WGL_EXT_display_color_table*/ #define wglCreateDisplayColorTableEXT _al_wglCreateDisplayColorTableEXT #define wglLoadDisplayColorTableEXT _al_wglLoadDisplayColorTableEXT #define wglBindDisplayColorTableEXT _al_wglBindDisplayColorTableEXT #define wglDestroyDisplayColorTableEXT _al_wglDestroyDisplayColorTableEXT /*WGL_EXT_extensions_string*/ #define wglGetExtensionsStringEXT _al_wglGetExtensionsStringEXT /*WGL_EXT_make_current_read*/ #define wglMakeContextCurrentEXT _al_wglMakeContextCurrentEXT #define wglGetCurrentReadDCEXT _al_wglGetCurrentReadDCEXT /*WGL_EXT_pbuffer*/ #define wglCreatePbufferEXT _al_wglCreatePbufferEXT #define wglGetPbufferDCEXT _al_wglGetPbufferDCEXT #define wglReleasePbufferDCEXT _al_wglReleasePbufferDCEXT #define wglDestroyPbufferEXT _al_wglDestroyPbufferEXT #define wglQueryPbufferEXT _al_wglQueryPbufferEXT /*WGL_EXT_pixel_format*/ #define wglGetPixelFormatAttribivEXT _al_wglGetPixelFormatAttribivEXT #define wglGetPixelFormatAttribfvEXT _al_wglGetPixelFormatAttribfvEXT #define wglChoosePixelFormatEXT _al_wglChoosePixelFormatEXT /*WGL_EXT_swap_control*/ #define wglSwapIntervalEXT _al_wglSwapIntervalEXT #define wglGetSwapIntervalEXT _al_wglGetSwapIntervalEXT /*WGL_NV_vertex_array_range*/ #define wglAllocateMemoryNV _al_wglAllocateMemoryNV #define wglFreeMemoryNV _al_wglFreeMemoryNV /*WGL_OML_sync_control*/ #define wglGetSyncValuesOML _al_wglGetSyncValuesOML #define wglGetMscRateOML _al_wglGetMscRateOML #define wglSwapBuffersMscOML _al_wglSwapBuffersMscOML #define wglSwapLayerBuffersMscOML _al_wglSwapLayerBuffersMscOML #define wglWaitForMscOML _al_wglWaitForMscOML #define wglWaitForSbcOML _al_wglWaitForSbcOML /*WGL_I3D_digital_video_control*/ #define wglGetDigitalVideoParametersI3D _al_wglGetDigitalVideoParametersI3D #define wglSetDigitalVideoParametersI3D _al_wglSetDigitalVideoParametersI3D /*WGL_I3D_gamma*/ #define wglGetGammaTableParametersI3D _al_wglGetGammaTableParametersI3D #define wglSetGammaTableParametersI3D _al_wglSetGammaTableParametersI3D #define wglGetGammaTableI3D _al_wglGetGammaTableI3D #define wglSetGammaTableI3D _al_wglSetGammaTableI3D /*WGL_I3D_genlock*/ #define wglEnableGenlockI3D _al_wglEnableGenlockI3D #define wglDisableGenlockI3D _al_wglDisableGenlockI3D #define wglIsEnabledGenlockI3D _al_wglIsEnabledGenlockI3D #define wglGenlockSourceI3D _al_wglGenlockSourceI3D #define wglGetGenlockSourceI3D _al_wglGetGenlockSourceI3D #define wglGenlockSourceEdgeI3D _al_wglGenlockSourceEdgeI3D #define wglGetGenlockSourceEdgeI3D _al_wglGetGenlockSourceEdgeI3D #define wglGenlockSampleRateI3D _al_wglGenlockSampleRateI3D #define wglGetGenlockSampleRateI3D _al_wglGetGenlockSampleRateI3D #define wglGenlockSourceDelayI3D _al_wglGenlockSourceDelayI3D #define wglGetGenlockSourceDelayI3D _al_wglGetGenlockSourceDelayI3D #define wglQueryGenlockMaxSourceDelayI3D _al_wglQueryGenlockMaxSourceDelayI3D /*WGL_I3D_image_buffer*/ #define wglCreateImageBufferI3D _al_wglCreateImageBufferI3D #define wglDestroyImageBufferI3D _al_wglDestroyImageBufferI3D #define wglAssociateImageBufferEventsI3D _al_wglAssociateImageBufferEventsI3D #define wglReleaseImageBufferEventsI3D _al_wglReleaseImageBufferEventsI3D /*WGL_I3D_swap_frame_lock*/ #define wglEnableFrameLockI3D _al_wglEnableFrameLockI3D #define wglDisableFrameLockI3D _al_wglDisableFrameLockI3D #define wglIsEnabledFrameLockI3D _al_wglIsEnabledFrameLockI3D #define wglQueryFrameLockMasterI3D _al_wglQueryFrameLockMasterI3D /*WGL_I3D_swap_frame_usage*/ #define wglGetFrameUsageI3D _al_wglGetFrameUsageI3D #define wglBeginFrameTrackingI3D _al_wglBeginFrameTrackingI3D #define wglEndFrameTrackingI3D _al_wglEndFrameTrackingI3D #define wglQueryFrameTrackingI3D _al_wglQueryFrameTrackingI3D /*glAddSwapHintRectWIN*/ #define wglAddSwapHintRectWIN _al_wglAddSwapHintRectWIN /*WGL_NV_present_video*/ #define wglEnumerateVideoDevicesNV _al_wglEnumerateVideoDevicesNV #define wglBindVideoDeviceNV _al_wglBindVideoDeviceNV #define wglQueryCurrentContextNV _al_wglQueryCurrentContextNV /*WGL_NV_video_out*/ #define wglGetVideoDeviceNV _al_wglGetVideoDeviceNV #define wglReleaseVideoDeviceNV _al_wglReleaseVideoDeviceNV #define wglBindVideoImageNV _al_wglBindVideoImageNV #define wglReleaseVideoImageNV _al_wglReleaseVideoImageNV #define wglSendPbufferToVideoNV _al_wglSendPbufferToVideoNV #define wglGetVideoInfoNV _al_wglGetVideoInfoNV /*WGL_NV_swap_group*/ #define wglJoinSwapGroupNV _al_wglJoinSwapGroupNV #define wglBindSwapBarrierNV _al_wglBindSwapBarrierNV #define wglQuerySwapGroupNV _al_wglQuerySwapGroupNV #define wglQueryMaxSwapGroupsNV _al_wglQueryMaxSwapGroupsNV #define wglQueryFrameCountNV _al_wglQueryFrameCountNV #define wglResetFrameCountNV _al_wglResetFrameCountNV /*WGL_NV_gpu_affinity*/ #define wglEnumGpusNV _al_wglEnumGpusNV #define wglEnumGpuDevicesNV _al_wglEnumGpuDevicesNV #define wglCreateAffinityDCNV _al_wglCreateAffinityDCNV #define wglEnumGpusFromAffinityDCNV _al_wglEnumGpusFromAffinityDCNV #define wglDeleteDCNV _al_wglDeleteDCNV /*WGL_AMD_gpu_association*/ #define wglGetGPUIDsAMD _al_wglGetGPUIDsAMD #define wglGetGPUInfoAMD _al_wglGetGPUInfoAMD #define wglGetContextGPUIDAMD _al_wglGetContextGPUIDAMD #define wglCreateAssociatedContextAMD _al_wglCreateAssociatedContextAMD #define wglCreateAssociatedContextAttribsAMD _al_wglCreateAssociatedContextAttribsAMD #define wglDeleteAssociatedContextAMD _al_wglDeleteAssociatedContextAMD #define wglMakeAssociatedContextCurrentAMD _al_wglMakeAssociatedContextCurrentAMD #define wglGetCurrentAssociatedContextAMD _al_wglGetCurrentAssociatedContextAMD #define wglBlitContextFramebufferAMD _al_wglBlitContextFramebufferAMD /*WGL_NV_video_capture*/ #define wglBindVideoCaptureDeviceNV _al_wglBindVideoCaptureDeviceNV #define wglEnumerateVideoCaptureDevicesNV _al_wglEnumerateVideoCaptureDevicesNV #define wglLockVideoCaptureDeviceNV _al_wglLockVideoCaptureDeviceNV #define wglQueryVideoCaptureDeviceNV _al_wglQueryVideoCaptureDeviceNV #define wglReleaseVideoCaptureDeviceNV _al_wglReleaseVideoCaptureDeviceNV /*WGL_NV_copy_image*/ #define wglCopyImageSubDataNV _al_wglCopyImageSubDataNV allegro-5.0.10/include/allegro5/opengl/GLext/wgl_ext_defs.h0000644000175000001440000003311711364043251022701 0ustar tjadenusers#ifndef WGL_ARB_buffer_region #define WGL_ARB_buffer_region #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 #endif #ifndef WGL_ARB_multisample #define WGL_ARB_multisample #define WGL_SAMPLE_BUFFERS_ARB 0x2041 #define WGL_SAMPLES_ARB 0x2042 #endif #ifndef WGL_ARB_pixel_format #define WGL_ARB_pixel_format #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_DRAW_TO_BITMAP_ARB 0x2002 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_NEED_PALETTE_ARB 0x2004 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 #define WGL_SWAP_METHOD_ARB 0x2007 #define WGL_NUMBER_OVERLAYS_ARB 0x2008 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 #define WGL_TRANSPARENT_ARB 0x200A #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B #define WGL_SHARE_DEPTH_ARB 0x200C #define WGL_SHARE_STENCIL_ARB 0x200D #define WGL_SHARE_ACCUM_ARB 0x200E #define WGL_SUPPORT_GDI_ARB 0x200F #define WGL_SUPPORT_OPENGL_ARB 0x2010 #define WGL_DOUBLE_BUFFER_ARB 0x2011 #define WGL_STEREO_ARB 0x2012 #define WGL_PIXEL_TYPE_ARB 0x2013 #define WGL_COLOR_BITS_ARB 0x2014 #define WGL_RED_BITS_ARB 0x2015 #define WGL_RED_SHIFT_ARB 0x2016 #define WGL_GREEN_BITS_ARB 0x2017 #define WGL_GREEN_SHIFT_ARB 0x2018 #define WGL_BLUE_BITS_ARB 0x2019 #define WGL_BLUE_SHIFT_ARB 0x201A #define WGL_ALPHA_BITS_ARB 0x201B #define WGL_ALPHA_SHIFT_ARB 0x201C #define WGL_ACCUM_BITS_ARB 0x201D #define WGL_ACCUM_RED_BITS_ARB 0x201E #define WGL_ACCUM_GREEN_BITS_ARB 0x201F #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 #define WGL_DEPTH_BITS_ARB 0x2022 #define WGL_STENCIL_BITS_ARB 0x2023 #define WGL_AUX_BUFFERS_ARB 0x2024 #define WGL_NO_ACCELERATION_ARB 0x2025 #define WGL_GENERIC_ACCELERATION_ARB 0x2026 #define WGL_FULL_ACCELERATION_ARB 0x2027 #define WGL_SWAP_EXCHANGE_ARB 0x2028 #define WGL_SWAP_COPY_ARB 0x2029 #define WGL_SWAP_UNDEFINED_ARB 0x202A #define WGL_TYPE_RGBA_ARB 0x202B #define WGL_TYPE_COLORINDEX_ARB 0x202C #endif #ifndef WGL_ARB_make_current_read #define WGL_ARB_make_current_read #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 #endif #ifndef WGL_ARB_pbuffer #define WGL_ARB_pbuffer DECLARE_HANDLE(HPBUFFERARB); #define WGL_DRAW_TO_PBUFFER_ARB 0x202D #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 #define WGL_PBUFFER_LARGEST_ARB 0x2033 #define WGL_PBUFFER_WIDTH_ARB 0x2034 #define WGL_PBUFFER_HEIGHT_ARB 0x2035 #define WGL_PBUFFER_LOST_ARB 0x2036 #endif #ifndef WGL_ARB_render_texture #define WGL_ARB_render_texture #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 #define WGL_TEXTURE_FORMAT_ARB 0x2072 #define WGL_TEXTURE_TARGET_ARB 0x2073 #define WGL_MIPMAP_TEXTURE_ARB 0x2074 #define WGL_TEXTURE_RGB_ARB 0x2075 #define WGL_TEXTURE_RGBA_ARB 0x2076 #define WGL_NO_TEXTURE_ARB 0x2077 #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 #define WGL_TEXTURE_1D_ARB 0x2079 #define WGL_TEXTURE_2D_ARB 0x207A #define WGL_MIPMAP_LEVEL_ARB 0x207B #define WGL_CUBE_MAP_FACE_ARB 0x207C #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 #define WGL_FRONT_LEFT_ARB 0x2083 #define WGL_FRONT_RIGHT_ARB 0x2084 #define WGL_BACK_LEFT_ARB 0x2085 #define WGL_BACK_RIGHT_ARB 0x2086 #define WGL_AUX0_ARB 0x2087 #define WGL_AUX1_ARB 0x2088 #define WGL_AUX2_ARB 0x2089 #define WGL_AUX3_ARB 0x208A #define WGL_AUX4_ARB 0x208B #define WGL_AUX5_ARB 0x208C #define WGL_AUX6_ARB 0x208D #define WGL_AUX7_ARB 0x208E #define WGL_AUX8_ARB 0x208F #define WGL_AUX9_ARB 0x2090 #endif #ifndef WGL_ARB_pixel_format_float #define WGL_ARB_pixel_format_float #define AWGL_ARB_pixel_format_float #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 #endif #ifndef WGL_ARB_create_context #define WGL_ARB_create_context #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 #define WGL_CONTEXT_FLAGS_ARB 0x2094 #define ERROR_INVALID_VERSION_ARB 0x2095 #endif #ifndef WGL_ARB_create_context_profile #define WGL_ARB_create_context_profile #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define ERROR_INVALID_PROFILE_ARB 0x2096 #endif #ifndef WGL_EXT_make_current_read #define WGL_EXT_make_current_read #define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 #endif #ifndef WGL_EXT_pixel_format #define WGL_EXT_pixel_format #define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 #define WGL_DRAW_TO_WINDOW_EXT 0x2001 #define WGL_DRAW_TO_BITMAP_EXT 0x2002 #define WGL_ACCELERATION_EXT 0x2003 #define WGL_NEED_PALETTE_EXT 0x2004 #define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 #define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 #define WGL_SWAP_METHOD_EXT 0x2007 #define WGL_NUMBER_OVERLAYS_EXT 0x2008 #define WGL_NUMBER_UNDERLAYS_EXT 0x2009 #define WGL_TRANSPARENT_EXT 0x200A #define WGL_TRANSPARENT_VALUE_EXT 0x200B #define WGL_SHARE_DEPTH_EXT 0x200C #define WGL_SHARE_STENCIL_EXT 0x200D #define WGL_SHARE_ACCUM_EXT 0x200E #define WGL_SUPPORT_GDI_EXT 0x200F #define WGL_SUPPORT_OPENGL_EXT 0x2010 #define WGL_DOUBLE_BUFFER_EXT 0x2011 #define WGL_STEREO_EXT 0x2012 #define WGL_PIXEL_TYPE_EXT 0x2013 #define WGL_COLOR_BITS_EXT 0x2014 #define WGL_RED_BITS_EXT 0x2015 #define WGL_RED_SHIFT_EXT 0x2016 #define WGL_GREEN_BITS_EXT 0x2017 #define WGL_GREEN_SHIFT_EXT 0x2018 #define WGL_BLUE_BITS_EXT 0x2019 #define WGL_BLUE_SHIFT_EXT 0x201A #define WGL_ALPHA_BITS_EXT 0x201B #define WGL_ALPHA_SHIFT_EXT 0x201C #define WGL_ACCUM_BITS_EXT 0x201D #define WGL_ACCUM_RED_BITS_EXT 0x201E #define WGL_ACCUM_GREEN_BITS_EXT 0x201F #define WGL_ACCUM_BLUE_BITS_EXT 0x2020 #define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 #define WGL_DEPTH_BITS_EXT 0x2022 #define WGL_STENCIL_BITS_EXT 0x2023 #define WGL_AUX_BUFFERS_EXT 0x2024 #define WGL_NO_ACCELERATION_EXT 0x2025 #define WGL_GENERIC_ACCELERATION_EXT 0x2026 #define WGL_FULL_ACCELERATION_EXT 0x2027 #define WGL_SWAP_EXCHANGE_EXT 0x2028 #define WGL_SWAP_COPY_EXT 0x2029 #define WGL_SWAP_UNDEFINED_EXT 0x202A #define WGL_TYPE_RGBA_EXT 0x202B #define WGL_TYPE_COLORINDEX_EXT 0x202C #endif #ifndef WGL_EXT_pbuffer #define WGL_EXT_pbuffer DECLARE_HANDLE(HPBUFFEREXT); #define WGL_DRAW_TO_PBUFFER_EXT 0x202D #define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E #define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F #define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 #define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 #define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 #define WGL_PBUFFER_LARGEST_EXT 0x2033 #define WGL_PBUFFER_WIDTH_EXT 0x2034 #define WGL_PBUFFER_HEIGHT_EXT 0x2035 #endif #ifndef WGL_EXT_depth_float #define WGL_EXT_depth_float #define WGL_DEPTH_FLOAT_EXT 0x2040 #endif #ifndef WGL_3DFX_multisample #define WGL_3DFX_multisample #define WGL_SAMPLE_BUFFERS_3DFX 0x2060 #define WGL_SAMPLES_3DFX 0x2061 #endif #ifndef WGL_EXT_multisample #define WGL_EXT_multisample #define WGL_SAMPLE_BUFFERS_EXT 0x2041 #define WGL_SAMPLES_EXT 0x2042 #endif #ifndef WGL_I3D_digital_video_control #define WGL_I3D_digital_video_control #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 #define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 #define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 #define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 #endif #ifndef WGL_I3D_gamma #define WGL_I3D_gamma #define WGL_GAMMA_TABLE_SIZE_I3D 0x204E #define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F #endif #ifndef WGL_I3D_genlock #define WGL_I3D_genlock #define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 #define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 #define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 #define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 #define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 #define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 #define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A #define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B #define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C #endif #ifndef WGL_I3D_image_buffer #define WGL_I3D_image_buffer #define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 #define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 #endif #ifndef WGL_NV_render_depth_texture #define WGL_NV_render_depth_texture #define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 #define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 #define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 #define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 #define WGL_DEPTH_COMPONENT_NV 0x20A7 #endif #ifndef WGL_NV_render_texture_rectangle #define WGL_NV_render_texture_rectangle #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 #define WGL_TEXTURE_RECTANGLE_NV 0x20A2 #endif #ifndef WGL_NV_float_buffer #define WGL_NV_float_buffer #define WGL_FLOAT_COMPONENTS_NV 0x20B0 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 #define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 #define WGL_TEXTURE_FLOAT_R_NV 0x20B5 #define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 #define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 #define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 #endif #ifndef WGL_3DL_stereo_control #define WGL_3DL_stereo_control #define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 #define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 #define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 #define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 #endif #ifndef WGL_EXT_framebuffer_sRGB #define WGL_EXT_framebuffer_sRGB #define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 #endif #ifndef WGL_EXT_pixel_format_packed_float #define WGL_EXT_pixel_format_packed_float #define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 #endif #ifndef WGL_WIN_swap_hint #define WGL_WIN_swap_hint #endif #ifndef WGL_NV_present_video #define WGL_NV_present_video DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); #define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 #endif #ifndef WGL_NV_video_out #define WGL_NV_video_out DECLARE_HANDLE(HPVIDEODEV); #define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 #define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 #define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 #define WGL_VIDEO_OUT_COLOR_NV 0x20C3 #define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 #define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 #define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 #define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 #define WGL_VIDEO_OUT_FRAME 0x20C8 #define WGL_VIDEO_OUT_FIELD_1 0x20C9 #define WGL_VIDEO_OUT_FIELD_2 0x20CA #define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB #define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC #endif #ifndef WGL_NV_swap_group #define WGL_NV_swap_group #endif #ifndef WGL_NV_gpu_affinity #define WGL_NV_gpu_affinity DECLARE_HANDLE(HPGPUNV); DECLARE_HANDLE(HGPUNV); typedef struct _GPU_DEVICE { DWORD cb; CHAR DeviceName[32]; CHAR DeviceString[128]; DWORD Flags; RECT rcVirtualScreen; } GPU_DEVICE, *PGPU_DEVICE; #define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 #define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 #endif #ifndef WGL_AMD_gpu_association #define WGL_AMD_gpu_association #define WGL_GPU_VENDOR_AMD 0x1F00 #define WGL_GPU_RENDERER_STRING_AMD 0x1F01 #define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 #define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 #define WGL_GPU_RAM_AMD 0x21A3 #define WGL_GPU_CLOCK_AMD 0x21A4 #define WGL_GPU_NUM_PIPES_AMD 0x21A5 #define WGL_GPU_NUM_SIMD_AMD 0x21A6 #define WGL_GPU_NUM_RB_AMD 0x21A7 #define WGL_GPU_NUM_SPI_AMD 0x21A8 #endif #ifndef WGL_NV_video_capture #define WGL_NV_video_capture DECLARE_HANDLE(HVIDEOINPUTDEVICENV); #define WGL_UNIQUE_ID_NV 0x20CE #define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF #endif #ifndef WGL_NV_copy_image #define WGL_NV_copy_image #endif allegro-5.0.10/include/allegro5/monitor.h0000644000175000001440000000101412057114567017407 0ustar tjadenusers#ifndef __al_included_allegro5_monitor_h #define __al_included_allegro5_monitor_h #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_MONITOR_INFO */ typedef struct ALLEGRO_MONITOR_INFO { int x1; int y1; int x2; int y2; } ALLEGRO_MONITOR_INFO; enum { ALLEGRO_DEFAULT_DISPLAY_ADAPTER = -1 }; AL_FUNC(int, al_get_num_video_adapters, (void)); AL_FUNC(bool, al_get_monitor_info, (int adapter, ALLEGRO_MONITOR_INFO *info)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/allegro.h0000644000175000001440000000370212063331525017343 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Main header file for the entire Allegro library. * (separate modules can be included from the allegro/ directory) * * By Shawn Hargreaves. * * Vincent Penquerc'h split the original allegro.h into separate headers. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_allegro_h #define __al_included_allegro5_allegro_h #include "allegro5/base.h" #include "allegro5/altime.h" #include "allegro5/bitmap.h" #include "allegro5/bitmap_draw.h" #include "allegro5/bitmap_io.h" #include "allegro5/bitmap_lock.h" #include "allegro5/blender.h" #include "allegro5/color.h" #include "allegro5/config.h" #include "allegro5/debug.h" #include "allegro5/display.h" #include "allegro5/drawing.h" #include "allegro5/error.h" #include "allegro5/events.h" #include "allegro5/file.h" #include "allegro5/fixed.h" #include "allegro5/fmaths.h" #include "allegro5/fshook.h" #include "allegro5/fullscreen_mode.h" #include "allegro5/joystick.h" #include "allegro5/keyboard.h" #include "allegro5/memory.h" #include "allegro5/monitor.h" #include "allegro5/mouse.h" #include "allegro5/mouse_cursor.h" #include "allegro5/path.h" #include "allegro5/system.h" #include "allegro5/threads.h" #include "allegro5/timer.h" #include "allegro5/tls.h" #include "allegro5/transformations.h" #include "allegro5/utf8.h" #ifndef ALLEGRO_NO_COMPATIBILITY #include "allegro5/alcompat.h" #endif #ifdef ALLEGRO_EXTRA_HEADER #include ALLEGRO_EXTRA_HEADER #endif #endif allegro-5.0.10/include/allegro5/platform/0000755000175000001440000000000012157230743017373 5ustar tjadenusersallegro-5.0.10/include/allegro5/platform/aintxglx.h0000644000175000001440000000031712132152266021377 0ustar tjadenusers#ifndef __al_included_allegro5_aintxglx_h #define __al_included_allegro5_aintxglx_h ALLEGRO_DISPLAY_INTERFACE *_al_display_xglx_driver(void); ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void); #endif allegro-5.0.10/include/allegro5/platform/alwiz.h0000644000175000001440000000170011234143620020660 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Wiz-specific header defines. * * By Trent Gamblin * * See readme.txt for copyright information. */ #ifndef ALLEGRO_GP2XWIZ #error bad include #endif #define AL_JOY_TYPE_GP2XWIZ AL_ID('W','I','Z',' ') AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_gp2xwiz); #define _AL_JOYSTICK_DRIVER_GP2XWIZ \ { AL_JOY_TYPE_GP2XWIZ, &_al_joydrv_gp2xwiz, true }, #include "allegro5/platform/alunix.h" allegro-5.0.10/include/allegro5/platform/almsvc.h0000644000175000001440000000567112132137604021035 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with MSVC. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include #include #include #include #include "allegro5/platform/alplatf.h" #pragma warning (disable: 4200 4244 4305 4800) /* describe this platform */ #ifdef ALLEGRO_STATICLINK #define ALLEGRO_PLATFORM_STR "MSVC.s" #else #define ALLEGRO_PLATFORM_STR "MSVC" #endif #define ALLEGRO_WINDOWS #define ALLEGRO_I386 #define ALLEGRO_LITTLE_ENDIAN #define ALLEGRO_GUESS_INTTYPES_OK #ifdef ALLEGRO_USE_CONSOLE #define ALLEGRO_NO_MAGIC_MAIN #endif /* describe how function prototypes look to MSVC */ #ifndef ALLEGRO_STATICLINK #ifdef ALLEGRO_SRC #define _AL_DLL __declspec(dllexport) #else #define _AL_DLL __declspec(dllimport) #endif #else #define _AL_DLL #endif #define AL_VAR(type, name) extern _AL_DLL type name #define AL_ARRAY(type, name) extern _AL_DLL type name[] #define AL_FUNC(type, name, args) _AL_DLL type __cdecl name args #define AL_METHOD(type, name, args) type (__cdecl *name) args #define AL_FUNCPTR(type, name, args) extern _AL_DLL type (__cdecl *name) args #ifdef AL_INLINE #define END_OF_INLINE(name) void *_force_instantiate_##name = name; #else #define END_OF_INLINE(name) #endif #undef AL_INLINE #undef AL_INLINE_STATIC #define AL_INLINE(type, name, args, code) __inline _AL_DLL type __cdecl name args code END_OF_INLINE(name) #define AL_INLINE_STATIC(type, name, args, code) __inline type __cdecl name args code END_OF_INLINE(name) #define INLINE __inline #define LONG_LONG __int64 /* VC10 is the first version to define int64_t and uint64_t */ #if _MSC_VER < 1600 #define int64_t signed __int64 #define uint64_t unsigned __int64 #endif /* __func__ is C99 */ #ifndef __func__ /* MSVC versions before VC7 don't have __FUNCTION__ */ #if _MSC_VER < 1300 #define __func__ "???" #else #define __func__ __FUNCTION__ #endif #endif /* life would be so easy if compilers would all use the same names! */ #if (!defined S_IRUSR) #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #define S_IXUSR S_IEXEC #endif /* arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" allegro-5.0.10/include/allegro5/platform/aintwiz.h0000644000175000001440000000106011426530515021224 0ustar tjadenusers#ifndef __al_included_allegro5_aintwiz_h #define __al_included_allegro5_aintwiz_h #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/system.h" #include "allegro5/platform/aintunix.h" ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_opengl_driver(void); ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_framebuffer_driver(void); ALLEGRO_SYSTEM_INTERFACE *_al_system_gp2xwiz_driver(void); ALLEGRO_BITMAP_INTERFACE *_al_bitmap_gp2xwiz_driver(void); #endif allegro-5.0.10/include/allegro5/platform/astdint.h0000644000175000001440000000411611426530515021212 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * A header file to get definitions of uint*_t and int*_t. * * By Peter Wang. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_astdint_h #define __al_included_allegro5_astdint_h /* Please only include this file from include/allegro5/internal/alconfig.h * and don't add more than inttypes.h/stdint.h emulation here. Thanks. */ #if defined ALLEGRO_HAVE_INTTYPES_H #include #elif defined ALLEGRO_HAVE_STDINT_H #include #elif defined ALLEGRO_I386 && defined ALLEGRO_LITTLE_ENDIAN #ifndef ALLEGRO_GUESS_INTTYPES_OK #warning Guessing the definitions of fixed-width integer types. #endif #define int8_t signed char #define uint8_t unsigned char #define int16_t signed short #define uint16_t unsigned short #define int32_t signed int #define uint32_t unsigned int #ifdef ALLEGRO_WINDOWS #ifndef _INTPTR_T_DEFINED #ifdef _WIN64 #define intptr_t __int64 #else #define intptr_t int #endif #define _INTPTR_T_DEFINED #endif #ifndef _UINTPTR_T_DEFINED #ifdef _WIN64 #define uintptr_t unsigned __int64 #else #define uintptr_t unsigned int #endif #define _UINTPTR_T_DEFINED #endif #else #define intptr_t int32_t #define uintptr_t uint32_t #endif #else #error I dunno how to get the definitions of fixed-width integer types on your platform. Please report this to your friendly Allegro developer. #endif #endif allegro-5.0.10/include/allegro5/platform/alunix.h0000644000175000001440000000122211340737410021035 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Unix-specific header defines. * * See readme.txt for copyright information. */ #ifndef ALLEGRO_UNIX #error bad include #endif /* Nothing left */ allegro-5.0.10/include/allegro5/platform/aintlnx.h0000644000175000001440000000546712132133074021225 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Some definitions for internal use by the Linux console code. * * By George Foot. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintlnx_h #define __al_included_allegro5_aintlnx_h #ifdef __cplusplus extern "C" { #endif /**************************************/ /************ Driver lists ************/ /**************************************/ extern _AL_DRIVER_INFO _al_linux_keyboard_driver_list[]; extern _AL_DRIVER_INFO _al_linux_mouse_driver_list[]; /****************************************/ /************ Memory mapping ************/ /* (src/linux/lmemory.c) */ /****************************************/ /* struct MAPPED_MEMORY: Used to describe a block of memory mapped * into our address space (in particular, the video memory). */ struct MAPPED_MEMORY { unsigned int base, size; /* linear address and size of block */ int perms; /* PROT_READ | PROT_WRITE, etc */ void *data; /* pointer to block after mapping */ }; extern int __al_linux_have_ioperms; int __al_linux_init_memory (void); int __al_linux_shutdown_memory (void); int __al_linux_map_memory (struct MAPPED_MEMORY *info); int __al_linux_unmap_memory (struct MAPPED_MEMORY *info); /******************************************/ /************ Console routines ************/ /* (src/linux/lconsole.c) */ /******************************************/ extern int __al_linux_vt; extern int __al_linux_console_fd; extern int __al_linux_prev_vt; extern int __al_linux_got_text_message; extern struct termios __al_linux_startup_termio; extern struct termios __al_linux_work_termio; int __al_linux_use_console (void); int __al_linux_leave_console (void); int __al_linux_console_graphics (void); int __al_linux_console_text (void); int __al_linux_wait_for_display (void); /**************************************/ /************ VT switching ************/ /* (src/linux/vtswitch.c) */ /**************************************/ /* signals for VT switching */ #define SIGRELVT SIGUSR1 #define SIGACQVT SIGUSR2 int __al_linux_init_vtswitch (void); int __al_linux_done_vtswitch (void); int __al_linux_set_display_switch_mode (int mode); void __al_linux_display_switch_lock (int lock, int foreground); extern volatile int __al_linux_switching_blocked; #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/platform/alwatcom.h0000644000175000001440000001302012132136342021340 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with Watcom. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __SW_3S #error Allegro only supports stack based calling convention #endif #ifndef __SW_S #error Stack overflow checking must be disabled #endif #include #include #include #include #include #include #pragma disable_message (120 201 202) /* these are available in OpenWatcom 1.3 (12.3) */ #if __WATCOMC__ >= 1230 #define ALLEGRO_HAVE_INTTYPES_H 1 #define ALLEGRO_HAVE_STDINT_H 1 #else #define ALLEGRO_GUESS_INTTYPES_OK #endif /* describe this platform */ #define ALLEGRO_PLATFORM_STR "Watcom" #define ALLEGRO_DOS #define ALLEGRO_I386 #define ALLEGRO_LITTLE_ENDIAN #define LONG_LONG long long #ifdef ALLEGRO_GUESS_INTTYPES_OK #define int64_t signed long long #define uint64_t unsigned long long #endif /* emulate some important djgpp routines */ #define inportb(port) inp(port) #define inportw(port) inpw(port) #define outportb(port, val) outp(port, val) #define outportw(port, val) outpw(port, val) #define ffblk find_t #define ff_name name #define ff_attrib attrib #define ff_fsize size #define ff_ftime wr_time #define ff_fdate wr_date #define findfirst(name, dta, attrib) _dos_findfirst(name, attrib, dta) #define findnext(dta) _dos_findnext(dta) #define random() rand() #define srandom(n) srand(n) #define _dos_ds _default_ds() #define dosmemget(offset, length, buffer) memcpy(buffer, (void *)(offset), length) #define dosmemput(buffer, length, offset) memcpy((void *)(offset), buffer, length) #define __djgpp_nearptr_enable() 1 #define __djgpp_nearptr_disable() #define __djgpp_base_address 0 #define __djgpp_conventional_base 0 #define _crt0_startup_flags 1 #define _CRT0_FLAG_NEARPTR 1 #ifdef __cplusplus extern "C" { #endif typedef union __dpmi_regs { struct { unsigned long edi, esi, ebp, res, ebx, edx, ecx, eax; } d; struct { unsigned short di, di_hi, si, si_hi, bp, bp_hi, res, res_hi; unsigned short bx, bx_hi, dx, dx_hi, cx, cx_hi, ax, ax_hi; unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss; } x; struct { unsigned char edi[4], esi[4], ebp[4], res[4]; unsigned char bl, bh, ebx_b2, ebx_b3, dl, dh, edx_b2, edx_b3; unsigned char cl, ch, ecx_b2, ecx_b3, al, ah, eax_b2, eax_b3; } h; } __dpmi_regs; typedef struct __dpmi_meminfo { unsigned long handle; unsigned long size; unsigned long address; } __dpmi_meminfo; typedef struct __dpmi_free_mem_info { unsigned long largest_available_free_block_in_bytes; unsigned long maximum_unlocked_page_allocation_in_pages; unsigned long maximum_locked_page_allocation_in_pages; unsigned long linear_address_space_size_in_pages; unsigned long total_number_of_unlocked_pages; unsigned long total_number_of_free_pages; unsigned long total_number_of_physical_pages; unsigned long free_linear_address_space_in_pages; unsigned long size_of_paging_file_partition_in_pages; unsigned long reserved[3]; } __dpmi_free_mem_info; extern unsigned long __tb; int __dpmi_int(int vector, __dpmi_regs *regs); int __dpmi_allocate_dos_memory(int paragraphs, int *ret); int __dpmi_free_dos_memory(int selector); int __dpmi_physical_address_mapping(__dpmi_meminfo *info); int __dpmi_free_physical_address_mapping(__dpmi_meminfo *info); int __dpmi_lock_linear_region(__dpmi_meminfo *info); int __dpmi_unlock_linear_region(__dpmi_meminfo *info); int __dpmi_allocate_ldt_descriptors(int count); int __dpmi_free_ldt_descriptor(int descriptor); int __dpmi_get_segment_base_address(int selector, unsigned long *addr); int __dpmi_set_segment_base_address(int selector, unsigned long address); int __dpmi_set_segment_limit(int selector, unsigned long limit); int __dpmi_get_free_memory_information(__dpmi_free_mem_info *info); int __dpmi_simulate_real_mode_interrupt(int vector, __dpmi_regs *regs); int __dpmi_simulate_real_mode_procedure_retf(__dpmi_regs *regs); int _go32_dpmi_lock_data(void *lockaddr, unsigned long locksize); int _go32_dpmi_lock_code(void *lockaddr, unsigned long locksize); long _allocate_real_mode_callback(void (*handler)(__dpmi_regs *r), __dpmi_regs *regs); /* memory locking macros */ void _unlock_dpmi_data(void *addr, int size); #ifdef __cplusplus } #endif #define END_OF_FUNCTION(x) void x##_end(void) { } #define END_OF_STATIC_FUNCTION(x) static void x##_end(void) { } #define LOCK_DATA(d, s) _go32_dpmi_lock_data(d, s) #define LOCK_CODE(c, s) _go32_dpmi_lock_code(c, s) #define UNLOCK_DATA(d,s) _unlock_dpmi_data(d, s) #define LOCK_VARIABLE(x) LOCK_DATA((void *)&x, sizeof(x)) #define LOCK_FUNCTION(x) LOCK_CODE((void *)FP_OFF(x), (long)FP_OFF(x##_end) - (long)FP_OFF(x)) /* arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/aldos.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintdos.h" allegro-5.0.10/include/allegro5/platform/alwin.h0000644000175000001440000000316411454330122020651 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Windows-specific header defines. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef ALLEGRO_WINDOWS #error bad include #endif #include /*******************************************/ /********** magic main emulation ***********/ /*******************************************/ #ifdef __cplusplus extern "C" { #endif AL_FUNC(int, _WinMain, (void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)); #ifdef __cplusplus } #endif /* The following is due to torhu from A.cc (see * http://www.allegro.cc/forums/thread/596872/756993#target) */ #ifndef ALLEGRO_NO_MAGIC_MAIN #if defined _MSC_VER && !defined ALLEGRO_LIB_BUILD #pragma comment(linker,"/ENTRY:mainCRTStartup") #endif #endif /*******************************************/ /************ joystick drivers *************/ /*******************************************/ #define AL_JOY_TYPE_DIRECTX AL_ID('D','X',' ',' ') AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_directx); #define _AL_JOYSTICK_DRIVER_DIRECTX \ { AL_JOY_TYPE_DIRECTX, &_al_joydrv_directx, true }, allegro-5.0.10/include/allegro5/platform/alplatf.h.cmake0000644000175000001440000000601012132132453022233 0ustar tjadenusers/* alplatf.h is generated from alplatf.h.cmake */ #cmakedefine ALLEGRO_MINGW32 #cmakedefine ALLEGRO_UNIX #cmakedefine ALLEGRO_MSVC #cmakedefine ALLEGRO_CFG_D3D #cmakedefine ALLEGRO_CFG_D3D9EX #cmakedefine ALLEGRO_CFG_OPENGL #cmakedefine ALLEGRO_MACOSX #cmakedefine ALLEGRO_BCC32 #cmakedefine ALLEGRO_GP2XWIZ #cmakedefine ALLEGRO_IPHONE #cmakedefine ALLEGRO_CFG_NO_FPU #cmakedefine ALLEGRO_CFG_DLL_TLS #cmakedefine ALLEGRO_CFG_PTHREADS_TLS /*---------------------------------------------------------------------------*/ /* Define to 1 if you have the corresponding header file. */ #cmakedefine ALLEGRO_HAVE_DIRENT_H #cmakedefine ALLEGRO_HAVE_INTTYPES_H #cmakedefine ALLEGRO_HAVE_LINUX_AWE_VOICE_H #cmakedefine ALLEGRO_HAVE_LINUX_INPUT_H #cmakedefine ALLEGRO_HAVE_LINUX_JOYSTICK_H #cmakedefine ALLEGRO_HAVE_LINUX_SOUNDCARD_H #cmakedefine ALLEGRO_HAVE_MACHINE_SOUNDCARD_H #cmakedefine ALLEGRO_HAVE_SOUNDCARD_H #cmakedefine ALLEGRO_HAVE_STDBOOL_H #cmakedefine ALLEGRO_HAVE_STDINT_H #cmakedefine ALLEGRO_HAVE_SV_PROCFS_H #cmakedefine ALLEGRO_HAVE_SYS_IO_H #cmakedefine ALLEGRO_HAVE_SYS_SOUNDCARD_H #cmakedefine ALLEGRO_HAVE_SYS_STAT_H #cmakedefine ALLEGRO_HAVE_SYS_TIME_H #cmakedefine ALLEGRO_HAVE_TIME_H #cmakedefine ALLEGRO_HAVE_SYS_UTSNAME_H #cmakedefine ALLEGRO_HAVE_SYS_TYPES_H #cmakedefine ALLEGRO_HAVE_OSATOMIC_H #cmakedefine ALLEGRO_HAVE_SYS_INOTIFY_H #cmakedefine ALLEGRO_HAVE_SYS_TIMERFD_H /* Define to 1 if the corresponding functions are available. */ #cmakedefine ALLEGRO_HAVE_GETEXECNAME #cmakedefine ALLEGRO_HAVE_MKSTEMP #cmakedefine ALLEGRO_HAVE_MMAP #cmakedefine ALLEGRO_HAVE_MPROTECT #cmakedefine ALLEGRO_HAVE_SCHED_YIELD #cmakedefine ALLEGRO_HAVE_SYSCONF #cmakedefine ALLEGRO_HAVE_FSEEKO #cmakedefine ALLEGRO_HAVE_FTELLO #cmakedefine ALLEGRO_HAVE_VA_COPY /* Define to 1 if procfs reveals argc and argv */ #cmakedefine ALLEGRO_HAVE_PROCFS_ARGCV /*---------------------------------------------------------------------------*/ /* Define if target machine is little endian. */ #cmakedefine ALLEGRO_LITTLE_ENDIAN /* Define if target machine is big endian. */ #cmakedefine ALLEGRO_BIG_ENDIAN /* Define if target platform is Darwin. */ #cmakedefine ALLEGRO_DARWIN /*---------------------------------------------------------------------------*/ /* Define if you need support for X-Windows. */ #cmakedefine ALLEGRO_WITH_XWINDOWS /* Define if XCursor ARGB extension is available. */ #cmakedefine ALLEGRO_XWINDOWS_WITH_XCURSOR /* Define if XF86VidMode extension is supported. */ #cmakedefine ALLEGRO_XWINDOWS_WITH_XF86VIDMODE /* Define if Xinerama extension is supported. */ #cmakedefine ALLEGRO_XWINDOWS_WITH_XINERAMA /* Define if XRandR extension is supported. */ #cmakedefine ALLEGRO_XWINDOWS_WITH_XRANDR /* Define if XIM extension is supported. */ #cmakedefine ALLEGRO_XWINDOWS_WITH_XIM /*---------------------------------------------------------------------------*/ /* Define if target platform is linux. */ #cmakedefine ALLEGRO_LINUX /*---------------------------------------------------------------------------*/ /* vi: set ft=c ts=3 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/platform/aldmc.h0000644000175000001440000000441712132137604020625 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with Digital Mars C compiler. * * By Matthew Leverton. * * See readme.txt for copyright information. */ #include #include #include /* a static auto config */ #define ALLEGRO_HAVE_INTTYPES_H #define ALLEGRO_HAVE_STDINT_H #define LONG_LONG long long /* describe this platform */ #ifdef ALLEGRO_STATICLINK #define ALLEGRO_PLATFORM_STR "DMC.s" #else #define ALLEGRO_PLATFORM_STR "DMC" #endif #define ALLEGRO_WINDOWS #define ALLEGRO_I386 #define ALLEGRO_LITTLE_ENDIAN #ifdef ALLEGRO_USE_CONSOLE #define ALLEGRO_NO_MAGIC_MAIN #endif /* describe how function prototypes look to DMC */ #if (defined ALLEGRO_STATICLINK) || (defined ALLEGRO_SRC) #define _AL_DLL #else #define _AL_DLL __declspec(dllimport) #endif #define AL_VAR(type, name) extern _AL_DLL type name #define AL_ARRAY(type, name) extern _AL_DLL type name[] #define AL_FUNC(type, name, args) extern type name args #define AL_METHOD(type, name, args) type (*name) args #define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args /* Windows specific defines */ #if (defined ALLEGRO_SRC) #if (!defined S_IRUSR) #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #endif typedef unsigned long _fsize_t; struct _wfinddata_t { unsigned attrib; time_t time_create; /* -1 for FAT file systems */ time_t time_access; /* -1 for FAT file systems */ time_t time_write; _fsize_t size; wchar_t name[260]; /* may include spaces. */ }; #endif /* ALLEGRO_SRC */ /* arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" allegro-5.0.10/include/allegro5/platform/albcc32.h0000644000175000001440000000560512132137604020756 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with Borland C++Builder. * * By Greg Hackmann. * * See readme.txt for copyright information. */ /* #ifdef ALLEGRO_SRC #error Currently BCC32 cannot build the library #endif */ #include #include #include #include #pragma warn -8004 /* unused assigned value */ #pragma warn -8008 /* condition always met */ #pragma warn -8057 /* unused parameter */ #pragma warn -8066 /* unreachable code */ /* describe this platform */ #define ALLEGRO_PLATFORM_STR "BCC32" #define ALLEGRO_WINDOWS #define ALLEGRO_I386 #define ALLEGRO_LITTLE_ENDIAN #define ALLEGRO_GUESS_INTTYPES_OK /* TODO: check if BCC has inttypes.h and/or stdint.h */ #ifdef ALLEGRO_USE_CONSOLE #define ALLEGRO_NO_MAGIC_MAIN #endif /* describe how function prototypes look to BCC32 */ #if (defined ALLEGRO_STATICLINK) #define _AL_DLL #elif (defined ALLEGRO_SRC) #define _AL_DLL __declspec(dllexport) #else #define _AL_DLL __declspec(dllimport) #endif #define AL_VAR(type, name) extern _AL_DLL type name #define AL_ARRAY(type, name) extern _AL_DLL type name[] #define AL_FUNC(type, name, args) extern _AL_DLL type name args #define AL_METHOD(type, name, args) type (*name) args #define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args #define END_OF_INLINE(name) //#define AL_INLINE(type, name, args, code) extern __inline type name args code END_OF_INLINE(name) #define INLINE __inline #undef AL_INLINE #undef AL_INLINE_STATIC #define AL_INLINE(type, name, args, code) extern __inline type __cdecl name args code END_OF_INLINE(name) #define AL_INLINE_STATIC(type, name, args, code) static __inline type name args code END_OF_INLINE(name) #define LONG_LONG __int64 #define int64_t signed __int64 #define uint64_t unsigned __int64 #define __func__ "FIXME" #define _wfindfirst __wfindfirst #define _wfindnext __wfindnext #define WinMain _main /* windows specific defines */ #ifdef NONAMELESSUNION #undef NONAMELESSUNION #endif /* This fixes 99.999999% of Borland C++Builder's problems with structs. */ /* arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" allegro-5.0.10/include/allegro5/platform/almngw32.h0000644000175000001440000000447612132137604021204 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with Mingw32. * * By Michael Rickmann. * * Native build version by Henrik Stokseth. * * See readme.txt for copyright information. */ #include #include #include #include #include "allegro5/platform/alplatf.h" /* describe this platform */ #ifdef ALLEGRO_STATICLINK #define ALLEGRO_PLATFORM_STR "MinGW32.s" #else #define ALLEGRO_PLATFORM_STR "MinGW32" #endif #define ALLEGRO_WINDOWS #define ALLEGRO_I386 #define ALLEGRO_LITTLE_ENDIAN #ifdef ALLEGRO_USE_CONSOLE #define ALLEGRO_NO_MAGIC_MAIN #endif /* describe how function prototypes look to MINGW32 */ #if (defined ALLEGRO_STATICLINK) || (defined ALLEGRO_SRC) #define _AL_DLL #else #define _AL_DLL __declspec(dllimport) #endif #define AL_VAR(type, name) extern _AL_DLL type name #define AL_ARRAY(type, name) extern _AL_DLL type name[] #define AL_FUNC(type, name, args) extern type name args #define AL_METHOD(type, name, args) type (*name) args #define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args /* windows specific defines */ #if (defined ALLEGRO_SRC) /* pathches to handle DX7 headers on a win9x system */ /* should WINNT be defined on win9x systems? */ #ifdef WINNT #undef WINNT #endif /* defined in windef.h */ #ifndef HMONITOR_DECLARED #define HMONITOR_DECLARED 1 #endif #endif /* ALLEGRO_SRC */ /* another instance of missing constants in the mingw32 headers */ #ifndef ENUM_CURRENT_SETTINGS #define ENUM_CURRENT_SETTINGS ((DWORD)-1) #endif /* arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" allegro-5.0.10/include/allegro5/platform/aintunix.h0000644000175000001440000000356312132133074021402 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Some definitions for internal use by the Unix library code. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintunix_h #define __al_included_allegro5_aintunix_h #include "allegro5/path.h" #include "allegro5/internal/aintern_driver.h" /* Need right now for XKeyEvent --pw */ #ifdef ALLEGRO_WITH_XWINDOWS #include #endif #ifdef __cplusplus extern "C" { #endif AL_FUNC(ALLEGRO_PATH *, _al_unix_get_path, (int id)); #ifdef __cplusplus } #endif #ifdef ALLEGRO_LINUX #include "allegro5/platform/aintlnx.h" #endif /*----------------------------------------------------------------------* * * * New stuff * * * *----------------------------------------------------------------------*/ /* TODO: integrate this above */ #include "allegro5/platform/aintuthr.h" #ifdef __cplusplus extern "C" { #endif /* time */ AL_FUNC(void, _al_unix_init_time, (void)); /* fdwatch */ void _al_unix_start_watching_fd(int fd, void (*callback)(void *), void *cb_data); void _al_unix_stop_watching_fd(int fd); /* ljoynu.c */ /* This isn't in aintlnx.h because it's needed for the X11 port as well. */ #define _ALLEGRO_JOYDRV_LINUX AL_ID('L','N','X','A') #ifdef ALLEGRO_HAVE_LINUX_JOYSTICK_H AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_linux); #endif #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/platform/aintiphone.h0000644000175000001440000000070611520362736021706 0ustar tjadenusers#ifndef __al_included_allegro5_aintiphone_h #define __al_included_allegro5_aintiphone_h #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/system.h" #include "allegro5/platform/aintunix.h" ALLEGRO_DISPLAY_INTERFACE *_al_display_iphone(void); ALLEGRO_SYSTEM_INTERFACE *_al_system_iphone(void); ALLEGRO_PATH *_al_iphone_get_path(int id); #endif allegro-5.0.10/include/allegro5/platform/aintwthr.h0000644000175000001440000000246011426530515021404 0ustar tjadenusers/* * Windows threads */ #ifndef __al_included_allegro5_aintwthr_h #define __al_included_allegro5_aintwthr_h #include #ifdef __cplusplus extern "C" { #endif /* threads */ struct _AL_THREAD { /* private: */ HANDLE thread; CRITICAL_SECTION cs; bool should_stop; /* XXX: use a dedicated terminate Event object? */ void (*proc)(struct _AL_THREAD *self, void *arg); void *arg; }; struct _AL_MUTEX { PCRITICAL_SECTION cs; }; #define _AL_MUTEX_UNINITED { NULL } #define _AL_MARK_MUTEX_UNINITED(M) do { M.cs = NULL; } while (0) struct _AL_COND { long nWaitersBlocked; long nWaitersGone; long nWaitersToUnblock; HANDLE semBlockQueue; CRITICAL_SECTION semBlockLock; CRITICAL_SECTION mtxUnblockLock; }; typedef struct ALLEGRO_TIMEOUT_WIN ALLEGRO_TIMEOUT_WIN; struct ALLEGRO_TIMEOUT_WIN { DWORD abstime; }; AL_INLINE(bool, _al_get_thread_should_stop, (struct _AL_THREAD *t), { bool ret; EnterCriticalSection(&t->cs); ret = t->should_stop; LeaveCriticalSection(&t->cs); return ret; }) AL_INLINE(void, _al_mutex_lock, (struct _AL_MUTEX *m), { if (m->cs) EnterCriticalSection(m->cs); }) AL_INLINE(void, _al_mutex_unlock, (struct _AL_MUTEX *m), { if (m->cs) LeaveCriticalSection(m->cs); }) #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/platform/aliphone.h0000644000175000001440000000033311327152025021334 0ustar tjadenusers#ifndef ALLEGRO_IPHONE #error bad include #endif #ifndef ALLEGRO_LIB_BUILD #define ALLEGRO_MAGIC_MAIN #define main _al_mangled_main #ifdef __cplusplus extern "C" int _al_mangled_main(int, char **); #endif #endif allegro-5.0.10/include/allegro5/platform/alwizcfg.h0000644000175000001440000000204612132136744021353 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use on GP2X Wiz * * By Trent Gamblin * * See readme.txt for copyright information. */ #include #include /* Describe this platform. */ #define ALLEGRO_PLATFORM_STR "GP2XWIZ" #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwiz.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwiz.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" /* Include configuration information. */ #include "allegro5/platform/alplatf.h" /* No GLX on the Wiz */ #define ALLEGRO_EXCLUDE_GLX allegro-5.0.10/include/allegro5/platform/alosx.h0000644000175000001440000000406011536530240020665 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X specific header defines. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_alosx_h #define __al_included_allegro5_alosx_h #ifndef ALLEGRO_MACOSX #error bad include #endif #include #include #include #include #include #include #if defined __OBJC__ && defined ALLEGRO_SRC #import #import #import #import #import #import #import #import #import #import #import #import #import #import #endif ALLEGRO_PATH *_al_osx_get_path(int id); #ifndef ALLEGRO_LIB_BUILD #ifndef ALLEGRO_NO_MAGIC_MAIN #define ALLEGRO_MAGIC_MAIN #if __GNUC__ >= 4 #define main __attribute__ ((visibility("default"))) _al_mangled_main #else #define main _al_mangled_main #endif #ifdef __cplusplus extern "C" int _al_mangled_main(int, char **); #endif #endif #endif /* Keyboard driver */ #define KEYBOARD_MACOSX AL_ID('O','S','X','K') #endif /* Local variables: */ /* mode: objc */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/platform/alucfg.h0000644000175000001440000000223112132136342020774 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use on Unix platforms. * * By Michael Bukin. * * See readme.txt for copyright information. */ #include #include /* Describe this platform. */ #define ALLEGRO_PLATFORM_STR "Unix" #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alunix.h" #ifdef _this_is_a_hack_to_fool_scons #include "alunix.h" #endif #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintunix.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" /* Include configuration information. */ #include "allegro5/platform/alplatf.h" /* Enable OpenGL if GLX is available. */ #ifdef ALLEGRO_GLX #define ALLEGRO_CFG_OPENGL #endif allegro-5.0.10/include/allegro5/platform/aintwin.h0000644000175000001440000001620312056253610021213 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Some definitions for internal use by the Windows library code. * * By Stefan Schimanski. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintwin_h #define __al_included_allegro5_aintwin_h #ifndef __al_included_allegro5_allegro_h #error must include allegro.h first #endif #ifndef ALLEGRO_WINDOWS #error bad include #endif #include "allegro5/platform/aintwthr.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/system.h" #define WINDOWS_RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_DISPLAY_WIN ALLEGRO_DISPLAY_WIN; struct ALLEGRO_DISPLAY_WIN { ALLEGRO_DISPLAY display; HWND window; HCURSOR mouse_selected_hcursor; bool mouse_cursor_shown; UINT adapter; /* * The display thread must communicate with the main thread * through these variables. */ volatile bool end_thread; /* The display thread should end */ volatile bool thread_ended; /* The display thread has ended */ /* For internal use by drivers, when this has been set to true * after al_resize_display called you can call acknowledge_resize */ bool can_acknowledge; /* For internal use by the windows driver. When this is set and a Windows * window resize event is received by the window procedure, the event is * ignored and this value is set to false. */ bool ignore_resize; /* Size to reset to when al_set_display_flag(FULLSCREEN_WINDOW, false) * is called. */ int toggle_w; int toggle_h; }; /* standard path */ ALLEGRO_PATH *_al_win_get_path(int id); /* thread routines */ void _al_win_thread_init(void); void _al_win_thread_exit(void); /* input routines */ void _al_win_grab_input(ALLEGRO_DISPLAY_WIN *win_disp); /* keyboard routines */ void _al_win_kbd_handle_key_press(int scode, int vcode, bool extended, bool repeated, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_fix_modifiers(void); /* mouse routines */ void _al_win_mouse_handle_move(int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_mouse_handle_wheel(int d, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_mouse_handle_hwheel(int d, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_mouse_handle_button(int button, bool down, int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); void _al_win_mouse_handle_leave(ALLEGRO_DISPLAY_WIN *win_display); void _al_win_mouse_handle_enter(ALLEGRO_DISPLAY_WIN *win_display); /* joystick routines */ void _al_win_joystick_dinput_unacquire(void *unused); void _al_win_joystick_dinput_grab(void *ALLEGRO_DISPLAY_WIN); /* custom Allegro messages */ extern UINT _al_win_msg_call_proc; extern UINT _al_win_msg_suicide; /* main window routines */ AL_FUNC(void, _al_win_wnd_schedule_proc, (HWND wnd, void (*proc)(void*), void *param)); AL_FUNC(void, _al_win_wnd_call_proc, (HWND wnd, void (*proc)(void*), void *param)); int _al_win_determine_adapter(void); extern bool _al_win_disable_screensaver; /* dynamic library loading */ HMODULE _al_win_safe_load_library(const char *filename); /* time */ void _al_win_init_time(void); void _al_win_shutdown_time(void); /* This is used to stop MinGW from complaining about type-punning */ #define MAKE_UNION(ptr, t) \ union { \ LPVOID *v; \ t p; \ } u; \ u.p = (ptr); typedef struct ALLEGRO_SYSTEM_WIN ALLEGRO_SYSTEM_WIN; /* This is our version of ALLEGRO_SYSTEM with driver specific extra data. */ struct ALLEGRO_SYSTEM_WIN { ALLEGRO_SYSTEM system; /* This must be the first member, we "derive" from it. */ ALLEGRO_DISPLAY *mouse_grab_display; /* May be inaccurate. */ int toggle_mouse_grab_keycode; /* Disabled if zero. */ unsigned int toggle_mouse_grab_modifiers; }; /* helpers to create windows */ HWND _al_win_create_window(ALLEGRO_DISPLAY *display, int width, int height, int flags); HWND _al_win_create_faux_fullscreen_window(LPCTSTR devname, ALLEGRO_DISPLAY *display, int x1, int y1, int width, int height, int refresh_rate, int flags); int _al_win_init_window(void); HWND _al_win_create_hidden_window(void); /* icon helpers */ void _al_win_set_display_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmap[]); HICON _al_win_create_icon(HWND wnd, ALLEGRO_BITMAP *sprite, int xfocus, int yfocus, bool is_cursor, bool resize); /* window decorations */ void _al_win_set_window_position(HWND window, int x, int y); void _al_win_get_window_position(HWND window, int *x, int *y); void _al_win_set_window_frameless(ALLEGRO_DISPLAY *display, HWND window, bool frameless); bool _al_win_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff); void _al_win_set_window_title(ALLEGRO_DISPLAY *display, const char *title); /* cursor routines */ typedef struct ALLEGRO_MOUSE_CURSOR_WIN ALLEGRO_MOUSE_CURSOR_WIN; struct ALLEGRO_MOUSE_CURSOR_WIN { HCURSOR hcursor; }; ALLEGRO_MOUSE_CURSOR* _al_win_create_mouse_cursor(ALLEGRO_BITMAP *sprite, int xfocus, int yfocus); void _al_win_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor); bool _al_win_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor); bool _al_win_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id); bool _al_win_show_mouse_cursor(ALLEGRO_DISPLAY *display); bool _al_win_hide_mouse_cursor(ALLEGRO_DISPLAY *display); /* driver specific functions */ #if defined ALLEGRO_CFG_D3D ALLEGRO_DISPLAY_INTERFACE* _al_display_d3d_driver(void); int _al_d3d_get_num_display_modes(int format, int refresh_rate, int flags); ALLEGRO_DISPLAY_MODE* _al_d3d_get_display_mode(int index, int format, int refresh_rate, int flags, ALLEGRO_DISPLAY_MODE *mode); bool _al_d3d_init_display(void); #endif /* defined ALLEGRO_CFG_D3D */ #if defined ALLEGRO_CFG_OPENGL ALLEGRO_DISPLAY_INTERFACE *_al_display_wgl_driver(void); int _al_wgl_get_num_display_modes(int format, int refresh_rate, int flags); ALLEGRO_DISPLAY_MODE* _al_wgl_get_display_mode(int index, int format, int refresh_rate, int flags, ALLEGRO_DISPLAY_MODE *mode); bool _al_wgl_init_display(void); #endif /* defined ALLEGRO_CFG_OPENGL */ #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/platform/alosxcfg.h0000644000175000001440000000215012132137604021343 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use with MacOS X. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_alosxcfg_h #define __al_included_allegro5_alosxcfg_h /* Include configuration information. */ #include "allegro5/platform/alplatf.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" /* Describe this platform */ #define ALLEGRO_PLATFORM_STR "MacOS X" /* Arrange for other headers to be included later on */ #define ALLEGRO_EXTRA_HEADER "allegro5/platform/alosx.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintosx.h" #endif allegro-5.0.10/include/allegro5/platform/aintuthr.h0000644000175000001440000000366711426530515021414 0ustar tjadenusers/* * UNIX threads */ #ifndef __al_included_allegro5_aintuthr_h #define __al_included_allegro5_aintuthr_h #include #include "allegro5/internal/aintern_thread.h" #ifdef __cplusplus extern "C" { #endif /* threads */ struct _AL_THREAD { /* private: */ pthread_t thread; pthread_mutex_t mutex; bool should_stop; void (*proc)(struct _AL_THREAD *self, void *arg); void *arg; }; struct _AL_MUTEX { bool inited; pthread_mutex_t mutex; }; #define _AL_MUTEX_UNINITED { false, PTHREAD_MUTEX_INITIALIZER } /* makes no sense, but shuts gcc up */ #define _AL_MARK_MUTEX_UNINITED(M) do { M.inited = false; } while (0) struct _AL_COND { pthread_cond_t cond; }; typedef struct ALLEGRO_TIMEOUT_UNIX ALLEGRO_TIMEOUT_UNIX; struct ALLEGRO_TIMEOUT_UNIX { struct timespec abstime; }; AL_INLINE(bool, _al_get_thread_should_stop, (struct _AL_THREAD *t), { bool ret; pthread_mutex_lock(&t->mutex); ret = t->should_stop; pthread_mutex_unlock(&t->mutex); return ret; }) AL_FUNC(void, _al_mutex_init, (struct _AL_MUTEX*)); AL_FUNC(void, _al_mutex_destroy, (struct _AL_MUTEX*)); AL_INLINE(void, _al_mutex_lock, (struct _AL_MUTEX *m), { if (m->inited) pthread_mutex_lock(&m->mutex); }) AL_INLINE(void, _al_mutex_unlock, (struct _AL_MUTEX *m), { if (m->inited) pthread_mutex_unlock(&m->mutex); }) AL_INLINE(void, _al_cond_init, (struct _AL_COND *cond), { pthread_cond_init(&cond->cond, NULL); }) AL_INLINE(void, _al_cond_destroy, (struct _AL_COND *cond), { pthread_cond_destroy(&cond->cond); }) AL_INLINE(void, _al_cond_wait, (struct _AL_COND *cond, struct _AL_MUTEX *mutex), { pthread_cond_wait(&cond->cond, &mutex->mutex); }) AL_INLINE(void, _al_cond_broadcast, (struct _AL_COND *cond), { pthread_cond_broadcast(&cond->cond); }) AL_INLINE(void, _al_cond_signal, (struct _AL_COND *cond), { pthread_cond_signal(&cond->cond); }) #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/platform/aliphonecfg.h0000644000175000001440000000207412103733650022022 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines for use on iOS. * * See readme.txt for copyright information. */ #include #include /* Describe this platform. */ #define ALLEGRO_PLATFORM_STR "IPHONE" #define ALLEGRO_EXTRA_HEADER "allegro5/platform/aliphone.h" #define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintiphone.h" #define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" #define ALLEGRO_EXCLUDE_GLX #ifndef AL_INLINE #define AL_INLINE(type, name, args, code) \ static __inline__ type name args; \ static __inline__ type name args code #endif allegro-5.0.10/include/allegro5/platform/astdbool.h0000644000175000001440000000175711426530515021363 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * A header file to get C99's stdbool.h. * * By Peter Wang. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_astdbool_h #define __al_included_allegro5_astdbool_h #ifndef __cplusplus # ifdef ALLEGRO_HAVE_STDBOOL_H # include # else # ifndef ALLEGRO_HAVE__BOOL typedef unsigned char _Bool; # endif # define bool _Bool # define false 0 # define true 1 # define __bool_true_false_are_defined 1 # endif #endif #endif allegro-5.0.10/include/allegro5/platform/aintosx.h0000644000175000001440000001227211771522663021243 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Internal header file for the MacOS X Allegro library port. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintosx_h #define __al_included_allegro5_aintosx_h #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/platform/aintunix.h" #ifdef __OBJC__ #include #include #include #include #include #include #ifndef NSAppKitVersionNumber10_1 #define NSAppKitVersionNumber10_1 620 #endif #ifndef NSAppKitVersionNumber10_2 #define NSAppKitVersionNumber10_2 663 #endif #if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 #error Cannot target OS X versions before 10.4 #endif /* We include code to detect a "dead bootstrap context" and fail * gracefully if that situation is detected, but some of the code uses * deprecated functions and it isn't generally clear what "dead bootstrap * context" means (google's first result points back to Allegro). It is * also not clear if the problem this aims to solve still occurs on recent * versions of OS X. * Define OSX_BOOTSTRAP_DETECTION to compile this check in. It can * be brought back/reactivated when someone finds out how. */ //#define OSX_BOOTSTRAP_DETECTION #define HID_MAX_DEVICES MAX_JOYSTICKS #define HID_MOUSE 0 #define HID_JOYSTICK 1 #define HID_GAMEPAD 2 #define HID_MAX_DEVICE_ELEMENTS ((MAX_JOYSTICK_AXIS * MAX_JOYSTICK_STICKS) + MAX_JOYSTICK_BUTTONS) #define HID_ELEMENT_BUTTON 0 #define HID_ELEMENT_AXIS 1 #define HID_ELEMENT_AXIS_PRIMARY_X 2 #define HID_ELEMENT_AXIS_PRIMARY_Y 3 #define HID_ELEMENT_STANDALONE_AXIS 4 #define HID_ELEMENT_HAT 5 typedef struct HID_ELEMENT { int type; IOHIDElementCookie cookie; int max, min; int app; int col; int index; char *name; } HID_ELEMENT; typedef struct HID_DEVICE { int type; char *manufacturer; char *product; int num_elements; int capacity; HID_ELEMENT *element; IOHIDDeviceInterface **interface; int cur_app; } HID_DEVICE; typedef struct { int count; int capacity; HID_DEVICE* devices; } HID_DEVICE_COLLECTION; int _al_osx_bootstrap_ok(void); void _al_osx_keyboard_handler(int pressed, NSEvent *event, ALLEGRO_DISPLAY*); void _al_osx_keyboard_modifiers(unsigned int new_mods, ALLEGRO_DISPLAY*); void _al_osx_keyboard_focused(int focused, int state); void _al_osx_mouse_generate_event(NSEvent*, ALLEGRO_DISPLAY*); void _al_osx_mouse_handler(NSEvent*); int _al_osx_mouse_set_sprite(ALLEGRO_BITMAP *sprite, int x, int y); int _al_osx_mouse_show(ALLEGRO_BITMAP *bmp, int x, int y); void _al_osx_mouse_hide(void); void _al_osx_mouse_move(int x, int y); HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION*); void _al_osx_hid_free(HID_DEVICE_COLLECTION *); // Record in the keyboard state that the main window has changed void _al_osx_switch_keyboard_focus(ALLEGRO_DISPLAY *, bool switch_in); // Record in the mouse state that the main window has changed void _al_osx_switch_mouse_focus(ALLEGRO_DISPLAY *, bool switch_in); // Clear the mouse state when a dialog closes in the dialog addon void _al_osx_clear_mouse_state(void); // Notify the display that the mouse driver was installed/uninstalled. void _al_osx_mouse_was_installed(BOOL); // Create and destroy mouse cursors ALLEGRO_MOUSE_CURSOR *_al_osx_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus); void _al_osx_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *curs); // Notify the display that the keyboard driver was installed/uninstalled. void _al_osx_keyboard_was_installed(BOOL); // Notify that the quit menu was clicked void _al_osx_post_quit(void); // Get the underlying view NSView* _al_osx_view_from_display(ALLEGRO_DISPLAY*); // Create an image from an allegro bitmap NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp); // Drivers AL_FUNC(ALLEGRO_KEYBOARD_DRIVER*, _al_osx_get_keyboard_driver, (void)); AL_FUNC(ALLEGRO_DISPLAY_INTERFACE*, _al_osx_get_display_driver, (void)); AL_FUNC(ALLEGRO_MOUSE_DRIVER*, _al_osx_get_mouse_driver, (void)); AL_FUNC(ALLEGRO_JOYSTICK_DRIVER*, _al_osx_get_joystick_driver, (void)); #endif AL_FUNC(int, _al_osx_run_main, (int argc, char **argv, int (*real_main)(int, char **))); #endif /* Local variables: */ /* mode: objc */ /* c-basic-offset: 3 */ /* indent-tabs-mode: nil */ /* End: */ allegro-5.0.10/include/allegro5/debug.h0000644000175000001440000000606012027206737017012 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Debug facilities. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_debug_h #define __al_included_allegro5_debug_h #include #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif AL_FUNC(bool, _al_trace_prefix, (char const *channel, int level, char const *file, int line, char const *function)); AL_PRINTFUNC(void, _al_trace_suffix, (const char *msg, ...), 1, 2); #ifdef DEBUGMODE /* Must not be used with a trailing semicolon. */ #ifdef ALLEGRO_GCC #define ALLEGRO_DEBUG_CHANNEL(x) \ static char const *__al_debug_channel __attribute__((unused)) = x; #else #define ALLEGRO_DEBUG_CHANNEL(x) \ static char const *__al_debug_channel = x; #endif #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, level) \ !_al_trace_prefix(channel, level, __FILE__, __LINE__, __func__) \ ? (void)0 : _al_trace_suffix #else #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, x) 1 ? (void) 0 : _al_trace_suffix #define ALLEGRO_DEBUG_CHANNEL(x) #endif #define ALLEGRO_TRACE_LEVEL(x) ALLEGRO_TRACE_CHANNEL_LEVEL(__al_debug_channel, x) #define ALLEGRO_DEBUG ALLEGRO_TRACE_LEVEL(0) #define ALLEGRO_INFO ALLEGRO_TRACE_LEVEL(1) #define ALLEGRO_WARN ALLEGRO_TRACE_LEVEL(2) #define ALLEGRO_ERROR ALLEGRO_TRACE_LEVEL(3) /* Run-time assertions. */ AL_FUNCPTR(void, _al_user_assert_handler, (char const *expr, char const *file, int line, char const *func)); AL_FUNC(void, al_register_assert_handler, (void (*handler)(char const *expr, char const *file, int line, char const *func))); #ifdef NDEBUG #define ALLEGRO_ASSERT(e) ((void)(0 && (e))) #else #define ALLEGRO_ASSERT(e) \ ((e) ? (void) 0 \ : (_al_user_assert_handler) ? \ _al_user_assert_handler(#e, __FILE__, __LINE__, __func__) \ : assert(e)) #endif /* Compile time assertions. */ #define ALLEGRO_ASSERT_CONCAT_(a, b) a##b #define ALLEGRO_ASSERT_CONCAT(a, b) ALLEGRO_ASSERT_CONCAT_(a, b) #define ALLEGRO_STATIC_ASSERT(module, e) \ struct ALLEGRO_ASSERT_CONCAT(static_assert_##module##_line_, __LINE__) \ { unsigned int bf : !!(e); } /* We are lazy and use just ASSERT while Allegro itself is compiled. */ #ifdef ALLEGRO_LIB_BUILD #define ASSERT(x) ALLEGRO_ASSERT(x) #endif #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/timer.h0000644000175000001440000000362411441714147017045 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Timer routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_timer_h #define __al_included_allegro5_timer_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Function: ALLEGRO_USECS_TO_SECS */ #define ALLEGRO_USECS_TO_SECS(x) ((x) / 1000000.0) /* Function: ALLEGRO_MSECS_TO_SECS */ #define ALLEGRO_MSECS_TO_SECS(x) ((x) / 1000.0) /* Function: ALLEGRO_BPS_TO_SECS */ #define ALLEGRO_BPS_TO_SECS(x) (1.0 / (x)) /* Function: ALLEGRO_BPM_TO_SECS */ #define ALLEGRO_BPM_TO_SECS(x) (60.0 / (x)) /* Type: ALLEGRO_TIMER */ typedef struct ALLEGRO_TIMER ALLEGRO_TIMER; AL_FUNC(ALLEGRO_TIMER*, al_create_timer, (double speed_secs)); AL_FUNC(void, al_destroy_timer, (ALLEGRO_TIMER *timer)); AL_FUNC(void, al_start_timer, (ALLEGRO_TIMER *timer)); AL_FUNC(void, al_stop_timer, (ALLEGRO_TIMER *timer)); AL_FUNC(bool, al_get_timer_started, (const ALLEGRO_TIMER *timer)); AL_FUNC(double, al_get_timer_speed, (const ALLEGRO_TIMER *timer)); AL_FUNC(void, al_set_timer_speed, (ALLEGRO_TIMER *timer, double speed_secs)); AL_FUNC(int64_t, al_get_timer_count, (const ALLEGRO_TIMER *timer)); AL_FUNC(void, al_set_timer_count, (ALLEGRO_TIMER *timer, int64_t count)); AL_FUNC(void, al_add_timer_count, (ALLEGRO_TIMER *timer, int64_t diff)); AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_timer_event_source, (ALLEGRO_TIMER *timer)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/color.h0000644000175000001440000000455212063331525017040 0ustar tjadenusers#ifndef __al_included_allegro5_color_h #define __al_included_allegro5_color_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_COLOR */ typedef struct ALLEGRO_COLOR ALLEGRO_COLOR; struct ALLEGRO_COLOR { float r, g, b, a; }; /* Enum: ALLEGRO_PIXEL_FORMAT */ typedef enum ALLEGRO_PIXEL_FORMAT { ALLEGRO_PIXEL_FORMAT_ANY = 0, ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_PIXEL_FORMAT_ARGB_4444, ALLEGRO_PIXEL_FORMAT_RGB_888, /* 24 bit format */ ALLEGRO_PIXEL_FORMAT_RGB_565, ALLEGRO_PIXEL_FORMAT_RGB_555, ALLEGRO_PIXEL_FORMAT_RGBA_5551, ALLEGRO_PIXEL_FORMAT_ARGB_1555, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_PIXEL_FORMAT_XBGR_8888, ALLEGRO_PIXEL_FORMAT_BGR_888, /* 24 bit format */ ALLEGRO_PIXEL_FORMAT_BGR_565, ALLEGRO_PIXEL_FORMAT_BGR_555, ALLEGRO_PIXEL_FORMAT_RGBX_8888, ALLEGRO_PIXEL_FORMAT_XRGB_8888, ALLEGRO_PIXEL_FORMAT_ABGR_F32, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_PIXEL_FORMAT_RGBA_4444, ALLEGRO_NUM_PIXEL_FORMATS } ALLEGRO_PIXEL_FORMAT; /* Pixel mapping */ AL_FUNC(ALLEGRO_COLOR, al_map_rgb, (unsigned char r, unsigned char g, unsigned char b)); AL_FUNC(ALLEGRO_COLOR, al_map_rgba, (unsigned char r, unsigned char g, unsigned char b, unsigned char a)); AL_FUNC(ALLEGRO_COLOR, al_map_rgb_f, (float r, float g, float b)); AL_FUNC(ALLEGRO_COLOR, al_map_rgba_f, (float r, float g, float b, float a)); /* Pixel unmapping */ AL_FUNC(void, al_unmap_rgb, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b)); AL_FUNC(void, al_unmap_rgba, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)); AL_FUNC(void, al_unmap_rgb_f, (ALLEGRO_COLOR color, float *r, float *g, float *b)); AL_FUNC(void, al_unmap_rgba_f, (ALLEGRO_COLOR color, float *r, float *g, float *b, float *a)); /* Pixel formats */ AL_FUNC(int, al_get_pixel_size, (int format)); AL_FUNC(int, al_get_pixel_format_bits, (int format)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/bitmap_draw.h0000644000175000001440000000406412057357022020214 0ustar tjadenusers#ifndef __al_included_allegro5_bitmap_draw_h #define __al_included_allegro5_bitmap_draw_h #include "allegro5/bitmap.h" #ifdef __cplusplus extern "C" { #endif /* Flags for the blitting functions */ enum { ALLEGRO_FLIP_HORIZONTAL = 0x00001, ALLEGRO_FLIP_VERTICAL = 0x00002 }; /* Blitting */ AL_FUNC(void, al_draw_bitmap, (ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)); AL_FUNC(void, al_draw_bitmap_region, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); AL_FUNC(void, al_draw_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); AL_FUNC(void, al_draw_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float angle, int flags)); AL_FUNC(void, al_draw_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); /* Tinted blitting */ AL_FUNC(void, al_draw_tinted_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float dx, float dy, int flags)); AL_FUNC(void, al_draw_tinted_bitmap_region, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); AL_FUNC(void, al_draw_tinted_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); AL_FUNC(void, al_draw_tinted_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float angle, int flags)); AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap_region, ( ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/inline/0000755000175000001440000000000012157230743017025 5ustar tjadenusersallegro-5.0.10/include/allegro5/inline/fmaths.inl0000644000175000001440000001240112132131662021002 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Fixed point math inline functions (generic C). * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_inline_fmaths_inl #define __al_included_allegro5_inline_fmaths_inl #include "allegro5/error.h" #ifdef __cplusplus extern "C" { #endif /* al_ftofix and al_fixtof are used in generic C versions of al_fixmul and al_fixdiv */ AL_INLINE(al_fixed, al_ftofix, (double x), { if (x > 32767.0) { al_set_errno(ERANGE); return 0x7FFFFFFF; } if (x < -32767.0) { al_set_errno(ERANGE); return -0x7FFFFFFF; } return (al_fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); }) AL_INLINE(double, al_fixtof, (al_fixed x), { return (double)x / 65536.0; }) AL_INLINE(al_fixed, al_fixadd, (al_fixed x, al_fixed y), { al_fixed result = x + y; if (result >= 0) { if ((x < 0) && (y < 0)) { al_set_errno(ERANGE); return -0x7FFFFFFF; } else return result; } else { if ((x > 0) && (y > 0)) { al_set_errno(ERANGE); return 0x7FFFFFFF; } else return result; } }) AL_INLINE(al_fixed, al_fixsub, (al_fixed x, al_fixed y), { al_fixed result = x - y; if (result >= 0) { if ((x < 0) && (y > 0)) { al_set_errno(ERANGE); return -0x7FFFFFFF; } else return result; } else { if ((x > 0) && (y < 0)) { al_set_errno(ERANGE); return 0x7FFFFFFF; } else return result; } }) /* In benchmarks conducted circa May 2005 we found that, in the main: * - IA32 machines performed faster with one implementation; * - AMD64 and G4 machines performed faster with another implementation. * * Benchmarks were mainly done with differing versions of gcc. * Results varied with other compilers, optimisation levels, etc. * so this is not optimal, though a tenable compromise. * * Note that the following implementation are NOT what were benchmarked. * We had forgotten to put in overflow detection in those versions. * If you don't need overflow detection then previous versions in the * CVS tree might be worth looking at. * * PS. Don't move the #ifs inside the AL_INLINE; BCC doesn't like it. */ #if (defined ALLEGRO_I386) || (!defined LONG_LONG) AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), { return al_ftofix(al_fixtof(x) * al_fixtof(y)); }) #else AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), { LONG_LONG lx = x; LONG_LONG ly = y; LONG_LONG lres = (lx*ly); if (lres > 0x7FFFFFFF0000LL) { al_set_errno(ERANGE); return 0x7FFFFFFF; } else if (lres < -0x7FFFFFFF0000LL) { al_set_errno(ERANGE); return 0x80000000; } else { int res = lres >> 16; return res; } }) #endif /* al_fixmul() C implementations */ #if (defined ALLEGRO_CFG_NO_FPU) && (defined LONG_LONG) AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), { LONG_LONG lres = x; if (y == 0) { al_set_errno(ERANGE); return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; } lres <<= 16; lres /= y; if (lres > 0x7FFFFFFF) { al_set_errno(ERANGE); return 0x7FFFFFFF; } else if (lres < -0x7FFFFFFF) { al_set_errno(ERANGE); return 0x80000000; } else { return (al_fixed)(lres); } }) #else AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), { if (y == 0) { al_set_errno(ERANGE); return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; } else return al_ftofix(al_fixtof(x) / al_fixtof(y)); }) #endif AL_INLINE(int, al_fixfloor, (al_fixed x), { /* (x >> 16) is not portable */ if (x >= 0) return (x >> 16); else return ~((~x) >> 16); }) AL_INLINE(int, al_fixceil, (al_fixed x), { if (x > 0x7FFF0000) { al_set_errno(ERANGE); return 0x7FFF; } return al_fixfloor(x + 0xFFFF); }) AL_INLINE(al_fixed, al_itofix, (int x), { return x << 16; }) AL_INLINE(int, al_fixtoi, (al_fixed x), { return al_fixfloor(x) + ((x & 0x8000) >> 15); }) AL_INLINE(al_fixed, al_fixcos, (al_fixed x), { return _al_fix_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; }) AL_INLINE(al_fixed, al_fixsin, (al_fixed x), { return _al_fix_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; }) AL_INLINE(al_fixed, al_fixtan, (al_fixed x), { return _al_fix_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; }) AL_INLINE(al_fixed, al_fixacos, (al_fixed x), { if ((x < -65536) || (x > 65536)) { al_set_errno(EDOM); return 0; } return _al_fix_acos_tbl[(x+65536+127)>>8]; }) AL_INLINE(al_fixed, al_fixasin, (al_fixed x), { if ((x < -65536) || (x > 65536)) { al_set_errno(EDOM); return 0; } return 0x00400000 - _al_fix_acos_tbl[(x+65536+127)>>8]; }) #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/allegro_windows.h0000644000175000001440000000164611431556561021131 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Header file for Windows specific API. * * By Trent Gamblin. * */ #ifndef __al_included_allegro5_allegro_windows_h #define __al_included_allegro5_allegro_windows_h #include #ifdef __cplusplus extern "C" { #endif /* * Public Windows-related API */ AL_FUNC(HWND, al_get_win_window_handle, (ALLEGRO_DISPLAY *)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/keyboard.h0000644000175000001440000000352312057357022017522 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Keyboard routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_keyboard_h #define __al_included_allegro5_keyboard_h #include "allegro5/base.h" #include "allegro5/events.h" #include "allegro5/keycodes.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_KEYBOARD ALLEGRO_KEYBOARD; /* Type: ALLEGRO_KEYBOARD_STATE */ typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE; struct ALLEGRO_KEYBOARD_STATE { struct ALLEGRO_DISPLAY *display; /* public */ /* internal */ unsigned int __key_down__internal__[(ALLEGRO_KEY_MAX + 31) / 32]; }; AL_FUNC(bool, al_is_keyboard_installed, (void)); AL_FUNC(bool, al_install_keyboard, (void)); AL_FUNC(void, al_uninstall_keyboard, (void)); AL_FUNC(bool, al_set_keyboard_leds, (int leds)); AL_FUNC(const char *, al_keycode_to_name, (int keycode)); AL_FUNC(void, al_get_keyboard_state, (ALLEGRO_KEYBOARD_STATE *ret_state)); AL_FUNC(bool, al_key_down, (const ALLEGRO_KEYBOARD_STATE *, int keycode)); AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_keyboard_event_source, (void)); /* TODO: use the config system */ AL_VAR(bool, _al_three_finger_flag); AL_VAR(bool, _al_key_led_flag); #ifdef __cplusplus } #endif #endif /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/include/allegro5/altime.h0000644000175000001440000000076611446133765017212 0ustar tjadenusers#ifndef __al_included_allegro5_altime_h #define __al_included_allegro5_altime_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_TIMEOUT */ typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT; struct ALLEGRO_TIMEOUT { uint64_t __pad1__; uint64_t __pad2__; }; AL_FUNC(double, al_get_time, (void)); AL_FUNC(void, al_rest, (double seconds)); AL_FUNC(void, al_init_timeout, (ALLEGRO_TIMEOUT *timeout, double seconds)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/drawing.h0000644000175000001440000000060112057357022017347 0ustar tjadenusers#ifndef __al_included_allegro5_drawing_h #define __al_included_allegro5_drawing_h #include "allegro5/color.h" #ifdef __cplusplus extern "C" { #endif /* Drawing primitives */ AL_FUNC(void, al_clear_to_color, (ALLEGRO_COLOR color)); AL_FUNC(void, al_draw_pixel, (float x, float y, ALLEGRO_COLOR color)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/allegro_osx.h0000644000175000001440000000140011777641345020244 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * */ #ifndef A5_OSX_ALLEGRO_H #define A5_OSX_ALLEGRO_H /* * Public Objective-C OSX-related API */ #ifdef __cplusplus extern "C" { #endif AL_FUNC(NSWindow *, al_osx_get_window, (ALLEGRO_DISPLAY *d)); #ifdef __cplusplus } #endif #endif /* A5_OSX_ALLEGRO_H */ allegro-5.0.10/include/allegro5/events.h0000644000175000001440000001533212057357022017227 0ustar tjadenusers#ifndef __al_included_allegro5_events_h #define __al_included_allegro5_events_h #include "allegro5/altime.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_EVENT_TYPE */ typedef unsigned int ALLEGRO_EVENT_TYPE; enum { ALLEGRO_EVENT_JOYSTICK_AXIS = 1, ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN = 2, ALLEGRO_EVENT_JOYSTICK_BUTTON_UP = 3, ALLEGRO_EVENT_JOYSTICK_CONFIGURATION = 4, ALLEGRO_EVENT_KEY_DOWN = 10, ALLEGRO_EVENT_KEY_CHAR = 11, ALLEGRO_EVENT_KEY_UP = 12, ALLEGRO_EVENT_MOUSE_AXES = 20, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN = 21, ALLEGRO_EVENT_MOUSE_BUTTON_UP = 22, ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY = 23, ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY = 24, ALLEGRO_EVENT_MOUSE_WARPED = 25, ALLEGRO_EVENT_TIMER = 30, ALLEGRO_EVENT_DISPLAY_EXPOSE = 40, ALLEGRO_EVENT_DISPLAY_RESIZE = 41, ALLEGRO_EVENT_DISPLAY_CLOSE = 42, ALLEGRO_EVENT_DISPLAY_LOST = 43, ALLEGRO_EVENT_DISPLAY_FOUND = 44, ALLEGRO_EVENT_DISPLAY_SWITCH_IN = 45, ALLEGRO_EVENT_DISPLAY_SWITCH_OUT = 46, ALLEGRO_EVENT_DISPLAY_ORIENTATION = 47 }; /* Function: ALLEGRO_EVENT_TYPE_IS_USER * * 1 <= n < 512 - builtin events * 512 <= n < 1024 - reserved user events (for addons) * 1024 <= n - unreserved user events */ #define ALLEGRO_EVENT_TYPE_IS_USER(t) ((t) >= 512) /* Function: ALLEGRO_GET_EVENT_TYPE */ #define ALLEGRO_GET_EVENT_TYPE(a, b, c, d) AL_ID(a, b, c, d) /* Type: ALLEGRO_EVENT_SOURCE */ typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE; struct ALLEGRO_EVENT_SOURCE { int __pad[32]; }; /* * Event structures * * All event types have the following fields in common. * * type -- the type of event this is * timestamp -- when this event was generated * source -- which event source generated this event * * For people writing event sources: The common fields must be at the * very start of each event structure, i.e. put _AL_EVENT_HEADER at the * front. */ #define _AL_EVENT_HEADER(srctype) \ ALLEGRO_EVENT_TYPE type; \ srctype *source; \ double timestamp; typedef struct ALLEGRO_ANY_EVENT { _AL_EVENT_HEADER(ALLEGRO_EVENT_SOURCE) } ALLEGRO_ANY_EVENT; typedef struct ALLEGRO_DISPLAY_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_DISPLAY) int x, y; int width, height; int orientation; } ALLEGRO_DISPLAY_EVENT; typedef struct ALLEGRO_JOYSTICK_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_JOYSTICK) struct ALLEGRO_JOYSTICK *id; int stick; int axis; float pos; int button; } ALLEGRO_JOYSTICK_EVENT; typedef struct ALLEGRO_KEYBOARD_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_KEYBOARD) struct ALLEGRO_DISPLAY *display; /* the window the key was pressed in */ int keycode; /* the physical key pressed */ int unichar; /* unicode character or negative */ unsigned int modifiers; /* bitfield */ bool repeat; /* auto-repeated or not */ } ALLEGRO_KEYBOARD_EVENT; typedef struct ALLEGRO_MOUSE_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_MOUSE) struct ALLEGRO_DISPLAY *display; /* (display) Window the event originate from * (x, y) Primary mouse position * (z) Mouse wheel position (1D 'wheel'), or, * (w, z) Mouse wheel position (2D 'ball') * (pressure) The pressure applied, for stylus (0 or 1 for normal mouse) */ int x, y, z, w; int dx, dy, dz, dw; unsigned int button; float pressure; } ALLEGRO_MOUSE_EVENT; typedef struct ALLEGRO_TIMER_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_TIMER) int64_t count; double error; } ALLEGRO_TIMER_EVENT; /* Type: ALLEGRO_USER_EVENT */ typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT; struct ALLEGRO_USER_EVENT { _AL_EVENT_HEADER(struct ALLEGRO_EVENT_SOURCE) struct ALLEGRO_USER_EVENT_DESCRIPTOR *__internal__descr; intptr_t data1; intptr_t data2; intptr_t data3; intptr_t data4; }; /* Type: ALLEGRO_EVENT */ typedef union ALLEGRO_EVENT ALLEGRO_EVENT; union ALLEGRO_EVENT { /* This must be the same as the first field of _AL_EVENT_HEADER. */ ALLEGRO_EVENT_TYPE type; /* `any' is to allow the user to access the other fields which are * common to all event types, without using some specific type * structure. */ ALLEGRO_ANY_EVENT any; ALLEGRO_DISPLAY_EVENT display; ALLEGRO_JOYSTICK_EVENT joystick; ALLEGRO_KEYBOARD_EVENT keyboard; ALLEGRO_MOUSE_EVENT mouse; ALLEGRO_TIMER_EVENT timer; ALLEGRO_USER_EVENT user; }; /* Event sources */ AL_FUNC(void, al_init_user_event_source, (ALLEGRO_EVENT_SOURCE *)); AL_FUNC(void, al_destroy_user_event_source, (ALLEGRO_EVENT_SOURCE *)); /* The second argument is ALLEGRO_EVENT instead of ALLEGRO_USER_EVENT * to prevent users passing a pointer to a too-short structure. */ AL_FUNC(bool, al_emit_user_event, (ALLEGRO_EVENT_SOURCE *, ALLEGRO_EVENT *, void (*dtor)(ALLEGRO_USER_EVENT *))); AL_FUNC(void, al_unref_user_event, (ALLEGRO_USER_EVENT *)); AL_FUNC(void, al_set_event_source_data, (ALLEGRO_EVENT_SOURCE*, intptr_t data)); AL_FUNC(intptr_t, al_get_event_source_data, (const ALLEGRO_EVENT_SOURCE*)); /* Event queues */ /* Type: ALLEGRO_EVENT_QUEUE */ typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE; AL_FUNC(ALLEGRO_EVENT_QUEUE*, al_create_event_queue, (void)); AL_FUNC(void, al_destroy_event_queue, (ALLEGRO_EVENT_QUEUE*)); AL_FUNC(void, al_register_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, al_unregister_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); AL_FUNC(bool, al_is_event_queue_empty, (ALLEGRO_EVENT_QUEUE*)); AL_FUNC(bool, al_get_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); AL_FUNC(bool, al_peek_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); AL_FUNC(bool, al_drop_next_event, (ALLEGRO_EVENT_QUEUE*)); AL_FUNC(void, al_flush_event_queue, (ALLEGRO_EVENT_QUEUE*)); AL_FUNC(void, al_wait_for_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); AL_FUNC(bool, al_wait_for_event_timed, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event, float secs)); AL_FUNC(bool, al_wait_for_event_until, (ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/bitmap_lock.h0000644000175000001440000000157412057361616020216 0ustar tjadenusers#ifndef __al_included_allegro5_bitmap_lock_h #define __al_included_allegro5_bitmap_lock_h #include "allegro5/bitmap.h" #ifdef __cplusplus extern "C" { #endif /* * Locking flags */ enum { ALLEGRO_LOCK_READWRITE = 0, ALLEGRO_LOCK_READONLY = 1, ALLEGRO_LOCK_WRITEONLY = 2 }; /* Type: ALLEGRO_LOCKED_REGION */ typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION; struct ALLEGRO_LOCKED_REGION { void *data; int format; int pitch; int pixel_size; }; AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap, (ALLEGRO_BITMAP *bitmap, int format, int flags)); AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_region, (ALLEGRO_BITMAP *bitmap, int x, int y, int width, int height, int format, int flags)); AL_FUNC(void, al_unlock_bitmap, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(bool, al_is_bitmap_locked, (ALLEGRO_BITMAP *bitmap)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/alcompat.h0000644000175000001440000000072112146021714017512 0ustar tjadenusers#ifndef __al_included_allegro5_alcompat_h #define __al_included_allegro5_alcompat_h #ifdef __cplusplus extern "C" { #endif #define ALLEGRO_DST_COLOR (ALLEGRO_DEST_COLOR) #define ALLEGRO_INVERSE_DST_COLOR (ALLEGRO_INVERSE_DEST_COLOR) #define al_current_time() (al_get_time()) #define al_event_queue_is_empty(q) (al_is_event_queue_empty(q)) #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/keycodes.h0000644000175000001440000001167711520366440017537 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Keycode constants. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_keycodes_h #define __al_included_allegro5_keycodes_h /* Note these values are deliberately the same as in Allegro 4.1.x */ enum { ALLEGRO_KEY_A = 1, ALLEGRO_KEY_B = 2, ALLEGRO_KEY_C = 3, ALLEGRO_KEY_D = 4, ALLEGRO_KEY_E = 5, ALLEGRO_KEY_F = 6, ALLEGRO_KEY_G = 7, ALLEGRO_KEY_H = 8, ALLEGRO_KEY_I = 9, ALLEGRO_KEY_J = 10, ALLEGRO_KEY_K = 11, ALLEGRO_KEY_L = 12, ALLEGRO_KEY_M = 13, ALLEGRO_KEY_N = 14, ALLEGRO_KEY_O = 15, ALLEGRO_KEY_P = 16, ALLEGRO_KEY_Q = 17, ALLEGRO_KEY_R = 18, ALLEGRO_KEY_S = 19, ALLEGRO_KEY_T = 20, ALLEGRO_KEY_U = 21, ALLEGRO_KEY_V = 22, ALLEGRO_KEY_W = 23, ALLEGRO_KEY_X = 24, ALLEGRO_KEY_Y = 25, ALLEGRO_KEY_Z = 26, ALLEGRO_KEY_0 = 27, ALLEGRO_KEY_1 = 28, ALLEGRO_KEY_2 = 29, ALLEGRO_KEY_3 = 30, ALLEGRO_KEY_4 = 31, ALLEGRO_KEY_5 = 32, ALLEGRO_KEY_6 = 33, ALLEGRO_KEY_7 = 34, ALLEGRO_KEY_8 = 35, ALLEGRO_KEY_9 = 36, ALLEGRO_KEY_PAD_0 = 37, ALLEGRO_KEY_PAD_1 = 38, ALLEGRO_KEY_PAD_2 = 39, ALLEGRO_KEY_PAD_3 = 40, ALLEGRO_KEY_PAD_4 = 41, ALLEGRO_KEY_PAD_5 = 42, ALLEGRO_KEY_PAD_6 = 43, ALLEGRO_KEY_PAD_7 = 44, ALLEGRO_KEY_PAD_8 = 45, ALLEGRO_KEY_PAD_9 = 46, ALLEGRO_KEY_F1 = 47, ALLEGRO_KEY_F2 = 48, ALLEGRO_KEY_F3 = 49, ALLEGRO_KEY_F4 = 50, ALLEGRO_KEY_F5 = 51, ALLEGRO_KEY_F6 = 52, ALLEGRO_KEY_F7 = 53, ALLEGRO_KEY_F8 = 54, ALLEGRO_KEY_F9 = 55, ALLEGRO_KEY_F10 = 56, ALLEGRO_KEY_F11 = 57, ALLEGRO_KEY_F12 = 58, ALLEGRO_KEY_ESCAPE = 59, ALLEGRO_KEY_TILDE = 60, ALLEGRO_KEY_MINUS = 61, ALLEGRO_KEY_EQUALS = 62, ALLEGRO_KEY_BACKSPACE = 63, ALLEGRO_KEY_TAB = 64, ALLEGRO_KEY_OPENBRACE = 65, ALLEGRO_KEY_CLOSEBRACE = 66, ALLEGRO_KEY_ENTER = 67, ALLEGRO_KEY_SEMICOLON = 68, ALLEGRO_KEY_QUOTE = 69, ALLEGRO_KEY_BACKSLASH = 70, ALLEGRO_KEY_BACKSLASH2 = 71, /* DirectInput calls this DIK_OEM_102: "< > | on UK/Germany keyboards" */ ALLEGRO_KEY_COMMA = 72, ALLEGRO_KEY_FULLSTOP = 73, ALLEGRO_KEY_SLASH = 74, ALLEGRO_KEY_SPACE = 75, ALLEGRO_KEY_INSERT = 76, ALLEGRO_KEY_DELETE = 77, ALLEGRO_KEY_HOME = 78, ALLEGRO_KEY_END = 79, ALLEGRO_KEY_PGUP = 80, ALLEGRO_KEY_PGDN = 81, ALLEGRO_KEY_LEFT = 82, ALLEGRO_KEY_RIGHT = 83, ALLEGRO_KEY_UP = 84, ALLEGRO_KEY_DOWN = 85, ALLEGRO_KEY_PAD_SLASH = 86, ALLEGRO_KEY_PAD_ASTERISK = 87, ALLEGRO_KEY_PAD_MINUS = 88, ALLEGRO_KEY_PAD_PLUS = 89, ALLEGRO_KEY_PAD_DELETE = 90, ALLEGRO_KEY_PAD_ENTER = 91, ALLEGRO_KEY_PRINTSCREEN = 92, ALLEGRO_KEY_PAUSE = 93, ALLEGRO_KEY_ABNT_C1 = 94, ALLEGRO_KEY_YEN = 95, ALLEGRO_KEY_KANA = 96, ALLEGRO_KEY_CONVERT = 97, ALLEGRO_KEY_NOCONVERT = 98, ALLEGRO_KEY_AT = 99, ALLEGRO_KEY_CIRCUMFLEX = 100, ALLEGRO_KEY_COLON2 = 101, ALLEGRO_KEY_KANJI = 102, ALLEGRO_KEY_PAD_EQUALS = 103, /* MacOS X */ ALLEGRO_KEY_BACKQUOTE = 104, /* MacOS X */ ALLEGRO_KEY_SEMICOLON2 = 105, /* MacOS X -- TODO: ask lillo what this should be */ ALLEGRO_KEY_COMMAND = 106, /* MacOS X */ ALLEGRO_KEY_UNKNOWN = 107, /* All codes up to before ALLEGRO_KEY_MODIFIERS can be freely * assignedas additional unknown keys, like various multimedia * and application keys keyboards may have. */ ALLEGRO_KEY_MODIFIERS = 215, ALLEGRO_KEY_LSHIFT = 215, ALLEGRO_KEY_RSHIFT = 216, ALLEGRO_KEY_LCTRL = 217, ALLEGRO_KEY_RCTRL = 218, ALLEGRO_KEY_ALT = 219, ALLEGRO_KEY_ALTGR = 220, ALLEGRO_KEY_LWIN = 221, ALLEGRO_KEY_RWIN = 222, ALLEGRO_KEY_MENU = 223, ALLEGRO_KEY_SCROLLLOCK = 224, ALLEGRO_KEY_NUMLOCK = 225, ALLEGRO_KEY_CAPSLOCK = 226, ALLEGRO_KEY_MAX }; enum { ALLEGRO_KEYMOD_SHIFT = 0x00001, ALLEGRO_KEYMOD_CTRL = 0x00002, ALLEGRO_KEYMOD_ALT = 0x00004, ALLEGRO_KEYMOD_LWIN = 0x00008, ALLEGRO_KEYMOD_RWIN = 0x00010, ALLEGRO_KEYMOD_MENU = 0x00020, ALLEGRO_KEYMOD_ALTGR = 0x00040, ALLEGRO_KEYMOD_COMMAND = 0x00080, ALLEGRO_KEYMOD_SCROLLLOCK = 0x00100, ALLEGRO_KEYMOD_NUMLOCK = 0x00200, ALLEGRO_KEYMOD_CAPSLOCK = 0x00400, ALLEGRO_KEYMOD_INALTSEQ = 0x00800, ALLEGRO_KEYMOD_ACCENT1 = 0x01000, ALLEGRO_KEYMOD_ACCENT2 = 0x02000, ALLEGRO_KEYMOD_ACCENT3 = 0x04000, ALLEGRO_KEYMOD_ACCENT4 = 0x08000 }; #endif allegro-5.0.10/include/allegro5/bitmap.h0000644000175000001440000000443212125156642017177 0ustar tjadenusers#ifndef __al_included_allegro5_bitmap_h #define __al_included_allegro5_bitmap_h #include "allegro5/color.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_BITMAP */ typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP; /* * Bitmap flags */ enum { ALLEGRO_MEMORY_BITMAP = 0x0001, ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002, ALLEGRO_FORCE_LOCKING = 0x0004, ALLEGRO_NO_PRESERVE_TEXTURE = 0x0008, ALLEGRO_ALPHA_TEST = 0x0010, _ALLEGRO_INTERNAL_OPENGL = 0x0020, ALLEGRO_MIN_LINEAR = 0x0040, ALLEGRO_MAG_LINEAR = 0x0080, ALLEGRO_MIPMAP = 0x0100, ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200, ALLEGRO_VIDEO_BITMAP = 0x0400 }; AL_FUNC(void, al_set_new_bitmap_format, (int format)); AL_FUNC(void, al_set_new_bitmap_flags, (int flags)); AL_FUNC(int, al_get_new_bitmap_format, (void)); AL_FUNC(int, al_get_new_bitmap_flags, (void)); AL_FUNC(void, al_add_new_bitmap_flag, (int flag)); AL_FUNC(int, al_get_bitmap_width, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(int, al_get_bitmap_height, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(int, al_get_bitmap_format, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(int, al_get_bitmap_flags, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(ALLEGRO_BITMAP*, al_create_bitmap, (int w, int h)); AL_FUNC(void, al_destroy_bitmap, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(void, al_put_pixel, (int x, int y, ALLEGRO_COLOR color)); AL_FUNC(void, al_put_blended_pixel, (int x, int y, ALLEGRO_COLOR color)); AL_FUNC(ALLEGRO_COLOR, al_get_pixel, (ALLEGRO_BITMAP *bitmap, int x, int y)); /* Masking */ AL_FUNC(void, al_convert_mask_to_alpha, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)); /* Clipping */ AL_FUNC(void, al_set_clipping_rectangle, (int x, int y, int width, int height)); AL_FUNC(void, al_reset_clipping_rectangle, (void)); AL_FUNC(void, al_get_clipping_rectangle, (int *x, int *y, int *w, int *h)); /* Sub bitmaps */ AL_FUNC(ALLEGRO_BITMAP *, al_create_sub_bitmap, (ALLEGRO_BITMAP *parent, int x, int y, int w, int h)); AL_FUNC(bool, al_is_sub_bitmap, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(ALLEGRO_BITMAP *, al_get_parent_bitmap, (ALLEGRO_BITMAP *bitmap)); /* Miscellaneous */ AL_FUNC(ALLEGRO_BITMAP *, al_clone_bitmap, (ALLEGRO_BITMAP *bitmap)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/error.h0000644000175000001440000000162711426530515017055 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Error handling. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_error_h #define __al_included_allegro5_error_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif AL_FUNC(int, al_get_errno, (void)); AL_FUNC(void, al_set_errno, (int errnum)); #ifdef __cplusplus } #endif #endif /* * Local Variables: * c-basic-offset: 3 * indent-tabs-mode: nil * End: */ allegro-5.0.10/include/allegro5/utf8.h0000644000175000001440000001374611771526542016627 0ustar tjadenusers#ifndef __al_included_allegro5_utf8_h #define __al_included_allegro5_utf8_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_USTR */ typedef struct _al_tagbstring ALLEGRO_USTR; /* Type: ALLEGRO_USTR_INFO */ typedef struct _al_tagbstring ALLEGRO_USTR_INFO; #ifndef __al_tagbstring_defined #define __al_tagbstring_defined struct _al_tagbstring { int mlen; int slen; unsigned char * data; }; #endif /* Creating strings */ AL_FUNC(ALLEGRO_USTR *, al_ustr_new, (const char *s)); AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_buffer, (const char *s, size_t size)); AL_PRINTFUNC(ALLEGRO_USTR *, al_ustr_newf, (const char *fmt, ...), 1, 2); AL_FUNC(void, al_ustr_free, (ALLEGRO_USTR *us)); AL_FUNC(const char *, al_cstr, (const ALLEGRO_USTR *us)); AL_FUNC(void, al_ustr_to_buffer, (const ALLEGRO_USTR *us, char *buffer, int size)); AL_FUNC(char *, al_cstr_dup, (const ALLEGRO_USTR *us)); AL_FUNC(ALLEGRO_USTR *, al_ustr_dup, (const ALLEGRO_USTR *us)); AL_FUNC(ALLEGRO_USTR *, al_ustr_dup_substr, (const ALLEGRO_USTR *us, int start_pos, int end_pos)); /* Predefined string */ AL_FUNC(const ALLEGRO_USTR *, al_ustr_empty_string, (void)); /* Reference strings */ AL_FUNC(const ALLEGRO_USTR *, al_ref_cstr, (ALLEGRO_USTR_INFO *info, const char *s)); AL_FUNC(const ALLEGRO_USTR *, al_ref_buffer, (ALLEGRO_USTR_INFO *info, const char *s, size_t size)); AL_FUNC(const ALLEGRO_USTR *, al_ref_ustr, (ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us, int start_pos, int end_pos)); /* Sizes and offsets */ AL_FUNC(size_t, al_ustr_size, (const ALLEGRO_USTR *us)); AL_FUNC(size_t, al_ustr_length, (const ALLEGRO_USTR *us)); AL_FUNC(int, al_ustr_offset, (const ALLEGRO_USTR *us, int index)); AL_FUNC(bool, al_ustr_next, (const ALLEGRO_USTR *us, int *pos)); AL_FUNC(bool, al_ustr_prev, (const ALLEGRO_USTR *us, int *pos)); /* Get codepoints */ AL_FUNC(int32_t, al_ustr_get, (const ALLEGRO_USTR *us, int pos)); AL_FUNC(int32_t, al_ustr_get_next, (const ALLEGRO_USTR *us, int *pos)); AL_FUNC(int32_t, al_ustr_prev_get, (const ALLEGRO_USTR *us, int *pos)); /* Insert */ AL_FUNC(bool, al_ustr_insert, (ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2)); AL_FUNC(bool, al_ustr_insert_cstr, (ALLEGRO_USTR *us, int pos, const char *us2)); AL_FUNC(size_t, al_ustr_insert_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); /* Append */ AL_FUNC(bool, al_ustr_append, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); AL_FUNC(bool, al_ustr_append_cstr, (ALLEGRO_USTR *us, const char *s)); AL_FUNC(size_t, al_ustr_append_chr, (ALLEGRO_USTR *us, int32_t c)); AL_PRINTFUNC(bool, al_ustr_appendf, (ALLEGRO_USTR *us, const char *fmt, ...), 2, 3); AL_FUNC(bool, al_ustr_vappendf, (ALLEGRO_USTR *us, const char *fmt, va_list ap)); /* Remove */ AL_FUNC(bool, al_ustr_remove_chr, (ALLEGRO_USTR *us, int pos)); AL_FUNC(bool, al_ustr_remove_range, (ALLEGRO_USTR *us, int start_pos, int end_pos)); AL_FUNC(bool, al_ustr_truncate, (ALLEGRO_USTR *us, int start_pos)); AL_FUNC(bool, al_ustr_ltrim_ws, (ALLEGRO_USTR *us)); AL_FUNC(bool, al_ustr_rtrim_ws, (ALLEGRO_USTR *us)); AL_FUNC(bool, al_ustr_trim_ws, (ALLEGRO_USTR *us)); /* Assign */ AL_FUNC(bool, al_ustr_assign, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); AL_FUNC(bool, al_ustr_assign_substr, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int start_pos, int end_pos)); AL_FUNC(bool, al_ustr_assign_cstr, (ALLEGRO_USTR *us1, const char *s)); /* Replace */ AL_FUNC(size_t, al_ustr_set_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); AL_FUNC(bool, al_ustr_replace_range, (ALLEGRO_USTR *us1, int start_pos1, int end_pos1, const ALLEGRO_USTR *us2)); /* Searching */ AL_FUNC(int, al_ustr_find_chr, (const ALLEGRO_USTR *us, int start_pos, int32_t c)); AL_FUNC(int, al_ustr_rfind_chr, (const ALLEGRO_USTR *us, int start_pos, int32_t c)); AL_FUNC(int, al_ustr_find_set, (const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *accept)); AL_FUNC(int, al_ustr_find_set_cstr, (const ALLEGRO_USTR *us, int start_pos, const char *accept)); AL_FUNC(int, al_ustr_find_cset, (const ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *reject)); AL_FUNC(int, al_ustr_find_cset_cstr, (const ALLEGRO_USTR *us, int start_pos, const char *reject)); AL_FUNC(int, al_ustr_find_str, (const ALLEGRO_USTR *haystack, int start_pos, const ALLEGRO_USTR *needle)); AL_FUNC(int, al_ustr_find_cstr, (const ALLEGRO_USTR *haystack, int start_pos, const char *needle)); AL_FUNC(int, al_ustr_rfind_str, (const ALLEGRO_USTR *haystack, int start_pos, const ALLEGRO_USTR *needle)); AL_FUNC(int, al_ustr_rfind_cstr, (const ALLEGRO_USTR *haystack, int start_pos, const char *needle)); AL_FUNC(bool, al_ustr_find_replace, (ALLEGRO_USTR *us, int start_pos, const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)); AL_FUNC(bool, al_ustr_find_replace_cstr, (ALLEGRO_USTR *us, int start_pos, const char *find, const char *replace)); /* Compare */ AL_FUNC(bool, al_ustr_equal, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); AL_FUNC(int, al_ustr_compare, (const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); AL_FUNC(int, al_ustr_ncompare, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n)); AL_FUNC(bool, al_ustr_has_prefix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); AL_FUNC(bool, al_ustr_has_prefix_cstr, (const ALLEGRO_USTR *u, const char *s)); AL_FUNC(bool, al_ustr_has_suffix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); AL_FUNC(bool, al_ustr_has_suffix_cstr,(const ALLEGRO_USTR *us1, const char *s)); /* Low level UTF-8 functions */ AL_FUNC(size_t, al_utf8_width, (int32_t c)); AL_FUNC(size_t, al_utf8_encode, (char s[], int32_t c)); /* UTF-16 */ AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_utf16, (uint16_t const *s)); AL_FUNC(size_t, al_ustr_size_utf16, (const ALLEGRO_USTR *us)); AL_FUNC(size_t, al_ustr_encode_utf16, (const ALLEGRO_USTR *us, uint16_t *s, size_t n)); AL_FUNC(size_t, al_utf16_width, (int c)); AL_FUNC(size_t, al_utf16_encode, (uint16_t s[], int32_t c)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/alinline.h0000644000175000001440000000163611065314145017515 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Inline functions (generic C). * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #include "allegro5/inline/gfx.inl" #include "allegro5/inline/color.inl" #include "allegro5/inline/draw.inl" #include "allegro5/inline/fmaths.inl" #include "allegro5/inline/3dmaths.inl" #include "allegro5/inline/matrix.inl" /* alcompat.h includes some inline functions */ #include "allegro5/alcompat.h" allegro-5.0.10/include/allegro5/fshook.h0000644000175000001440000001154212057357022017213 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * File System Hooks. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_fshook_h #define __al_included_allegro5_fshook_h #include "allegro5/base.h" #include "allegro5/file.h" #include "allegro5/path.h" #ifdef ALLEGRO_HAVE_SYS_TYPES_H #include #else /* 4 Gig max offsets if sys/types doesn't exist. */ typedef unsigned int off_t; #endif #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_FS_ENTRY */ typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY; struct ALLEGRO_FS_ENTRY { struct ALLEGRO_FS_INTERFACE const *vtable; }; /* Enum: ALLEGRO_FILE_MODE */ typedef enum ALLEGRO_FILE_MODE { ALLEGRO_FILEMODE_READ = 1, ALLEGRO_FILEMODE_WRITE = 1 << 1, ALLEGRO_FILEMODE_EXECUTE = 1 << 2, ALLEGRO_FILEMODE_HIDDEN = 1 << 3, ALLEGRO_FILEMODE_ISFILE = 1 << 4, ALLEGRO_FILEMODE_ISDIR = 1 << 5 } ALLEGRO_FILE_MODE; #ifndef EOF #define EOF (-1) #endif /* Type: ALLEGRO_FS_INTERFACE */ typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE; struct ALLEGRO_FS_INTERFACE { AL_METHOD(ALLEGRO_FS_ENTRY *, fs_create_entry, (const char *path)); AL_METHOD(void, fs_destroy_entry, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(const char *, fs_entry_name, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_update_entry, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(uint32_t, fs_entry_mode, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(time_t, fs_entry_atime, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(time_t, fs_entry_mtime, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(time_t, fs_entry_ctime, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(off_t, fs_entry_size, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_remove_entry, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_open_directory, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(ALLEGRO_FS_ENTRY *, fs_read_directory,(ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_close_directory, (ALLEGRO_FS_ENTRY *e)); AL_METHOD(bool, fs_filename_exists, (const char *path)); AL_METHOD(bool, fs_remove_filename, (const char *path)); AL_METHOD(char *, fs_get_current_directory, (void)); AL_METHOD(bool, fs_change_directory, (const char *path)); AL_METHOD(bool, fs_make_directory, (const char *path)); AL_METHOD(ALLEGRO_FILE *, fs_open_file, (ALLEGRO_FS_ENTRY *e, const char *mode)); }; AL_FUNC(ALLEGRO_FS_ENTRY *, al_create_fs_entry, (const char *path)); AL_FUNC(void, al_destroy_fs_entry, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(const char *, al_get_fs_entry_name,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_update_fs_entry, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(uint32_t, al_get_fs_entry_mode,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(time_t, al_get_fs_entry_atime,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(time_t, al_get_fs_entry_mtime,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(time_t, al_get_fs_entry_ctime,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(off_t, al_get_fs_entry_size,(ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_remove_fs_entry, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_open_directory, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(ALLEGRO_FS_ENTRY *, al_read_directory, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_close_directory, (ALLEGRO_FS_ENTRY *e)); AL_FUNC(bool, al_filename_exists, (const char *path)); AL_FUNC(bool, al_remove_filename, (const char *path)); AL_FUNC(char *, al_get_current_directory, (void)); AL_FUNC(bool, al_change_directory, (const char *path)); AL_FUNC(bool, al_make_directory, (const char *path)); AL_FUNC(ALLEGRO_FILE *, al_open_fs_entry, (ALLEGRO_FS_ENTRY *e, const char *mode)); /* Thread-local state. */ AL_FUNC(const ALLEGRO_FS_INTERFACE *, al_get_fs_interface, (void)); AL_FUNC(void, al_set_fs_interface, (const ALLEGRO_FS_INTERFACE *vtable)); AL_FUNC(void, al_set_standard_fs_interface, (void)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/tls.h0000644000175000001440000000332511426530515016523 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread local storage routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_tls_h #define __al_included_allegro5_tls_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Enum: ALLEGRO_STATE_FLAGS */ typedef enum ALLEGRO_STATE_FLAGS { ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS = 0x0001, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS = 0x0002, ALLEGRO_STATE_DISPLAY = 0x0004, ALLEGRO_STATE_TARGET_BITMAP = 0x0008, ALLEGRO_STATE_BLENDER = 0x0010, ALLEGRO_STATE_NEW_FILE_INTERFACE = 0x0020, ALLEGRO_STATE_TRANSFORM = 0x0040, ALLEGRO_STATE_BITMAP = ALLEGRO_STATE_TARGET_BITMAP +\ ALLEGRO_STATE_NEW_BITMAP_PARAMETERS, ALLEGRO_STATE_ALL = 0xffff } ALLEGRO_STATE_FLAGS; /* Type: ALLEGRO_STATE */ typedef struct ALLEGRO_STATE ALLEGRO_STATE; struct ALLEGRO_STATE { /* Internally, a thread_local_state structure is placed here. */ char _tls[1024]; }; AL_FUNC(void, al_store_state, (ALLEGRO_STATE *state, int flags)); AL_FUNC(void, al_restore_state, (ALLEGRO_STATE const *state)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/display.h0000644000175000001440000001225312057357022017367 0ustar tjadenusers#ifndef __al_included_allegro5_display_h #define __al_included_allegro5_display_h #include "allegro5/bitmap.h" #include "allegro5/color.h" #include "allegro5/events.h" #ifdef __cplusplus extern "C" { #endif /* Possible bit combinations for the flags parameter of al_create_display. */ enum { ALLEGRO_WINDOWED = 1 << 0, ALLEGRO_FULLSCREEN = 1 << 1, ALLEGRO_OPENGL = 1 << 2, ALLEGRO_DIRECT3D_INTERNAL = 1 << 3, ALLEGRO_RESIZABLE = 1 << 4, ALLEGRO_FRAMELESS = 1 << 5, ALLEGRO_NOFRAME = ALLEGRO_FRAMELESS, /* older synonym */ ALLEGRO_GENERATE_EXPOSE_EVENTS = 1 << 6, ALLEGRO_OPENGL_3_0 = 1 << 7, ALLEGRO_OPENGL_FORWARD_COMPATIBLE = 1 << 8, ALLEGRO_FULLSCREEN_WINDOW = 1 << 9, ALLEGRO_MINIMIZED = 1 << 10 }; /* Possible parameters for al_set_display_option. * Make sure to update ALLEGRO_EXTRA_DISPLAY_SETTINGS if you modify * anything here. */ enum ALLEGRO_DISPLAY_OPTIONS { ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE, ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT, ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE, ALLEGRO_STEREO, ALLEGRO_AUX_BUFFERS, ALLEGRO_COLOR_SIZE, ALLEGRO_DEPTH_SIZE, ALLEGRO_STENCIL_SIZE, ALLEGRO_SAMPLE_BUFFERS, ALLEGRO_SAMPLES, ALLEGRO_RENDER_METHOD, ALLEGRO_FLOAT_COLOR, ALLEGRO_FLOAT_DEPTH, ALLEGRO_SINGLE_BUFFER, ALLEGRO_SWAP_METHOD, ALLEGRO_COMPATIBLE_DISPLAY, ALLEGRO_UPDATE_DISPLAY_REGION, ALLEGRO_VSYNC, ALLEGRO_MAX_BITMAP_SIZE, ALLEGRO_SUPPORT_NPOT_BITMAP, ALLEGRO_CAN_DRAW_INTO_BITMAP, ALLEGRO_SUPPORT_SEPARATE_ALPHA, ALLEGRO_DISPLAY_OPTIONS_COUNT }; enum { ALLEGRO_DONTCARE, ALLEGRO_REQUIRE, ALLEGRO_SUGGEST }; enum ALLEGRO_DISPLAY_ORIENTATION { ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES, ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES, ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES, ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES, ALLEGRO_DISPLAY_ORIENTATION_FACE_UP, ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN }; /* Type: ALLEGRO_DISPLAY */ typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY; AL_FUNC(void, al_set_new_display_refresh_rate, (int refresh_rate)); AL_FUNC(void, al_set_new_display_flags, (int flags)); AL_FUNC(int, al_get_new_display_refresh_rate, (void)); AL_FUNC(int, al_get_new_display_flags, (void)); AL_FUNC(int, al_get_display_width, (ALLEGRO_DISPLAY *display)); AL_FUNC(int, al_get_display_height, (ALLEGRO_DISPLAY *display)); AL_FUNC(int, al_get_display_format, (ALLEGRO_DISPLAY *display)); AL_FUNC(int, al_get_display_refresh_rate, (ALLEGRO_DISPLAY *display)); AL_FUNC(int, al_get_display_flags, (ALLEGRO_DISPLAY *display)); AL_FUNC(bool, al_set_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff)); AL_FUNC(bool, al_toggle_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff)); AL_FUNC(ALLEGRO_DISPLAY*, al_create_display, (int w, int h)); AL_FUNC(void, al_destroy_display, (ALLEGRO_DISPLAY *display)); AL_FUNC(ALLEGRO_DISPLAY*, al_get_current_display, (void)); AL_FUNC(void, al_set_target_bitmap, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(void, al_set_target_backbuffer, (ALLEGRO_DISPLAY *display)); AL_FUNC(ALLEGRO_BITMAP*, al_get_backbuffer, (ALLEGRO_DISPLAY *display)); AL_FUNC(ALLEGRO_BITMAP*, al_get_target_bitmap, (void)); AL_FUNC(bool, al_acknowledge_resize, (ALLEGRO_DISPLAY *display)); AL_FUNC(bool, al_resize_display, (ALLEGRO_DISPLAY *display, int width, int height)); AL_FUNC(void, al_flip_display, (void)); AL_FUNC(void, al_update_display_region, (int x, int y, int width, int height)); AL_FUNC(bool, al_is_compatible_bitmap, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(bool, al_wait_for_vsync, (void)); AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_display_event_source, (ALLEGRO_DISPLAY *display)); AL_FUNC(void, al_set_display_icon, (ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)); AL_FUNC(void, al_set_display_icons, (ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *icons[])); /* Stuff for multihead/window management */ AL_FUNC(int, al_get_new_display_adapter, (void)); AL_FUNC(void, al_set_new_display_adapter, (int adapter)); AL_FUNC(void, al_set_new_window_position, (int x, int y)); AL_FUNC(void, al_get_new_window_position, (int *x, int *y)); AL_FUNC(void, al_set_window_position, (ALLEGRO_DISPLAY *display, int x, int y)); AL_FUNC(void, al_get_window_position, (ALLEGRO_DISPLAY *display, int *x, int *y)); AL_FUNC(void, al_set_window_title, (ALLEGRO_DISPLAY *display, const char *title)); /* Defined in display_settings.c */ AL_FUNC(void, al_set_new_display_option, (int option, int value, int importance)); AL_FUNC(int, al_get_new_display_option, (int option, int *importance)); AL_FUNC(void, al_reset_new_display_options, (void)); AL_FUNC(int, al_get_display_option, (ALLEGRO_DISPLAY *display, int option)); /*Deferred drawing*/ AL_FUNC(void, al_hold_bitmap_drawing, (bool hold)); AL_FUNC(bool, al_is_bitmap_drawing_held, (void)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/fixed.h0000644000175000001440000000163211426530515017017 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Fixed point type. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_fixed_h #define __al_included_allegro5_fixed_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif /* Type: al_fixed */ typedef int32_t al_fixed; AL_VAR(const al_fixed, al_fixtorad_r); AL_VAR(const al_fixed, al_radtofix_r); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/allegro_opengl.h0000644000175000001440000000775611502642227020725 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Main header file for all OpenGL drivers. * * By Milan Mimica. * */ #ifndef __al_included_allegro5_allegro_opengl_h #define __al_included_allegro5_allegro_opengl_h #ifdef __cplusplus extern "C" { #endif #if defined(ALLEGRO_WINDOWS) #include #endif #if defined ALLEGRO_IPHONE #include #include #include #include /* Apple defines OES versions for these - however the separated alpha ones * don't seem to work on the device and just crash. */ #define glBlendEquation glBlendEquationOES #define glBlendFuncSeparate glBlendFuncSeparateOES #define glBlendEquationSeparate glBlendEquationSeparateOES #ifdef GL_FUNC_ADD #undef GL_FUNC_ADD #undef GL_FUNC_SUBTRACT #undef GL_FUNC_REVERSE_SUBTRACT #endif #define GL_FUNC_ADD GL_FUNC_ADD_OES #define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES #define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES #elif defined ALLEGRO_MACOSX #include #include #include #ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES #endif #elif defined ALLEGRO_GP2XWIZ #include #include #include #include #else /* ALLEGRO_MACOSX */ /* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ #define __glext_h_ #define __glxext_h_ #include #undef __glext_h_ #undef __glxext_h_ #endif /* ALLEGRO_MACOSX */ #include "allegro5/opengl/gl_ext.h" #ifdef ALLEGRO_WINDOWS /* Missing #defines from Mingw */ #ifndef PFD_SWAP_LAYER_BUFFERS #define PFD_SWAP_LAYER_BUFFERS 0x00000800 #endif #ifndef PFD_GENERIC_ACCELERATED #define PFD_GENERIC_ACCELERATED 0x00001000 #endif #ifndef PFD_SUPPORT_DIRECTDRAW #define PFD_SUPPORT_DIRECTDRAW 0x00002000 #endif #ifndef CDS_FULLSCREEN #define CDS_FULLSCREEN 0x00000004 #endif #ifndef ENUM_CURRENT_SETTINGS #define ENUM_CURRENT_SETTINGS ((DWORD)-1) #endif #endif /* ALLEGRO_WINDOWS */ #if defined ALLEGRO_WINDOWS #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ typedef type (APIENTRY * name) args; #else #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ typedef type (*name) args; #endif /* * Public OpenGL-related API */ /* Enum: ALLEGRO_OPENGL_VARIANT */ typedef enum ALLEGRO_OPENGL_VARIANT { ALLEGRO_DESKTOP_OPENGL = 0, ALLEGRO_OPENGL_ES } ALLEGRO_OPENGL_VARIANT; AL_FUNC(uint32_t, al_get_opengl_version, (void)); AL_FUNC(bool, al_have_opengl_extension, (const char *extension)); AL_FUNC(void*, al_get_opengl_proc_address, (const char *name)); AL_FUNC(ALLEGRO_OGL_EXT_LIST*, al_get_opengl_extension_list, (void)); AL_FUNC(GLuint, al_get_opengl_texture, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(void, al_remove_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(GLuint, al_get_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); AL_FUNC(void, al_get_opengl_texture_size, (ALLEGRO_BITMAP *bitmap, int *w, int *h)); AL_FUNC(void, al_get_opengl_texture_position, (ALLEGRO_BITMAP *bitmap, int *u, int *v)); AL_FUNC(void, al_set_current_opengl_context, (ALLEGRO_DISPLAY *display)); AL_FUNC(int, al_get_opengl_variant, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/allegro_direct3d.h0000644000175000001440000000273211431777622021140 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Header file for Direct3D specific API. * * By Milan Mimica. * */ #ifndef __al_included_allegro5_allegro_direct3d_h #define __al_included_allegro5_allegro_direct3d_h #include #ifdef __cplusplus extern "C" { #endif /* * Public Direct3D-related API */ /* Display creation flag. */ #define ALLEGRO_DIRECT3D ALLEGRO_DIRECT3D_INTERNAL AL_FUNC(LPDIRECT3DDEVICE9, al_get_d3d_device, (ALLEGRO_DISPLAY *)); AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_system_texture, (ALLEGRO_BITMAP *)); AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_video_texture, (ALLEGRO_BITMAP *)); AL_FUNC(bool, al_have_d3d_non_pow2_texture_support, (void)); AL_FUNC(bool, al_have_d3d_non_square_texture_support, (void)); AL_FUNC(void, al_get_d3d_texture_position, (ALLEGRO_BITMAP *bitmap, int *u, int *v)); AL_FUNC(bool, al_is_d3d_device_lost, (ALLEGRO_DISPLAY *display)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/memory.h0000644000175000001440000000423711454330274017235 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory management routines. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_memory_h #define __al_included_allegro5_memory_h #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_MEMORY_INTERFACE */ typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE; struct ALLEGRO_MEMORY_INTERFACE { void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); void (*mi_free)(void *ptr, int line, const char *file, const char *func); void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, const char *func); void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, const char *func); }; AL_FUNC(void, al_set_memory_interface, (ALLEGRO_MEMORY_INTERFACE *iface)); /* Function: al_malloc */ #define al_malloc(n) \ (al_malloc_with_context((n), __LINE__, __FILE__, __func__)) /* Function: al_free */ #define al_free(p) \ (al_free_with_context((p), __LINE__, __FILE__, __func__)) /* Function: al_realloc */ #define al_realloc(p, n) \ (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__)) /* Function: al_calloc */ #define al_calloc(c, n) \ (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__)) AL_FUNC(void *, al_malloc_with_context, (size_t n, int line, const char *file, const char *func)); AL_FUNC(void, al_free_with_context, (void *ptr, int line, const char *file, const char *func)); AL_FUNC(void *, al_realloc_with_context, (void *ptr, size_t n, int line, const char *file, const char *func)); AL_FUNC(void *, al_calloc_with_context, (size_t count, size_t n, int line, const char *file, const char *func)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/config.h0000644000175000001440000000361511437710515017172 0ustar tjadenusers#ifndef __al_included_allegro5_config_h #define __al_included_allegro5_config_h #include "allegro5/file.h" #ifdef __cplusplus extern "C" { #endif /* Type: ALLEGRO_CONFIG */ typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG; /* Type: ALLEGRO_CONFIG_SECTION */ typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION; /* Type: ALLEGRO_CONFIG_ENTRY */ typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY; AL_FUNC(ALLEGRO_CONFIG *, al_create_config, (void)); AL_FUNC(void, al_add_config_section, (ALLEGRO_CONFIG *config, const char *name)); AL_FUNC(void, al_set_config_value, (ALLEGRO_CONFIG *config, const char *section, const char *key, const char *value)); AL_FUNC(void, al_add_config_comment, (ALLEGRO_CONFIG *config, const char *section, const char *comment)); AL_FUNC(const char*, al_get_config_value, (const ALLEGRO_CONFIG *config, const char *section, const char *key)); AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file, (const char *filename)); AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file_f, (ALLEGRO_FILE *filename)); AL_FUNC(bool, al_save_config_file, (const char *filename, const ALLEGRO_CONFIG *config)); AL_FUNC(bool, al_save_config_file_f, (ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)); AL_FUNC(void, al_merge_config_into, (ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)); AL_FUNC(ALLEGRO_CONFIG *, al_merge_config, (const ALLEGRO_CONFIG *cfg1, const ALLEGRO_CONFIG *cfg2)); AL_FUNC(void, al_destroy_config, (ALLEGRO_CONFIG *config)); AL_FUNC(char const *, al_get_first_config_section, (ALLEGRO_CONFIG const *config, ALLEGRO_CONFIG_SECTION **iterator)); AL_FUNC(char const *, al_get_next_config_section, (ALLEGRO_CONFIG_SECTION **iterator)); AL_FUNC(char const *, al_get_first_config_entry, (ALLEGRO_CONFIG const *config, char const *section, ALLEGRO_CONFIG_ENTRY **iterator)); AL_FUNC(char const *, al_get_next_config_entry, (ALLEGRO_CONFIG_ENTRY **iterator)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/system.h0000644000175000001440000000243111771523426017250 0ustar tjadenusers#ifndef __al_included_allegro5_system_h #define __al_included_allegro5_system_h #include "allegro5/config.h" #include "allegro5/path.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_SYSTEM ALLEGRO_SYSTEM; /* Function: al_init */ #define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit)) AL_FUNC(bool, al_install_system, (int version, int (*atexit_ptr)(void (*)(void)))); AL_FUNC(void, al_uninstall_system, (void)); AL_FUNC(bool, al_is_system_installed, (void)); AL_FUNC(ALLEGRO_SYSTEM *, al_get_system_driver, (void)); AL_FUNC(ALLEGRO_CONFIG *, al_get_system_config, (void)); enum { ALLEGRO_RESOURCES_PATH = 0, ALLEGRO_TEMP_PATH, ALLEGRO_USER_DATA_PATH, ALLEGRO_USER_HOME_PATH, ALLEGRO_USER_SETTINGS_PATH, ALLEGRO_USER_DOCUMENTS_PATH, ALLEGRO_EXENAME_PATH, ALLEGRO_LAST_PATH /* must be last */ }; AL_FUNC(ALLEGRO_PATH *, al_get_standard_path, (int id)); AL_FUNC(void, al_set_exe_name, (char const *path)); AL_FUNC(void, al_set_org_name, (const char *org_name)); AL_FUNC(void, al_set_app_name, (const char *app_name)); AL_FUNC(const char *, al_get_org_name, (void)); AL_FUNC(const char *, al_get_app_name, (void)); AL_FUNC(bool, al_inhibit_screensaver, (bool inhibit)); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/0000755000175000001440000000000012157230745017365 5ustar tjadenusersallegro-5.0.10/include/allegro5/internal/aintern_wunicode.h0000644000175000001440000000054612061103376023071 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_wunicode_h #define __al_included_allegro5_aintern_wunicode_h #ifdef ALLEGRO_WINDOWS #ifdef __cplusplus extern "C" { #endif AL_FUNC(wchar_t *, _al_win_utf16, (const char *s)); AL_FUNC(char *, _al_win_utf8, (const wchar_t *ws)); #ifdef __cplusplus } #endif #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_direct3d.h0000644000175000001440000000043111521376134022752 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_direct3d_h #define __al_included_allegro5_aintern_direct3d_h #ifdef __cplusplus extern "C" { #endif struct ALLEGRO_DISPLAY_D3D; AL_FUNC(void, _al_d3d_set_blender, (struct ALLEGRO_DISPLAY_D3D *disp)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_debug.h0000644000175000001440000000032212125161267022336 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_debug_h #define __al_included_allegro5_aintern_debug_h #ifdef __cplusplus extern "C" { #endif void _al_shutdown_logging(void); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_xdisplay.h0000644000175000001440000000374312104442100023100 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xdisplay_h #define __al_included_allegro5_aintern_xdisplay_h #include #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_x.h" /* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ struct ALLEGRO_DISPLAY_XGLX { /* This must be the first member. */ ALLEGRO_DISPLAY display; /* Driver specifics. */ Window window; int xscreen; /* X Screen ID */ int adapter; /* allegro virtual adapter id/index */ GLXWindow glxwindow; GLXContext context; Atom wm_delete_window_atom; XVisualInfo *xvinfo; /* Used when selecting the X11 visual to use. */ GLXFBConfig *fbc; /* Used when creating the OpenGL context. */ int glx_version; /* 130 means 1 major and 3 minor, aka 1.3 */ /* If our window is embedded by the XEmbed protocol, this gives * the window ID of the embedder; Otherwise None. */ Window embedder_window; _AL_COND mapped; /* Condition variable to wait for mapping a window. */ bool is_mapped; /* Set to true when mapped. */ int resize_count; /* Increments when resized. */ bool programmatic_resize; /* Set while programmatic resize in progress. */ /* Cursor for this window. */ Cursor invisible_cursor; Cursor current_cursor; bool cursor_hidden; /* Icon for this window. */ Pixmap icon, icon_mask; /* Desktop position. */ int x, y; /* al_set_mouse_xy implementation */ bool mouse_warp; }; void _al_display_xglx_await_resize(ALLEGRO_DISPLAY *d, int old_resize_count, bool delay_hack); void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y, int width, int height, bool setglxy); void _al_xglx_display_configure_event(ALLEGRO_DISPLAY *d, XEvent *event); void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *d, XFocusChangeEvent *event); void _al_xwin_display_switch_handler_inner(ALLEGRO_DISPLAY *d, bool focus_in); void _al_xwin_display_expose(ALLEGRO_DISPLAY *display, XExposeEvent *xevent); #endif allegro-5.0.10/include/allegro5/internal/aintern_vector.h0000644000175000001440000000312711721435174022562 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_vector_h #define __al_included_allegro5_aintern_vector_h #ifdef __cplusplus extern "C" { #endif typedef struct _AL_VECTOR { /* private */ size_t _itemsize; char* _items; /* total size == (size + unused) * itemsize */ size_t _size; size_t _unused; } _AL_VECTOR; #define _AL_VECTOR_INITIALIZER(typ) { sizeof(typ), 0, 0, 0 } AL_FUNC(void, _al_vector_init, (_AL_VECTOR*, size_t itemsize)); AL_INLINE(size_t, _al_vector_size, (const _AL_VECTOR *vec), { return vec->_size; }) AL_INLINE(bool, _al_vector_is_empty, (const _AL_VECTOR *vec), { ASSERT(vec); return vec->_size == 0 ? true : false; }) AL_INLINE(bool, _al_vector_is_nonempty, (const _AL_VECTOR *vec), { ASSERT(vec); return !_al_vector_is_empty(vec); }) AL_FUNC(void*, _al_vector_ref, (const _AL_VECTOR*, unsigned int index)); AL_FUNC(void*, _al_vector_ref_front, (const _AL_VECTOR*)); AL_FUNC(void*, _al_vector_ref_back, (const _AL_VECTOR*)); AL_FUNC(bool, _al_vector_append_array, (_AL_VECTOR *vec, unsigned int num, const void *arr)); AL_FUNC(void*, _al_vector_alloc_back, (_AL_VECTOR*)); AL_FUNC(void*, _al_vector_alloc_mid, (_AL_VECTOR*, unsigned int index)); AL_FUNC(int, _al_vector_find, (const _AL_VECTOR*, const void *ptr_item)); AL_FUNC(bool, _al_vector_contains, (const _AL_VECTOR*, const void *ptr_item)); AL_FUNC(void, _al_vector_delete_at, (_AL_VECTOR*, unsigned int index)); AL_FUNC(bool, _al_vector_find_and_delete, (_AL_VECTOR*, const void *ptr_item)); AL_FUNC(void, _al_vector_free, (_AL_VECTOR*)); #ifdef __cplusplus } #endif #endif /* vi ts=8 sts=3 sw=3 et */ allegro-5.0.10/include/allegro5/internal/aintern_xmouse.h0000644000175000001440000000114712104442100022557 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xmouse_h #define __al_included_allegro5_aintern_xmouse_h #include "allegro5/internal/aintern_mouse.h" ALLEGRO_MOUSE_DRIVER *_al_xwin_mouse_driver(void); void _al_xwin_mouse_button_press_handler(int button, ALLEGRO_DISPLAY *display); void _al_xwin_mouse_button_release_handler(int button, ALLEGRO_DISPLAY *d); void _al_xwin_mouse_motion_notify_handler(int x, int y, ALLEGRO_DISPLAY *d); void _al_xwin_mouse_switch_handler(ALLEGRO_DISPLAY *display, const XCrossingEvent *event); bool _al_xwin_grab_mouse(ALLEGRO_DISPLAY *display); bool _al_xwin_ungrab_mouse(void); #endif allegro-5.0.10/include/allegro5/internal/aintern.h0000644000175000001440000000270212125160224021164 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Some definitions for internal use by the library code. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintern_h #define __al_included_allegro5_aintern_h #ifndef __al_included_allegro5_allegro_h #error must include allegro5/allegro.h first #endif #ifdef __cplusplus extern "C" { #endif #define _ALLEGRO_MIN(x,y) (((x) < (y)) ? (x) : (y)) #define _ALLEGRO_MAX(x,y) (((x) > (y)) ? (x) : (y)) #define _ALLEGRO_CLAMP(x,y,z) _ALLEGRO_MAX((x), _ALLEGRO_MIN((y), (z))) /* message stuff */ #define ALLEGRO_MESSAGE_SIZE 4096 /* various libc stuff */ AL_FUNC(void *, _al_sane_realloc, (void *ptr, size_t size)); AL_FUNC(char *, _al_sane_strncpy, (char *dest, const char *src, size_t n)); #define _AL_RAND_MAX 0xFFFF AL_FUNC(void, _al_srand, (int seed)); AL_FUNC(int, _al_rand, (void)); AL_FUNC(int, _al_stricmp, (const char *s1, const char *s2)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_xevents.h0000644000175000001440000000033012104442100022724 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xevents_h #define __al_included_allegro5_aintern_xevents_h #include "allegro5/internal/aintern_thread.h" void _al_xwin_background_thread(_AL_THREAD *self, void *arg); #endif allegro-5.0.10/include/allegro5/internal/aintern_file.h0000644000175000001440000000070511505637264022202 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_file_h #define __al_included_allegro5_aintern_file_h #ifdef __cplusplus extern "C" { #endif extern const ALLEGRO_FILE_INTERFACE _al_file_interface_stdio; #define ALLEGRO_UNGETC_SIZE 16 struct ALLEGRO_FILE { const ALLEGRO_FILE_INTERFACE *vtable; void *userdata; unsigned char ungetc[ALLEGRO_UNGETC_SIZE]; int ungetc_len; }; #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_gp2xwiz.h0000644000175000001440000000301011426530515022656 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_gp2xwiz_h #define __al_included_allegro5_aintern_gp2xwiz_h #include "allegro5/allegro.h" #include "allegro5/allegro_opengl.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_system.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/platform/aintwiz.h" #include "allegro5/internal/aintern_opengl.h" #include typedef struct ALLEGRO_SYSTEM_GP2XWIZ ALLEGRO_SYSTEM_GP2XWIZ; typedef struct ALLEGRO_DISPLAY_GP2XWIZ_OGL ALLEGRO_DISPLAY_GP2XWIZ_OGL; typedef struct ALLEGRO_DISPLAY_GP2XWIZ_FB ALLEGRO_DISPLAY_GP2XWIZ_FB; struct ALLEGRO_SYSTEM_GP2XWIZ { ALLEGRO_SYSTEM system; /* This must be the first member, we "derive" from it. */ ALLEGRO_EXTRA_DISPLAY_SETTINGS extras; }; /* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ struct ALLEGRO_DISPLAY_GP2XWIZ_OGL { ALLEGRO_DISPLAY display; /* This must be the first member. */ EGLDisplay egl_display; EGLConfig egl_config; EGLContext egl_context; EGLSurface egl_surface; NativeWindowType hNativeWnd; }; /* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ struct ALLEGRO_DISPLAY_GP2XWIZ_FB { ALLEGRO_DISPLAY display; /* This must be the first member. */ ALLEGRO_BITMAP *backbuffer; /* * We create the backbuffer bitmap then points it's ->memory at * lc_fb1 (initialized with libcastor. This is a backup of the * ->memory as created by al_create_bitmap. */ unsigned char *screen_mem; }; #endif allegro-5.0.10/include/allegro5/internal/aintern_convert.h0000644000175000001440000021427411426530515022744 0ustar tjadenusers// Warning: This file was created by make_converters.py - do not edit. #ifndef __al_included_allegro5_aintern_convert_h #define __al_included_allegro5_aintern_convert_h #include "allegro5/allegro.h" #include "allegro5/internal/aintern_pixels.h" #define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_8888(x) \ ((((x) & 0xff000000) >> 24) /* A */ | \ (((x) & 0x00ffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_4444(x) \ ((((x) & 0xf0000000) >> 16) /* A */ | \ (((x) & 0x000000f0) >> 4) /* B */ | \ (((x) & 0x0000f000) >> 8) /* G */ | \ (((x) & 0x00f00000) >> 12) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_565(x) \ ((((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 8) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_555(x) \ ((((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 9) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_5551(x) \ ((((x) & 0x80000000) >> 31) /* A */ | \ (((x) & 0x000000f8) >> 2) /* B */ | \ (((x) & 0x0000f800) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 8) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_1555(x) \ ((((x) & 0x80000000) >> 16) /* A */ | \ (((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 9) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ (((x) & 0x00ff0000) >> 16) /* R */ | \ ((x) & 0xff00ff00) /* AG */) #define ALLEGRO_CONVERT_ARGB_8888_TO_XBGR_8888(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_888(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_565(x) \ ((((x) & 0x000000f8) << 8) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 19) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_555(x) \ ((((x) & 0x000000f8) << 7) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 19) /* R */) #define ALLEGRO_CONVERT_ARGB_8888_TO_RGBX_8888(x) \ ((((x) & 0x00ffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_ARGB_8888_TO_XRGB_8888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_F32(x) \ al_map_rgba(((x) >> 16) & 255,\ ((x) >> 8) & 255,\ ((x) >> 0) & 255,\ ((x) >> 24) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(x) \ ((((x) & 0xff000000) >> 24) /* A */ | \ (((x) & 0x00ffffff) << 8) /* BGR */) #else #define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ (((x) & 0x00ff0000) >> 16) /* R */ | \ ((x) & 0xff00ff00) /* AG */) #endif #define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_4444(x) \ ((((x) & 0xf0000000) >> 28) /* A */ | \ ((x) & 0x000000f0) /* B */ | \ (((x) & 0x0000f000) >> 4) /* G */ | \ (((x) & 0x00f00000) >> 8) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_8888(x) \ ((((x) & 0x000000ff) << 24) /* A */ | \ (((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_4444(x) \ ((((x) & 0x000000f0) << 8) /* A */ | \ (((x) & 0x0000f000) >> 12) /* B */ | \ (((x) & 0x00f00000) >> 16) /* G */ | \ (((x) & 0xf0000000) >> 20) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_565(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_555(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_5551(x) \ ((((x) & 0x00000080) >> 7) /* A */ | \ (((x) & 0x0000f800) >> 10) /* B */ | \ (((x) & 0x00f80000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_1555(x) \ ((((x) & 0x00000080) << 8) /* A */ | \ (((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888(x) \ ((((x) & 0x000000ff) << 24) /* A */ | \ (((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_XBGR_8888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_565(x) \ (((x) & 0x0000f800) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_555(x) \ ((((x) & 0x0000f800) >> 1) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #define ALLEGRO_CONVERT_RGBA_8888_TO_RGBX_8888(x) \ (((x) & 0xffffff00) /* BGR */) #define ALLEGRO_CONVERT_RGBA_8888_TO_XRGB_8888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_F32(x) \ al_map_rgba(((x) >> 24) & 255,\ ((x) >> 16) & 255,\ ((x) >> 8) & 255,\ ((x) >> 0) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(x) \ (((x) & 0xffffffff) /* ABGR */) #else #define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(x) \ ((((x) & 0x000000ff) << 24) /* A */ | \ (((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #endif #define ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_4444(x) \ ((((x) & 0x000000f0) >> 4) /* A */ | \ (((x) & 0x0000f000) >> 8) /* B */ | \ (((x) & 0x00f00000) >> 12) /* G */ | \ (((x) & 0xf0000000) >> 16) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_8888(x) \ ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_8888(x) \ ((_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* A */ | \ (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_565(x) \ ((((x) & 0x000f) << 1) /* B */ | \ (((x) & 0x00f0) << 3) /* G */ | \ (((x) & 0x0f00) << 4) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_555(x) \ ((((x) & 0x000f) << 1) /* B */ | \ (((x) & 0x00f0) << 2) /* G */ | \ (((x) & 0x0f00) << 3) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_5551(x) \ ((((x) & 0x8000) >> 15) /* A */ | \ (((x) & 0x000f) << 2) /* B */ | \ (((x) & 0x00f0) << 3) /* G */ | \ (((x) & 0x0f00) << 4) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_1555(x) \ (((x) & 0x8000) /* A */ | \ (((x) & 0x000f) << 1) /* B */ | \ (((x) & 0x00f0) << 2) /* G */ | \ (((x) & 0x0f00) << 3) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888(x) \ ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_XBGR_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_565(x) \ ((((x) & 0x000f) << 12) /* B */ | \ (((x) & 0x00f0) << 3) /* G */ | \ (((x) & 0x0f00) >> 7) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_555(x) \ ((((x) & 0x000f) << 11) /* B */ | \ (((x) & 0x00f0) << 2) /* G */ | \ (((x) & 0x0f00) >> 7) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_RGBX_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_XRGB_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_F32(x) \ al_map_rgba(_al_rgb_scale_4[((x) >> 8) & 15],\ _al_rgb_scale_4[((x) >> 4) & 15],\ _al_rgb_scale_4[((x) >> 0) & 15],\ _al_rgb_scale_4[((x) >> 12) & 15]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* A */ | \ (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) #else #define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) #endif #define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_4444(x) \ ((((x) & 0xf000) >> 12) /* A */ | \ (((x) & 0x0fff) << 4) /* BGR */) #define ALLEGRO_CONVERT_RGB_888_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ ((x) & 0xffffff) /* BGR */) #define ALLEGRO_CONVERT_RGB_888_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (((x) & 0xffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_RGB_888_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x0000f0) >> 4) /* B */ | \ (((x) & 0x00f000) >> 8) /* G */ | \ (((x) & 0xf00000) >> 12) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_RGB_565(x) \ ((((x) & 0x0000f8) >> 3) /* B */ | \ (((x) & 0x00fc00) >> 5) /* G */ | \ (((x) & 0xf80000) >> 8) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_RGB_555(x) \ ((((x) & 0x0000f8) >> 3) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0xf80000) >> 9) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x0000f8) >> 2) /* B */ | \ (((x) & 0x00f800) >> 5) /* G */ | \ (((x) & 0xf80000) >> 8) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0x0000f8) >> 3) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0xf80000) >> 9) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0x0000ff) << 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0xff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_XBGR_8888(x) \ ((((x) & 0x0000ff) << 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0xff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_BGR_888(x) \ ((((x) & 0x0000ff) << 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0xff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_BGR_565(x) \ ((((x) & 0x0000f8) << 8) /* B */ | \ (((x) & 0x00fc00) >> 5) /* G */ | \ (((x) & 0xf80000) >> 19) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_BGR_555(x) \ ((((x) & 0x0000f8) << 7) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0xf80000) >> 19) /* R */) #define ALLEGRO_CONVERT_RGB_888_TO_RGBX_8888(x) \ ((((x) & 0xffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_RGB_888_TO_XRGB_8888(x) \ (((x) & 0xffffff) /* BGR */) #define ALLEGRO_CONVERT_RGB_888_TO_ABGR_F32(x) \ al_map_rgb(((x) >> 16) & 255,\ ((x) >> 8) & 255,\ ((x) >> 0) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (((x) & 0xffffff) << 8) /* BGR */) #else #define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (((x) & 0x0000ff) << 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0xff0000) >> 16) /* R */) #endif #define ALLEGRO_CONVERT_RGB_888_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ ((x) & 0x0000f0) /* B */ | \ (((x) & 0x00f000) >> 4) /* G */ | \ (((x) & 0xf00000) >> 8) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x001e) >> 1) /* B */ | \ (((x) & 0x0780) >> 3) /* G */ | \ (((x) & 0xf000) >> 4) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_RGB_555(x) \ (((x) & 0x001f) /* B */ | \ (((x) & 0xffc0) >> 1) /* GR */) #define ALLEGRO_CONVERT_RGB_565_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x001f) << 1) /* B */ | \ ((x) & 0xffc0) /* GR */) #define ALLEGRO_CONVERT_RGB_565_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ ((x) & 0x001f) /* B */ | \ (((x) & 0xffc0) >> 1) /* GR */) #define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_BGR_565(x) \ ((((x) & 0x001f) << 11) /* B */ | \ ((x) & 0x07e0) /* G */ | \ (((x) & 0xf800) >> 11) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_BGR_555(x) \ ((((x) & 0x001f) << 10) /* B */ | \ (((x) & 0x07c0) >> 1) /* G */ | \ (((x) & 0xf800) >> 11) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_565_TO_ABGR_F32(x) \ al_map_rgb(_al_rgb_scale_5[((x) >> 11) & 31],\ _al_rgb_scale_6[((x) >> 5) & 63],\ _al_rgb_scale_5[((x) >> 0) & 31]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #else #define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #endif #define ALLEGRO_CONVERT_RGB_565_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0x001e) << 3) /* B */ | \ (((x) & 0x0780) << 1) /* G */ | \ ((x) & 0xf000) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x01e) >> 1) /* B */ | \ (((x) & 0x3c0) >> 2) /* G */ | \ (((x) & 0x7800) >> 3) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_RGB_565(x) \ (((x) & 0x01f) /* B */ | \ (((x) & 0x7fe0) << 1) /* GR */) #define ALLEGRO_CONVERT_RGB_555_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x7fff) << 1) /* BGR */) #define ALLEGRO_CONVERT_RGB_555_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ ((x) & 0x7fff) /* BGR */) #define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_BGR_565(x) \ ((((x) & 0x01f) << 11) /* B */ | \ (((x) & 0x3e0) << 1) /* G */ | \ (((x) & 0x7c00) >> 10) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_BGR_555(x) \ ((((x) & 0x01f) << 10) /* B */ | \ ((x) & 0x3e0) /* G */ | \ (((x) & 0x7c00) >> 10) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_RGB_555_TO_ABGR_F32(x) \ al_map_rgb(_al_rgb_scale_5[((x) >> 10) & 31],\ _al_rgb_scale_5[((x) >> 5) & 31],\ _al_rgb_scale_5[((x) >> 0) & 31]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #else #define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #endif #define ALLEGRO_CONVERT_RGB_555_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0x01e) << 3) /* B */ | \ (((x) & 0x3c0) << 2) /* G */ | \ (((x) & 0x7800) << 1) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_8888(x) \ ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_8888(x) \ ((_al_rgb_scale_1[((x) & 0x0001) >> 0] ) /* A */ | \ (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_4444(x) \ ((((x) & 0x0001) << 15) /* A */ | \ (((x) & 0x003c) >> 2) /* B */ | \ (((x) & 0x0780) >> 3) /* G */ | \ (((x) & 0xf000) >> 4) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_565(x) \ ((((x) & 0x003e) >> 1) /* B */ | \ ((x) & 0xffc0) /* GR */) #define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_555(x) \ ((((x) & 0xfffe) >> 1) /* BGR */) #define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_1555(x) \ ((((x) & 0x0001) << 15) /* A */ | \ (((x) & 0xfffe) >> 1) /* BGR */) #define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888(x) \ ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_565(x) \ ((((x) & 0x003e) << 10) /* B */ | \ ((x) & 0x07c0) /* G */ | \ (((x) & 0xf800) >> 11) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_555(x) \ ((((x) & 0x003e) << 9) /* B */ | \ (((x) & 0x07c0) >> 1) /* G */ | \ (((x) & 0xf800) >> 11) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_F32(x) \ al_map_rgba(_al_rgb_scale_5[((x) >> 11) & 31],\ _al_rgb_scale_5[((x) >> 6) & 31],\ _al_rgb_scale_5[((x) >> 1) & 31],\ _al_rgb_scale_1[((x) >> 0) & 1]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_1[((x) & 0x0001) >> 0] ) /* A */ | \ (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) #else #define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) #endif #define ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_4444(x) \ ((((x) & 0x0001) << 3) /* A */ | \ (((x) & 0x003c) << 2) /* B */ | \ (((x) & 0x0780) << 1) /* G */ | \ ((x) & 0xf000) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_8888(x) \ ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_8888(x) \ ((_al_rgb_scale_1[((x) & 0x8000) >> 15] ) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_4444(x) \ (((x) & 0x8000) /* A */ | \ (((x) & 0x001e) >> 1) /* B */ | \ (((x) & 0x03c0) >> 2) /* G */ | \ (((x) & 0x7800) >> 3) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_565(x) \ (((x) & 0x001f) /* B */ | \ (((x) & 0x7fe0) << 1) /* GR */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_555(x) \ (((x) & 0x7fff) /* BGR */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_5551(x) \ ((((x) & 0x8000) >> 15) /* A */ | \ (((x) & 0x7fff) << 1) /* BGR */) #define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888(x) \ ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_565(x) \ ((((x) & 0x001f) << 11) /* B */ | \ (((x) & 0x03e0) << 1) /* G */ | \ (((x) & 0x7c00) >> 10) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_555(x) \ ((((x) & 0x001f) << 10) /* B */ | \ ((x) & 0x03e0) /* G */ | \ (((x) & 0x7c00) >> 10) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) #define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_F32(x) \ al_map_rgba(_al_rgb_scale_5[((x) >> 10) & 31],\ _al_rgb_scale_5[((x) >> 5) & 31],\ _al_rgb_scale_5[((x) >> 0) & 31],\ _al_rgb_scale_1[((x) >> 15) & 1]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_1[((x) & 0x8000) >> 15] ) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) #else #define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) #endif #define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_4444(x) \ ((((x) & 0x8000) >> 12) /* A */ | \ (((x) & 0x001e) << 3) /* B */ | \ (((x) & 0x03c0) << 2) /* G */ | \ (((x) & 0x7800) << 1) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_8888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ (((x) & 0x000000ff) << 16) /* R */ | \ ((x) & 0xff00ff00) /* AG */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_8888(x) \ ((((x) & 0xff000000) >> 24) /* A */ | \ (((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_4444(x) \ ((((x) & 0xf0000000) >> 16) /* A */ | \ (((x) & 0x00f00000) >> 20) /* B */ | \ (((x) & 0x0000f000) >> 8) /* G */ | \ (((x) & 0x000000f0) << 4) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_565(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_555(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_5551(x) \ ((((x) & 0x80000000) >> 31) /* A */ | \ (((x) & 0x00f80000) >> 18) /* B */ | \ (((x) & 0x0000f800) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_1555(x) \ ((((x) & 0x80000000) >> 16) /* A */ | \ (((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_XBGR_8888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_565(x) \ ((((x) & 0x00f80000) >> 8) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_555(x) \ ((((x) & 0x00f80000) >> 9) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_RGBX_8888(x) \ ((((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_XRGB_8888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_F32(x) \ al_map_rgba(((x) >> 0) & 255,\ ((x) >> 8) & 255,\ ((x) >> 16) & 255,\ ((x) >> 24) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(x) \ ((((x) & 0xff000000) >> 24) /* A */ | \ (((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(x) \ (((x) & 0xffffffff) /* ABGR */) #endif #define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_4444(x) \ ((((x) & 0xf0000000) >> 28) /* A */ | \ (((x) & 0x00f00000) >> 16) /* B */ | \ (((x) & 0x0000f000) >> 4) /* G */ | \ (((x) & 0x000000f0) << 8) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x00f00000) >> 20) /* B */ | \ (((x) & 0x0000f000) >> 8) /* G */ | \ (((x) & 0x000000f0) << 4) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_565(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_555(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x00f80000) >> 18) /* B */ | \ (((x) & 0x0000f800) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ ((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_565(x) \ ((((x) & 0x00f80000) >> 8) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_555(x) \ ((((x) & 0x00f80000) >> 9) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_RGBX_8888(x) \ ((((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_XRGB_8888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_F32(x) \ al_map_rgb(((x) >> 0) & 255,\ ((x) >> 8) & 255,\ ((x) >> 16) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #else #define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ ((x) & 0x00ffffff) /* BGR */) #endif #define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0x00f00000) >> 16) /* B */ | \ (((x) & 0x0000f000) >> 4) /* G */ | \ (((x) & 0x000000f0) << 8) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0xff0000) >> 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0x0000ff) << 16) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (((x) & 0xff0000) >> 8) /* B */ | \ (((x) & 0x00ff00) << 8) /* G */ | \ (((x) & 0x0000ff) << 24) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0xf00000) >> 20) /* B */ | \ (((x) & 0x00f000) >> 8) /* G */ | \ (((x) & 0x0000f0) << 4) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGB_888(x) \ ((((x) & 0xff0000) >> 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0x0000ff) << 16) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGB_565(x) \ ((((x) & 0xf80000) >> 19) /* B */ | \ (((x) & 0x00fc00) >> 5) /* G */ | \ (((x) & 0x0000f8) << 8) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGB_555(x) \ ((((x) & 0xf80000) >> 19) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0x0000f8) << 7) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0xf80000) >> 18) /* B */ | \ (((x) & 0x00f800) >> 5) /* G */ | \ (((x) & 0x0000f8) << 8) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0xf80000) >> 19) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0x0000f8) << 7) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ ((x) & 0xffffff) /* BGR */) #define ALLEGRO_CONVERT_BGR_888_TO_XBGR_8888(x) \ (((x) & 0xffffff) /* BGR */) #define ALLEGRO_CONVERT_BGR_888_TO_BGR_565(x) \ ((((x) & 0xf80000) >> 8) /* B */ | \ (((x) & 0x00fc00) >> 5) /* G */ | \ (((x) & 0x0000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_BGR_555(x) \ ((((x) & 0xf80000) >> 9) /* B */ | \ (((x) & 0x00f800) >> 6) /* G */ | \ (((x) & 0x0000f8) >> 3) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_RGBX_8888(x) \ ((((x) & 0xff0000) >> 8) /* B */ | \ (((x) & 0x00ff00) << 8) /* G */ | \ (((x) & 0x0000ff) << 24) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_XRGB_8888(x) \ ((((x) & 0xff0000) >> 16) /* B */ | \ ((x) & 0x00ff00) /* G */ | \ (((x) & 0x0000ff) << 16) /* R */) #define ALLEGRO_CONVERT_BGR_888_TO_ABGR_F32(x) \ al_map_rgb(((x) >> 0) & 255,\ ((x) >> 8) & 255,\ ((x) >> 16) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (((x) & 0xff0000) >> 8) /* B */ | \ (((x) & 0x00ff00) << 8) /* G */ | \ (((x) & 0x0000ff) << 24) /* R */) #else #define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ ((x) & 0xffffff) /* BGR */) #endif #define ALLEGRO_CONVERT_BGR_888_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0xf00000) >> 16) /* B */ | \ (((x) & 0x00f000) >> 4) /* G */ | \ (((x) & 0x0000f0) << 8) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0xf000) >> 12) /* B */ | \ (((x) & 0x0780) >> 3) /* G */ | \ (((x) & 0x001e) << 7) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_RGB_565(x) \ ((((x) & 0xf800) >> 11) /* B */ | \ ((x) & 0x07e0) /* G */ | \ (((x) & 0x001f) << 11) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_RGB_555(x) \ ((((x) & 0xf800) >> 11) /* B */ | \ (((x) & 0x07c0) >> 1) /* G */ | \ (((x) & 0x001f) << 10) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0xf800) >> 10) /* B */ | \ ((x) & 0x07c0) /* G */ | \ (((x) & 0x001f) << 11) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0xf800) >> 11) /* B */ | \ (((x) & 0x07c0) >> 1) /* G */ | \ (((x) & 0x001f) << 10) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_BGR_555(x) \ (((x) & 0x001f) /* R */ | \ (((x) & 0xffc0) >> 1) /* BG */) #define ALLEGRO_CONVERT_BGR_565_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_565_TO_ABGR_F32(x) \ al_map_rgb(_al_rgb_scale_5[((x) >> 0) & 31],\ _al_rgb_scale_6[((x) >> 5) & 63],\ _al_rgb_scale_5[((x) >> 11) & 31]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) #else #define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) #endif #define ALLEGRO_CONVERT_BGR_565_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0xf000) >> 8) /* B */ | \ (((x) & 0x0780) << 1) /* G */ | \ (((x) & 0x001e) << 11) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x7800) >> 11) /* B */ | \ (((x) & 0x3c0) >> 2) /* G */ | \ (((x) & 0x01e) << 7) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_RGB_888(x) \ ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_RGB_565(x) \ ((((x) & 0x7c00) >> 10) /* B */ | \ (((x) & 0x3e0) << 1) /* G */ | \ (((x) & 0x01f) << 11) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_RGB_555(x) \ ((((x) & 0x7c00) >> 10) /* B */ | \ ((x) & 0x3e0) /* G */ | \ (((x) & 0x01f) << 10) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x7c00) >> 9) /* B */ | \ (((x) & 0x3e0) << 1) /* G */ | \ (((x) & 0x01f) << 11) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0x7c00) >> 10) /* B */ | \ ((x) & 0x3e0) /* G */ | \ (((x) & 0x01f) << 10) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_XBGR_8888(x) \ ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_BGR_888(x) \ ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_BGR_565(x) \ (((x) & 0x01f) /* R */ | \ (((x) & 0x7fe0) << 1) /* BG */) #define ALLEGRO_CONVERT_BGR_555_TO_RGBX_8888(x) \ ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_XRGB_8888(x) \ ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) #define ALLEGRO_CONVERT_BGR_555_TO_ABGR_F32(x) \ al_map_rgb(_al_rgb_scale_5[((x) >> 0) & 31],\ _al_rgb_scale_5[((x) >> 5) & 31],\ _al_rgb_scale_5[((x) >> 10) & 31]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) #else #define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) #endif #define ALLEGRO_CONVERT_BGR_555_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0x7800) >> 7) /* B */ | \ (((x) & 0x3c0) << 2) /* G */ | \ (((x) & 0x01e) << 11) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ ((x) & 0xffffff00) /* BGR */) #define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x0000f000) >> 12) /* B */ | \ (((x) & 0x00f00000) >> 16) /* G */ | \ (((x) & 0xf0000000) >> 20) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_565(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_555(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x0000f800) >> 10) /* B */ | \ (((x) & 0x00f80000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_XBGR_8888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_565(x) \ (((x) & 0x0000f800) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_555(x) \ ((((x) & 0x0000f800) >> 1) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #define ALLEGRO_CONVERT_RGBX_8888_TO_XRGB_8888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_F32(x) \ al_map_rgb(((x) >> 24) & 255,\ ((x) >> 16) & 255,\ ((x) >> 8) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ ((x) & 0xffffff00) /* BGR */) #else #define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #endif #define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ (((x) & 0x0000f000) >> 8) /* B */ | \ (((x) & 0x00f00000) >> 12) /* G */ | \ (((x) & 0xf0000000) >> 16) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_8888(x) \ ((0xff000000) /* A */ | \ ((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_8888(x) \ ((0x000000ff) /* A */ | \ (((x) & 0x00ffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_4444(x) \ ((0xf000) /* A */ | \ (((x) & 0x000000f0) >> 4) /* B */ | \ (((x) & 0x0000f000) >> 8) /* G */ | \ (((x) & 0x00f00000) >> 12) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_888(x) \ (((x) & 0x00ffffff) /* BGR */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_565(x) \ ((((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 8) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_555(x) \ ((((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 9) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_5551(x) \ ((0x0001) /* A */ | \ (((x) & 0x000000f8) >> 2) /* B */ | \ (((x) & 0x0000f800) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 8) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_1555(x) \ ((0x8000) /* A */ | \ (((x) & 0x000000f8) >> 3) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 9) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888(x) \ ((0xff000000) /* A */ | \ (((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_XBGR_8888(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_888(x) \ ((((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_565(x) \ ((((x) & 0x000000f8) << 8) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x00f80000) >> 19) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_555(x) \ ((((x) & 0x000000f8) << 7) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x00f80000) >> 19) /* R */) #define ALLEGRO_CONVERT_XRGB_8888_TO_RGBX_8888(x) \ ((((x) & 0x00ffffff) << 8) /* BGR */) #define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_F32(x) \ al_map_rgb(((x) >> 16) & 255,\ ((x) >> 8) & 255,\ ((x) >> 0) & 255) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(x) \ ((0x000000ff) /* A */ | \ (((x) & 0x00ffffff) << 8) /* BGR */) #else #define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(x) \ ((0xff000000) /* A */ | \ (((x) & 0x000000ff) << 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x00ff0000) >> 16) /* R */) #endif #define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_4444(x) \ ((0x000f) /* A */ | \ ((x) & 0x000000f0) /* B */ | \ (((x) & 0x0000f000) >> 4) /* G */ | \ (((x) & 0x00f00000) >> 8) /* R */) #define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_8888(x) \ (((uint32_t)((x).a * 255) << 24) | \ ((uint32_t)((x).b * 255) << 0) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 16)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_8888(x) \ (((uint32_t)((x).a * 255) << 0) | \ ((uint32_t)((x).b * 255) << 8) | \ ((uint32_t)((x).g * 255) << 16) | \ ((uint32_t)((x).r * 255) << 24)) #define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_4444(x) \ (((uint32_t)((x).a * 15) << 12) | \ ((uint32_t)((x).b * 15) << 0) | \ ((uint32_t)((x).g * 15) << 4) | \ ((uint32_t)((x).r * 15) << 8)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_888(x) \ (((uint32_t)((x).b * 255) << 0) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 16)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_565(x) \ (((uint32_t)((x).b * 31) << 0) | \ ((uint32_t)((x).g * 63) << 5) | \ ((uint32_t)((x).r * 31) << 11)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_555(x) \ (((uint32_t)((x).b * 31) << 0) | \ ((uint32_t)((x).g * 31) << 5) | \ ((uint32_t)((x).r * 31) << 10)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_5551(x) \ (((uint32_t)((x).a * 1) << 0) | \ ((uint32_t)((x).b * 31) << 1) | \ ((uint32_t)((x).g * 31) << 6) | \ ((uint32_t)((x).r * 31) << 11)) #define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_1555(x) \ (((uint32_t)((x).a * 1) << 15) | \ ((uint32_t)((x).b * 31) << 0) | \ ((uint32_t)((x).g * 31) << 5) | \ ((uint32_t)((x).r * 31) << 10)) #define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888(x) \ (((uint32_t)((x).a * 255) << 24) | \ ((uint32_t)((x).b * 255) << 16) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 0)) #define ALLEGRO_CONVERT_ABGR_F32_TO_XBGR_8888(x) \ (((uint32_t)((x).b * 255) << 16) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 0)) #define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_888(x) \ (((uint32_t)((x).b * 255) << 16) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 0)) #define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_565(x) \ (((uint32_t)((x).b * 31) << 11) | \ ((uint32_t)((x).g * 63) << 5) | \ ((uint32_t)((x).r * 31) << 0)) #define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_555(x) \ (((uint32_t)((x).b * 31) << 10) | \ ((uint32_t)((x).g * 31) << 5) | \ ((uint32_t)((x).r * 31) << 0)) #define ALLEGRO_CONVERT_ABGR_F32_TO_RGBX_8888(x) \ (((uint32_t)((x).b * 255) << 8) | \ ((uint32_t)((x).g * 255) << 16) | \ ((uint32_t)((x).r * 255) << 24)) #define ALLEGRO_CONVERT_ABGR_F32_TO_XRGB_8888(x) \ (((uint32_t)((x).b * 255) << 0) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 16)) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(x) \ (((uint32_t)((x).a * 255) << 0) | \ ((uint32_t)((x).b * 255) << 8) | \ ((uint32_t)((x).g * 255) << 16) | \ ((uint32_t)((x).r * 255) << 24)) #else #define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(x) \ (((uint32_t)((x).a * 255) << 24) | \ ((uint32_t)((x).b * 255) << 16) | \ ((uint32_t)((x).g * 255) << 8) | \ ((uint32_t)((x).r * 255) << 0)) #endif #define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_4444(x) \ (((uint32_t)((x).a * 15) << 0) | \ ((uint32_t)((x).b * 15) << 4) | \ ((uint32_t)((x).g * 15) << 8) | \ ((uint32_t)((x).r * 15) << 12)) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(x) \ ((((x) & 0x000000ff) << 24) /* A */ | \ (((x) & 0xffffff00) >> 8) /* BGR */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ (((x) & 0x000000ff) << 16) /* R */ | \ ((x) & 0xff00ff00) /* AG */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(x) \ (((x) & 0xffffffff) /* ABGR */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(x) \ ((((x) & 0xff000000) >> 24) /* A */ | \ (((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(x) \ ((((x) & 0x000000f0) << 8) /* A */ | \ (((x) & 0x0000f000) >> 12) /* B */ | \ (((x) & 0x00f00000) >> 16) /* G */ | \ (((x) & 0xf0000000) >> 20) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(x) \ ((((x) & 0xf0000000) >> 16) /* A */ | \ (((x) & 0x00f00000) >> 20) /* B */ | \ (((x) & 0x0000f000) >> 8) /* G */ | \ (((x) & 0x000000f0) << 4) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(x) \ ((((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(x) \ ((((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(x) \ ((((x) & 0x00000080) >> 7) /* A */ | \ (((x) & 0x0000f800) >> 10) /* B */ | \ (((x) & 0x00f80000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 16) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(x) \ ((((x) & 0x80000000) >> 31) /* A */ | \ (((x) & 0x00f80000) >> 18) /* B */ | \ (((x) & 0x0000f800) >> 5) /* G */ | \ (((x) & 0x000000f8) << 8) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(x) \ ((((x) & 0x00000080) << 8) /* A */ | \ (((x) & 0x0000f800) >> 11) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 17) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(x) \ ((((x) & 0x80000000) >> 16) /* A */ | \ (((x) & 0x00f80000) >> 19) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) << 7) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(x) \ ((((x) & 0x000000ff) << 24) /* A */ | \ (((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(x) \ (((x) & 0xffffffff) /* ABGR */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(x) \ (((x) & 0x00ffffff) /* BGR */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(x) \ ((((x) & 0x0000ff00) << 8) /* B */ | \ (((x) & 0x00ff0000) >> 8) /* G */ | \ (((x) & 0xff000000) >> 24) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(x) \ (((x) & 0x00ffffff) /* BGR */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(x) \ (((x) & 0x0000f800) /* B */ | \ (((x) & 0x00fc0000) >> 13) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(x) \ ((((x) & 0x00f80000) >> 8) /* B */ | \ (((x) & 0x0000fc00) >> 5) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(x) \ ((((x) & 0x0000f800) >> 1) /* B */ | \ (((x) & 0x00f80000) >> 14) /* G */ | \ (((x) & 0xf8000000) >> 27) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(x) \ ((((x) & 0x00f80000) >> 9) /* B */ | \ (((x) & 0x0000f800) >> 6) /* G */ | \ (((x) & 0x000000f8) >> 3) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(x) \ (((x) & 0xffffff00) /* BGR */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(x) \ ((((x) & 0x00ff0000) >> 8) /* B */ | \ (((x) & 0x0000ff00) << 8) /* G */ | \ (((x) & 0x000000ff) << 24) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(x) \ ((((x) & 0xffffff00) >> 8) /* BGR */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(x) \ ((((x) & 0x00ff0000) >> 16) /* B */ | \ ((x) & 0x0000ff00) /* G */ | \ (((x) & 0x000000ff) << 16) /* R */) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(x) \ al_map_rgba(((x) >> 24) & 255,\ ((x) >> 16) & 255,\ ((x) >> 8) & 255,\ ((x) >> 0) & 255) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(x) \ al_map_rgba(((x) >> 0) & 255,\ ((x) >> 8) & 255,\ ((x) >> 16) & 255,\ ((x) >> 24) & 255) #endif #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(x) \ ((((x) & 0x000000f0) >> 4) /* A */ | \ (((x) & 0x0000f000) >> 8) /* B */ | \ (((x) & 0x00f00000) >> 12) /* G */ | \ (((x) & 0xf0000000) >> 16) /* R */) #else #define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(x) \ ((((x) & 0xf0000000) >> 28) /* A */ | \ (((x) & 0x00f00000) >> 16) /* B */ | \ (((x) & 0x0000f000) >> 4) /* G */ | \ (((x) & 0x000000f0) << 8) /* R */) #endif #define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* A */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_4444(x) \ ((((x) & 0x000f) << 12) /* A */ | \ (((x) & 0xfff0) >> 4) /* BGR */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_888(x) \ ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(x) \ ((((x) & 0x00f0) >> 3) /* B */ | \ (((x) & 0x0f00) >> 1) /* G */ | \ ((x) & 0xf000) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_555(x) \ ((((x) & 0x00f0) >> 3) /* B */ | \ (((x) & 0x0f00) >> 2) /* G */ | \ (((x) & 0xf000) >> 1) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_5551(x) \ ((((x) & 0x0008) >> 3) /* A */ | \ (((x) & 0x00f0) >> 2) /* B */ | \ (((x) & 0x0f00) >> 1) /* G */ | \ ((x) & 0xf000) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_1555(x) \ ((((x) & 0x0008) << 12) /* A */ | \ (((x) & 0x00f0) >> 3) /* B */ | \ (((x) & 0x0f00) >> 2) /* G */ | \ (((x) & 0xf000) >> 1) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_XBGR_8888(x) \ ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_888(x) \ ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_565(x) \ ((((x) & 0x00f0) << 8) /* B */ | \ (((x) & 0x0f00) >> 1) /* G */ | \ (((x) & 0xf000) >> 11) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_555(x) \ ((((x) & 0x00f0) << 7) /* B */ | \ (((x) & 0x0f00) >> 2) /* G */ | \ (((x) & 0xf000) >> 11) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_RGBX_8888(x) \ ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_XRGB_8888(x) \ ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) #define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_F32(x) \ al_map_rgba(_al_rgb_scale_4[((x) >> 12) & 15],\ _al_rgb_scale_4[((x) >> 8) & 15],\ _al_rgb_scale_4[((x) >> 4) & 15],\ _al_rgb_scale_4[((x) >> 0) & 15]) #ifdef ALLEGRO_BIG_ENDIAN #define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* A */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) #else #define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(x) \ ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) #endif #endif // Warning: This file was created by make_converters.py - do not edit. allegro-5.0.10/include/allegro5/internal/aintern_opengl.h0000644000175000001440000001104512146021714022533 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_opengl_h #define __al_included_allegro5_aintern_opengl_h #include "allegro5/opengl/gl_ext.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_display.h" enum { _ALLEGRO_OPENGL_VERSION_0 = 0, /* dummy */ _ALLEGRO_OPENGL_VERSION_1_0 = 0x01000000, _ALLEGRO_OPENGL_VERSION_1_1 = 0x01010000, _ALLEGRO_OPENGL_VERSION_1_2 = 0x01020000, _ALLEGRO_OPENGL_VERSION_1_2_1 = 0x01020100, _ALLEGRO_OPENGL_VERSION_1_3 = 0x01030000, _ALLEGRO_OPENGL_VERSION_1_4 = 0x01040000, _ALLEGRO_OPENGL_VERSION_1_5 = 0x01050000, _ALLEGRO_OPENGL_VERSION_2_0 = 0x02000000, _ALLEGRO_OPENGL_VERSION_2_1 = 0x02010000, _ALLEGRO_OPENGL_VERSION_3_0 = 0x03000000, _ALLEGRO_OPENGL_VERSION_3_1 = 0x03010000, _ALLEGRO_OPENGL_VERSION_3_2 = 0x03020000, _ALLEGRO_OPENGL_VERSION_3_3 = 0x03030000, _ALLEGRO_OPENGL_VERSION_4_0 = 0x04000000 }; #define ALLEGRO_MAX_OPENGL_FBOS 8 struct ALLEGRO_BITMAP_OGL; enum { FBO_INFO_UNUSED = 0, FBO_INFO_TRANSIENT = 1, /* may be destroyed for another bitmap */ FBO_INFO_PERSISTENT = 2 /* exclusive to the owner bitmap */ }; typedef struct ALLEGRO_FBO_INFO { int fbo_state; GLuint fbo; struct ALLEGRO_BITMAP_OGL *owner; double last_use_time; } ALLEGRO_FBO_INFO; typedef struct ALLEGRO_BITMAP_OGL { ALLEGRO_BITMAP bitmap; /* This must be the first member. */ /* Driver specifics. */ int true_w; int true_h; GLuint texture; /* 0 means, not uploaded yet. */ #if defined ALLEGRO_GP2XWIZ EGLSurface pbuffer; EGLContext context; NativeWindowType pbuf_native_wnd; bool changed; #else ALLEGRO_FBO_INFO *fbo_info; #endif unsigned char *lock_buffer; float left, top, right, bottom; /* Texture coordinates. */ bool is_backbuffer; /* This is not a real bitmap, but the backbuffer. */ } ALLEGRO_BITMAP_OGL; typedef struct OPENGL_INFO { uint32_t version; /* OpenGL version */ int max_texture_size; /* Maximum texture size */ int is_voodoo3_and_under; /* Special cases for Voodoo 1-3 */ int is_voodoo; /* Special cases for Voodoo cards */ int is_matrox_g200; /* Special cases for Matrox G200 boards */ int is_ati_rage_pro; /* Special cases for ATI Rage Pro boards */ int is_ati_radeon_7000; /* Special cases for ATI Radeon 7000 */ int is_ati_r200_chip; /* Special cases for ATI card with chip R200 */ int is_mesa_driver; /* Special cases for MESA */ } OPENGL_INFO; typedef struct ALLEGRO_OGL_EXTRAS { /* A list of extensions supported by Allegro, for this context. */ ALLEGRO_OGL_EXT_LIST *extension_list; /* A list of extension API, loaded by Allegro, for this context. */ ALLEGRO_OGL_EXT_API *extension_api; /* Various info about OpenGL implementation. */ OPENGL_INFO ogl_info; ALLEGRO_BITMAP_OGL *opengl_target; ALLEGRO_BITMAP_OGL *backbuffer; /* True if display resources are shared among displays. */ bool is_shared; ALLEGRO_FBO_INFO fbos[ALLEGRO_MAX_OPENGL_FBOS]; } ALLEGRO_OGL_EXTRAS; typedef struct ALLEGRO_OGL_BITMAP_VERTEX { float x, y; float tx, ty; float r, g, b, a; } ALLEGRO_OGL_BITMAP_VERTEX; /* extensions */ int _al_ogl_look_for_an_extension(const char *name, const GLubyte *extensions); void _al_ogl_set_extensions(ALLEGRO_OGL_EXT_API *ext); void _al_ogl_manage_extensions(ALLEGRO_DISPLAY *disp); void _al_ogl_unmanage_extensions(ALLEGRO_DISPLAY *disp); /* bitmap */ ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h); ALLEGRO_BITMAP *_al_ogl_create_sub_bitmap(ALLEGRO_DISPLAY *d, ALLEGRO_BITMAP *parent, int x, int y, int w, int h); /* common driver */ void _al_ogl_reset_fbo_info(ALLEGRO_FBO_INFO *info); bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap); ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_FBO_INFO *transient_fbo_info); void _al_ogl_setup_gl(ALLEGRO_DISPLAY *d); void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); void _al_ogl_setup_bitmap_clipping(const ALLEGRO_BITMAP *bitmap); ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d); ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp); void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP_OGL *b); bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP_OGL *b, int w, int h); struct ALLEGRO_DISPLAY_INTERFACE; /* draw */ void _al_ogl_add_drawing_functions(struct ALLEGRO_DISPLAY_INTERFACE *vt); AL_FUNC(bool, _al_opengl_set_blender, (ALLEGRO_DISPLAY *disp)); #endif allegro-5.0.10/include/allegro5/internal/aintern_tls.h0000644000175000001440000000043412066715441022061 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_tls_h #define __al_included_allegro5_aintern_tls_h #ifdef __cplusplus extern "C" { #endif void _al_tls_init_once(void); int *_al_tls_get_dtor_owner_count(void); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_blend.h0000644000175000001440000001507112146027215022340 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_blend_h #define __al_included_allegro5_aintern_blend_h #include "allegro5/internal/aintern.h" #ifdef __cplusplus extern "C" { #endif #ifdef __GNUC__ #define _AL_ALWAYS_INLINE inline __attribute__((always_inline)) #else #define _AL_ALWAYS_INLINE INLINE #endif #define _AL_DEST_IS_ZERO \ (dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO && \ op != ALLEGRO_DEST_MINUS_SRC && op_alpha != ALLEGRO_DEST_MINUS_SRC) #define _AL_SRC_NOT_MODIFIED \ (src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE) #define _AL_SRC_NOT_MODIFIED_TINT_WHITE \ (_AL_SRC_NOT_MODIFIED && \ tint.r == 1.0f && tint.g == 1.0f && tint.b == 1.0f && tint.a == 1.0f) #ifndef _AL_NO_BLEND_INLINE_FUNC /* Only cares about alpha blending modes. */ static _AL_ALWAYS_INLINE float get_alpha_factor(enum ALLEGRO_BLEND_MODE operation, float src_alpha, float dst_alpha) { switch (operation) { case ALLEGRO_ZERO: return 0; case ALLEGRO_ONE: return 1; case ALLEGRO_ALPHA: return src_alpha; case ALLEGRO_INVERSE_ALPHA: return 1 - src_alpha; case ALLEGRO_SRC_COLOR: return src_alpha; case ALLEGRO_DEST_COLOR: return dst_alpha; case ALLEGRO_INVERSE_SRC_COLOR: return 1 - src_alpha; case ALLEGRO_INVERSE_DEST_COLOR: return 1 - dst_alpha; default: ASSERT(false); return 0; /* silence warning in release build */ } } /* Puts the blending factor in an ALLEGRO_COLOR object. */ static _AL_ALWAYS_INLINE void get_factor(enum ALLEGRO_BLEND_MODE operation, const ALLEGRO_COLOR *source, const ALLEGRO_COLOR *dest, ALLEGRO_COLOR *factor) { switch (operation) { case ALLEGRO_ZERO: factor->r = factor->g = factor->b = factor->a = 0; break; case ALLEGRO_ONE: factor->r = factor->g = factor->b = factor->a = 1; break; case ALLEGRO_ALPHA: factor->r = factor->g = factor->b = factor->a = source->a; break; case ALLEGRO_INVERSE_ALPHA: factor->r = factor->g = factor->b = factor->a = 1 - source->a; break; case ALLEGRO_SRC_COLOR: *factor = *source; break; case ALLEGRO_DEST_COLOR: *factor = *dest; break; case ALLEGRO_INVERSE_SRC_COLOR: factor->r = 1 - source->r; factor->g = 1 - source->g; factor->b = 1 - source->b; factor->a = 1 - source->a; break; case ALLEGRO_INVERSE_DEST_COLOR: factor->r = 1 - dest->r; factor->g = 1 - dest->g; factor->b = 1 - dest->b; factor->a = 1 - dest->a; break; default: ASSERT(false); factor->r = factor->g = factor->b = factor->a = 0; break; } } /* Only call this if the blend modes are one of: * ALLEGRO_ONE, ALLEGRO_ZERO, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA */ static _AL_ALWAYS_INLINE void _al_blend_alpha_inline( const ALLEGRO_COLOR *scol, const ALLEGRO_COLOR *dcol, int op, int src_, int dst_, int aop, int asrc_, int adst_, ALLEGRO_COLOR *result) { float asrc, adst; float src, dst; result->r = scol->r; result->g = scol->g; result->b = scol->b; result->a = scol->a; asrc = get_alpha_factor(asrc_, scol->a, dcol->a); adst = get_alpha_factor(adst_, scol->a, dcol->a); src = get_alpha_factor(src_, scol->a, dcol->a); dst = get_alpha_factor(dst_, scol->a, dcol->a); #define BLEND(c, src, dst) \ result->c = OP(result->c * src, dcol->c * dst); switch (op) { case ALLEGRO_ADD: #define OP(x, y) _ALLEGRO_MIN(1, x + y) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; case ALLEGRO_SRC_MINUS_DEST: #define OP(x, y) _ALLEGRO_MAX(0, x - y) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; case ALLEGRO_DEST_MINUS_SRC: #define OP(x, y) _ALLEGRO_MAX(0, y - x) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; } switch (aop) { case ALLEGRO_ADD: #define OP(x, y) _ALLEGRO_MIN(1, x + y) BLEND(a, asrc, adst) #undef OP break; case ALLEGRO_SRC_MINUS_DEST: #define OP(x, y) _ALLEGRO_MAX(0, x - y) BLEND(a, asrc, adst) #undef OP break; case ALLEGRO_DEST_MINUS_SRC: #define OP(x, y) _ALLEGRO_MAX(0, y - x) BLEND(a, asrc, adst) #undef OP break; } #undef BLEND } /* call this for general blending. its a little slower than just using alpha */ static _AL_ALWAYS_INLINE void _al_blend_inline( const ALLEGRO_COLOR *scol, const ALLEGRO_COLOR *dcol, int op, int src_, int dst_, int aop, int asrc_, int adst_, ALLEGRO_COLOR *result) { float asrc, adst; ALLEGRO_COLOR src, dst; result->r = scol->r; result->g = scol->g; result->b = scol->b; result->a = scol->a; asrc = get_alpha_factor(asrc_, scol->a, dcol->a); adst = get_alpha_factor(adst_, scol->a, dcol->a); get_factor(src_, scol, dcol, &src); get_factor(dst_, scol, dcol, &dst); #define BLEND(c, src, dst) \ result->c = OP(result->c * src.c, dcol->c * dst.c); switch (op) { case ALLEGRO_ADD: #define OP(x, y) _ALLEGRO_MIN(1, x + y) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; case ALLEGRO_SRC_MINUS_DEST: #define OP(x, y) _ALLEGRO_MAX(0, x - y) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; case ALLEGRO_DEST_MINUS_SRC: #define OP(x, y) _ALLEGRO_MAX(0, y - x) BLEND(r, src, dst) BLEND(g, src, dst) BLEND(b, src, dst) #undef OP break; } #undef BLEND #define BLEND(c, src, dst) \ result->c = OP(result->c * src, dcol->c * dst); switch (aop) { case ALLEGRO_ADD: #define OP(x, y) _ALLEGRO_MIN(1, x + y) BLEND(a, asrc, adst) #undef OP break; case ALLEGRO_SRC_MINUS_DEST: #define OP(x, y) _ALLEGRO_MAX(0, x - y) BLEND(a, asrc, adst) #undef OP break; case ALLEGRO_DEST_MINUS_SRC: #define OP(x, y) _ALLEGRO_MAX(0, y - x) BLEND(a, asrc, adst) #undef OP break; } #undef BLEND } #endif void _al_blend_memory(ALLEGRO_COLOR *src_color, ALLEGRO_BITMAP *dest, int dx, int dy, ALLEGRO_COLOR *result); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_config.h0000644000175000001440000000114511437710515022522 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_config_h #define __al_included_allegro5_aintern_config_h #include "allegro5/internal/aintern_aatree.h" struct ALLEGRO_CONFIG_ENTRY { bool is_comment; ALLEGRO_USTR *key; /* comment if is_comment is true */ ALLEGRO_USTR *value; ALLEGRO_CONFIG_ENTRY *next; }; struct ALLEGRO_CONFIG_SECTION { ALLEGRO_USTR *name; ALLEGRO_CONFIG_ENTRY *head; ALLEGRO_CONFIG_ENTRY *last; _AL_AATREE *tree; ALLEGRO_CONFIG_SECTION *next; }; struct ALLEGRO_CONFIG { ALLEGRO_CONFIG_SECTION *head; ALLEGRO_CONFIG_SECTION *last; _AL_AATREE *tree; }; #endif allegro-5.0.10/include/allegro5/internal/aintern_xfullscreen.h0000644000175000001440000000600512104442100023567 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xfullscreen_h #define __al_included_allegro5_aintern_xfullscreen_h /* fullscreen and multi monitor stuff */ typedef struct _ALLEGRO_XGLX_MMON_INTERFACE _ALLEGRO_XGLX_MMON_INTERFACE; struct _ALLEGRO_XGLX_MMON_INTERFACE { int (*get_num_display_modes)(ALLEGRO_SYSTEM_XGLX *s, int adapter); ALLEGRO_DISPLAY_MODE *(*get_display_mode)(ALLEGRO_SYSTEM_XGLX *s, int, int, ALLEGRO_DISPLAY_MODE*); bool (*set_mode)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *, int, int, int, int); void (*store_mode)(ALLEGRO_SYSTEM_XGLX *); void (*restore_mode)(ALLEGRO_SYSTEM_XGLX *, int); void (*get_display_offset)(ALLEGRO_SYSTEM_XGLX *, int, int *, int *); int (*get_num_adapters)(ALLEGRO_SYSTEM_XGLX *); bool (*get_monitor_info)(ALLEGRO_SYSTEM_XGLX *, int, ALLEGRO_MONITOR_INFO *); int (*get_default_adapter)(ALLEGRO_SYSTEM_XGLX *); int (*get_adapter)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *); int (*get_xscreen)(ALLEGRO_SYSTEM_XGLX *, int); void (*post_setup)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *); void (*handle_xevent)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *, XEvent *e); }; extern _ALLEGRO_XGLX_MMON_INTERFACE _al_xglx_mmon_interface; int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s); int _al_xsys_mheadx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y); void _al_xsys_mmon_exit(ALLEGRO_SYSTEM_XGLX *s); int _al_xglx_get_num_display_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter); ALLEGRO_DISPLAY_MODE *_al_xglx_get_display_mode( ALLEGRO_SYSTEM_XGLX *s, int adapter, int index, ALLEGRO_DISPLAY_MODE *mode); bool _al_xglx_fullscreen_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh_rate); void _al_xglx_store_video_mode(ALLEGRO_SYSTEM_XGLX *s); void _al_xglx_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter); void _al_xglx_fullscreen_to_display(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d); void _al_xglx_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value); void _al_xglx_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y); int _al_xglx_fullscreen_select_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int w, int h, int format, int refresh_rate); bool _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info); int _al_xglx_get_num_video_adapters(ALLEGRO_SYSTEM_XGLX *s); int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s); int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); void _al_xglx_set_above(ALLEGRO_DISPLAY *display, int value); int _al_xglx_get_adapter(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool recalc); void _al_xglx_handle_mmon_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e); #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR void _al_xsys_xrandr_init(ALLEGRO_SYSTEM_XGLX *s); void _al_xsys_xrandr_exit(ALLEGRO_SYSTEM_XGLX *s); #endif /* ALLEGRO_XWINDOWS_WITH_XRANDR */ #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_joystick.h0000644000175000001440000000435412125426002023107 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_joystick_h #define __al_included_allegro5_aintern_joystick_h #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_events.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_JOYSTICK_DRIVER { int joydrv_id; const char *joydrv_name; const char *joydrv_desc; const char *joydrv_ascii_name; AL_METHOD(bool, init_joystick, (void)); AL_METHOD(void, exit_joystick, (void)); AL_METHOD(bool, reconfigure_joysticks, (void)); AL_METHOD(int, num_joysticks, (void)); AL_METHOD(ALLEGRO_JOYSTICK *, get_joystick, (int joyn)); AL_METHOD(void, release_joystick, (ALLEGRO_JOYSTICK *joy)); AL_METHOD(void, get_joystick_state, (ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state)); AL_METHOD(const char *, get_name, (ALLEGRO_JOYSTICK *joy)); AL_METHOD(bool, get_active, (ALLEGRO_JOYSTICK *joy)); } ALLEGRO_JOYSTICK_DRIVER; AL_ARRAY(_AL_DRIVER_INFO, _al_joystick_driver_list); /* macros for constructing the driver list */ #define _AL_BEGIN_JOYSTICK_DRIVER_LIST \ _AL_DRIVER_INFO _al_joystick_driver_list[] = \ { #define _AL_END_JOYSTICK_DRIVER_LIST \ { 0, NULL, false } \ }; /* information about a single joystick axis */ typedef struct _AL_JOYSTICK_AXIS_INFO { char *name; } _AL_JOYSTICK_AXIS_INFO; /* information about one or more axis (a slider or directional control) */ typedef struct _AL_JOYSTICK_STICK_INFO { int flags; /* bit-field */ int num_axes; _AL_JOYSTICK_AXIS_INFO axis[_AL_MAX_JOYSTICK_AXES]; char *name; } _AL_JOYSTICK_STICK_INFO; /* information about a joystick button */ typedef struct _AL_JOYSTICK_BUTTON_INFO { const char *name; } _AL_JOYSTICK_BUTTON_INFO; /* information about an entire joystick */ typedef struct _AL_JOYSTICK_INFO { int num_sticks; int num_buttons; _AL_JOYSTICK_STICK_INFO stick[_AL_MAX_JOYSTICK_STICKS]; _AL_JOYSTICK_BUTTON_INFO button[_AL_MAX_JOYSTICK_BUTTONS]; } _AL_JOYSTICK_INFO; struct ALLEGRO_JOYSTICK { _AL_JOYSTICK_INFO info; }; void _al_generate_joystick_event(ALLEGRO_EVENT *event); #ifdef __cplusplus } #endif #endif /* vi ts=8 sts=3 sw=3 et */ allegro-5.0.10/include/allegro5/internal/aintern_dtor.h0000644000175000001440000000173711465256750022243 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_dtor_h #define __al_included_allegro5_aintern_dtor_h #ifdef __cplusplus extern "C" { #endif typedef struct _AL_DTOR_LIST _AL_DTOR_LIST; AL_FUNC(_AL_DTOR_LIST *, _al_init_destructors, (void)); AL_FUNC(void, _al_push_destructor_owner, (void)); AL_FUNC(void, _al_pop_destructor_owner, (void)); AL_FUNC(void, _al_run_destructors, (_AL_DTOR_LIST *dtors)); AL_FUNC(void, _al_shutdown_destructors, (_AL_DTOR_LIST *dtors)); AL_FUNC(void, _al_register_destructor, (_AL_DTOR_LIST *dtors, void *object, void (*func)(void*))); AL_FUNC(void, _al_unregister_destructor, (_AL_DTOR_LIST *dtors, void *object)); AL_FUNC(void, _al_foreach_destructor, (_AL_DTOR_LIST *dtors, void (*callback)(void *object, void (*func)(void *), void *udata), void *userdata)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_pixels.h0000644000175000001440000010546412124553574022576 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_pixels_h #define __al_included_allegro5_aintern_pixels_h #include "allegro5/internal/aintern_float.h" #ifdef __cplusplus extern "C" { #endif #define _AL_MAP_RGBA(_color, _r, _g, _b, _a) \ do { \ (_color).r = _al_u8_to_float[_r]; \ (_color).g = _al_u8_to_float[_g]; \ (_color).b = _al_u8_to_float[_b]; \ (_color).a = _al_u8_to_float[_a]; \ } while (0) #define _AL_INLINE_GET_PIXEL(format, data, color, advance) \ do { \ switch (format) { \ case ALLEGRO_PIXEL_FORMAT_ARGB_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0x00FF0000) >> 16, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x000000FF) >> 0, \ (_gp_pixel & 0xFF000000) >> 24); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0xFF000000) >> 24, \ (_gp_pixel & 0x00FF0000) >> 16, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x000000FF) >> 0); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ARGB_4444: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_4[(_gp_pixel & 0x0F00) >> 8], \ _al_rgb_scale_4[(_gp_pixel & 0x00F0) >> 4], \ _al_rgb_scale_4[(_gp_pixel & 0x000F)], \ _al_rgb_scale_4[(_gp_pixel & 0xF000) >> 12]); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGB_888: { \ uint32_t _gp_pixel = READ3BYTES(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0xFF0000) >> 16, \ (_gp_pixel & 0x00FF00) >> 8, \ (_gp_pixel & 0x0000FF) >> 0, \ 255); \ if (advance) \ data += 3; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGB_565: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ _al_rgb_scale_6[(_gp_pixel & 0x07E0) >> 5], \ _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ 255); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGB_555: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ 255); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_5551: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ _al_rgb_scale_5[(_gp_pixel & 0x07C0) >> 6], \ _al_rgb_scale_5[(_gp_pixel & 0x003E) >> 1], \ _al_rgb_scale_1[_gp_pixel & 1]); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ARGB_1555: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ _al_rgb_scale_1[(_gp_pixel & 0x8000) >> 15]); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0x000000FF) >> 0, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x00FF0000) >> 16, \ (_gp_pixel & 0xFF000000) >> 24); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_XBGR_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0x000000FF) >> 0, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x00FF0000) >> 16, \ 255); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_BGR_888: { \ uint32_t _gp_pixel = READ3BYTES(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0x000000FF) >> 0, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x00FF0000) >> 16, \ 255); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_BGR_565: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ _al_rgb_scale_6[(_gp_pixel & 0x07E0) >> 5], \ _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ 255); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_BGR_555: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ 255); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGBX_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0xFF000000) >> 24, \ (_gp_pixel & 0x00FF0000) >> 16, \ (_gp_pixel & 0x0000FF00) >> 8, \ 255); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_XRGB_8888: { \ uint32_t _gp_pixel = *(uint32_t *)(data); \ _AL_MAP_RGBA(color, \ (_gp_pixel & 0x00FF0000) >> 16, \ (_gp_pixel & 0x0000FF00) >> 8, \ (_gp_pixel & 0x000000FF), \ 255); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_F32: { \ float *f = (float *)data; \ color.r = f[0]; \ color.g = f[1]; \ color.b = f[2]; \ color.a = f[3]; \ if (advance) \ data += 4 * sizeof(float); \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE: { \ uint8_t *p = (uint8_t *)data; \ _AL_MAP_RGBA(color, *p, *(p + 1), *(p + 2), *(p + 3)); \ if (advance) \ data += 4; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_4444: { \ uint16_t _gp_pixel = *(uint16_t *)(data); \ _AL_MAP_RGBA(color, \ _al_rgb_scale_4[(_gp_pixel & 0xF000) >> 12], \ _al_rgb_scale_4[(_gp_pixel & 0x0F00) >> 8], \ _al_rgb_scale_4[(_gp_pixel & 0x00F0) >> 4], \ _al_rgb_scale_4[(_gp_pixel & 0x000F)]); \ if (advance) \ data += 2; \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ANY: \ case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: \ ALLEGRO_ERROR("INLINE_GET got fake _gp_pixel format: %d\n", format); \ abort(); \ break; \ \ case ALLEGRO_NUM_PIXEL_FORMATS: \ default: \ ALLEGRO_ERROR("INLINE_GET got non _gp_pixel format: %d\n", format); \ abort(); \ break; \ } \ } while (0) #define _AL_INLINE_PUT_PIXEL(format, data, color, advance) \ do { \ uint32_t _pp_pixel; \ switch (format) { \ case ALLEGRO_PIXEL_FORMAT_ARGB_8888: \ _pp_pixel = _al_fast_float_to_int(color.a * 255) << 24; \ _pp_pixel |= _al_fast_float_to_int(color.r * 255) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.b * 255); \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_8888: \ _pp_pixel = _al_fast_float_to_int(color.r * 255) << 24; \ _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.b * 255) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.a * 255); \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_ARGB_4444: \ _pp_pixel = _al_fast_float_to_int(color.a * 15) << 12; \ _pp_pixel |= _al_fast_float_to_int(color.r * 15) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.g * 15) << 4; \ _pp_pixel |= _al_fast_float_to_int(color.b * 15); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGB_888: \ _pp_pixel = _al_fast_float_to_int(color.r * 255) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.b * 255); \ WRITE3BYTES(data, _pp_pixel); \ if (advance) \ data += 3; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGB_565: \ _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 11; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x3f) << 5; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGB_555: \ _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 10; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_5551: \ _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 11; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 6; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f) << 1; \ _pp_pixel |= _al_fast_float_to_int(color.a); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_ARGB_1555: \ _pp_pixel = _al_fast_float_to_int(color.a) << 15; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f) << 10; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_8888: \ _pp_pixel = _al_fast_float_to_int(color.a * 0xff) << 24; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_XBGR_8888: \ _pp_pixel = 0xff000000; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_BGR_888: \ _pp_pixel = _al_fast_float_to_int(color.b * 0xff) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ WRITE3BYTES(data, _pp_pixel); \ if (advance) \ data += 3; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_BGR_565: \ _pp_pixel = _al_fast_float_to_int(color.b * 0x1f) << 11; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x3f) << 5; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_BGR_555: \ _pp_pixel = _al_fast_float_to_int(color.b * 0x1f) << 10; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f); \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGBX_8888: \ _pp_pixel = 0xff; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0xff) << 24; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 8; \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_XRGB_8888: \ _pp_pixel = 0xff000000; \ _pp_pixel |= _al_fast_float_to_int(color.r * 0xff) << 16; \ _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.b * 0xff); \ *(uint32_t *)(data) = _pp_pixel; \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_F32: { \ float *f = (float *)data; \ f[0] = color.r; \ f[1] = color.g; \ f[2] = color.b; \ f[3] = color.a; \ if (advance) \ data += 4 * sizeof(float); \ break; \ } \ \ case ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE: \ *((uint8_t *)data + 0) = _al_fast_float_to_int(color.r * 0xff); \ *((uint8_t *)data + 1) = _al_fast_float_to_int(color.g * 0xff); \ *((uint8_t *)data + 2) = _al_fast_float_to_int(color.b * 0xff); \ *((uint8_t *)data + 3) = _al_fast_float_to_int(color.a * 0xff); \ if (advance) \ data += 4; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_RGBA_4444: \ _pp_pixel = _al_fast_float_to_int(color.a * 15); \ _pp_pixel |= _al_fast_float_to_int(color.r * 15) << 12; \ _pp_pixel |= _al_fast_float_to_int(color.g * 15) << 8; \ _pp_pixel |= _al_fast_float_to_int(color.b * 15) << 4; \ *(uint16_t *)(data) = _pp_pixel; \ if (advance) \ data += 2; \ break; \ \ case ALLEGRO_PIXEL_FORMAT_ANY: \ case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: \ case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: \ ALLEGRO_ERROR("INLINE_PUT got fake _pp_pixel format: %d\n", format); \ abort(); \ break; \ \ case ALLEGRO_NUM_PIXEL_FORMATS: \ ALLEGRO_ERROR("INLINE_PUT got non _pp_pixel format: %d\n", format); \ abort(); \ break; \ } \ } while (0) AL_ARRAY(int, _al_rgb_scale_1); AL_ARRAY(int, _al_rgb_scale_4); AL_ARRAY(int, _al_rgb_scale_5); AL_ARRAY(int, _al_rgb_scale_6); AL_ARRAY(float, _al_u8_to_float); void _al_init_pixels(void); bool _al_pixel_format_has_alpha(int format); bool _al_pixel_format_is_real(int format); int _al_get_real_pixel_format(ALLEGRO_DISPLAY *display, int format); char const *_al_pixel_format_name(ALLEGRO_PIXEL_FORMAT format); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_xcursor.h0000644000175000001440000000116112104442100022740 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xcursor_h #define __al_included_allegro5_aintern_xcursor_h #ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR #include #endif #include "allegro5/internal/aintern_display.h" typedef struct ALLEGRO_MOUSE_CURSOR_XWIN ALLEGRO_MOUSE_CURSOR_XWIN; struct ALLEGRO_MOUSE_CURSOR_XWIN { Cursor cursor; }; ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus); void _al_xwin_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor); void _al_xwin_add_cursor_functions(ALLEGRO_DISPLAY_INTERFACE *vt); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_atomicops.h0000644000175000001440000000601511426530515023252 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_atomicops_h #define __al_included_allegro5_aintern_atomicops_h #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) /* gcc 4.1 and above have builtin atomic operations. */ typedef int _AL_ATOMIC; AL_INLINE(_AL_ATOMIC, _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), { return __sync_fetch_and_add(ptr, 1); }) AL_INLINE(_AL_ATOMIC, _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), { return __sync_sub_and_fetch(ptr, 1); }) #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) /* gcc, x86 or x86-64 */ typedef int _AL_ATOMIC; #define __al_fetch_and_add(ptr, value, result) \ __asm__ __volatile__ ( \ "lock; xaddl %0, %1" \ : "=r" (result), "=m" (*ptr) \ : "0" (value), "m" (*ptr) \ : "memory" \ ) AL_INLINE(_AL_ATOMIC, _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), { _AL_ATOMIC result; __al_fetch_and_add(ptr, 1, result); return result; }) AL_INLINE(_AL_ATOMIC, _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), { _AL_ATOMIC old; __al_fetch_and_add(ptr, -1, old); return old - 1; }) #elif defined(_MSC_VER) && _M_IX86 >= 400 /* MSVC, x86 */ /* MinGW supports these too, but we already have asm code above. */ typedef LONG _AL_ATOMIC; AL_INLINE(_AL_ATOMIC, _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), { return InterlockedIncrement(ptr) - 1; }) AL_INLINE(_AL_ATOMIC, _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), { return InterlockedDecrement(ptr); }) #elif defined(ALLEGRO_HAVE_OSATOMIC_H) /* OS X, GCC < 4.1 * These functions only work on Tiger (10.4) and above. * FIXME: Apple's manpage says these functions take volatile int* * arguments, but at least the 10.4 SDK seems to prototype them as * taking int * - should the volatile qualifier be removed from the * wrapper functions in this case? (EG) */ #include typedef int32_t _AL_ATOMIC; AL_INLINE(_AL_ATOMIC, _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), { return OSAtomicIncrement32Barrier((_AL_ATOMIC *)ptr) - 1; }) AL_INLINE(_AL_ATOMIC, _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), { return OSAtomicDecrement32Barrier((_AL_ATOMIC *)ptr); }) #else /* Hope for the best? */ #warning Atomic operations undefined for your compiler/architecture. typedef int _AL_ATOMIC; AL_INLINE(_AL_ATOMIC, _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), { return (*ptr)++; }) AL_INLINE(_AL_ATOMIC, _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), { return --(*ptr); }) #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_fshook.h0000644000175000001440000000153011426530515022542 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Internal File System Hook support. * * See readme.txt for copyright information. */ #ifndef __al_included_allegro5_aintern_fshook_h #define __al_included_allegro5_aintern_fshook_h #include "allegro5/base.h" #ifdef __cplusplus extern "C" { #endif extern struct ALLEGRO_FS_INTERFACE _al_fs_interface_stdio; #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_timer.h0000644000175000001440000000035511617372372022404 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_timer_h #define __al_included_allegro5_aintern_timer_h #ifdef __cplusplus extern "C" { #endif void _al_init_timers(void); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_xsystem.h0000644000175000001440000000535312066442652023001 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xsystem_h #define __al_included_allegro5_aintern_xsystem_h #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE #include #endif #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA #include #endif #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR #include #endif #include "allegro5/internal/aintern_system.h" /* This is our version of ALLEGRO_SYSTEM with driver specific extra data. */ struct ALLEGRO_SYSTEM_XGLX { /* This must be the first member, we "derive" from it. */ ALLEGRO_SYSTEM system; /* Driver specifics. */ /* X11 is not thread-safe. But we use a separate thread to handle X11 events. * Plus, users may call OpenGL commands in the main thread, and we have no * way to enforce locking for them. * The only solution seems to be two X11 display connections. One to do our * input handling, and one for OpenGL graphics. * * Note: these may be NULL if we are not connected to an X server, for * headless command-line tools. We don't have a separate "null" system * driver. */ /* The X11 display. You *MUST* only access this from one * thread at a time, use the mutex lock below to ensure it. */ Display *x11display; /* Another X11 display we use for graphics. You *MUST* * only use this in the main thread. */ Display *gfxdisplay; Atom AllegroAtom; Atom XEmbedAtom; _AL_THREAD thread; /* background thread. */ _AL_MUTEX lock; /* thread lock for whenever we access internals. */ // FIXME: One condition variable really would be enough. _AL_COND resized; /* Condition variable to wait for resizing a window. */ ALLEGRO_DISPLAY *mouse_grab_display; /* Best effort: may be inaccurate. */ int toggle_mouse_grab_keycode; /* Disabled if zero */ unsigned int toggle_mouse_grab_modifiers; bool inhibit_screensaver; /* Should we inhibit the screensaver? */ bool mmon_interface_inited; #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA int xinerama_available; int xinerama_screen_count; XineramaScreenInfo *xinerama_screen_info; #endif #ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE /* For VidMode extension. */ int xfvm_available; int xfvm_screen_count; struct { int mode_count; XF86VidModeModeInfo **modes; XF86VidModeModeInfo *original_mode; } *xfvm_screen; #endif #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR int xrandr_available; int xrandr_event_base; _AL_VECTOR xrandr_screens; _AL_VECTOR xrandr_adaptermap; #endif /* Used to keep track of how many adapters are in use, so the multi-head * code can bail if we try to use more than one. */ int adapter_use_count; int adapter_map[32]; /* XXX magic constant */ }; #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_float.h0000644000175000001440000000111011426530515022350 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_float_h #define __al_included_allegro5_aintern_float_h /* This file used to contain a tricky function that sped up float->int * conversions on x86 machines when the SSE instruction CVTTSS2SI wasn't * available (or when SSE wasn't enabled in the compiler). * * However, it performed rounding instead of truncating like (int)f, which * did cause problems. If an alternative is found we could define this * macro once again. */ #define _al_fast_float_to_int(f) ((int)(f)) #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_keyboard.h0000644000175000001440000000347412125426002023052 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_keyboard_h #define __al_included_allegro5_aintern_keyboard_h #include "allegro5/internal/aintern_driver.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_KEYBOARD_DRIVER { int keydrv_id; const char *keydrv_name; const char *keydrv_desc; const char *keydrv_ascii_name; AL_METHOD(bool, init_keyboard, (void)); AL_METHOD(void, exit_keyboard, (void)); AL_METHOD(ALLEGRO_KEYBOARD*, get_keyboard, (void)); AL_METHOD(bool, set_keyboard_leds, (int leds)); AL_METHOD(const char *, keycode_to_name, (int keycode)); AL_METHOD(void, get_keyboard_state, (ALLEGRO_KEYBOARD_STATE *ret_state)); } ALLEGRO_KEYBOARD_DRIVER; AL_ARRAY(_AL_DRIVER_INFO, _al_keyboard_driver_list); AL_ARRAY(const char *, _al_keyboard_common_names); int _al_parse_key_binding(const char *s, unsigned int *modifiers); struct ALLEGRO_KEYBOARD { ALLEGRO_EVENT_SOURCE es; }; /* Helpers for AL_KEYBOARD_STATE structures. */ #define _AL_KEYBOARD_STATE_KEY_DOWN(STATE, KEYCODE) \ (((STATE).__key_down__internal__[(KEYCODE) / 32] & (1 << ((KEYCODE) % 32)))\ ? true : false) #define _AL_KEYBOARD_STATE_SET_KEY_DOWN(STATE, KEYCODE) \ do { \ int kc = (KEYCODE); \ (STATE).__key_down__internal__[kc / 32] |= (1 << (kc % 32)); \ } while (0) #define _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(STATE, KEYCODE) \ do { \ int kc = (KEYCODE); \ (STATE).__key_down__internal__[kc / 32] &= ~(1 << (kc % 32)); \ } while (0) #ifdef __cplusplus } #endif #endif /* vi ts=8 sts=3 sw=3 et */ allegro-5.0.10/include/allegro5/internal/aintern_xkeyboard.h0000644000175000001440000000102112104442100023216 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xkeyboard_h #define __al_included_allegro5_aintern_xkeyboard_h #include "allegro5/internal/aintern_keyboard.h" ALLEGRO_KEYBOARD_DRIVER *_al_xwin_keyboard_driver(void); void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display); void _al_xwin_keyboard_switch_handler(ALLEGRO_DISPLAY *display, bool focus_in); void _al_xwin_keyboard_handler_alternative(bool press, int hardware_keycode, uint32_t unichar, ALLEGRO_DISPLAY *display); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_exitfunc.h0000644000175000001440000000066312125160224023075 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_exitfunc_h #define __al_included_allegro5_aintern_exitfunc_h #ifdef __cplusplus extern "C" { #endif /* list of functions to call at program cleanup */ AL_FUNC(void, _al_add_exit_func, (AL_METHOD(void, func, (void)), const char *desc)); AL_FUNC(void, _al_remove_exit_func, (AL_METHOD(void, func, (void)))); AL_FUNC(void, _al_run_exit_funcs, (void)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_xwindow.h0000644000175000001440000000105212104442100022731 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xwindow_h #define __al_included_allegro5_aintern_xwindow_h void _al_xwin_set_size_hints(ALLEGRO_DISPLAY *d, int x_off, int y_off); void _al_xwin_reset_size_hints(ALLEGRO_DISPLAY *d); void _al_xwin_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value); void _al_xwin_set_above(ALLEGRO_DISPLAY *display, int value); void _al_xwin_set_frame(ALLEGRO_DISPLAY *display, bool frame_on); void _al_xwin_set_icons(ALLEGRO_DISPLAY *d, int num_icons, ALLEGRO_BITMAP *bitmaps[]); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_tri_soft.h0000644000175000001440000000146411445373511023112 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_tri_soft_h #define __al_included_allegro5_aintern_tri_soft_h struct ALLEGRO_BITMAP; /* Duplicated in allegro_primitives.h */ #ifndef _ALLEGRO_VERTEX_DEFINED #define _ALLEGRO_VERTEX_DEFINED typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; struct ALLEGRO_VERTEX { float x, y, z; float u, v; ALLEGRO_COLOR color; }; #endif AL_FUNC(void, _al_triangle_2d, (ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3)); AL_FUNC(void, _al_draw_soft_triangle, ( ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), void (*first)(uintptr_t, int, int, int, int), void (*step)(uintptr_t, int), void (*draw)(uintptr_t, int, int, int))); #endif allegro-5.0.10/include/allegro5/internal/aintern_iphone.h0000644000175000001440000000330111476665340022543 0ustar tjadenusers#include "allegro5/allegro.h" #include #include typedef struct ALLEGRO_SYSTEM_IPHONE { ALLEGRO_SYSTEM system; ALLEGRO_MUTEX *mutex; ALLEGRO_COND *cond; bool has_shutdown, wants_shutdown; int visuals_count; ALLEGRO_EXTRA_DISPLAY_SETTINGS **visuals; } ALLEGRO_SYSTEM_IPHONE; typedef struct ALLEGRO_DISPLAY_IPHONE { ALLEGRO_DISPLAY display; } ALLEGRO_DISPLAY_IPHONE; void _al_iphone_init_path(void); void _al_iphone_add_view(ALLEGRO_DISPLAY *d); void _al_iphone_make_view_current(void); void _al_iphone_flip_view(void); void _al_iphone_reset_framebuffer(void); ALLEGRO_SYSTEM_INTERFACE *_al_get_iphone_system_interface(void); ALLEGRO_DISPLAY_INTERFACE *_al_get_iphone_display_interface(void); ALLEGRO_PATH *_al_iphone_get_path(int id); ALLEGRO_KEYBOARD_DRIVER *_al_get_iphone_keyboard_driver(void); ALLEGRO_MOUSE_DRIVER *_al_get_iphone_mouse_driver(void); ALLEGRO_JOYSTICK_DRIVER *_al_get_iphone_joystick_driver(void); void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d); void _al_iphone_generate_mouse_event(unsigned int type, int x, int y, unsigned int button, ALLEGRO_DISPLAY *d); void _al_iphone_update_visuals(void); void _al_iphone_accelerometer_control(int frequency); void _al_iphone_generate_joystick_event(float x, float y, float z); void _al_iphone_await_termination(void); void _al_iphone_get_screen_size(int *w, int *h); void _al_iphone_translate_from_screen(ALLEGRO_DISPLAY *d, int *x, int *y); void _al_iphone_translate_to_screen(ALLEGRO_DISPLAY *d, int *x, int *y); void _al_iphone_clip(ALLEGRO_BITMAP const *bitmap, int x_1, int y_1, int x_2, int y_2); float _al_iphone_get_screen_scale(void); allegro-5.0.10/include/allegro5/internal/aintern_memdraw.h0000644000175000001440000000060012142407204022674 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_memdraw_h #define __al_included_allegro5_aintern_memdraw_h #ifdef __cplusplus extern "C" { #endif void _al_clear_bitmap_by_locking(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color); void _al_draw_pixel_memory(ALLEGRO_BITMAP *bmp, float x, float y, ALLEGRO_COLOR *color); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_driver.h0000644000175000001440000000062212125426002022535 0ustar tjadenusers#ifndef __al_included_allegro5_internal_aintern_driver_h #define __al_included_allegro5_internal_aintern_driver_h typedef struct _AL_DRIVER_INFO /* info about a hardware driver */ { int id; /* integer ID */ void *driver; /* the driver structure */ int autodetect; /* set to allow autodetection */ } _AL_DRIVER_INFO; #endif allegro-5.0.10/include/allegro5/internal/bstrlib.h0000644000175000001440000003631011522502105021165 0ustar tjadenusers/* * This source file has had its exported symbols prefixed with _al_ or _AL_ * for the Allegro project. */ /* * This source file is part of the _al_bstring string library. This code was * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source * license and the GPL. Refer to the accompanying documentation for details * on usage and license. */ /* * bstrlib.c * * This file is the core module for implementing the _al_bstring functions. */ #ifndef _AL_BSTRLIB_INCLUDE #define _AL_BSTRLIB_INCLUDE #ifdef __cplusplus extern "C" { #endif #include #include #include #include #if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) # if defined (__TURBOC__) && !defined (__BORLANDC__) # define BSTRLIB_NOVSNP # endif #endif #define _AL_BSTR_ERR (-1) #define _AL_BSTR_OK (0) #define _AL_BSTR_BS_BUFF_LENGTH_GET (0) typedef struct _al_tagbstring * _al_bstring; typedef const struct _al_tagbstring * _al_const_bstring; /* Copy functions */ #define _al_cstr2bstr _al_bfromcstr extern _al_bstring _al_bfromcstr (const char * str); extern _al_bstring _al_bfromcstralloc (int mlen, const char * str); extern _al_bstring _al_blk2bstr (const void * blk, int len); extern char * _al_bstr2cstr (_al_const_bstring s, char z); extern int _al_bcstrfree (char * s); extern _al_bstring _al_bstrcpy (_al_const_bstring b1); extern int _al_bassign (_al_bstring a, _al_const_bstring b); extern int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len); extern int _al_bassigncstr (_al_bstring a, const char * str); extern int _al_bassignblk (_al_bstring a, const void * s, int len); /* Destroy function */ extern int _al_bdestroy (_al_bstring b); /* Space allocation hinting functions */ extern int _al_balloc (_al_bstring s, int len); extern int _al_ballocmin (_al_bstring b, int len); /* Substring extraction */ extern _al_bstring _al_bmidstr (_al_const_bstring b, int left, int len); /* Various standard manipulations */ extern int _al_bconcat (_al_bstring b0, _al_const_bstring b1); extern int _al_bconchar (_al_bstring b0, char c); extern int _al_bcatcstr (_al_bstring b, const char * s); extern int _al_bcatblk (_al_bstring b, const void * s, int len); extern int _al_binsert (_al_bstring s1, int pos, _al_const_bstring s2, unsigned char fill); extern int _al_binsertch (_al_bstring s1, int pos, int len, unsigned char fill); extern int _al_breplace (_al_bstring b1, int pos, int len, _al_const_bstring b2, unsigned char fill); extern int _al_bdelete (_al_bstring s1, int pos, int len); extern int _al_bsetstr (_al_bstring b0, int pos, _al_const_bstring b1, unsigned char fill); extern int _al_btrunc (_al_bstring b, int n); /* Scan/search functions */ extern int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1); extern int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n); extern int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1); extern int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len); extern int _al_biseq (_al_const_bstring b0, _al_const_bstring b1); extern int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len); extern int _al_biseqcstr (_al_const_bstring b, const char * s); extern int _al_biseqcstrcaseless (_al_const_bstring b, const char * s); extern int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1); extern int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n); extern int _al_binstr (_al_const_bstring s1, int pos, _al_const_bstring s2); extern int _al_binstrr (_al_const_bstring s1, int pos, _al_const_bstring s2); extern int _al_binstrcaseless (_al_const_bstring s1, int pos, _al_const_bstring s2); extern int _al_binstrrcaseless (_al_const_bstring s1, int pos, _al_const_bstring s2); extern int _al_bstrchrp (_al_const_bstring b, int c, int pos); extern int _al_bstrrchrp (_al_const_bstring b, int c, int pos); #define _al_bstrchr(b,c) _al_bstrchrp ((b), (c), 0) #define _al_bstrrchr(b,c) _al_bstrrchrp ((b), (c), _al_blength(b)-1) extern int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1); extern int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); extern int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1); extern int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); extern int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos); extern int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos); /* List of string container functions */ struct _al_bstrList { int qty, mlen; _al_bstring * entry; }; extern struct _al_bstrList * _al_bstrListCreate (void); extern int _al_bstrListDestroy (struct _al_bstrList * sl); extern int _al_bstrListAlloc (struct _al_bstrList * sl, int msz); extern int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz); /* String split and join functions */ extern struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar); extern struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_const_bstring splitStr); extern struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr); extern _al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep); extern int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); extern int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); extern int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm); /* Miscellaneous functions */ extern int _al_bpattern (_al_bstring b, int len); extern int _al_btoupper (_al_bstring b); extern int _al_btolower (_al_bstring b); extern int _al_bltrimws (_al_bstring b); extern int _al_brtrimws (_al_bstring b); extern int _al_btrimws (_al_bstring b); #if !defined (BSTRLIB_NOVSNP) extern _al_bstring _al_bformat (const char * fmt, ...); extern int _al_bformata (_al_bstring b, const char * fmt, ...); extern int _al_bassignformat (_al_bstring b, const char * fmt, ...); extern int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arglist); #define _al_bvformata(ret, b, fmt, lastarg) { \ _al_bstring bstrtmp_b = (b); \ const char * bstrtmp_fmt = (fmt); \ int bstrtmp_r = _AL_BSTR_ERR, bstrtmp_sz = 16; \ for (;;) { \ va_list bstrtmp_arglist; \ va_start (bstrtmp_arglist, lastarg); \ bstrtmp_r = _al_bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \ va_end (bstrtmp_arglist); \ if (bstrtmp_r >= 0) { /* Everything went ok */ \ bstrtmp_r = _AL_BSTR_OK; \ break; \ } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \ bstrtmp_r = _AL_BSTR_ERR; \ break; \ } \ bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \ } \ ret = bstrtmp_r; \ } #endif typedef int (*_al_bNgetc) (void *parm); typedef size_t (* _al_bNread) (void *buff, size_t elsize, size_t nelem, void *parm); /* Input functions */ extern _al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator); extern _al_bstring _al_bread (_al_bNread readPtr, void * parm); extern int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator); extern int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator); extern int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm); /* Stream functions */ extern struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm); extern void * _al_bsclose (struct _al_bStream * s); extern int _al_bsbufflength (struct _al_bStream * s, int sz); extern int _al_bsreadln (_al_bstring b, struct _al_bStream * s, char terminator); extern int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_const_bstring term); extern int _al_bsread (_al_bstring b, struct _al_bStream * s, int n); extern int _al_bsreadlna (_al_bstring b, struct _al_bStream * s, char terminator); extern int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_const_bstring term); extern int _al_bsreada (_al_bstring b, struct _al_bStream * s, int n); extern int _al_bsunread (struct _al_bStream * s, _al_const_bstring b); extern int _al_bspeek (_al_bstring r, const struct _al_bStream * s); extern int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm); extern int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm); extern int _al_bseof (const struct _al_bStream * s); #ifndef __al_tagbstring_defined #define __al_tagbstring_defined struct _al_tagbstring { int mlen; int slen; unsigned char * data; }; #endif /* Accessor macros */ #define _al_blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen)) #define _al_blength(b) (_al_blengthe ((b), 0)) #define _al_bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o)) #define _al_bdataofs(b, o) (_al_bdataofse ((b), (o), (void *)0)) #define _al_bdatae(b, e) (_al_bdataofse (b, 0, e)) #define _al_bdata(b) (_al_bdataofs (b, 0)) #define _al_bchare(b, p, e) ((((unsigned)(p)) < (unsigned)_al_blength(b)) ? ((b)->data[(p)]) : (e)) #define _al_bchar(b, p) _al_bchare ((b), (p), '\0') /* Static constant string initialization macro */ #define _al_bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")} #if defined(_MSC_VER) # define _al_bsStatic(q) _al_bsStaticMlen(q,-32) #endif #ifndef _al_bsStatic # define _al_bsStatic(q) _al_bsStaticMlen(q,-__LINE__) #endif /* Static constant block parameter pair */ #define _al_bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1) /* Reference building macros */ #define _al_cstr2tbstr _al_btfromcstr #define _al_btfromcstr(t,s) { \ (t).data = (unsigned char *) (s); \ (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \ (t).mlen = -1; \ } #define _al_blk2tbstr(t,s,l) { \ (t).data = (unsigned char *) (s); \ (t).slen = l; \ (t).mlen = -1; \ } #define _al_btfromblk(t,s,l) _al_blk2tbstr(t,s,l) #define _al_bmid2tbstr(t,b,p,l) { \ _al_const_bstring bstrtmp_s = (b); \ if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \ int bstrtmp_left = (p); \ int bstrtmp_len = (l); \ if (bstrtmp_left < 0) { \ bstrtmp_len += bstrtmp_left; \ bstrtmp_left = 0; \ } \ if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \ bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \ if (bstrtmp_len <= 0) { \ (t).data = (unsigned char *)""; \ (t).slen = 0; \ } else { \ (t).data = bstrtmp_s->data + bstrtmp_left; \ (t).slen = bstrtmp_len; \ } \ } else { \ (t).data = (unsigned char *)""; \ (t).slen = 0; \ } \ (t).mlen = -__LINE__; \ } #define _al_btfromblkltrimws(t,s,l) { \ int bstrtmp_idx = 0, bstrtmp_len = (l); \ unsigned char * bstrtmp_s = (s); \ if (bstrtmp_s && bstrtmp_len >= 0) { \ for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \ if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ } \ } \ (t).data = bstrtmp_s + bstrtmp_idx; \ (t).slen = bstrtmp_len - bstrtmp_idx; \ (t).mlen = -__LINE__; \ } #define _al_btfromblkrtrimws(t,s,l) { \ int bstrtmp_len = (l) - 1; \ unsigned char * bstrtmp_s = (s); \ if (bstrtmp_s && bstrtmp_len >= 0) { \ for (; bstrtmp_len >= 0; bstrtmp_len--) { \ if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ } \ } \ (t).data = bstrtmp_s; \ (t).slen = bstrtmp_len + 1; \ (t).mlen = -__LINE__; \ } #define _al_btfromblktrimws(t,s,l) { \ int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \ unsigned char * bstrtmp_s = (s); \ if (bstrtmp_s && bstrtmp_len >= 0) { \ for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \ if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ } \ for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \ if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ } \ } \ (t).data = bstrtmp_s + bstrtmp_idx; \ (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \ (t).mlen = -__LINE__; \ } /* Write protection macros */ #define _al_bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; } #define _al_bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); } #define _al_biswriteprotected(t) ((t).mlen <= 0) #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_display.h0000644000175000001440000001160412124557334022725 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_display_h #define __al_included_allegro5_aintern_display_h #include "allegro5/allegro.h" #include "allegro5/transformations.h" #include "allegro5/display.h" #include "allegro5/bitmap.h" #include "allegro5/internal/aintern_events.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_DISPLAY_INTERFACE ALLEGRO_DISPLAY_INTERFACE; struct ALLEGRO_DISPLAY_INTERFACE { int id; ALLEGRO_DISPLAY *(*create_display)(int w, int h); void (*destroy_display)(ALLEGRO_DISPLAY *display); bool (*set_current_display)(ALLEGRO_DISPLAY *d); void (*unset_current_display)(ALLEGRO_DISPLAY *d); void (*clear)(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color); void (*draw_pixel)(ALLEGRO_DISPLAY *d, float x, float y, ALLEGRO_COLOR *color); void (*flip_display)(ALLEGRO_DISPLAY *d); void (*update_display_region)(ALLEGRO_DISPLAY *d, int x, int y, int width, int height); bool (*acknowledge_resize)(ALLEGRO_DISPLAY *d); bool (*resize_display)(ALLEGRO_DISPLAY *d, int width, int height); void (*quick_size)(ALLEGRO_DISPLAY *d); ALLEGRO_BITMAP *(*create_bitmap)(ALLEGRO_DISPLAY *d, int w, int h); void (*set_target_bitmap)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); ALLEGRO_BITMAP *(*get_backbuffer)(ALLEGRO_DISPLAY *d); bool (*is_compatible_bitmap)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); void (*switch_out)(ALLEGRO_DISPLAY *display); void (*switch_in)(ALLEGRO_DISPLAY *display); void (*draw_memory_bitmap_region)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, int flags); ALLEGRO_BITMAP *(*create_sub_bitmap)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *parent, int x, int y, int width, int height); bool (*wait_for_vsync)(ALLEGRO_DISPLAY *display); bool (*set_mouse_cursor)(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor); bool (*set_system_mouse_cursor)(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id); bool (*show_mouse_cursor)(ALLEGRO_DISPLAY *display); bool (*hide_mouse_cursor)(ALLEGRO_DISPLAY *display); void (*set_icons)(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmap[]); void (*set_window_position)(ALLEGRO_DISPLAY *display, int x, int y); void (*get_window_position)(ALLEGRO_DISPLAY *display, int *x, int *y); bool (*set_display_flag)(ALLEGRO_DISPLAY *display, int flag, bool onoff); void (*set_window_title)(ALLEGRO_DISPLAY *display, const char *title); void (*flush_vertex_cache)(ALLEGRO_DISPLAY *d); void* (*prepare_vertex_cache)(ALLEGRO_DISPLAY *d, int num_new_vertices); void (*update_transformation)(ALLEGRO_DISPLAY* d, ALLEGRO_BITMAP *target); void (*shutdown)(void); }; struct ALLEGRO_OGL_EXTRAS; typedef struct ALLEGRO_BLENDER { int blend_op; int blend_source; int blend_dest; int blend_alpha_op; int blend_alpha_source; int blend_alpha_dest; } ALLEGRO_BLENDER; /* These are settings Allegro itself doesn't really care about on its * own, but which users may want to specify for a display anyway. */ ALLEGRO_STATIC_ASSERT(aintern_display, ALLEGRO_DISPLAY_OPTIONS_COUNT <= 32); typedef struct { int required, suggested; /* Bitfields. */ int settings[ALLEGRO_DISPLAY_OPTIONS_COUNT]; /* These are come in handy when creating a context. */ void *info; int index, score; } ALLEGRO_EXTRA_DISPLAY_SETTINGS; struct ALLEGRO_DISPLAY { /* Must be first, so the display can be used as event source. */ ALLEGRO_EVENT_SOURCE es; ALLEGRO_DISPLAY_INTERFACE *vt; int refresh_rate; int flags; int w, h; int backbuffer_format; /* ALLEGRO_PIXELFORMAT */ ALLEGRO_EXTRA_DISPLAY_SETTINGS extra_settings; struct ALLEGRO_OGL_EXTRAS *ogl_extras; _AL_VECTOR bitmaps; /* A list of bitmaps created for this display. */ int num_cache_vertices; bool cache_enabled; int vertex_cache_size; void* vertex_cache; uintptr_t cache_texture; ALLEGRO_BLENDER cur_blender; void (*display_invalidated)(ALLEGRO_DISPLAY*); }; int _al_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref); void _al_fill_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds); void _al_set_color_components(int format, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, int importance); int _al_deduce_color_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds); int _al_display_settings_sorter(const void *p0, const void *p1); void _al_destroy_display_bitmaps(ALLEGRO_DISPLAY *d); /* This is called from the primitives addon. */ AL_FUNC(void, _al_set_display_invalidated_callback, (ALLEGRO_DISPLAY *display, void (*display_invalidated)(ALLEGRO_DISPLAY*))); /* Defined in tls.c */ bool _al_set_current_display_only(ALLEGRO_DISPLAY *display); void _al_set_new_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings); ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_get_new_display_settings(void); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/alconfig.h0000644000175000001440000001760112132136546021322 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Configuration defines. * * By Shawn Hargreaves. * * See readme.txt for copyright information. */ /* for backward compatibility */ #ifdef USE_CONSOLE #define ALLEGRO_NO_MAGIC_MAIN #define ALLEGRO_USE_CONSOLE #endif /* include platform-specific stuff */ #include "allegro5/platform/alplatf.h" #if defined ALLEGRO_WATCOM #include "allegro5/platform/alwatcom.h" #elif defined ALLEGRO_MINGW32 #include "allegro5/platform/almngw32.h" #elif defined ALLEGRO_BCC32 #include "allegro5/platform/albcc32.h" #elif defined ALLEGRO_MSVC #include "allegro5/platform/almsvc.h" #elif defined ALLEGRO_IPHONE #include "allegro5/platform/aliphonecfg.h" #elif defined ALLEGRO_MACOSX #include "allegro5/platform/alosxcfg.h" #elif defined ALLEGRO_UNIX #include "allegro5/platform/alucfg.h" #else #error platform not supported #endif #include "allegro5/platform/astdint.h" #include "allegro5/platform/astdbool.h" /* special definitions for the GCC compiler */ #ifdef __GNUC__ #define ALLEGRO_GCC #ifndef AL_INLINE #ifdef __cplusplus #define AL_INLINE(type, name, args, code) \ static inline type name args; \ static inline type name args code /* Needed if this header is included by C99 code, as * "extern __inline__" in C99 exports a new global function. */ #elif __GNUC_STDC_INLINE__ #define AL_INLINE(type, name, args, code) \ extern __inline__ __attribute__((__gnu_inline__)) type name args; \ extern __inline__ __attribute__((__gnu_inline__)) type name args code #else #define AL_INLINE(type, name, args, code) \ extern __inline__ type name args; \ extern __inline__ type name args code #endif #endif #ifndef AL_INLINE_STATIC #ifdef __cplusplus #define AL_INLINE_STATIC(type, name, args, code) \ AL_INLINE(type, name, args, code) #else #define AL_INLINE_STATIC(type, name, args, code) \ static __inline__ type name args; \ static __inline__ type name args code #endif #endif #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) #ifndef INLINE #define INLINE __inline__ #endif #ifndef ZERO_SIZE_ARRAY #if __GNUC__ < 3 #define ZERO_SIZE_ARRAY(type, name) __extension__ type name[0] #else #define ZERO_SIZE_ARRAY(type, name) type name[] /* ISO C99 flexible array members */ #endif #endif #ifndef LONG_LONG #define LONG_LONG long long #ifdef ALLEGRO_GUESS_INTTYPES_OK #define int64_t signed long long #define uint64_t unsigned long long #endif #endif #ifdef __i386__ #define ALLEGRO_I386 #endif #ifdef __amd64__ #define ALLEGRO_AMD64 #endif #ifdef __arm__ #define ALLEGRO_ARM #endif #ifndef AL_FUNC_DEPRECATED #if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(__attribute__ ((deprecated)) type, name, args) #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(__attribute__ ((deprecated)) type, name, args, a, b) #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(__attribute__ ((deprecated)) type, name, args, code) #endif #endif #ifndef AL_ALIAS #define AL_ALIAS(DECL, CALL) \ static __attribute__((unused)) __inline__ DECL \ { \ return CALL; \ } #endif #ifndef AL_ALIAS_VOID_RET #define AL_ALIAS_VOID_RET(DECL, CALL) \ static __attribute__((unused)) __inline__ void DECL \ { \ CALL; \ } #endif #endif /* the rest of this file fills in some default definitions of language * features and helper functions, which are conditionalised so they will * only be included if none of the above headers defined custom versions. */ #ifndef INLINE #define INLINE #endif #ifndef ZERO_SIZE_ARRAY #define ZERO_SIZE_ARRAY(type, name) type name[] #endif #ifndef AL_VAR #define AL_VAR(type, name) extern type name #endif #ifndef AL_ARRAY #define AL_ARRAY(type, name) extern type name[] #endif #ifndef AL_FUNC #define AL_FUNC(type, name, args) type name args #endif #ifndef AL_PRINTFUNC #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) #endif #ifndef AL_METHOD #define AL_METHOD(type, name, args) type (*name) args #endif #ifndef AL_FUNCPTR #define AL_FUNCPTR(type, name, args) extern type (*name) args #endif #ifndef AL_FUNCPTRARRAY #define AL_FUNCPTRARRAY(type, name, args) extern type (*name[]) args #endif #ifndef AL_INLINE #define AL_INLINE(type, name, args, code) type name args; #endif #ifndef AL_FUNC_DEPRECATED #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(type, name, args) #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(type, name, args, a, b) #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(type, name, args, code) #endif #ifndef AL_ALIAS #define AL_ALIAS(DECL, CALL) \ static INLINE DECL \ { \ return CALL; \ } #endif #ifndef AL_ALIAS_VOID_RET #define AL_ALIAS_VOID_RET(DECL, CALL) \ static INLINE void DECL \ { \ CALL; \ } #endif #ifdef __cplusplus extern "C" { #endif /* endian-independent 3-byte accessor macros */ #ifdef ALLEGRO_LITTLE_ENDIAN #define READ3BYTES(p) ((*(unsigned char *)(p)) \ | (*((unsigned char *)(p) + 1) << 8) \ | (*((unsigned char *)(p) + 2) << 16)) #define WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c)), \ (*((unsigned char *)(p) + 1) = (c) >> 8), \ (*((unsigned char *)(p) + 2) = (c) >> 16)) #elif defined ALLEGRO_BIG_ENDIAN #define READ3BYTES(p) ((*(unsigned char *)(p) << 16) \ | (*((unsigned char *)(p) + 1) << 8) \ | (*((unsigned char *)(p) + 2))) #define WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c) >> 16), \ (*((unsigned char *)(p) + 1) = (c) >> 8), \ (*((unsigned char *)(p) + 2) = (c))) #else #error endianess not defined #endif /* generic versions of the video memory access helpers */ /* FIXME: why do we need macros for this? */ #define bmp_write16(addr, c) (*((uint16_t *)(addr)) = (c)) #define bmp_write32(addr, c) (*((uint32_t *)(addr)) = (c)) #define bmp_read16(addr) (*((uint16_t *)(addr))) #define bmp_read32(addr) (*((uint32_t *)(addr))) /* default random function definition */ #ifndef AL_RAND #define AL_RAND() (rand()) #endif #ifdef __cplusplus } #endif allegro-5.0.10/include/allegro5/internal/aintern_x.h0000644000175000001440000000035012104442100021501 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_x_h #define __al_included_allegro5_aintern_x_h #include typedef struct ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_XGLX; typedef struct ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_XGLX; #endif allegro-5.0.10/include/allegro5/internal/aintern_system.h0000644000175000001440000000434412125161267022604 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_system_h #define __al_included_allegro5_aintern_system_h #include "allegro5/system.h" #include "allegro5/internal/aintern_display.h" #include "allegro5/internal/aintern_dtor.h" #include "allegro5/internal/aintern_events.h" #include "allegro5/internal/aintern_joystick.h" #include "allegro5/internal/aintern_keyboard.h" #include "allegro5/internal/aintern_mouse.h" #include "allegro5/internal/aintern_vector.h" typedef struct ALLEGRO_SYSTEM_INTERFACE ALLEGRO_SYSTEM_INTERFACE; struct ALLEGRO_SYSTEM_INTERFACE { int id; ALLEGRO_SYSTEM *(*initialize)(int flags); ALLEGRO_DISPLAY_INTERFACE *(*get_display_driver)(void); ALLEGRO_KEYBOARD_DRIVER *(*get_keyboard_driver)(void); ALLEGRO_MOUSE_DRIVER *(*get_mouse_driver)(void); ALLEGRO_JOYSTICK_DRIVER *(*get_joystick_driver)(void); int (*get_num_display_modes)(void); ALLEGRO_DISPLAY_MODE *(*get_display_mode)(int index, ALLEGRO_DISPLAY_MODE *mode); void (*shutdown_system)(void); int (*get_num_video_adapters)(void); bool (*get_monitor_info)(int adapter, ALLEGRO_MONITOR_INFO *info); ALLEGRO_MOUSE_CURSOR *(*create_mouse_cursor)(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus); void (*destroy_mouse_cursor)(ALLEGRO_MOUSE_CURSOR *cursor); bool (*get_cursor_position)(int *ret_x, int *ret_y); bool (*grab_mouse)(ALLEGRO_DISPLAY *display); bool (*ungrab_mouse)(void); ALLEGRO_PATH *(*get_path)(int id); bool (*inhibit_screensaver)(bool inhibit); void (*thread_init)(ALLEGRO_THREAD *thread); void (*thread_exit)(ALLEGRO_THREAD *thread); void *(*open_library)(const char *filename); void *(*import_symbol)(void *library, const char *symbol); void (*close_library)(void *handle); }; struct ALLEGRO_SYSTEM { ALLEGRO_SYSTEM_INTERFACE *vt; _AL_VECTOR displays; /* Keep a list of all displays attached to us. */ ALLEGRO_CONFIG *config; ALLEGRO_PATH *user_exe_path; bool installed; }; AL_FUNC(void, _al_register_system_interfaces, (void)); AL_VAR(_AL_VECTOR, _al_system_interfaces); AL_VAR(_AL_DTOR_LIST *, _al_dtor_list); AL_FUNC(void *, _al_open_library, (const char *filename)); AL_FUNC(void *, _al_import_symbol, (void *library, const char *symbol)); AL_FUNC(void, _al_close_library, (void *library)); #endif allegro-5.0.10/include/allegro5/internal/aintern_aatree.h0000644000175000001440000000123112043106630022501 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_aatree_h #define __al_included_allegro5_aintern_aatree_h typedef struct _AL_AATREE _AL_AATREE; struct _AL_AATREE { int level; _AL_AATREE *left; _AL_AATREE *right; const void *key; void *value; }; typedef int (*_al_cmp_t)(const void *a, const void *b); _AL_AATREE *_al_aa_insert(_AL_AATREE *T, const void *key, void *value, _al_cmp_t compare); void *_al_aa_search(const _AL_AATREE *T, const void *key, _al_cmp_t compare); _AL_AATREE *_al_aa_delete(_AL_AATREE *T, const void *key, _al_cmp_t compare, void **ret_value); void _al_aa_free(_AL_AATREE *T); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_thread.h0000644000175000001440000000273111431672362022527 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_thread_h #define __al_included_allegro5_aintern_thread_h #include ALLEGRO_INTERNAL_THREAD_HEADER #ifdef __cplusplus extern "C" { #endif typedef struct _AL_THREAD _AL_THREAD; typedef struct _AL_MUTEX _AL_MUTEX; typedef struct _AL_COND _AL_COND; AL_FUNC(void, _al_thread_create, (_AL_THREAD*, void (*proc)(_AL_THREAD*, void*), void *arg)); AL_FUNC(void, _al_thread_set_should_stop, (_AL_THREAD *)); /* static inline bool _al_get_thread_should_stop(_AL_THREAD *); */ AL_FUNC(void, _al_thread_join, (_AL_THREAD*)); AL_FUNC(void, _al_thread_detach, (_AL_THREAD*)); AL_FUNC(void, _al_mutex_init, (_AL_MUTEX*)); AL_FUNC(void, _al_mutex_init_recursive, (_AL_MUTEX*)); AL_FUNC(void, _al_mutex_destroy, (_AL_MUTEX*)); /* static inline void _al_mutex_lock(_AL_MUTEX*); */ /* static inline void _al_mutex_unlock(_AL_MUTEX*); */ /* All 5 functions below are declared inline in aintuthr.h. * FIXME: Why are they all inline? And if they have to be, why not treat them * the same as the two functions above? */ #ifdef ALLEGRO_WINDOWS AL_FUNC(void, _al_cond_init, (_AL_COND*)); AL_FUNC(void, _al_cond_destroy, (_AL_COND*)); AL_FUNC(void, _al_cond_wait, (_AL_COND*, _AL_MUTEX*)); AL_FUNC(void, _al_cond_broadcast, (_AL_COND*)); AL_FUNC(void, _al_cond_signal, (_AL_COND*)); #endif AL_FUNC(int, _al_cond_timedwait, (_AL_COND*, _AL_MUTEX*, const ALLEGRO_TIMEOUT *timeout)); #ifdef __cplusplus } #endif #endif /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_bitmap.h0000644000175000001440000001014312125154301022515 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_bitmap_h #define __al_included_allegro5_aintern_bitmap_h #include "allegro5/bitmap.h" #include "allegro5/bitmap_lock.h" #include "allegro5/display.h" #include "allegro5/transformations.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_BITMAP_INTERFACE ALLEGRO_BITMAP_INTERFACE; struct ALLEGRO_BITMAP { ALLEGRO_BITMAP_INTERFACE *vt; ALLEGRO_DISPLAY *display; int format; int flags; int w, h; /* * The number of bytes between a pixel at (x,y) and (x,y+1). * This is larger than w * pixel_size if there is padding between lines. */ int pitch; /* * clip left, right, top, bottom * Clip anything outside of this. cr/cb are exclusive, that is (0, 0, 1, 1) * is the single pixel spawning a rectangle from floating point 0/0 to 1/1 - * or in other words, the single pixel 0/0. * * There is always confusion as to whether cr/cb are exclusive, leading to * subtle bugs. The suffixes are supposed to help with that. */ int cl; int cr_excl; int ct; int cb_excl; /* * Locking info. * * locked - locked or not? * lock_x/y - top left of the locked region * lock_w/h - width and height of the locked region * lock_flags - flags the region was locked with * locked_region - a copy of the locked rectangle */ bool locked; int lock_x; int lock_y; int lock_w; int lock_h; int lock_flags; ALLEGRO_LOCKED_REGION locked_region; /* Transformation for this bitmap */ ALLEGRO_TRANSFORM transform; /* Info for sub-bitmaps */ ALLEGRO_BITMAP *parent; int xofs; int yofs; /* A memory copy of the bitmap data. May be NULL for an empty bitmap. */ unsigned char *memory; /* Size of the bitmap object. Used only by functions to convert bitmap storage type. Can be missleading. */ size_t size; bool preserve_texture; }; struct ALLEGRO_BITMAP_INTERFACE { int id; void (*draw_bitmap_region)(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,float sx, float sy, float sw, float sh, int flags); /* After the memory-copy of the bitmap has been modified, need to call this * to update the display-specific copy. E.g. with an OpenGL driver, this * might create/update a texture. Returns false on failure. */ bool (*upload_bitmap)(ALLEGRO_BITMAP *bitmap); /* If the display version of the bitmap has been modified, use this to update * the memory copy accordingly. E.g. with an OpenGL driver, this might * read the contents of an associated texture. */ void (*update_clipping_rectangle)(ALLEGRO_BITMAP *bitmap); void (*destroy_bitmap)(ALLEGRO_BITMAP *bitmap); ALLEGRO_LOCKED_REGION * (*lock_region)(ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, int format, int flags); void (*unlock_region)(ALLEGRO_BITMAP *bitmap); }; extern void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] [ALLEGRO_NUM_PIXEL_FORMATS])(void *, int, void *, int, int, int, int, int, int, int); /* Bitmap conversion */ void _al_convert_bitmap_data( void *src, int src_format, int src_pitch, void *dst, int dst_format, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height); void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap); void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap); #ifdef ALLEGRO_GP2XWIZ /* Optimized blitters */ void _al_draw_bitmap_region_optimized_rgba_4444_to_rgb_565( ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags); void _al_draw_bitmap_region_optimized_rgb_565_to_rgb_565( ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags); void _al_draw_bitmap_region_optimized_rgba_4444_to_rgba_4444( ALLEGRO_BITMAP *src, int sx, int sy, int sw, int sh, ALLEGRO_BITMAP *dest, int dx, int dy, int flags); #endif /* Simple bitmap drawing */ /* _al_put_pixel was inadvertently exported in 5.0.x releases. */ AL_FUNC(void, _al_put_pixel, (ALLEGRO_BITMAP *bitmap, int x, int y, ALLEGRO_COLOR color)); /* Bitmap I/O */ void _al_init_iio_table(void); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_transform.h0000644000175000001440000000031512125153535023264 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_transform_h #define __al_included_allegro5_aintern_transform_h bool _al_transform_is_translation(const ALLEGRO_TRANSFORM* trans, float *dx, float *dy); #endif allegro-5.0.10/include/allegro5/internal/aintern_mouse.h0000644000175000001440000000201012125426002022363 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_mouse_h #define __al_included_allegro5_aintern_mouse_h #include "allegro5/internal/aintern_driver.h" #include "allegro5/internal/aintern_events.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_MOUSE_DRIVER { int msedrv_id; const char *msedrv_name; const char *msedrv_desc; const char *msedrv_ascii_name; AL_METHOD(bool, init_mouse, (void)); AL_METHOD(void, exit_mouse, (void)); AL_METHOD(ALLEGRO_MOUSE*, get_mouse, (void)); AL_METHOD(unsigned int, get_mouse_num_buttons, (void)); AL_METHOD(unsigned int, get_mouse_num_axes, (void)); AL_METHOD(bool, set_mouse_xy, (ALLEGRO_DISPLAY *display, int x, int y)); AL_METHOD(bool, set_mouse_axis, (int which, int value)); AL_METHOD(void, get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); } ALLEGRO_MOUSE_DRIVER; AL_ARRAY(_AL_DRIVER_INFO, _al_mouse_driver_list); struct ALLEGRO_MOUSE { ALLEGRO_EVENT_SOURCE es; }; #ifdef __cplusplus } #endif #endif /* vi ts=8 sts=3 sw=3 et */ allegro-5.0.10/include/allegro5/internal/aintern_list.h0000644000175000001440000000614411521376134022233 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_list_h #define __al_included_allegro5_aintern_list_h #ifdef __cplusplus extern "C" { #endif typedef struct _AL_LIST _AL_LIST; typedef struct _AL_LIST_ITEM _AL_LIST_ITEM; typedef void (*_AL_LIST_DTOR)(void* userdata); typedef void (*_AL_LIST_ITEM_DTOR)(void* value, void* userdata); AL_FUNC(_AL_LIST*, _al_list_create, (void)); AL_FUNC(_AL_LIST*, _al_list_create_static, (size_t capacity)); AL_FUNC(void, _al_list_destroy, (_AL_LIST* list)); AL_FUNC(void, _al_list_set_dtor, (_AL_LIST* list, _AL_LIST_DTOR dtor)); AL_FUNC(_AL_LIST_DTOR, _al_list_get_dtor, (_AL_LIST* list)); AL_FUNC(_AL_LIST_ITEM*, _al_list_push_front, (_AL_LIST* list, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_push_front_ex, (_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor)); AL_FUNC(_AL_LIST_ITEM*, _al_list_push_back, (_AL_LIST* list, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_push_back_ex, (_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor)); AL_FUNC(void, _al_list_pop_front, (_AL_LIST* list)); AL_FUNC(void, _al_list_pop_back, (_AL_LIST* list)); AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_after, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_after_ex, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor)); AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_before, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_before_ex, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor)); AL_FUNC(void, _al_list_erase, (_AL_LIST* list, _AL_LIST_ITEM* item)); AL_FUNC(void, _al_list_clear, (_AL_LIST* list)); AL_FUNC(void, _al_list_remove, (_AL_LIST* list, void* data)); AL_FUNC(bool, _al_list_is_empty, (_AL_LIST* list)); AL_FUNC(bool, _al_list_contains, (_AL_LIST* list, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_find_first, (_AL_LIST* list, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_find_last, (_AL_LIST* list, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_find_after, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); AL_FUNC(_AL_LIST_ITEM*, _al_list_find_before, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); AL_FUNC(size_t, _al_list_size, (_AL_LIST* list)); AL_FUNC(_AL_LIST_ITEM*, _al_list_at, (_AL_LIST* list, size_t index)); AL_FUNC(_AL_LIST_ITEM*, _al_list_front, (_AL_LIST* list)); AL_FUNC(_AL_LIST_ITEM*, _al_list_back, (_AL_LIST* list)); AL_FUNC(_AL_LIST_ITEM*, _al_list_next, (_AL_LIST* list, _AL_LIST_ITEM* item)); AL_FUNC(_AL_LIST_ITEM*, _al_list_previous, (_AL_LIST* list, _AL_LIST_ITEM* item)); AL_FUNC(_AL_LIST_ITEM*, _al_list_next_circular, (_AL_LIST* list, _AL_LIST_ITEM* item)); AL_FUNC(_AL_LIST_ITEM*, _al_list_previous_circular, (_AL_LIST* list, _AL_LIST_ITEM* item)); AL_FUNC(void*, _al_list_item_data, (_AL_LIST_ITEM* item)); AL_FUNC(void, _al_list_item_set_dtor, (_AL_LIST_ITEM* item, _AL_LIST_ITEM_DTOR dtor)); AL_FUNC(_AL_LIST_ITEM_DTOR, _al_list_item_get_dtor, (_AL_LIST_ITEM* item)); AL_FUNC(void, _al_list_set_user_data, (_AL_LIST* list, void* user_data)); AL_FUNC(void*, _al_list_get_user_data, (_AL_LIST* list)); #ifdef __cplusplus } #endif #endif allegro-5.0.10/include/allegro5/internal/aintern_xglx_config.h0000644000175000001440000000041612104442100023544 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_xglx_h #define __al_included_allegro5_aintern_xglx_h #include "allegro5/internal/aintern_x.h" void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx); bool _al_xglx_config_create_context(ALLEGRO_DISPLAY_XGLX *glx); #endif allegro-5.0.10/include/allegro5/internal/aintern_memblit.h0000644000175000001440000000055012125155766022713 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_memblit_h #define __al_included_allegro5_aintern_memblit_h #ifdef __cplusplus extern "C" { #endif void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int flags); #ifdef __cplusplus } #endif #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_path.h0000644000175000001440000000050311426530515022204 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_path_h #define __al_included_allegro5_aintern_path_h struct ALLEGRO_PATH { ALLEGRO_USTR *drive; ALLEGRO_USTR *filename; _AL_VECTOR segments; /* vector of ALLEGRO_USTR * */ ALLEGRO_USTR *basename; ALLEGRO_USTR *full_string; }; #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/include/allegro5/internal/aintern_events.h0000644000175000001440000000254611426530515022565 0ustar tjadenusers#ifndef __al_included_allegro5_aintern_events_h #define __al_included_allegro5_aintern_events_h #include "allegro5/internal/aintern_thread.h" #include "allegro5/internal/aintern_vector.h" #ifdef __cplusplus extern "C" { #endif typedef struct ALLEGRO_EVENT_SOURCE_REAL ALLEGRO_EVENT_SOURCE_REAL; struct ALLEGRO_EVENT_SOURCE_REAL { _AL_MUTEX mutex; _AL_VECTOR queues; intptr_t data; }; typedef struct ALLEGRO_USER_EVENT_DESCRIPTOR { void (*dtor)(ALLEGRO_USER_EVENT *event); int refcount; } ALLEGRO_USER_EVENT_DESCRIPTOR; AL_FUNC(void, _al_init_events, (void)); AL_FUNC(void, _al_event_source_init, (ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, _al_event_source_free, (ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, _al_event_source_lock, (ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, _al_event_source_unlock, (ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, _al_event_source_on_registration_to_queue, (ALLEGRO_EVENT_SOURCE*, ALLEGRO_EVENT_QUEUE*)); AL_FUNC(void, _al_event_source_on_unregistration_from_queue, (ALLEGRO_EVENT_SOURCE*, ALLEGRO_EVENT_QUEUE*)); AL_FUNC(bool, _al_event_source_needs_to_generate_event, (ALLEGRO_EVENT_SOURCE*)); AL_FUNC(void, _al_event_source_emit_event, (ALLEGRO_EVENT_SOURCE *, ALLEGRO_EVENT*)); AL_FUNC(void, _al_event_queue_push_event, (ALLEGRO_EVENT_QUEUE*, const ALLEGRO_EVENT*)); #ifdef __cplusplus } #endif #endif /* vi ts=8 sts=3 sw=3 et */ allegro-5.0.10/indent.pro0000644000175000001440000000014611066170075014415 0ustar tjadenusers-kr -nce -ss -ncs -i3 -cli3 -nut -bls -l80 -T ALLEGRO_BITMAP -T PACKFILE -T BMPINFOHEADER -T PalEntry allegro-5.0.10/README.txt0000644000175000001440000001265311520362452014113 0ustar tjadenusers% Allegro 5 Overview ======== Welcome to Allegro 5, a cross-platform game programming library. Currently supported platforms are Linux/Unix, Windows, MacOS X and iPhone. Note that Allegro 5 is wholly *incompatible* with Allegro 4 and earlier versions, but both may be installed at the same time without conflicts. This readme contains general information which applies to all platforms that Allegro builds on. README_cmake.txt discusses some build options for cmake. README_msvc.txt discusses compilation on Windows with Microsoft Visual C/C++. README_make.txt discusses compilation with GNU make. This applies to Unix-like operating systems such as Linux, MacOS X and MinGW on Windows. README_macosx.txt has a few additional notes for MacOS X. README_iphone.txt discusses iPhone operating systems. Requirements ============ We assume you have C and C++ compilers installed and functioning. We support gcc and MSVC. Allegro also requires CMake 2.6 or later to build. You may download it from Library dependencies ==================== Allegro is divided into a core library and a number of addon libraries. The core library depends on certain libraries to function. If you don't have those, nothing will work. These are required for the core library: - DirectX SDK (Windows only) You can get this for MSVC from the Microsoft web site (large download). Alternatively, smaller downloads for MSVC and MinGW are available here: Some of those are originally from: - X11 development libraries (Linux/Unix only) The libraries will be part of your Linux distribution, but you may have to install them explicitly. - OpenGL development libraries (optional only on Windows) The addons, too, may require additional libraries. Since the addons are strictly optional, they are not required to build Allegro, but a lot of functionality may be disabled if they are not present. Windows users may find some precompiled binaries for the additional libraries from . You need to get the `bin` and `lib` packages. The `bin` packages contain DLLs, and the `lib` packages contain the headers and import libraries. Mac users may find some dependencies in Fink or MacPorts. and Linux users likely have all the dependencies already, except PhysicsFS and DUMB. If your distribution uses separate development packages, they will need to be installed. The packages are probably named *-dev or *-devel. These are the dependencies required for the addons: - libpng and zlib, for PNG image support (Unix and older MinGW only) Home page: Windows binaries: On Windows/Mac OS X/iPhone, PNG image support is available by using the native facilities on the respective operating systems, so libpng is not required. - libjpeg, for JPEG image support (Unix and older MinGW only) Home page: Windows binaries: On Windows/Mac OS X/iPhone, JPEG image support is available by using the native facilities on the respective operating systems, so libjpeg is not required. - FreeType, for TrueType font support. Home page: Windows binaries: - Ogg Vorbis, a free lossy audio format. (libogg, libvorbis, libvorbisfile) Home page: - FLAC, a free lossless audio codec. (libFLAC, libogg) Home page: - DUMB, an IT, XM, S3M and MOD player library. (libdumb) Home page: - OpenAL, a 3D audio API. The audio addon can use OpenAL, although the 3D capabilities aren't used. On Mac OS X, OpenAL is *required* but should come with the OS anyway. On Linux and Windows, OpenAL will only be used if you request it, hence there is no reason to install it specifically. - PhysicsFS, provides access to archives, e.g. .zip files. Home page: On Windows it may be a pain to place all these libraries such that they can be found. Please see the README_cmake.txt section on the "deps subdirectory" when the time comes. API documentation ================= To build the documentation you will need Pandoc. Pandoc's home page is Installing Pandoc from source can be challenging, but you can build Allegro without building the documentation. Online documentation is available on the Allegro web site: Building with CMake =================== Building with CMake is a two step process. During the _configuration_ step, cmake will detect your compiler setup and find the libraries which are installed on your system. At the same time, you may select options to customise your build. If you are unsure of what you are doing, leave all the options at the defaults. Once the configuration step is successful, you will invoke another tool to build Allegro. The tool depends on your compiler, but is usually either `make`, or your IDE. To avoid problems, unpack Allegro into a directory *without spaces or other "weird" characters in the path*. This is a known problem. Now read README_msvc.txt, README_make.txt or README_macosx.txt. allegro-5.0.10/CMakeLists.txt0000644000175000001440000007025512132130644015153 0ustar tjadenusers# # # TODO: # # - some documentation targets still missing # - installing documentation # #-----------------------------------------------------------------------------# # # Build system setup # #-----------------------------------------------------------------------------# cmake_minimum_required(VERSION 2.6 FATAL_ERROR) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Profile." FORCE) endif() # Restrict configuration types to the selected build type. # Note: This needs to be done before the project command set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}" CACHE INTERNAL "internal") # Set the project name. # We use C++ in a few cases. project(ALLEGRO C CXX) set(ALLEGRO_VERSION 5.0.10) string(REGEX MATCH "^[0-9]+[.][0-9]+" ALLEGRO_SOVERSION ${ALLEGRO_VERSION}) string(REPLACE "." "" ALLEGRO_DLL_SHORTVER ${ALLEGRO_SOVERSION}) # Search in the `cmake' directory for additional CMake modules. list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) # Search in `deps' directories for dependency files. file(GLOB deps_subdirs "${CMAKE_SOURCE_DIR}/deps" "${CMAKE_SOURCE_DIR}/deps/*" "${CMAKE_BINARY_DIR}/deps" "${CMAKE_BINARY_DIR}/deps/*" ) foreach(subdir ${deps_subdirs}) if(EXISTS "${subdir}/include" OR EXISTS "${subdir}/lib") message(STATUS "Adding ${subdir} to CMAKE_FIND_ROOT_PATH") list(APPEND CMAKE_FIND_ROOT_PATH "${subdir}") endif() endforeach(subdir) # Search for C header files in these directories. include_directories( ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include ) # Put libraries into `lib'. set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) # Lists of all the source files. include(FileList) # Our own CMake macros and functions. include(Common) #-----------------------------------------------------------------------------# # # Build options # #-----------------------------------------------------------------------------# if(NOT IPHONE) option(SHARED "Build shared libraries" on) set(BUILD_SHARED_LIBS ${SHARED}) # actual CMake variable endif(NOT IPHONE) # On some 64-bit platforms, libraries should be installed into `lib64' # instead of `lib'. Set this to 64 to do that. set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' directories, e.g. '64'") option(WANT_FRAMEWORKS "Want frameworks on Mac OS X" off) option(WANT_EMBED "Make frameworks embeddable in application bundles (Mac OS X)" on) set(FRAMEWORK_INSTALL_PREFIX "/Library/Frameworks" CACHE STRING "Directory in which to install Mac OS X frameworks") # # Platforms and drivers. # option(WANT_X11 "X11 support" on) option(WANT_X11_XF86VIDMODE "X11 XF86VidMode Extension support" on) option(WANT_X11_XINERAMA "X11 Xinerama Extension support" on) option(WANT_X11_XRANDR "X11 XRandR Extension support" on) option(WANT_D3D "Enable Direct3D graphics driver (Windows)" on) option(WANT_D3D9EX "Enable Direct3D 9Ex extensions (Vista)" off) option(WANT_OPENGL "Enable OpenGL graphics driver (Windows, X11, OS X))" on) # # Addons. # option(WANT_FONT "Enable bitmap font add-on" on) option(WANT_AUDIO "Enable allegro_audio engine" on) option(WANT_IMAGE "Enable image load/save addon" on) if (NOT IPHONE) option(WANT_IMAGE_JPG "Enable JPEG support in image addon" on) option(WANT_IMAGE_PNG "Enable PNG support in image addon" on) endif (NOT IPHONE) option(WANT_TTF "Enable TTF addon" on) option(WANT_COLOR "Enable color addon" on) option(WANT_MEMFILE "Enable memfile addon" on) option(WANT_PHYSFS "Enable PhysicsFS addon" on) option(WANT_PRIMITIVES "Enable primitives addon" on) option(WANT_NATIVE_DIALOG "Enable native dialog addon" on) # # Wrappers. # option(WANT_PYTHON_WRAPPER "Enable generation of the Python wrapper" off) # # Documentation. # option(WANT_DOCS "Generate documentation" on) option(WANT_DOCS_HTML "Generate HTML documentation" on) option(WANT_DOCS_MAN "Generate man pages" on) option(WANT_DOCS_INFO "Generate Info document" off) option(WANT_DOCS_PDF "Generate PDF document (requires pdflatex)" off) option(WANT_DOCS_PDF_PAPER "Whether PDF output is destined for paper" off) # # For developers. # option(STRICT_WARN "Halt at warnings" off) option(WANT_MUDFLAP "Enable gcc mudflap (requires gcc 4.0+)" off) # # Minor options. # if(NOT IPHONE) option(WANT_ALLOW_SSE "Allow compiler to use SSE instructions (x86)" on) endif(NOT IPHONE) option(NO_FPU "No floating point unit" off) option(WANT_DLL_TLS "Force use of DllMain for TLS (Windows)" on) option(WANT_DEMO "Build demo programs" on) option(WANT_EXAMPLES "Build example programs" on) option(WANT_POPUP_EXAMPLES "Use popups instead of printf for fatal errors" on) option(WANT_TESTS "Build test programs" on) #-----------------------------------------------------------------------------# # # Set up compilers # #-----------------------------------------------------------------------------# include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) if(CMAKE_COMPILER_IS_GNUCC) set(COMPILER_GCC 1) endif(CMAKE_COMPILER_IS_GNUCC) if(WIN32) if(WANT_DLL_TLS AND SHARED) set(ALLEGRO_CFG_DLL_TLS 1) endif(WANT_DLL_TLS AND SHARED) endif(WIN32) if(MSVC) # MSVC never needs DLL TLS and it just confuses set(ALLEGRO_CFG_DLL_TLS 0) set(COMPILER_MSVC 1) set(ALLEGRO_MSVC 1) # Guess VCINSTALLDIR from the value of CMAKE_C_COMPILER if it's not set. # XXX CMAKE_C_COMPILER will often be simply "cl" so this won't work. if("$ENV{VCINSTALLDIR}" STREQUAL "") string(REGEX REPLACE "/bin/[^/]*$" "" VCINSTALLDIR "${CMAKE_C_COMPILER}") message(STATUS "Guessed MSVC directory: ${VCINSTALLDIR}") else("$ENV{VCINSTALLDIR}" STREQUAL "") file(TO_CMAKE_PATH "$ENV{VCINSTALLDIR}" VCINSTALLDIR) message(STATUS "Using VCINSTALLDIR: ${VCINSTALLDIR}") endif("$ENV{VCINSTALLDIR}" STREQUAL "") # Install in VCINSTALLDIR by default if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${VCINSTALLDIR} CACHE PATH "Install path prefix, prepended onto install directories." FORCE) endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(EXECUTABLE_TYPE "WIN32") endif(MSVC) if(MINGW) # For alplatf.h set(ALLEGRO_MINGW32 1) # Guess MINGDIR from the value of CMAKE_C_COMPILER if it's not set. if("$ENV{MINGDIR}" STREQUAL "") string(REGEX REPLACE "/bin/[^/]*$" "" MINGDIR "${CMAKE_C_COMPILER}") message(STATUS "Guessed MinGW directory: ${MINGDIR}") else("$ENV{MINGDIR}" STREQUAL "") file(TO_CMAKE_PATH "$ENV{MINGDIR}" MINGDIR) message(STATUS "Using MINGDIR: ${MINGDIR}") endif("$ENV{MINGDIR}" STREQUAL "") # Search in MINGDIR for headers and libraries. set(CMAKE_PREFIX_PATH "${MINGDIR}") # Install to MINGDIR if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${MINGDIR} CACHE PATH "Install path prefix, prepended onto install directories." FORCE) endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) # Check for a common problem (at the time of writing). check_c_source_compiles(" #include int main(void) { int x = DM_POSITION; return 0; }" HAVE_DM_POSITION) if(NOT HAVE_DM_POSITION) message(FATAL_ERROR "Missing DM_POSITION. Please update your MinGW " "w32api package, delete CMakeCache.txt and try again.") endif(NOT HAVE_DM_POSITION) endif(MINGW) if(UNIX AND NOT APPLE) set(ALLEGRO_UNIX 1) endif(UNIX AND NOT APPLE) if(APPLE AND NOT IPHONE) set(MACOSX 1) endif(APPLE AND NOT IPHONE) if(MACOSX) set(ALLEGRO_MACOSX 1) set(ALLEGRO_CFG_PTHREADS_TLS 1) set(ALLEGRO_UNIX 0) set(WANT_X11 off) # This flag is required on some versions of Mac OS X to avoid linker # problems with global variables which are not explicitly initialised. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-common") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common") endif(MACOSX) if(IPHONE) set(ALLEGRO_CFG_PTHREADS_TLS 1) set(ALLEGRO_IPHONE 1) set(ALLEGRO_UNIX 0) set(WANT_X11 off) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics -framework QuartzCore -framework UIKit -framework Foundation -framework CoreFoundation") endif(IPHONE) if(BORLAND) set(ALLEGRO_BCC32 1) endif(BORLAND) # Tell the compiler it can use SSE instructions on x86 architectures. # If compatibility with Pentium 2's and below is required then the user # should switch WANT_ALLOW_SSE off. # Workaround for a possible bug in CMake. Even if we set this variable in # the toolchain file when cross-compiling, as we should, it is empty. if(NOT CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_NAME STREQUAL Windows) set(CMAKE_SYSTEM_PROCESSOR i686) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86") set(ARCH_X86 1) endif() # CMake reports "x86" on my Windows Vista machine if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86") set(ARCH_X86 1) endif() if(ARCH_X86 AND WANT_ALLOW_SSE) if(COMPILER_GCC) message(STATUS "Allowing GCC to use SSE instructions") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse") endif(COMPILER_GCC) # Flags for other compilers should be added here. if(COMPILER_MSVC) message(STATUS "Allowing MSVC to use SSE instructions") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:SSE") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE") endif(COMPILER_MSVC) endif() if(GP2XWIZ) set(ALLEGRO_GP2XWIZ 1) set(CMAKE_C_COMPILER "arm-openwiz-linux-gnu-gcc") set(CMAKE_CXX_COMPILER "arm-openwiz-linux-gnu-g++") set(CMAKE_SIZEOF_UNSIGNED_SHORT "2") set(WANT_X11 off) set(ALLEGRO_CFG_PTHREADS_TLS 1) set(SUPPORT_OPENGL 1) set(ALLEGRO_CFG_OPENGL 1) include_directories(SYSTEM ${CMAKE_FIND_ROOT_PATH}/include) link_directories(${CMAKE_FIND_ROOT_PATH}/lib) set(CMAKE_C_FLAGS_RELEASE "-mcpu=arm926ej-s -mtune=arm926ej-s -O3") set(CMAKE_CXX_FLAGS_RELEASE "-mcpu=arm926ej-s -mtune=arm926ej-s -O3") set(WANT_DEMO off) endif(GP2XWIZ) #-----------------------------------------------------------------------------# # # Build types # #-----------------------------------------------------------------------------# # Warnings. if(STRICT_WARN) if(COMPILER_GCC) set(WFLAGS "-W -Wall -Werror -Wpointer-arith") set(WFLAGS_C_ONLY "-Wmissing-declarations -Wstrict-prototypes") if(ALLEGRO_UNIX) # Unfortunately we can't use this flag when magic main is used, # the mangled_main won't have a forward declaration. set(WFLAGS_C_ONLY "${WFLAGS_C_ONLY} -Wmissing-prototypes") endif(ALLEGRO_UNIX) endif(COMPILER_GCC) if(COMPILER_MSVC) set(WFLAGS "/W4 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE") endif(COMPILER_MSVC) else(STRICT_WARN) if(COMPILER_GCC) set(WFLAGS "-W -Wall") endif(COMPILER_GCC) if(COMPILER_MSVC) set(WFLAGS "/W3 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE") endif(COMPILER_MSVC) endif(STRICT_WARN) if(WIN32 AND COMPILER_GCC) # Helps to ensure the Windows port remains compatible with MSVC. set(WFLAGS_C_ONLY "${WFLAGS_C_ONLY} -Wdeclaration-after-statement") endif(WIN32 AND COMPILER_GCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WFLAGS} ${WFLAGS_C_ONLY}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WFLAGS}") if(WANT_MUDFLAP AND COMPILER_GCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmudflapth") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmudflapth") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fmudflapth -lmudflapth") endif(WANT_MUDFLAP AND COMPILER_GCC) # Debugging. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUGMODE=1 -DD3D_DEBUG_INFO") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUGMODE=1 -DD3D_DEBUG_INFO") # Profiling. list(APPEND CMAKE_BUILD_CONFIGURATIONS Profile) if(COMPILER_GCC) set(CMAKE_C_FLAGS_PROFILE "-pg" CACHE STRING "profiling flags") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE}" CACHE STRING "profiling flags") set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-pg" CACHE STRING "profiling flags") mark_as_advanced( CMAKE_C_FLAGS_PROFILE CMAKE_CXX_FLAGS_PROFILE CMAKE_EXE_LINKER_FLAGS_PROFILE ) endif(COMPILER_GCC) #-----------------------------------------------------------------------------# # # Begin tests # #-----------------------------------------------------------------------------# include(CheckFunctionExists) include(CheckIncludeFiles) include(CheckLibraryExists) include(CheckSymbolExists) include(CheckTypeSize) include(FindPkgConfig) include(TestBigEndian) if(NOT IPHONE) test_big_endian(ALLEGRO_BIG_ENDIAN) endif(NOT IPHONE) if(NOT ALLEGRO_BIG_ENDIAN) set(ALLEGRO_LITTLE_ENDIAN 1) endif(NOT ALLEGRO_BIG_ENDIAN) check_include_files(dirent.h ALLEGRO_HAVE_DIRENT_H) check_include_files(inttypes.h ALLEGRO_HAVE_INTTYPES_H) # On some systems including linux/joystick.h without sys/types.h results # in conflicting definitions of fd_set. check_include_files("sys/types.h;linux/joystick.h" ALLEGRO_HAVE_LINUX_JOYSTICK_H) check_include_files(stdbool.h ALLEGRO_HAVE_STDBOOL_H) check_include_files(stdint.h ALLEGRO_HAVE_STDINT_H) check_include_files(sys/io.h ALLEGRO_HAVE_SYS_IO_H) check_include_files(sys/stat.h ALLEGRO_HAVE_SYS_STAT_H) check_include_files(sys/time.h ALLEGRO_HAVE_SYS_TIME_H) check_include_files(time.h ALLEGRO_HAVE_TIME_H) check_include_files(sys/utsname.h ALLEGRO_HAVE_SYS_UTSNAME_H) check_include_files(sys/types.h ALLEGRO_HAVE_SYS_TYPES_H) check_include_files(soundcard.h ALLEGRO_HAVE_SOUNDCARD_H) check_include_files(sys/soundcard.h ALLEGRO_HAVE_SYS_SOUNDCARD_H) check_include_files(machine/soundcard.h ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) check_include_files(linux/soundcard.h ALLEGRO_HAVE_LINUX_SOUNDCARD_H) check_include_files(libkern/OSAtomic.h ALLEGRO_HAVE_OSATOMIC_H) check_include_files(sys/inotify.h ALLEGRO_HAVE_SYS_INOTIFY_H) check_include_files(sys/timerfd.h ALLEGRO_HAVE_SYS_TIMERFD_H) check_function_exists(getexecname ALLEGRO_HAVE_GETEXECNAME) check_function_exists(mkstemp ALLEGRO_HAVE_MKSTEMP) check_function_exists(mmap ALLEGRO_HAVE_MMAP) check_function_exists(mprotect ALLEGRO_HAVE_MPROTECT) check_function_exists(sched_yield ALLEGRO_HAVE_SCHED_YIELD) check_function_exists(sysconf ALLEGRO_HAVE_SYSCONF) # These functions exist on Wiz but don't work if(NOT GP2XWIZ) check_function_exists(fseeko ALLEGRO_HAVE_FSEEKO) check_function_exists(ftello ALLEGRO_HAVE_FTELLO) endif(NOT GP2XWIZ) check_type_size("_Bool" ALLEGRO_HAVE__BOOL) check_c_source_compiles(" #include int main(void) { struct prpsinfo psinfo; psinfo.pr_argc = 0; return 0; }" ALLEGRO_HAVE_PROCFS_ARGCV ) check_c_source_compiles(" #include #include int main(void) { struct prpsinfo psinfo; ioctl(0, PIOCPSINFO, &psinfo); return 0; }" ALLEGRO_HAVE_SV_PROCFS_H ) check_c_source_compiles(" #include int main(void) { va_list a, b; va_copy(a, b); return 0; }" ALLEGRO_HAVE_VA_COPY ) #-----------------------------------------------------------------------------# # # Driver configuration # #-----------------------------------------------------------------------------# # # These are the conventions for this CMakeFile. # # The WANT_* variables indicate whether the user wants to have an optional # feature enabled, i.e. whether they have selected something in the CMake UI. # # The CAN_* variables indicate whether a feature *can* be enabled on this # system/platform. As these variable values are cached, CAN_ variables could # be set even though the user has turned a corresponding WANT_* variable # off---it might have been tested and set in a previous run. # # The SUPPORT_* variables are the conjunction of WANT_FEATURE and CAN_FEATURE, # i.e. the user wants it and the system can support it. # # Those variables are internal to the CMake build. Allegro header files use # preprocessor constants with names like ALLEGRO_WITH_* and ALLEGRO_HAVE_*. # Sometimes we make use of those variables in this CMakeFile as well, but # generally that's just due to sloppiness. # if(WANT_OPENGL) find_package(OpenGL) # on cmake 2.8.1 OpenGL ES is not found in the iphone case if(IPHONE) set(OPENGL_LIBRARIES "-framework OpenGLES") set(OPENGL_gl_LIBRARY "-framework OpenGLES") set(OPENGL_glu_LIBRARY "") endif(IPHONE) if(OPENGL_FOUND) set(SUPPORT_OPENGL 1) set(ALLEGRO_CFG_OPENGL 1) endif(OPENGL_FOUND) endif(WANT_OPENGL) # # Unix-specific # if(UNIX) # includes MACOSX if(NOT GP2XWIZ AND NOT IPHONE) find_package(Threads) if(NOT CMAKE_USE_PTHREADS_INIT) message(FATAL_ERROR "Unix port requires pthreads support, not detected.") endif(NOT CMAKE_USE_PTHREADS_INIT) endif() endif(UNIX) # # X Window System # if(WANT_X11) find_package(X11) if(X11_FOUND) set(SUPPORT_X11 1) set(ALLEGRO_WITH_XWINDOWS 1) endif(X11_FOUND) endif(WANT_X11) if(ALLEGRO_UNIX AND NOT SUPPORT_X11 AND WANT_X11) # not MACOSX message(FATAL_ERROR "X11 not found. You may need to install X11 development libraries.") endif(ALLEGRO_UNIX AND NOT SUPPORT_X11 AND WANT_X11) if(SUPPORT_X11 AND NOT SUPPORT_OPENGL) message(FATAL_ERROR "X11 support currently requires OpenGL support.") endif(SUPPORT_X11 AND NOT SUPPORT_OPENGL) if(SUPPORT_X11) set(CMAKE_REQUIRED_LIBRARIES ${X11_LIBRARIES}) check_library_exists(Xcursor XcursorImageCreate "" CAN_XCURSOR) if(CAN_XCURSOR) set(ALLEGRO_XWINDOWS_WITH_XCURSOR 1) list(APPEND X11_LIBRARIES "Xcursor") else(CAN_XCURSOR) message(FATAL_ERROR "X11 support requires Xcursor library.") endif(CAN_XCURSOR) if(WANT_X11_XF86VIDMODE) check_include_file("X11/extensions/xf86vmode.h" HAVE_XF86VIDMODE_H) check_library_exists(Xxf86vm XF86VidModeQueryExtension "" CAN_XF86VIDMODE) if(CAN_XF86VIDMODE AND HAVE_XF86VIDMODE_H) set(ALLEGRO_XWINDOWS_WITH_XF86VIDMODE 1) list(APPEND X11_LIBRARIES "Xxf86vm") endif() endif(WANT_X11_XF86VIDMODE) if(WANT_X11_XINERAMA) check_include_file("X11/extensions/Xinerama.h" HAVE_XINERAMA_H) check_library_exists(Xinerama XineramaQueryExtension "" CAN_XINERAMA) if(CAN_XINERAMA AND HAVE_XINERAMA_H) set(ALLEGRO_XWINDOWS_WITH_XINERAMA 1) list(APPEND X11_LIBRARIES "Xinerama") endif() endif(WANT_X11_XINERAMA) if(WANT_X11_XRANDR) check_include_file("X11/extensions/Xrandr.h" HAVE_XRANDR_H) check_library_exists(Xrandr XRRQueryExtension "" CAN_XRANDR) if(CAN_XRANDR AND HAVE_XRANDR_H) set(ALLEGRO_XWINDOWS_WITH_XRANDR 1) list(APPEND X11_LIBRARIES "Xrandr") endif() endif(WANT_X11_XRANDR) check_library_exists(X11 XOpenIM "" CAN_XIM) if(CAN_XIM) set(ALLEGRO_XWINDOWS_WITH_XIM 1) endif(CAN_XIM) set(CMAKE_REQUIRED_LIBRARIES) endif(SUPPORT_X11) # # Windows # if(WIN32) find_package(DInput) if(DINPUT_FOUND) # At least some copies of dinput.h redefine some types multiple times. # We must add the directory as a system directory so that the compiler # will suppress such errors. include_directories(SYSTEM ${DINPUT_INCLUDE_DIR}) else(DINPUT_FOUND) message(FATAL_ERROR "Windows port requires DirectInput (not found).") endif(DINPUT_FOUND) if(WANT_D3D) find_package(D3D9) if(D3D9_FOUND) set(SUPPORT_D3D 1) set(ALLEGRO_CFG_D3D 1) endif(D3D9_FOUND) endif(WANT_D3D) if(SUPPORT_D3D) find_package(D3DX9) if(D3DX9_FOUND) include_directories(BEFORE SYSTEM ${D3DX9_INCLUDE_DIR}) endif(D3DX9_FOUND) endif(SUPPORT_D3D) if(WANT_D3D9EX AND SUPPORT_D3D) set(ALLEGRO_CFG_D3D9EX 1) endif(WANT_D3D9EX AND SUPPORT_D3D) endif(WIN32) #-----------------------------------------------------------------------------# # # Produce configuration file # #-----------------------------------------------------------------------------# if(NO_FPU) set(ALLEGRO_CFG_NO_FPU 1) endif(NO_FPU) # All relevant variables must be set before here. configure_file( include/allegro5/platform/alplatf.h.cmake ${CMAKE_BINARY_DIR}/include/allegro5/platform/alplatf.h ) #-----------------------------------------------------------------------------# # # Main library # #-----------------------------------------------------------------------------# # On Windows, disable shared build if either D3D or OpenGL are not present, # because it would produce a incompatible DLL. if(WIN32 AND SHARED) if(NOT SUPPORT_D3D OR NOT SUPPORT_OPENGL) message( "Both D3D and OpenGL must be present for the SHARED build. " "Disabling SHARED build.") set(SHARED off) set(BUILD_SHARED_LIBS off) endif(NOT SUPPORT_D3D OR NOT SUPPORT_OPENGL) endif(WIN32 AND SHARED) # List of source files need to compile Allegro in this configuration on # this platform. set(LIBRARY_SOURCES ${ALLEGRO_SRC_FILES} ) # Libraries that we always need to link against on this platform. set(PLATFORM_LIBS) if(ALLEGRO_UNIX) # not MACOSX list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_UNIX_FILES}) list(APPEND PLATFORM_LIBS m ${CMAKE_THREAD_LIBS_INIT}) endif(ALLEGRO_UNIX) if(SUPPORT_X11) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_X_FILES}) list(APPEND PLATFORM_LIBS ${X11_LIBRARIES}) endif(SUPPORT_X11) if(WIN32) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_WIN_FILES}) list(APPEND PLATFORM_LIBS kernel32 user32 gdi32 comdlg32 ole32 winmm psapi shlwapi ) if(SUPPORT_D3D) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_D3D_FILES}) list(APPEND PLATFORM_LIBS ${D3D9_LIBRARIES}) endif(SUPPORT_D3D) list(APPEND PLATFORM_LIBS ${DINPUT_LIBRARIES}) if(MINGW AND NOT SHARED) list(APPEND PLATFORM_LIBS stdc++) endif(MINGW AND NOT SHARED) endif(WIN32) if(MACOSX) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_MACOSX_FILES}) find_library(APPKIT_LIBRARY AppKit) find_library(IOKIT_LIBRARY IOKit) list(APPEND PLATFORM_LIBS ${APPKIT_LIBRARY}) list(APPEND PLATFORM_LIBS ${IOKIT_LIBRARY}) endif(MACOSX) if(SUPPORT_OPENGL) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_OPENGL_FILES}) if(WIN32) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_WGL_FILES}) endif(WIN32) if(NOT GP2XWIZ) list(APPEND PLATFORM_LIBS ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) endif(NOT GP2XWIZ) endif(SUPPORT_OPENGL) if(GP2XWIZ) list(APPEND PLATFORM_LIBS wiz pthread-0.10 dl) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_GP2XWIZ_FILES}) endif(GP2XWIZ) if(IPHONE) list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_IPHONE_FILES}) endif(IPHONE) # Header files that we need to install. set(ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_FILES} ${ALLEGRO_INCLUDE_ALLEGRO_INLINE_FILES} ${ALLEGRO_INCLUDE_ALLEGRO_INTERNAL_FILES} ${ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES} ) if(WIN32) list(APPEND ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_WINDOWS_FILES} ) endif(WIN32) if(MACOSX) list(APPEND ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_MACOSX_FILES} ) endif(MACOSX) if(IPHONE) list(APPEND ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_IPHONE_FILES} ) endif(IPHONE) if(SUPPORT_OPENGL) list(APPEND ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_OPENGL_FILES} ${ALLEGRO_INCLUDE_ALLEGRO_OPENGL_GLEXT_FILES} ) endif(SUPPORT_OPENGL) foreach(genfile ${ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES_GENERATED}) list(APPEND ALLEGRO_PUBLIC_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${genfile} ) endforeach(genfile) set_our_header_properties(${ALLEGRO_PUBLIC_HEADERS}) # ALLEGRO_LIB_BUILD is defined for all Allegro sources (core and addon) # ALLEGRO_SRC is defined only while compiling the core sources (its use is # to get the DLL #defines right under Windows for creating DLL export functions # when it is defined or import DLL functions when it is not). add_our_library(allegro "${LIBRARY_SOURCES};${ALLEGRO_PUBLIC_HEADERS}" "${LIBRARY_CFLAGS} -DALLEGRO_SRC" "${PLATFORM_LIBS}" ) # Allegro 4 has taken "Allegro" as the name of the framework. set_our_framework_properties(allegro Allegro-${ALLEGRO_SOVERSION}) install_our_library(allegro) install_our_headers(${ALLEGRO_PUBLIC_HEADERS}) # Addons and examples should link with this target. set(ALLEGRO_LINK_WITH allegro) #-----------------------------------------------------------------------------# # # Add-ons # #-----------------------------------------------------------------------------# add_subdirectory(addons) #-----------------------------------------------------------------------------# # # Demo # #-----------------------------------------------------------------------------# if(NOT MSVC80 AND WANT_DEMO) # XXX disabled because it breaks MSVC's intellisense for some reason add_subdirectory(demos/cosmic_protector) add_subdirectory(demos/speed) endif(NOT MSVC80 AND WANT_DEMO) #-----------------------------------------------------------------------------# # # Examples # #-----------------------------------------------------------------------------# if(WANT_EXAMPLES) add_subdirectory(examples) endif(WANT_EXAMPLES) #-----------------------------------------------------------------------------# # # Tests # #-----------------------------------------------------------------------------# if(WANT_TESTS) add_subdirectory(tests) endif(WANT_TESTS) #-----------------------------------------------------------------------------# # # pkg-config files # #-----------------------------------------------------------------------------# set(prefix "${CMAKE_INSTALL_PREFIX}") set(INCLUDE_PREFIX "\${prefix}") # XXX these should be configurable separately set(bindir "\${exec_prefix}/bin") set(includedir "\${prefix}/include") set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") set(PKG_CONFIG_FILES allegro ${ADDON_PKG_CONFIG_FILES}) # Install pkg-config files on Unix, and when cross-compiling on Unix. if(UNIX AND NOT WANT_FRAMEWORKS AND NOT IPHONE) set(INSTALL_PKG_CONFIG_FILES true) endif() if(CMAKE_CROSSCOMPILING AND CMAKE_HOST_UNIX) set(INSTALL_PKG_CONFIG_FILES true) endif() if(INSTALL_PKG_CONFIG_FILES) append_lib_type_suffix(lib_type) append_lib_linkage_suffix(lib_linkage) # Our pkg-config files are now named allegro*-5.pc, which will # work across branches. Allegro 5.0.8 and prior used the names # allegro*-5.0.pc so on the 5.0 branch we will continue to install # those files, for backwards compatibility. foreach(versuffix 5 ${ALLEGRO_SOVERSION}) foreach(name ${PKG_CONFIG_FILES}) if (SHARED) set(outname ${name}${lib_type}-${versuffix}.pc) else (SHARED) # For static linking: get extra libraries to link with. get_target_property(link_with ${name} static_link_with) set(outname ${name}${lib_type}-static-${versuffix}.pc) endif (SHARED) configure_file( misc/${name}.pc.in ${LIBRARY_OUTPUT_PATH}/pkgconfig/${outname} @ONLY ) install(FILES ${LIBRARY_OUTPUT_PATH}/pkgconfig/${outname} DESTINATION "lib${LIB_SUFFIX}/pkgconfig" ) endforeach(name) endforeach(versuffix) endif(INSTALL_PKG_CONFIG_FILES) #-----------------------------------------------------------------------------# # # Documentation # #-----------------------------------------------------------------------------# if(WANT_DOCS) add_subdirectory(docs) endif(WANT_DOCS) #-----------------------------------------------------------------------------# # # Wrappers # #-----------------------------------------------------------------------------# if(WANT_PYTHON_WRAPPER) add_subdirectory(python) endif(WANT_PYTHON_WRAPPER) #-----------------------------------------------------------------------------# # vim: set sts=4 sw=4 et: allegro-5.0.10/tests/0000755000175000001440000000000012157230745013556 5ustar tjadenusersallegro-5.0.10/tests/manual_bmpsuite1.ini0000644000175000001440000000540611771527320017531 0ustar tjadenusers# Test BMP loader with images from this source: # http://entropymine.com/jason/bmpsuite/ [bitmaps] g01bg =bmpsuite/g01bg.bmp g01bw =bmpsuite/g01bw.bmp g01p1 =bmpsuite/g01p1.bmp g01wb =bmpsuite/g01wb.bmp g04 =bmpsuite/g04.bmp g04p4 =bmpsuite/g04p4.bmp g04rle =bmpsuite/g04rle.bmp g08 =bmpsuite/g08.bmp g08offs =bmpsuite/g08offs.bmp g08os2 =bmpsuite/g08os2.bmp g08p64 =bmpsuite/g08p64.bmp g08p256 =bmpsuite/g08p256.bmp g08pi64 =bmpsuite/g08pi64.bmp g08pi256 =bmpsuite/g08pi256.bmp g08res11 =bmpsuite/g08res11.bmp g08res21 =bmpsuite/g08res21.bmp g08res22 =bmpsuite/g08res22.bmp g08rle =bmpsuite/g08rle.bmp g08s0 =bmpsuite/g08s0.bmp g08w124 =bmpsuite/g08w124.bmp g08w125 =bmpsuite/g08w125.bmp g08w126 =bmpsuite/g08w126.bmp g16bf555 =bmpsuite/g16bf555.bmp g16bf565 =bmpsuite/g16bf565.bmp g16def555=bmpsuite/g16def555.bmp g24 =bmpsuite/g24.bmp g32bf =bmpsuite/g32bf.bmp g32def =bmpsuite/g32def.bmp [template] op0=al_draw_bitmap(bmp, 0, 0, 0) [test bmpsuite g01bg] extend=template bmp=g01bg hash=9846dc91 [test bmpsuite g01bw] extend=template bmp=g01bw hash=e20721a5 [test bmpsuite g01p1] extend=template bmp=g01p1 hash=87931dc5 [test bmpsuite g01wb] extend=template bmp=g01wb hash=e20721a5 [test bmpsuite g04] extend=template bmp=g04 hash=3ba8f12f [test bmpsuite g04p4] extend=template bmp=g04p4 hash=ab1a2d4d [test bmpsuite g04rle] extend=template bmp=g04rle hash=3ba8f12f [test bmpsuite g08] extend=template bmp=g08 hash=7d8eb943 [test bmpsuite g08offs] extend=template bmp=g08offs hash=7d8eb943 [test bmpsuite g08os2] extend=template bmp=g08os2 hash=7d8eb943 [test bmpsuite g08p64] extend=template bmp=g08p64 hash=7b1f9739 [test bmpsuite g08p256] extend=template bmp=g08p256 hash=7d8eb943 [test bmpsuite g08pi64] extend=template bmp=g08pi64 hash=7d8eb943 [test bmpsuite g08pi256] extend=template bmp=g08pi256 hash=7d8eb943 [test bmpsuite g08res11] extend=template bmp=g08res11 hash=7d8eb943 [test bmpsuite g08res21] extend=template bmp=g08res21 hash=7d8eb943 [test bmpsuite g08res22] extend=template bmp=g08res22 hash=7d8eb943 [test bmpsuite g08rle] extend=template bmp=g08rle hash=7d8eb943 [test bmpsuite g08s0] extend=template bmp=g08s0 hash=7d8eb943 [test bmpsuite g08w124] extend=template bmp=g08w124 hash=a18fef34 [test bmpsuite g08w125] extend=template bmp=g08w125 hash=a25db914 [test bmpsuite g08w126] extend=template bmp=g08w126 hash=dde9c6c4 [test bmpsuite g16bf555] extend=template bmp=g16bf555 hash=096251dc [test bmpsuite g16bf565] extend=template bmp=g16bf565 hash=09f60795 [test bmpsuite g16def555] extend=template bmp=g16def555 hash=096251dc [test bmpsuite g24] extend=template bmp=g24 hash=f5bdf572 [test bmpsuite g32bf] extend=template bmp=g32bf hash=f5bdf572 [test bmpsuite g32def] extend=template bmp=g32def hash=f5bdf572 allegro-5.0.10/tests/test_locking.ini0000644000175000001440000000673311476663537016771 0ustar tjadenusers# Too many parameters to test... # target: memory, backbuffer, off-screen texture # mode: WRITEONLY, READWRITE, READONLY # all the pixel formats (24b especially problematic) # odd sizes especially problematic # lock region or entire bitmap # Locking an off-screen bitmap [texture] op0= al_clear_to_color(#554321) op1= op2= bmp = al_create_bitmap(640, 480) op3= al_set_target_bitmap(bmp) op4= al_clear_to_color(#00000000) op5= al_lock_bitmap_region(bmp, 133, 65, 381, 327, format, flags) op6= fill_lock_region(alphafactor, false) op7= al_unlock_bitmap(bmp) op8= op9= al_set_target_bitmap(target) op10=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op11=al_draw_bitmap(bmp, 0, 0, 0) flags=ALLEGRO_LOCK_WRITEONLY alphafactor=1.0 [test texture 32b ARGB_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_ARGB_8888 hash=25e01c26 sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF [test texture 32b RGBA_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGBA_8888 hash=25e01c26 sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF [test texture 16b ARGB_4444] extend=texture format=ALLEGRO_PIXEL_FORMAT_ARGB_4444 hash=94ba90ac sig=FFFFFFFFFFFDDDEIKFFFEEFIMOFFFEEHKQSFFFFGKOWXFFFFHMRabFFFGIOVffFFFGJQXkjFFFFFFFFFF [test texture 24b RGB_888] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGB_888 hash=5a844e39 sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF [test texture 16b RGB_565] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGB_565 hash=7ee470cd [test texture 15b RGB_555] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGB_555 hash=d8bcc9c6 [test texture 16b RGBA_5551] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGBA_5551 alphafactor=2.0 hash=752a4074 [test texture 16b ARGB_1555] extend=texture format=ALLEGRO_PIXEL_FORMAT_ARGB_1555 alphafactor=2.0 hash=752a4074 [test texture 32b ABGR_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_ABGR_8888 hash=25e01c26 sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF [test texture 32b XBGR_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_XBGR_8888 hash=5a844e39 sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF [test texture 24b BGR_888] extend=texture format=ALLEGRO_PIXEL_FORMAT_BGR_888 hash=5a844e39 sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF [test texture 16b BGR_565] extend=texture format=ALLEGRO_PIXEL_FORMAT_BGR_565 hash=7ee470cd [test texture 15b BGR_555] extend=texture format=ALLEGRO_PIXEL_FORMAT_BGR_555 hash=d8bcc9c6 [test texture 32b RGBX_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGBX_8888 hash=5a844e39 sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF [test texture 32b XRGB_8888] extend=texture format=ALLEGRO_PIXEL_FORMAT_XRGB_8888 hash=5a844e39 sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF [test texture f32 ABGR_F32] extend=texture format=ALLEGRO_PIXEL_FORMAT_ABGR_F32 hash=25e01c26 sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF [test texture 32b ABGR_8888_LE] extend=texture format=ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE hash=25e01c26 sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF [test texture 16b RGBA_4444] extend=texture format=ALLEGRO_PIXEL_FORMAT_RGBA_4444 hash=94ba90ac sig=FFFFFFFFFFFDDDEIKFFFEEFIMOFFFEEHKQSFFFFGKOWXFFFFHMRabFFFGIOVffFFFGJQXkjFFFFFFFFFF allegro-5.0.10/tests/CMakeLists.txt0000644000175000001440000000455312114120561016310 0ustar tjadenusersif(NOT ALLEGRO_LINK_WITH OR NOT ALLEGRO_MAIN_LINK_WITH OR NOT IMAGE_LINK_WITH OR NOT COLOR_LINK_WITH OR NOT FONT_LINK_WITH OR NOT TTF_LINK_WITH OR NOT PRIMITIVES_LINK_WITH) message(STATUS "Not building tests due to missing library. " "Have: ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} " "${IMAGE_LINK_WITH} ${COLOR_LINK_WITH} " "${FONT_LINK_WITH} ${TTF_LINK_WITH} " "${PRIMITIVES_LINK_WITH}") return() endif() include_directories( ../addons/acodec ../addons/audio ../addons/color ../addons/font ../addons/image ../addons/main ../addons/memfile ../addons/native_dialog ../addons/physfs ../addons/primitives ../addons/ttf ) if(MSVC) set(EXECUTABLE_TYPE) endif(MSVC) add_our_executable( test_driver ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} ${IMAGE_LINK_WITH} ${COLOR_LINK_WITH} ${FONT_LINK_WITH} ${TTF_LINK_WITH} ${PRIMITIVES_LINK_WITH} ) set(test_files ${CMAKE_CURRENT_SOURCE_DIR}/test_bitmaps.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_bitmaps2.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_blend.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_locking.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_locking2.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_backbuffer.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_image.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_fonts.ini ${CMAKE_CURRENT_SOURCE_DIR}/test_prim.ini ) add_custom_target(run_tests DEPENDS test_driver copy_example_data COMMAND test_driver ${test_files} ) add_custom_target(run_tests_gl DEPENDS test_driver copy_example_data COMMAND test_driver --force-opengl ${test_files} ) add_custom_target(run_tests_gl12 DEPENDS test_driver copy_example_data COMMAND test_driver --force-opengl-1.2 ${test_files} ) add_custom_target(run_tests_gl20 DEPENDS test_driver copy_example_data COMMAND test_driver --force-opengl-2.0 ${test_files} ) add_custom_target(run_tests_d3d DEPENDS test_driver copy_example_data COMMAND test_driver --force-d3d ${test_files} ) add_custom_target(run_tests_wine DEPENDS test_driver copy_example_data COMMAND wine test_driver ${test_files} ) add_custom_target(run_tests_wine_gl DEPENDS test_driver copy_example_data COMMAND wine test_driver --force-opengl ${test_files} ) # vim: set sts=4 sw=4 et: allegro-5.0.10/tests/test_image.ini0000644000175000001440000000332612054130035016367 0ustar tjadenusers[bitmaps] allegro=../examples/data/allegro.pcx # We can't assume that a backbuffer with alpha is available, so draw # to a temporary bitmap. [template] op0=temp = al_create_bitmap(640, 480) op1=al_set_target_bitmap(temp) op2=al_clear_to_color(brown) op3=b = al_load_bitmap(filename) op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) op5=al_draw_bitmap(b, 0, 0, 0) op6=al_set_target_bitmap(target) op7=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) op8=al_draw_bitmap(temp, 0, 0, 0) flags=ALLEGRO_NO_PREMULTIPLIED_ALPHA [test bmp] extend=template filename=../examples/data/fakeamp.bmp hash=62176b87 [test jpg] extend=template filename=../examples/data/obp.jpg hash=8e37f5f3 sig=lXWWYJaWKicWTKIXYKdecgPKaYKaeHLRLbYKhJSEFHbZKhJIHFJdYKn1IEFabVKPSQNPNNNKKKKKKKKKK [test pcx] extend=template filename=../examples/data/allegro.pcx hash=c44929e5 [test png] extend=template filename=../examples/data/mysha256x256.png hash=771a3491 [test tga] extend=template filename=../examples/data/fixed_font.tga hash=64fa3221 [test png interlaced] extend=template filename=../examples/data/icon.png hash=9e6b5342 [save template] op0=al_save_bitmap(filename, allegro) op1=b = al_load_bitmap(filename) op2=al_clear_to_color(brown) op3=al_draw_bitmap(b, 0, 0, 0) [test save bmp] extend=save template filename=tmp.bmp hash=c44929e5 [test save jpg] extend=save template filename=tmp.jpg sig=jdelWKKKKaYmeXKKKKLNVNKKKKKHHHLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK [test save pcx] extend=save template filename=tmp.pcx hash=c44929e5 [test save png] extend=save template filename=tmp.png hash=c44929e5 [test save tga] extend=save template filename=tmp.tga hash=c44929e5 allegro-5.0.10/tests/test_bitmaps2.ini0000644000175000001440000000506311721432147017037 0ustar tjadenusers# Test al_draw_tinted_bitmap et al. [bitmaps] mysha=../examples/data/mysha.pcx allegro=../examples/data/allegro.pcx [test tint blit] op0=al_clear_to_color(red) op1=al_draw_tinted_bitmap(mysha, #ccaa44, 37, 47, flags) flags=0 hash=706d8440 sig=BBBBALLLL8LS77LLLL9UID7LLLL9MB37LLLL11211LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test tint region] op0=al_clear_to_color(red) op1=al_draw_tinted_bitmap_region(mysha, #ccaa44, 111, 51, 77, 99, 37, 47, flags) flags=0 hash=1faa6d4d sig=SLLLLLLLLBLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test tint scale min] op0=al_clear_to_color(red) op1=al_draw_tinted_scaled_bitmap(mysha, #ccaa44, 0, 0, 320, 200, 11, 17, 77, 99, flags) flags=0 hash=742e9335 sig=8LLLLLLLL1LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test tint scale max] op0=al_clear_to_color(blue) op1=al_draw_tinted_scaled_bitmap(mysha, #ccaa44, 0, 0, 320, 200, 11, 17, 611, 415, flags) flags=0 hash=c09b38b8 sig=777777776789D977778BQVNL7779XWUHL8779WLOEEB779SOGBC87728KDBD57711122A111CCCCCCCCC [test tint rotate] op0=al_clear_to_color(purple) op1=al_draw_tinted_rotated_bitmap(allegro, #88aa44, 50, 50, 320, 240, theta, flags) op2=al_draw_pixel(320, 240, cyan) theta=-1.0 hash=da5afb88 sig=LLLLLJNALLLLLLHLBBLLLLGNHDLLLLLEKL8LLLLKGDALLLLLLHABLLLLLLLCLLLLLLLLLLLLLLLLLLLLL [test tint scaled rotate] op0=al_clear_to_color(firebrick) op1=al_draw_tinted_scaled_rotated_bitmap(allegro, #88aa44, 50, 50, 320, 240, xscale, yscale, theta, flags) op2=al_draw_pixel(320, 240, cyan) xscale=0.25 yscale=0.25 theta=0.7854 flags=0 hash=3f12b882 sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK8KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK [test tint transform compose] op0=al_translate_transform(Tt, 200, 50) op1=al_use_transform(Tt) op2=al_draw_tinted_bitmap(allegro, #aa0000, 0, 0, 0) op3=al_rotate_transform(Tr, 0.5) op4=al_use_transform(Tr) op5=al_draw_tinted_bitmap(mysha, #00aa00, 0, 0, 0) op6=al_scale_transform(T, 1.5, 0.7) op7=al_compose_transform(T, Tr) op8=al_compose_transform(T, Tt) op9=al_use_transform(T) op10=al_draw_tinted_bitmap(allegro, #0000aa, 0, 0, 0) hash=68ba872b sig=200112220C2A9DCCB0B642AAEB044433A53002234006000000300A000000557000000000000000000 [test al_draw_tinted_scaled_rotated_bitmap_region] op0=al_draw_tinted_scaled_rotated_bitmap_region(mysha, 80, 50, 160, 100, #8080ff, 0, 0, 320, 240, 1.41, 1.41, -0.78, 0) op1=al_draw_tinted_scaled_rotated_bitmap_region(mysha, 80, 50, 160, 100, #8080ff, 60, 0, 320, 240, 1.41, 1.41, 0.78, 0) hash=7669c5a4 sig=000000000000000000000000PF0000R0YIE0000dPcMD000ROMYD00000EH90000000A0000000090000 allegro-5.0.10/tests/manual_bmpsuite3.ini0000644000175000001440000000143411771527320017530 0ustar tjadenusers# Test BMP loader with images from this source: # http://wvnvms.wvnet.edu/vmswww/bmp.html [bitmaps] test32bfv4 = wvnet/test32bfv4.bmp test32v5 = wvnet/test32v5.bmp # test4os2v2= wvnet/test4os2v2.bmp # OS/2 v2 headers not supported trans = wvnet/trans.bmp [template] op0=buf = al_create_bitmap(640, 480) op1=al_set_target_bitmap(buf) op2=al_clear_to_color(#ff00ff) op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op4=al_draw_bitmap(bmp, 0, 0, 0) op5=al_set_target_bitmap(target) op6=al_draw_bitmap(buf, 0, 0, 0) [test bmpsuite test32bfv4] extend=template bmp=test32bfv4 # This image really *is* fully transparent. hash=6a451dc5 [test bmpsuite test32v5] extend=template bmp=test32v5 hash=f5c38217 [test bmpsuite trans] extend=template bmp=trans hash=da824687 allegro-5.0.10/tests/manual_bmpsuite2.ini0000644000175000001440000002604711771527320017536 0ustar tjadenusers# Test BMP loader with images from this source: # http://bmptestsuite.sourceforge.net/ [bitmaps] 1bpp-1x1 =bmptestsuite-0.9/valid/1bpp-1x1.bmp 1bpp-320x240 =bmptestsuite-0.9/valid/1bpp-320x240.bmp 1bpp-320x240-color =bmptestsuite-0.9/valid/1bpp-320x240-color.bmp 1bpp-320x240-overlappingcolor =bmptestsuite-0.9/valid/1bpp-320x240-overlappingcolor.bmp 1bpp-321x240 =bmptestsuite-0.9/valid/1bpp-321x240.bmp 1bpp-322x240 =bmptestsuite-0.9/valid/1bpp-322x240.bmp 1bpp-323x240 =bmptestsuite-0.9/valid/1bpp-323x240.bmp 1bpp-324x240 =bmptestsuite-0.9/valid/1bpp-324x240.bmp 1bpp-325x240 =bmptestsuite-0.9/valid/1bpp-325x240.bmp 1bpp-326x240 =bmptestsuite-0.9/valid/1bpp-326x240.bmp 1bpp-327x240 =bmptestsuite-0.9/valid/1bpp-327x240.bmp 1bpp-328x240 =bmptestsuite-0.9/valid/1bpp-328x240.bmp 1bpp-329x240 =bmptestsuite-0.9/valid/1bpp-329x240.bmp 1bpp-330x240 =bmptestsuite-0.9/valid/1bpp-330x240.bmp 1bpp-331x240 =bmptestsuite-0.9/valid/1bpp-331x240.bmp 1bpp-332x240 =bmptestsuite-0.9/valid/1bpp-332x240.bmp 1bpp-333x240 =bmptestsuite-0.9/valid/1bpp-333x240.bmp 1bpp-334x240 =bmptestsuite-0.9/valid/1bpp-334x240.bmp 1bpp-335x240 =bmptestsuite-0.9/valid/1bpp-335x240.bmp 1bpp-topdown-320x240 =bmptestsuite-0.9/valid/1bpp-topdown-320x240.bmp 4bpp-1x1 =bmptestsuite-0.9/valid/4bpp-1x1.bmp 4bpp-320x240 =bmptestsuite-0.9/valid/4bpp-320x240.bmp 4bpp-321x240 =bmptestsuite-0.9/valid/4bpp-321x240.bmp 4bpp-322x240 =bmptestsuite-0.9/valid/4bpp-322x240.bmp 4bpp-323x240 =bmptestsuite-0.9/valid/4bpp-323x240.bmp 4bpp-324x240 =bmptestsuite-0.9/valid/4bpp-324x240.bmp 4bpp-325x240 =bmptestsuite-0.9/valid/4bpp-325x240.bmp 4bpp-326x240 =bmptestsuite-0.9/valid/4bpp-326x240.bmp 4bpp-327x240 =bmptestsuite-0.9/valid/4bpp-327x240.bmp 4bpp-topdown-320x240 =bmptestsuite-0.9/valid/4bpp-topdown-320x240.bmp 8bpp-1x1 =bmptestsuite-0.9/valid/8bpp-1x1.bmp # 8bpp-1x64000 =bmptestsuite-0.9/valid/8bpp-1x64000.bmp # due to hardware limitation 8bpp-320x240 =bmptestsuite-0.9/valid/8bpp-320x240.bmp 8bpp-321x240 =bmptestsuite-0.9/valid/8bpp-321x240.bmp 8bpp-322x240 =bmptestsuite-0.9/valid/8bpp-322x240.bmp 8bpp-323x240 =bmptestsuite-0.9/valid/8bpp-323x240.bmp 8bpp-colorsimportant-two =bmptestsuite-0.9/valid/8bpp-colorsimportant-two.bmp 8bpp-colorsused-zero =bmptestsuite-0.9/valid/8bpp-colorsused-zero.bmp 8bpp-topdown-320x240 =bmptestsuite-0.9/valid/8bpp-topdown-320x240.bmp 24bpp-1x1 =bmptestsuite-0.9/valid/24bpp-1x1.bmp 24bpp-320x240 =bmptestsuite-0.9/valid/24bpp-320x240.bmp 24bpp-321x240 =bmptestsuite-0.9/valid/24bpp-321x240.bmp 24bpp-322x240 =bmptestsuite-0.9/valid/24bpp-322x240.bmp 24bpp-323x240 =bmptestsuite-0.9/valid/24bpp-323x240.bmp 24bpp-imagesize-zero =bmptestsuite-0.9/valid/24bpp-imagesize-zero.bmp 24bpp-topdown-320x240 =bmptestsuite-0.9/valid/24bpp-topdown-320x240.bmp 32bpp-1x1 =bmptestsuite-0.9/valid/32bpp-1x1.bmp 32bpp-320x240 =bmptestsuite-0.9/valid/32bpp-320x240.bmp 32bpp-888-optimalpalette-320x240=bmptestsuite-0.9/valid/32bpp-888-optimalpalette-320x240.bmp # 32bpp-101110-320x240 =bmptestsuite-0.9/valid/32bpp-101110-320x240.bmp # due to unsupported RGB bit masks 32bpp-optimalpalette-320x240 =bmptestsuite-0.9/valid/32bpp-optimalpalette-320x240.bmp 32bpp-topdown-320x240 =bmptestsuite-0.9/valid/32bpp-topdown-320x240.bmp 555-1x1 =bmptestsuite-0.9/valid/555-1x1.bmp 555-320x240 =bmptestsuite-0.9/valid/555-320x240.bmp 555-321x240 =bmptestsuite-0.9/valid/555-321x240.bmp 565-1x1 =bmptestsuite-0.9/valid/565-1x1.bmp 565-320x240 =bmptestsuite-0.9/valid/565-320x240.bmp 565-320x240-topdown =bmptestsuite-0.9/valid/565-320x240-topdown.bmp 565-321x240 =bmptestsuite-0.9/valid/565-321x240.bmp 565-321x240-topdown =bmptestsuite-0.9/valid/565-321x240-topdown.bmp 565-322x240 =bmptestsuite-0.9/valid/565-322x240.bmp 565-322x240-topdown =bmptestsuite-0.9/valid/565-322x240-topdown.bmp rle4-absolute-320x240 =bmptestsuite-0.9/valid/rle4-absolute-320x240.bmp rle4-alternate-320x240 =bmptestsuite-0.9/valid/rle4-alternate-320x240.bmp rle4-delta-320x240 =bmptestsuite-0.9/valid/rle4-delta-320x240.bmp rle4-encoded-320x240 =bmptestsuite-0.9/valid/rle4-encoded-320x240.bmp # rle8-64000x1 =bmptestsuite-0.9/valid/rle8-64000x1.bmp # due to hardware limitation rle8-absolute-320x240 =bmptestsuite-0.9/valid/rle8-absolute-320x240.bmp rle8-blank-160x120 =bmptestsuite-0.9/valid/rle8-blank-160x120.bmp rle8-delta-320x240 =bmptestsuite-0.9/valid/rle8-delta-320x240.bmp rle8-encoded-320x240 =bmptestsuite-0.9/valid/rle8-encoded-320x240.bmp [template] op0=buf = al_create_bitmap(640, 480) op1=al_set_target_bitmap(buf) op2=al_clear_to_color(#ff00ff) op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op4=al_draw_bitmap(bmp, 0, 0, 0) op5=al_set_target_bitmap(target) op6=al_draw_bitmap(buf, 0, 0, 0) [test bmpsuite 1bpp-1x1] extend=template bmp=1bpp-1x1 hash=c6c3a3fd [test bmpsuite 1bpp-320x240] extend=template bmp=1bpp-320x240 hash=6050ef7d [test bmpsuite 1bpp-320x240-color] extend=template bmp=1bpp-320x240-color hash=9a3e4ae9 [test bmpsuite 1bpp-320x240-overlappingcolor] extend=template bmp=1bpp-320x240-overlappingcolor hash=9ebc16c5 [test bmpsuite 1bpp-323x240] extend=template bmp=1bpp-323x240 hash=a9d171bd [test bmpsuite 1bpp-324x240] extend=template bmp=1bpp-324x240 hash=c83ad13d [test bmpsuite 1bpp-325x240] extend=template bmp=1bpp-325x240 hash=d20c6b6d [test bmpsuite 1bpp-326x240] extend=template bmp=1bpp-326x240 hash=9cfd0a6d [test bmpsuite 1bpp-327x240] extend=template bmp=1bpp-327x240 hash=2c50ba1d [test bmpsuite 1bpp-328x240] extend=template bmp=1bpp-328x240 hash=c8ba84ed [test bmpsuite 1bpp-329x240] extend=template bmp=1bpp-329x240 hash=5763db1d [test bmpsuite 1bpp-330x240] extend=template bmp=1bpp-330x240 hash=6ab7842d [test bmpsuite 1bpp-331x240] extend=template bmp=1bpp-331x240 hash=adbad50d [test bmpsuite 1bpp-332x240] extend=template bmp=1bpp-332x240 hash=c6ae5b5d [test bmpsuite 1bpp-333x240] extend=template bmp=1bpp-333x240 hash=cd269f7d [test bmpsuite 1bpp-334x240] extend=template bmp=1bpp-334x240 hash=76d2f81d [test bmpsuite 1bpp-335x240] extend=template bmp=1bpp-335x240 hash=74e8607d [test bmpsuite 1bpp-topdown-320x240] extend=template bmp=1bpp-topdown-320x240 hash=6050ef7d [test bmpsuite 4bpp-1x1] extend=template bmp=4bpp-1x1 hash=5413ad0c [test bmpsuite 4bpp-320x240] extend=template bmp=4bpp-320x240 hash=14e6fb1d [test bmpsuite 4bpp-321x240] extend=template bmp=4bpp-321x240 hash=05a7bc6d [test bmpsuite 4bpp-322x240] extend=template bmp=4bpp-322x240 hash=4d583135 [test bmpsuite 4bpp-323x240] extend=template bmp=4bpp-323x240 hash=69d41ddd [test bmpsuite 4bpp-324x240] extend=template bmp=4bpp-324x240 hash=97b402cd [test bmpsuite 4bpp-325x240] extend=template bmp=4bpp-325x240 hash=e54ba235 [test bmpsuite 4bpp-326x240] extend=template bmp=4bpp-326x240 hash=f0ca000d [test bmpsuite 4bpp-327x240] extend=template bmp=4bpp-327x240 hash=c7c5e10d [test bmpsuite 4bpp-topdown-320x240] extend=template bmp=4bpp-topdown-320x240 hash=14e6fb1d [test bmpsuite 8bpp-1x1] extend=template bmp=8bpp-1x1 hash=5413ad0c [test bmpsuite 8bpp-320x240] extend=template bmp=8bpp-320x240 hash=14e6fb1d [test bmpsuite 8bpp-321x240] extend=template bmp=8bpp-321x240 hash=05a7bc6d [test bmpsuite 8bpp-322x240] extend=template bmp=8bpp-322x240 hash=4d583135 [test bmpsuite 8bpp-323x240] extend=template bmp=8bpp-323x240 hash=69d41ddd [test bmpsuite 8bpp-colorsimportant-two] extend=template bmp=8bpp-colorsimportant-two hash=14e6fb1d [test bmpsuite 8bpp-colorsused-zero] extend=template bmp=8bpp-colorsused-zero hash=14e6fb1d [test bmpsuite 8bpp-topdown-320x240] extend=template bmp=8bpp-topdown-320x240 hash=14e6fb1d [test bmpsuite 24bpp-1x1] extend=template bmp=24bpp-1x1 hash=5413ad0c [test bmpsuite 24bpp-320x240] extend=template bmp=24bpp-320x240 hash=14e6fb1d [test bmpsuite 24bpp-321x240] extend=template bmp=24bpp-321x240 hash=05a7bc6d [test bmpsuite 24bpp-322x240] extend=template bmp=24bpp-322x240 hash=4d583135 [test bmpsuite 24bpp-323x240] extend=template bmp=24bpp-323x240 hash=69d41ddd [test bmpsuite 24bpp-imagesize-zero] extend=template bmp=24bpp-imagesize-zero hash=14e6fb1d [test bmpsuite 24bpp-topdown-320x240] extend=template bmp=24bpp-topdown-320x240 hash=14e6fb1d [test bmpsuite 32bpp-1x1] extend=template bmp=32bpp-1x1 hash=5413ad0c [test bmpsuite 32bpp-320x240] extend=template bmp=32bpp-320x240 hash=14e6fb1d [test bmpsuite 32bpp-888-optimalpalette-320x240] extend=template bmp=32bpp-888-optimalpalette-320x240 hash=14e6fb1d [test bmpsuite 32bpp-optimalpalette-320x240] extend=template bmp=32bpp-optimalpalette-320x240 hash=14e6fb1d [test bmpsuite 32bpp-topdown-320x240] extend=template bmp=32bpp-topdown-320x240 hash=14e6fb1d [test bmpsuite 555-1x1] extend=template bmp=555-1x1 hash=5413ad0c [test bmpsuite 555-320x240] extend=template bmp=555-320x240 hash=14e6fb1d [test bmpsuite 555-321x240] extend=template bmp=555-321x240 hash=05a7bc6d [test bmpsuite 565-1x1] extend=template bmp=565-1x1 hash=5413ad0c [test bmpsuite 565-320x240] extend=template bmp=565-320x240 hash=14e6fb1d [test bmpsuite 565-320x240-topdown] extend=template bmp=565-320x240-topdown hash=14e6fb1d [test bmpsuite 565-321x240] extend=template bmp=565-321x240 hash=05a7bc6d [test bmpsuite 565-321x240-topdown] extend=template bmp=565-321x240-topdown hash=05a7bc6d [test bmpsuite 565-322x240] extend=template bmp=565-322x240 hash=4d583135 [test bmpsuite 565-322x240-topdown] extend=template bmp=565-322x240-topdown hash=4d583135 [test bmpsuite rle4-absolute-320x240] extend=template bmp=rle4-absolute-320x240 hash=14e6fb1d [test bmpsuite rle4-alternate-320x240] extend=template bmp=rle4-alternate-320x240 hash=bcf6e8cd [test bmpsuite rle4-delta-320x240] extend=template bmp=rle4-delta-320x240 hash=ef879d9d [test bmpsuite rle4-encoded-320x240] extend=template bmp=rle4-encoded-320x240 hash=14e6fb1d [test bmpsuite rle8-absolute-320x240] extend=template bmp=rle8-absolute-320x240 hash=14e6fb1d [test bmpsuite rle8-blank-160x120] extend=template bmp=rle8-blank-160x120 hash=6a451dc5 [test bmpsuite rle8-delta-320x240] extend=template bmp=rle8-delta-320x240 hash=ef879d9d [test bmpsuite rle8-encoded-320x240] extend=template bmp=rle8-encoded-320x240 hash=14e6fb1d allegro-5.0.10/tests/test_blend.ini0000644000175000001440000003253312145642411016402 0ustar tjadenusers[bitmaps] allegro=../examples/data/allegro.pcx green=../examples/data/green.png bkg=../examples/data/bkg.png # We can't assume that a backbuffer with alpha is available, so draw # to a temporary bitmap. [template] op0=b = al_create_bitmap(640, 480) op1=al_set_target_bitmap(b) op2=al_draw_tinted_scaled_bitmap(allegro, #aaaaaa80, 0, 0, 320, 200, 0, 0, 640, 480, 0) op3=al_set_blender(mode, src, dst1) op4=al_draw_bitmap(green, x, 5, 0) op5=al_set_blender(mode, src, dst2) op6=al_draw_bitmap(green, x, 125, 0) op7=al_set_blender(mode, src, dst3) op8=al_draw_bitmap(green, x, 245, 0) op9=al_set_blender(mode, src, dst4) op10=al_draw_bitmap(green, x, 365, 0) op11=al_set_target_bitmap(target) op12=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) op13=al_draw_bitmap(bkg, 0, 0, 0) op14=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) op15=al_draw_bitmap(b, 0, 0, 0) x=140 [template dst=1,0,a,ia] extend=template dst1=ALLEGRO_ONE dst2=ALLEGRO_ZERO dst3=ALLEGRO_ALPHA dst4=ALLEGRO_INVERSE_ALPHA [template dst=sc,dc,isc,idc] extend=template dst1=ALLEGRO_SRC_COLOR dst2=ALLEGRO_DEST_COLOR dst3=ALLEGRO_INVERSE_SRC_COLOR dst4=ALLEGRO_INVERSE_DEST_COLOR #-----------------------------------------------------------------------------# [template mode=ADD dst=1,0,a,ia] extend=template dst=1,0,a,ia mode=ALLEGRO_ADD [test blend mode=ADD src=1 dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_ONE hash=7bc85f46 sig=GDD9PNGlHJJqJIHHHHEDL3566KLCCH78T6QCBCCBDFHCF9A76MM5bBCAZ66676BBAP7B8ALAABJ8CUBQA [test blend mode=ADD src=0 dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_ZERO hash=441baf02 sig=GDA9BAGHHJJJJIHHHHED665767LCC676766CBCCBDFHCF9A66A95ABCA866676BBA77A7A6AAB6886B5A [test blend mode=ADD src=a dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_ALPHA hash=a8d416f9 sig=GDB9NMGlHJJoJIHHHHEDJ5576KLCCH76T6PCBCCBDFHCF9A66LL5bBCAY66676BBAM7A9ALAABI89TBPA [test blend mode=ADD src=ia dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_INVERSE_ALPHA hash=16223282 sig=GDB9DCGIHJJMJIHHHHED655566LCC676666CBCCBDFHCF9A76BB5ABCA966676BBA87B7A6AAB6896B5A [test blend mode=ADD src=sc dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_SRC_COLOR hash=f926f4cd sig=GDA9KJGeHJJhJIHHHHEDF5556ELCCB76L6ICBCCBDFHCF9A66II5TBCAR66676BBAH7A7AFAABC89LBIA [test blend mode=ADD src=dc dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_DEST_COLOR hash=b2630b89 sig=GDA9HGGeHJJjJIHHHHED855568LCC776D68CBCCBDFHCF9A66IH5MBCAE66676BBA87A6A6AAB6885B6A [test blend mode=ADD src=isc dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_INVERSE_SRC_COLOR hash=1e52eaf0 sig=GDC9FEGLHJJQJIHHHHED655566LCC676766CBCCBDFHCF9A76DC5EBCAC66676BBA97B7A7AAB6896B6A [test blend mode=ADD src=idc dst=1,0,a,ia] extend=template mode=ADD dst=1,0,a,ia src=ALLEGRO_INVERSE_DEST_COLOR hash=fe52c382 sig=GDC9LKGgHJJiJIHHHHED955568LCC87686ACBCCBDFHCF9A76JI5YBCAW66676BBAD7A7ABAABB8AFBCA #-----------------------------------------------------------------------------# [template mode=ADD dst=sc,dc,isc,idc] extend=template dst=sc,dc,isc,idc mode=ALLEGRO_ADD [test blend mode=ADD src=1 dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_ONE hash=0ce01bb8 sig=GD76AA6VHJJZ66676HEDV6AG7YLCCT6Dn8ZCBCCBDFIDF9ACCPPDYBCAXCCEFABBAU98E7TAABR7Ca8YA [test blend mode=ADD src=0 dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_ZERO hash=90e041ac sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9AAC88D5BCA6CCEFABBA878878AAB777787A [test blend mode=ADD src=a dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_ALPHA hash=a2c1dee3 sig=GD66BA6VHJJY66676HEDS69F7XLCCR6An8ZCBCCBDFIDF9AACMMDXBCAUCCEFABBAS88D7SAABQ79a8YA [test blend mode=ADD src=ia dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_ALPHA hash=597e5032 sig=GD763369HJJC66676HED96A97ALCC969D88CBCCBDFIDF9ABCAAD6BCA7CCEFABBA988978AAB878787A [test blend mode=ADD src=sc dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_SRC_COLOR hash=901f4244 sig=GD66776NHJJR66676HEDN69D7RLCCM69f8RCBCCBDFIDF9AACJJDQBCAOCCEFABBAN88C7MAABK78S8QA [test blend mode=ADD src=dc dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_DEST_COLOR hash=b80bdb24 sig=GD66556OHJJS66676HEDI6AC7LLCCH69a8JCBCCBDFIDF9AACEEDBBCA8CCEFABBAE88A7DAABC77B8EA [test blend mode=ADD src=isc dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_SRC_COLOR hash=020d43da sig=GD76556CHJJF66676HEDB6AA7CLCCB69F8ACBCCBDFIDF9ABCBBD6BCA8CCEFABBAB8897AAABA79989A [test blend mode=ADD src=idc dst=sc,dc,isc,idc] extend=template mode=ADD dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_DEST_COLOR hash=2349d015 sig=GD76996QHJJS66676HEDI6AC7LLCCH6AU8MCBCCBDFIDF9ABCFEDGBCAICCEFABBAL88B7KAABJ79Q8OA #-----------------------------------------------------------------------------# [template mode=DEST_MINUS_SRC dst=1,0,a,ia] extend=template dst=1,0,a,ia mode=ALLEGRO_DEST_MINUS_SRC [test blend mode=DEST_MINUS_SRC src=1 dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_ONE hash=2e819fcc sig=GD9966G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA76A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=0 dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_ZERO hash=441baf02 sig=GDA9BAGHHJJJJIHHHHED665767LCC676766CBCCBDFHCF9A66A95ABCA866676BBA77A7A6AAB6886B5A [test blend mode=DEST_MINUS_SRC src=a dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_ALPHA hash=6fcd619c sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=ia dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_INVERSE_ALPHA hash=77192dfe sig=GD9998GGHJJHJIHHHHED665767LCC676766CBCCBDFHCF9A66985ABCA766676BBA76A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=sc dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_SRC_COLOR hash=2dc73562 sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=dc dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_DEST_COLOR hash=683a8d24 sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=isc dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_INVERSE_SRC_COLOR hash=c590b4b7 sig=GD9977GCHJJEJIHHHHED665767LCC676766CBCCBDFHCF9A668756BCA566676BBA76A7A7AAB6886B6A [test blend mode=DEST_MINUS_SRC src=idc dst=1,0,a,ia] extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia src=ALLEGRO_INVERSE_DEST_COLOR hash=c0986966 sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA76A7A7AAB6886B6A #-----------------------------------------------------------------------------# [template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc] extend=template dst=sc,dc,isc,idc mode=ALLEGRO_DEST_MINUS_SRC [test blend mode=DEST_MINUS_SRC src=1 dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_ONE hash=8b11d273 sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC65D6BCA6CCEFABBA768777AAB677686A [test blend mode=DEST_MINUS_SRC src=0 dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_ZERO hash=90e041ac sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9AAC88D5BCA6CCEFABBA878878AAB777787A [test blend mode=DEST_MINUS_SRC src=a dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_ALPHA hash=b4a2ce11 sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A [test blend mode=DEST_MINUS_SRC src=ia dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_ALPHA hash=59fcf94a sig=GD665568HJJA66676HED769778LCC767B88CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB777686A [test blend mode=DEST_MINUS_SRC src=sc dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_SRC_COLOR hash=861e7e3e sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A [test blend mode=DEST_MINUS_SRC src=dc dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_DEST_COLOR hash=d0317d02 sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A [test blend mode=DEST_MINUS_SRC src=isc dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_SRC_COLOR hash=6d493d98 sig=GD664466HJJ866676HED669777LCC667A87CBCCBDFIDF9AAC55D6BCA6CCEFABBA668776AAB677585A [test blend mode=DEST_MINUS_SRC src=idc dst=sc,dc,isc,idc] extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_DEST_COLOR hash=18079776 sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A #-----------------------------------------------------------------------------# [template mode=SRC_MINUS_DEST dst=1,0,a,ia] extend=template dst=1,0,a,ia mode=ALLEGRO_SRC_MINUS_DEST [test blend mode=SRC_MINUS_DEST src=1 dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_ONE hash=2a79c7ac sig=GD666667HJJ766676HEDL3566KLCCH78T6QCBCCBDFHCF9A665559BCAC66676BBAL5775KAABH67T7PA [test blend mode=SRC_MINUS_DEST src=0 dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_ZERO hash=82bce5d4 sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=a dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_ALPHA hash=98761b88 sig=GD666667HJJ766676HEDJ5576KLCCH76T6PCBCCBDFHCF9A666659BCAB66676BBAJ6785KAABG67S7PA [test blend mode=SRC_MINUS_DEST src=ia dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_INVERSE_ALPHA hash=5bc32bdb sig=GD666666HJJ666676HED655566LCC676666CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=sc dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_SRC_COLOR hash=bebf46ff sig=GD666667HJJ766676HEDF5556ELCCB76L6ICBCCBDFHCF9A665558BCAA66676BBAF6765EAABB66L7IA [test blend mode=SRC_MINUS_DEST src=dc dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_DEST_COLOR hash=721318ba sig=GD666666HJJ666676HED855568LCC776D68CBCCBDFHCF9A666556BCA666676BBA767656AAB666576A [test blend mode=SRC_MINUS_DEST src=isc dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_INVERSE_SRC_COLOR hash=b3cf8aac sig=GD666666HJJ666676HED655566LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=idc dst=1,0,a,ia] extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia src=ALLEGRO_INVERSE_DEST_COLOR hash=0793889c sig=GD666666HJJ666676HED955568LCC87686ACBCCBDFHCF9A666556BCA666676BBAB6775BAABA67F7CA #-----------------------------------------------------------------------------# [template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc] extend=template dst=sc,dc,isc,idc mode=ALLEGRO_SRC_MINUS_DEST [test blend mode=SRC_MINUS_DEST src=1 dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_ONE hash=a5bc2ba0 sig=GD666669HJJA66676HEDB55569LCC97696ECBCCBDFHCF9A66885IBCAM66676BBAC5755BAAB967H7DA [test blend mode=SRC_MINUS_DEST src=0 dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_ZERO hash=82bce5d4 sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=a dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_ALPHA hash=eda1ec1b sig=GD667769HJJ966676HEDA65769LCC97696ECBCCBDFHCF9A66985IBCAL66676BBAB6765BAAB966G7DA [test blend mode=SRC_MINUS_DEST src=ia dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_ALPHA hash=33a0483e sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A665555BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=sc dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_SRC_COLOR hash=fb2978c6 sig=GD666667HJJ766676HED965669LCC77696BCBCCBDFHCF9A66775FBCAG66676BBAA67659AAB866D7BA [test blend mode=SRC_MINUS_DEST src=dc dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_DEST_COLOR hash=5a1c8feb sig=GD666666HJJ666676HED665666LCC675666CBCCBDFHCF9A665555BCA566676BBA667655AAB566574A [test blend mode=SRC_MINUS_DEST src=isc dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_SRC_COLOR hash=612ad8c8 sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A665555BCA666676BBA767757AAB666676A [test blend mode=SRC_MINUS_DEST src=idc dst=sc,dc,isc,idc] extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc src=ALLEGRO_INVERSE_DEST_COLOR hash=77b28a0b sig=GD666666HJJ666676HED665666LCC676567CBCCBDFHCF9A666659BCAC66676BBA767757AAB766876A #-----------------------------------------------------------------------------# #-----------------------------------------------------------------------------# [test blend bullet] op0=image = al_create_bitmap(180, 160) op1=al_set_target_bitmap(image) op2=al_clear_to_color(#ffffff) op3=al_set_target_bitmap(target) op4=al_clear_to_color(#808080) op5=al_draw_line(10, 10, 190, 10, white, 2) op6=al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ALPHA, ALLEGRO_ONE) op7=al_draw_bitmap(image, 10, 20, 0) op8=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op9=al_draw_line(10, 190, 190, 190, white, 2) hash=610f2805 allegro-5.0.10/tests/test_bitmaps.ini0000644000175000001440000003050212002377260016746 0ustar tjadenusers[bitmaps] mysha=../examples/data/mysha.pcx allegro=../examples/data/allegro.pcx [test blit] op0=al_clear_to_color(red) op1=al_draw_bitmap(mysha, 37, 47, flags) flags=0 hash=dabe9c74 [test blit vflip] extend=test blit flags=ALLEGRO_FLIP_VERTICAL hash=ee8c112c [test blit hflip] extend=test blit flags=ALLEGRO_FLIP_HORIZONTAL hash=7e343e90 [test blit vhflip] extend=test blit flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=72d59a18 [test region] op0=al_clear_to_color(red) op1=al_draw_bitmap(mysha, 37, 47, flags) op2=al_draw_bitmap_region(mysha, 111, 51, 77, 99, 37, 47, flags) flags=0 hash=8e5335ae [test region hflip] extend=test region flags=ALLEGRO_FLIP_HORIZONTAL hash=569472fc [test region vflip] extend=test region flags=ALLEGRO_FLIP_VERTICAL hash=f479bb0d [test region vhflip] extend=test region flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL hash=cadc1987 [test scale min] op0=al_clear_to_color(red) op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 11, 17, 77, 99, flags) flags=0 hash=ae4b4301 [test scale min vflip] extend=test scale min flags=ALLEGRO_FLIP_VERTICAL hash=973bd6bd sig=DLLLLLLLLELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test scale min hflip] extend=test scale min flags=ALLEGRO_FLIP_HORIZONTAL hash=807e7ae5 [test scale min vhflip] extend=test scale min flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=5c2b54ad [test scale max] op0=al_clear_to_color(blue) op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 11, 17, 611, 415, flags) flags=0 hash=1ede4355 sig=EEEEEEDDCEFGPGEEDDFKjsebEDDGwvsVaEEDHvcgQPKDDHogTKMFEE4EaNLN9DE22254I222DDDDDDDDD [test scale max hflip] extend=test scale max flags=ALLEGRO_FLIP_HORIZONTAL hash=99b05f69 sig=CDEEEEEEECDEMFRFFECDEairgGFDEIZburwFDEMOTlrvGDECLLUeqGDD2HMNaA3222385222DDDDDDDDD [test scale max vflip] extend=test scale max flags=ALLEGRO_FLIP_VERTICAL hash=d9f0a6ea sig=22221222222VM2K222GmePLLDEEJrmeRQJEDHuuoTUHDDFlovXaEDDEFPsgVEDCEEEEEEEDCIIIIIIHHH [test scale max2] op0=al_clear_to_color(aqua) op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 320, 240, dw, dh, flags) dw=600 dh=600 flags=0 hash=edba302f sig=ggggggggggggggggggggggggggggggggggggggggXPQQQggggQEEEEggggQEEFFggggQFOtsggggQFomt [test scale max2 vflip] extend=test scale max2 flags=ALLEGRO_FLIP_VERTICAL hash=e6bc6d52 sig=ggggggggggggggggggggggggggggggggggggggggTJJJJggggJ222BggggJ22LGggggJ1baOggggVIkgP [test scale max2 negy hflip] extend=test scale max2 dh=-600 flags=ALLEGRO_FLIP_HORIZONTAL hash=e6bc6d52 sig=ggggPDEEYggggPCDEXggggPDDEDggggOCDDEggggYTTUUgggggggggggggggggggggggggggggggggggg [test scale max2 negy vhflip] extend=test scale max2 dh=-600 flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=cf1b15e6 sig=ggggQEEDMggggQDE7HggggJ1211ggggJ2222ggggWPPPPgggggggggggggggggggggggggggggggggggg [test scale max2 negx vflip] extend=test scale max2 dw=-600 flags=ALLEGRO_FLIP_VERTICAL hash=635d9cf1 sig=ggggggggggggggggggggggggggggggggggggJJJJWgggg9222PggggHK22PggggOab1PggggQgkIYgggg [test scale max2 negx negy] extend=test scale max2 dw=-600 dh=-600 sig=tmnFUggggrrIFUggggFFEEUggggEEEEUggggUUUTbgggggggggggggggggggggggggggggggggggggggg [test scale max2 negx negy hflip] extend=test scale max2 negx negy flags=ALLEGRO_FLIP_HORIZONTAL sig=ZEEDTggggXEDCTggggDEDCTggggEDDCTggggUTTTagggggggggggggggggggggggggggggggggggggggg [test scale max2 negx negy vflip] extend=test scale max2 negx negy flags=ALLEGRO_FLIP_VERTICAL sig=QgkHYggggOaZ2PggggHH22Pgggg9222PggggPPPPZgggggggggggggggggggggggggggggggggggggggg [test scale max2 negx negy vhflip] extend=test scale max2 negx negy flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL sig=MCEEUggggG7EDUgggg1121Pgggg2222PggggPPPPZgggggggggggggggggggggggggggggggggggggggg [test rotate] op0=al_clear_to_color(purple) op1=al_draw_rotated_bitmap(allegro, 50, 50, 320, 240, theta, flags) op2=al_draw_pixel(320, 240, cyan) theta=0 flags=0 hash=435c5d10 [test rotate 0.5] extend=test rotate theta=0.5 hash=f03d3240 sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLULLLLLLLLRKLLLLLLLQaaTLLLLOKSOkRLLLLGQXTLLLLLLINOL [test rotate 1.0] extend=test rotate theta=1.0 hash=78bf9ff5 sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLkLLLLLLLIRLLLLLLOLcLLLLLLLOQkLLLLLLGaXeLLLLLLSinLL [test rotate 1.0 vflip] extend=test rotate 1.0 flags=ALLEGRO_FLIP_VERTICAL hash=5b75eca4 sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLSNLLLLLLYTPHLLLLLLeVNLLLLLLL+WMLLLLLLhgNLL [test rotate -1.0] extend=test rotate theta=-1.0 hash=d86fa86f sig=LLLLLVmMLLLLLLYhNNLLLLKlUOLLLLLUdbHLLLLLTOLLLLLLLbLMLLLLLLLNLLLLLLLLLLLLLLLLLLLLL [test rotate -2.0] extend=test rotate theta=-2.0 hash=1b5ff6da sig=LLifZHLLLLLLgUJLLLLLLaYKLLLLLLKfOILLLLLLTJLLLLLLLkLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test rotate -2.0 hflip] extend=test rotate -2.0 flags=ALLEGRO_FLIP_HORIZONTAL hash=0a4986c3 sig=LLVSMGLLLLLLYSKLLLLLLabULLLLLLPTNMLLLLLLlNLLLLLLLiLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test rotate -2.0 vhflip] extend=test rotate -2.0 flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=4ddeb3e3 sig=LLJPcKLLLLLLJcZLLLLLLKWgLLLLLLIYUjLLLLLLNBLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test scaled rotate] op0=al_clear_to_color(firebrick) op1=al_draw_scaled_rotated_bitmap(allegro, 50, 50, 320, 240, xscale, yscale, theta, flags) op2=al_draw_pixel(320, 240, cyan) xscale=0.25 yscale=0.25 theta=0.7854 flags=0 hash=dc4ad82d sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKdKKKKKKKKIKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK [test scaled rotate 2] extend=test scaled rotate xscale=0.777 yscale=0.777 hash=8fc7ecf8 sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKXKKKKKKKKTKKKKKKKNehKKKKKKHSsgKKKKKKHTgKKKKKKKMKKK [test scaled rotate 2 neg] extend=test scaled rotate xscale=-0.777 yscale=-0.777 hash=96153b14 sig=KKKLKKKKKKKbTHKKKKKKhxSHKKKKKKheNKKKKKKKVKKKKKKKKXKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK [test scaled rotate 3] extend=test scaled rotate xscale=1.777 yscale=1.777 hash=1d003c91 sig=KKKKKKKKKKKKKKKKKKKKKKXKKKKKKKllQKKKKKJYQYKKKKKJRTjKKKKNNQYdnKKKOKKQUnZRKKLMYWjgf [test scaled rotate 4] extend=test scaled rotate xscale=3.0 yscale=3.0 theta=-2.5 hash=31a17741 sig=nhjTTOLOOlgdgSOJMMNnORRVNKLKOngKDEHKKKTnQYYKKKKMfnifKKKKKThiKKKKKKKWkKKKKKKKKKKKK [test scaled rotate 4 vflip] extend=test scaled rotate 4 flags=ALLEGRO_FLIP_VERTICAL hash=055000e8 sig=NSTPVQYDjMHQMTVWYnGKJKOJPXVFHOOQJKNKKGMONQMKKKKKSOPMKKKKKINNKKKKKKKONKKKKKKKKKKKK [test scaled rotate 4 hflip] extend=test scaled rotate 4 flags=ALLEGRO_FLIP_HORIZONTAL hash=59ba09c8 sig=mbfcaSMKOieel/TMNNQihgcHMONOYfi//DNKLbgclyqKKKLdhcnmKKKKKiflKKKKKKLlhKKKKKKKLKKKK [test scaled rotate 4 vhflip] extend=test scaled rotate 4 flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=e3236edd sig=NVTZGmClnNRYXVf/ClGPUTPRsDhGJQSLMNlKKKMKNLOKKKKMLNNNKKKKKLLNKKKKKKKNNKKKKKKKKKKKK [test scaled rotate 5] extend=test scaled rotate xscale=200 yscale=3.0 theta=-2 # It is known that the sw version is slightly offset from the hw version. hash=e941f051 sig=LXnQfPMOMKTkQXUGJLKRjmYGKJOKKXnUfQKNKKTkQXVJJKKRjnYCHJKKKYneaQLKKKTkQXWJKKKQimYDN [test sub src] op0=al_clear_to_color(teal) op1=b = al_create_sub_bitmap(allegro, 3, 40, 310, 70) op2=al_draw_bitmap(b, 50, 50, flags) op3=al_draw_rectangle(49.5, 49.5, 360.5, 120.5, black, 1) flags=0 hash=ec890555 [test sub src hflip] extend=test sub src flags=ALLEGRO_FLIP_HORIZONTAL hash=8862d735 sig=QNOQQLLLLDGbSVLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test sub src outside] op0=al_clear_to_color(teal) op1=al_draw_rectangle(9.5, 9.5, 380.5, 260.5, black, 1) op2=b = al_create_sub_bitmap(allegro, -50, -50, 370, 250) op3=al_draw_bitmap(b, 10, 10, flags) flags=0 hash=208f7025 [test sub src outside hflip] extend=test sub src outside flags=ALLEGRO_FLIP_HORIZONTAL hash=c72f2d45 [test sub src outside vflip] extend=test sub src outside flags=ALLEGRO_FLIP_VERTICAL hash=287e0fbd [test sub src outside vhflip] extend=test sub src outside flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=4696783d [test sub src outside scale] op0=al_clear_to_color(teal) op1=b = al_create_sub_bitmap(allegro, -50, -50, 370, 250) op2=al_draw_rectangle(9.5, 9.5, 610.5, 410.5, black, 1) op3=al_draw_scaled_bitmap(b, 0, 0, 370, 250, 10, 10, 600, 400, flags) flags=0 hash=ac298a45 sig=LLLLLLLLLLTNKKNXbkLmnkkffVhLnNOhcv/zLKZPaepcOLKNKZYYNOLMNMMOSOOLONIHHKLNLLLLLLLLL [test sub src outside scale hflip] extend=test sub src outside scale flags=ALLEGRO_FLIP_HORIZONTAL hash=898f5e8d sig=LLLLLLLLLjcRKKKRWLYYheknnjLW/P+UWYkLQ/qgPaRRLLQWZXQJKLNRQOKONQLLMIFGOKNLLLLLLLLLL [test sub src outside scale vflip] extend=test sub src outside scale flags=ALLEGRO_FLIP_VERTICAL hash=762b67d5 sig=LMPLHHMLMLQMHJSWNNLLPMZXYSNLMdMjbdLDLcbOmfgkmLjhTQReegLLLLLLLLLLLLLLLLLLLLLLLLLLL [test sub src outside scale vhflip] extend=test sub src outside scale flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL hash=7c95685d sig=LNJGGONOLNNVMMGKPLMUfdWRKJLh/hcUaYVLmkekXhYjLfeYVPYjkLLLLLLLLLLLLLLLLLLLLLLLLLLLL [test sub dest] op0=b = al_create_sub_bitmap(target, 35, 37, 103, 104) op1=al_set_target_bitmap(b) op2=al_draw_bitmap(allegro, 0, 0, 0) hash=1127286c [test sub dest pixel] op0=b = al_create_sub_bitmap(target, 35, 37, 103, 104) op1=al_set_target_bitmap(b) op2=al_draw_pixel(0.5, 0.5, red) op3=al_put_pixel(1, 0, limegreen) op4=al_draw_pixel(14.5, 17.5, red) op5=al_put_pixel(15, 17, limegreen) op6=al_draw_pixel(24.5, 27.5, red) op7=al_put_pixel(25, 27, limegreen) hash=b4d84cb9 tolerance=0.0 [test subsub dest] op0=al_clear_to_color(tan) op1=b1 = al_create_sub_bitmap(target, 70, 90, 200, 200) op2=al_set_target_bitmap(b1) op3=al_clear_to_color(seagreen) op4=b2 = al_create_sub_bitmap(b1, -50, -50, 200, 200) op5=al_set_target_bitmap(b2) op6=al_clear_to_color(royalblue) op7=al_draw_bitmap(allegro, 10, 10, 0) hash=066a6e10 [test sub transform] op0=al_clear_to_color(teal) op1=b = al_create_sub_bitmap(mysha, 160, 0, 160, 200) op2=al_translate_transform(Tt, -80, 0) op3=al_use_transform(Tt) op4=al_draw_bitmap(b, 320, 10, flags) op5=al_use_transform(Ti) op6=al_draw_line(320.5, 0, 320.5, 480, #ffffff, 1) flags=0 hash=945d520b sig=LLLZLCLLLLLLPLDLLLLLLMLDLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test sub transform hflip] extend=test sub transform flags=ALLEGRO_FLIP_HORIZONTAL hash=ee8a23a0 sig=LLLCLZLLLLLLDLPLLLLLLDLMLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test sub transform vflip] extend=test sub transform flags=ALLEGRO_FLIP_VERTICAL hash=9290db87 sig=LLL2B1LLLLLLKLDLLLLLLVLCLLLLLLEKCLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test sub transform vhflip] extend=test sub transform flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=d43a7e7c sig=LLL1A2LLLLLLDLLLLLLLLCLVLLLLLLCKELLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test region transform] op0=al_clear_to_color(teal) op1=al_translate_transform(Tt, -80, 0) op2=al_use_transform(Tt) op3=al_draw_bitmap_region(mysha, 160, 0, 160, 200, 320, 10, flags) op4=al_use_transform(Ti) op5=al_draw_line(320.5, 0, 320.5, 480, #ffffff, 1) flags=0 hash=945d520b sig=LLLZLCLLLLLLPLDLLLLLLMLDLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test region transform hflip] extend=test region transform flags=ALLEGRO_FLIP_HORIZONTAL hash=ee8a23a0 sig=LLLCLZLLLLLLDLPLLLLLLDLMLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test region transform vflip] extend=test region transform flags=ALLEGRO_FLIP_VERTICAL hash=9290db87 sig=LLL2B1LLLLLLKLDLLLLLLVLCLLLLLLEKCLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test region transform vhflip] extend=test region transform flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL hash=d43a7e7c sig=LLL1A2LLLLLLDLLLLLLLLCLVLLLLLLCKELLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL [test transform compose] op0=al_translate_transform(Tt, 200, 50) op1=al_use_transform(Tt) op2=al_draw_bitmap(allegro, 0, 0, 0) op3=al_rotate_transform(Tr, 0.5) op4=al_use_transform(Tr) op5=al_draw_bitmap(mysha, 0, 0, 0) op6=al_scale_transform(T, 1.5, 0.7) op7=al_compose_transform(T, Tr) op8=al_compose_transform(T, Tt) op9=al_use_transform(T) op10=al_draw_bitmap(allegro, 0, 0, 0) hash=e1c88814 sig=E0075AAD0wElcvfjm0pYKUlWto0LLKKZnPM02CEHKZNe002100JZPl000000MNV000000000000000000 [test transform per bitmap] op0=al_clear_to_color(gray) op1=al_build_transform(T1, 200, 50, 1, 1, -0.333) op2=al_use_transform(T1) op3=sub = al_create_sub_bitmap(target, 30, 150, 400, 300) op4=al_set_target_bitmap(sub) op5=al_clear_to_color(azure) op6=al_build_transform(Tsub, 0, 0, 1.5, 1.5, 0.5) op7=al_use_transform(Tsub) op8=al_draw_bitmap(mysha, 0, 0, 0) op9=al_set_target_bitmap(target) op10=al_draw_bitmap(allegro, 0, 0, 0) hash=341b718b sig=WWWVngLbWWWWBUUaNWWWWJNKLLWE++POGWWWFEP+++WWWmtEE++WWWqvlFD+WWWjaPQECWWWVLKPDCWWW allegro-5.0.10/tests/test_driver.c0000644000175000001440000012233112145642337016257 0ustar tjadenusers/* * Automated testing driver program for Allegro. * * By Peter Wang. */ #include #include #include #include #include #include #include #include #include #include #define MAX_BITMAPS 128 #define MAX_TRANS 8 #define MAX_FONTS 16 #define MAX_VERTICES 100 typedef struct { ALLEGRO_USTR *name; ALLEGRO_BITMAP *bitmap[2]; } Bitmap; typedef enum { SW = 0, HW = 1 } BmpType; typedef struct { ALLEGRO_USTR *name; ALLEGRO_TRANSFORM transform; } Transform; typedef struct { int x; int y; int w; int h; ALLEGRO_LOCKED_REGION *lr; } LockRegion; typedef struct { ALLEGRO_USTR *name; ALLEGRO_FONT *font; } Font; int argc; char **argv; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *membuf; Bitmap bitmaps[MAX_BITMAPS]; LockRegion lock_region; Transform transforms[MAX_TRANS]; Font fonts[MAX_FONTS]; ALLEGRO_VERTEX vertices[MAX_VERTICES]; int num_global_bitmaps; float delay = 0.0; bool save_outputs = false; bool quiet = false; bool want_display = true; int verbose = 0; int total_tests = 0; int passed_tests = 0; int failed_tests = 0; #define streq(a, b) (0 == strcmp((a), (b))) /* Helper macros for scanning statements. */ #define PAT " %80[A-Za-z0-9_.$|#-] " #define PAT1 PAT #define PAT2 PAT1 "," PAT1 #define PAT3 PAT2 "," PAT1 #define PAT4 PAT3 "," PAT1 #define PAT5 PAT4 "," PAT1 #define PAT6 PAT5 "," PAT1 #define PAT7 PAT6 "," PAT1 #define PAT8 PAT7 "," PAT1 #define PAT9 PAT8 "," PAT1 #define PAT10 PAT9 "," PAT1 #define PAT11 PAT10 "," PAT1 #define PAT12 PAT11 "," PAT1 #define PAT13 PAT12 "," PAT1 #define PAT14 PAT13 "," PAT1 #define ARGS1 arg[0] #define ARGS2 ARGS1, arg[1] #define ARGS3 ARGS2, arg[2] #define ARGS4 ARGS3, arg[3] #define ARGS5 ARGS4, arg[4] #define ARGS6 ARGS5, arg[5] #define ARGS7 ARGS6, arg[6] #define ARGS8 ARGS7, arg[7] #define ARGS9 ARGS8, arg[8] #define ARGS10 ARGS9, arg[9] #define ARGS11 ARGS10, arg[10] #define ARGS12 ARGS11, arg[11] #define ARGS13 ARGS12, arg[12] #define ARGS14 ARGS13, arg[13] #define V(a) resolve_var(cfg, section, arg[(a)]) #define I(a) atoi(V(a)) #define F(a) atof(V(a)) #define C(a) get_color(V(a)) #define B(a) get_bitmap(V(a), bmp_type, target) #define SCAN0(fn) \ (sscanf(stmt, fn " (" " )") == 0) #define SCAN(fn, arity) \ (sscanf(stmt, fn " (" PAT##arity " )", ARGS##arity) == arity) #define SCANLVAL(fn, arity) \ (sscanf(stmt, PAT " = " fn " (" PAT##arity " )", lval, ARGS##arity) \ == 1 + arity) static void error(char const *msg, ...) { va_list ap; va_start(ap, msg); fprintf(stderr, "test_driver: "); vfprintf(stderr, msg, ap); fprintf(stderr, "\n"); va_end(ap); exit(EXIT_FAILURE); } static char const *bmp_type_to_string(BmpType bmp_type) { switch (bmp_type) { case SW: return "sw"; case HW: return "hw"; } return "error"; } static ALLEGRO_BITMAP *load_relative_bitmap(char const *filename) { ALLEGRO_BITMAP *bmp; bmp = al_load_bitmap(filename); if (!bmp) { error("failed to load %s", filename); } return bmp; } static void load_bitmaps(ALLEGRO_CONFIG const *cfg, const char *section, BmpType bmp_type) { int i = 0; ALLEGRO_CONFIG_ENTRY *iter; char const *key; char const *value; key = al_get_first_config_entry(cfg, section, &iter); while (key && i < MAX_BITMAPS) { value = al_get_config_value(cfg, section, key); bitmaps[i].name = al_ustr_new(key); bitmaps[i].bitmap[bmp_type] = load_relative_bitmap(value); key = al_get_next_config_entry(&iter); i++; } if (i == MAX_BITMAPS) error("bitmap limit reached"); num_global_bitmaps = i; } static ALLEGRO_BITMAP **reserve_local_bitmap(const char *name, BmpType bmp_type) { int i; for (i = num_global_bitmaps; i < MAX_BITMAPS; i++) { if (!bitmaps[i].name) { bitmaps[i].name = al_ustr_new(name); return &bitmaps[i].bitmap[bmp_type]; } } error("bitmap limit reached"); return NULL; } static void unload_data(void) { int i; for (i = 0; i < MAX_BITMAPS; i++) { al_ustr_free(bitmaps[i].name); al_destroy_bitmap(bitmaps[i].bitmap[0]); al_destroy_bitmap(bitmaps[i].bitmap[1]); } memset(bitmaps, 0, sizeof(bitmaps)); for (i = 0; i < MAX_FONTS; i++) { al_ustr_free(fonts[i].name); al_destroy_font(fonts[i].font); } memset(fonts, 0, sizeof(fonts)); num_global_bitmaps = 0; } static void set_target_reset(ALLEGRO_BITMAP *target) { ALLEGRO_TRANSFORM ident; al_set_target_bitmap(target); al_clear_to_color(al_map_rgb(0, 0, 0)); al_reset_clipping_rectangle(); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_identity_transform(&ident); al_use_transform(&ident); } static char const *resolve_var(ALLEGRO_CONFIG const *cfg, char const *section, char const *v) { char const *vv = al_get_config_value(cfg, section, v); return (vv) ? vv : v; } static bool get_bool(char const *value) { return streq(value, "true") ? true : streq(value, "false") ? false : atoi(value); } static ALLEGRO_COLOR get_color(char const *value) { int r, g, b, a; if (sscanf(value, "#%02x%02x%02x%02x", &r, &g, &b, &a) == 4) return al_map_rgba(r, g, b, a); if (sscanf(value, "#%02x%02x%02x", &r, &g, &b) == 3) return al_map_rgb(r, g, b); return al_color_name(value); } static ALLEGRO_BITMAP *get_bitmap(char const *value, BmpType bmp_type, ALLEGRO_BITMAP *target) { int i; for (i = 0; i < MAX_BITMAPS; i++) { if (bitmaps[i].name && streq(al_cstr(bitmaps[i].name), value)) return bitmaps[i].bitmap[bmp_type]; } if (streq(value, "target")) return target; if (streq(value, "0") || streq(value, "NULL")) return NULL; error("undefined bitmap: %s", value); return NULL; } static int get_draw_bitmap_flag(char const *value) { if (streq(value, "ALLEGRO_FLIP_HORIZONTAL")) return ALLEGRO_FLIP_HORIZONTAL; if (streq(value, "ALLEGRO_FLIP_VERTICAL")) return ALLEGRO_FLIP_VERTICAL; if (streq(value, "ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL")) return ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL; if (streq(value, "ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL")) return ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL; return atoi(value); } static int get_blender_op(char const *value) { return streq(value, "ALLEGRO_ADD") ? ALLEGRO_ADD : streq(value, "ALLEGRO_DEST_MINUS_SRC") ? ALLEGRO_DEST_MINUS_SRC : streq(value, "ALLEGRO_SRC_MINUS_DEST") ? ALLEGRO_SRC_MINUS_DEST : atoi(value); } static int get_blend_factor(char const *value) { return streq(value, "ALLEGRO_ZERO") ? ALLEGRO_ZERO : streq(value, "ALLEGRO_ONE") ? ALLEGRO_ONE : streq(value, "ALLEGRO_ALPHA") ? ALLEGRO_ALPHA : streq(value, "ALLEGRO_INVERSE_ALPHA") ? ALLEGRO_INVERSE_ALPHA : streq(value, "ALLEGRO_SRC_COLOR") ? ALLEGRO_SRC_COLOR : streq(value, "ALLEGRO_DEST_COLOR") ? ALLEGRO_DEST_COLOR : streq(value, "ALLEGRO_INVERSE_SRC_COLOR") ? ALLEGRO_INVERSE_SRC_COLOR : streq(value, "ALLEGRO_INVERSE_DEST_COLOR") ? ALLEGRO_INVERSE_DEST_COLOR : atoi(value); } static ALLEGRO_TRANSFORM *get_transform(const char *name) { int i; for (i = 0; i < MAX_TRANS; i++) { if (!transforms[i].name) { transforms[i].name = al_ustr_new(name); al_identity_transform(&transforms[i].transform); return &transforms[i].transform; } if (transforms[i].name && streq(al_cstr(transforms[i].name), name)) return &transforms[i].transform; } error("transforms limit reached"); return NULL; } static int get_pixel_format(char const *v) { int format = streq(v, "ALLEGRO_PIXEL_FORMAT_ANY") ? ALLEGRO_PIXEL_FORMAT_ANY : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_8888") ? ALLEGRO_PIXEL_FORMAT_ARGB_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_8888") ? ALLEGRO_PIXEL_FORMAT_RGBA_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_4444") ? ALLEGRO_PIXEL_FORMAT_ARGB_4444 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_888") ? ALLEGRO_PIXEL_FORMAT_RGB_888 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_565") ? ALLEGRO_PIXEL_FORMAT_RGB_565 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_555") ? ALLEGRO_PIXEL_FORMAT_RGB_555 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_5551") ? ALLEGRO_PIXEL_FORMAT_RGBA_5551 : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_1555") ? ALLEGRO_PIXEL_FORMAT_ARGB_1555 : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_8888") ? ALLEGRO_PIXEL_FORMAT_ABGR_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_XBGR_8888") ? ALLEGRO_PIXEL_FORMAT_XBGR_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_888") ? ALLEGRO_PIXEL_FORMAT_BGR_888 : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_565") ? ALLEGRO_PIXEL_FORMAT_BGR_565 : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_555") ? ALLEGRO_PIXEL_FORMAT_BGR_555 : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBX_8888") ? ALLEGRO_PIXEL_FORMAT_RGBX_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_XRGB_8888") ? ALLEGRO_PIXEL_FORMAT_XRGB_8888 : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_F32") ? ALLEGRO_PIXEL_FORMAT_ABGR_F32 : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE") ? ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_4444") ? ALLEGRO_PIXEL_FORMAT_RGBA_4444 : -1; if (format == -1) error("invalid format: %s", v); return format; } static int get_lock_bitmap_flags(char const *v) { return streq(v, "ALLEGRO_LOCK_READWRITE") ? ALLEGRO_LOCK_READWRITE : streq(v, "ALLEGRO_LOCK_READONLY") ? ALLEGRO_LOCK_READONLY : streq(v, "ALLEGRO_LOCK_WRITEONLY") ? ALLEGRO_LOCK_WRITEONLY : atoi(v); } static void fill_lock_region(LockRegion *lr, float alphafactor, bool blended) { int x, y; float r, g, b, a; ALLEGRO_COLOR c; for (y = 0; y < lr->h; y++) { for (x = 0; x < lr->w; x++) { /* -1 to make the last pixel use the full color, allows easier * manual inspection of the test results as we have a fixed * color on each side. */ r = (float)x / (lr->w - 1); b = (float)y / (lr->h - 1); g = r*b; a = r * alphafactor; c = al_map_rgba_f(r, g, b, a); if (blended) al_put_blended_pixel(lr->x + x, lr->y + y, c); else al_put_pixel(lr->x + x, lr->y + y, c); } } } static int get_load_font_flags(char const *v) { return streq(v, "ALLEGRO_NO_PREMULTIPLIED_ALPHA") ? ALLEGRO_NO_PREMULTIPLIED_ALPHA : streq(v, "ALLEGRO_TTF_NO_KERNING") ? ALLEGRO_TTF_NO_KERNING : streq(v, "ALLEGRO_TTF_MONOCHROME") ? ALLEGRO_TTF_MONOCHROME : atoi(v); } static void load_fonts(ALLEGRO_CONFIG const *cfg, const char *section) { #define MAXBUF 80 int i = 0; ALLEGRO_CONFIG_ENTRY *iter; char const *key; char arg[14][MAXBUF]; key = al_get_first_config_entry(cfg, section, &iter); while (key && i < MAX_FONTS) { char const *stmt = al_get_config_value(cfg, section, key); ALLEGRO_FONT *font = NULL; bool load_stmt = false; if (SCAN("al_load_font", 3)) { font = al_load_font(V(0), I(1), get_load_font_flags(V(2))); load_stmt = true; } else if (SCAN("al_load_ttf_font", 3)) { font = al_load_ttf_font(V(0), I(1), get_load_font_flags(V(2))); load_stmt = true; } else if (SCAN("al_load_ttf_font_stretch", 4)) { font = al_load_ttf_font_stretch(V(0), I(1), I(2), get_load_font_flags(V(3))); load_stmt = true; } else if (SCAN0("al_create_builtin_font")) { font = al_create_builtin_font(); load_stmt = true; } if (load_stmt) { if (!font) { error("failed to load font: %s", key); } fonts[i].name = al_ustr_new(key); fonts[i].font = font; i++; } key = al_get_next_config_entry(&iter); } if (i == MAX_FONTS) error("font limit reached"); #undef MAXBUF } static ALLEGRO_FONT *get_font(char const *name) { int i; for (i = 0; i < MAX_FONTS; i++) { if (fonts[i].name && streq(al_cstr(fonts[i].name), name)) return fonts[i].font; } error("undefined font: %s", name); return NULL; } static int get_font_align(char const *value) { return streq(value, "ALLEGRO_ALIGN_LEFT") ? ALLEGRO_ALIGN_LEFT : streq(value, "ALLEGRO_ALIGN_CENTRE") ? ALLEGRO_ALIGN_CENTRE : streq(value, "ALLEGRO_ALIGN_RIGHT") ? ALLEGRO_ALIGN_RIGHT : atoi(value); } static void set_config_int(ALLEGRO_CONFIG *cfg, char const *section, char const *var, int value) { char buf[40]; sprintf(buf, "%d", value); al_set_config_value(cfg, section, var, buf); } static void fill_vertices(ALLEGRO_CONFIG const *cfg, char const *name) { #define MAXBUF 80 char const *value; char buf[MAXBUF]; float x, y, z; float u, v; int i; memset(vertices, 0, sizeof(vertices)); for (i = 0; i < MAX_VERTICES; i++) { sprintf(buf, "v%d", i); value = al_get_config_value(cfg, name, buf); if (!value) return; if (sscanf(value, " %f , %f , %f ; %f , %f ; %s", &x, &y, &z, &u, &v, buf) == 6) { vertices[i].x = x; vertices[i].y = y; vertices[i].z = z; vertices[i].u = u; vertices[i].v = v; vertices[i].color = get_color(buf); } } #undef MAXBUF } static int get_prim_type(char const *value) { return streq(value, "ALLEGRO_PRIM_POINT_LIST") ? ALLEGRO_PRIM_POINT_LIST : streq(value, "ALLEGRO_PRIM_LINE_LIST") ? ALLEGRO_PRIM_LINE_LIST : streq(value, "ALLEGRO_PRIM_LINE_STRIP") ? ALLEGRO_PRIM_LINE_STRIP : streq(value, "ALLEGRO_PRIM_LINE_LOOP") ? ALLEGRO_PRIM_LINE_LOOP : streq(value, "ALLEGRO_PRIM_TRIANGLE_LIST") ? ALLEGRO_PRIM_TRIANGLE_LIST : streq(value, "ALLEGRO_PRIM_TRIANGLE_STRIP") ? ALLEGRO_PRIM_TRIANGLE_STRIP : streq(value, "ALLEGRO_PRIM_TRIANGLE_FAN") ? ALLEGRO_PRIM_TRIANGLE_FAN : atoi(value); } /* FNV-1a algorithm, parameters from: * http://www.isthe.com/chongo/tech/comp/fnv/index.html */ #define FNV_OFFSET_BASIS 2166136261UL #define FNV_PRIME 16777619 static uint32_t hash_bitmap(ALLEGRO_BITMAP *bmp) { ALLEGRO_LOCKED_REGION *lr; int x, y, w, h; uint32_t hash; w = al_get_bitmap_width(bmp); h = al_get_bitmap_height(bmp); hash = FNV_OFFSET_BASIS; lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY); for (y = 0; y < h; y++) { /* Oops, I unintentially committed the first version of this with signed * chars and computing in BGRA order, so leave it like that so we don't * have to update a bunch of old hashes. */ signed char const *data = ((signed char const *)lr->data) + y*lr->pitch; for (x = 0; x < w; x++) { hash ^= data[x*4 + 3]; hash *= FNV_PRIME; hash ^= data[x*4 + 2]; hash *= FNV_PRIME; hash ^= data[x*4 + 1]; hash *= FNV_PRIME; hash ^= data[x*4 + 0]; hash *= FNV_PRIME; } } al_unlock_bitmap(bmp); return hash; } /* Image "signature" I just made up: * We take the average intensity of 7x7 patches centred at 9x9 grid points on * the image. Each of these values is reduced down to 6 bits so it can be * represented by one printable character in base64 encoding. This gives a * reasonable signature length. */ #define SIG_GRID 9 #define SIG_LEN (SIG_GRID * SIG_GRID) #define SIG_LENZ (SIG_LEN + 1) static int patch_intensity(ALLEGRO_BITMAP *bmp, int cx, int cy) { float sum = 0.0; int x, y; for (y = -3; y <= 3; y++) { for (x = -3; x <= 3; x++) { ALLEGRO_COLOR c = al_get_pixel(bmp, cx + x, cy + y); sum += c.r + c.g + c.b; } } return 255 * sum/(7*7*3); } static char const base64[64] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; static int base64_decode(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'A' && c <= 'Z') return 10 + (c - 'A'); if (c >= 'a' && c <= 'z') return 36 + (c - 'a'); if (c == '+') return 62; if (c == '/') return 63; error("invalid base64 character: %c", c); return -1; } static void compute_signature(ALLEGRO_BITMAP *bmp, char sig[SIG_LENZ]) { int w = al_get_bitmap_width(bmp); int h = al_get_bitmap_height(bmp); int x, y; int n = 0; al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); for (y = 0; y < SIG_GRID; y++) { for (x = 0; x < SIG_GRID; x++) { int cx = (1 + x) * w/(1 + SIG_GRID); int cy = (1 + y) * h/(1 + SIG_GRID); int level = patch_intensity(bmp, cx, cy); sig[n] = base64[level >> 2]; n++; } } sig[n] = '\0'; al_unlock_bitmap(bmp); } static bool similar_signatures(char const sig1[SIG_LEN], char const sig2[SIG_LEN]) { int correct = 0; int i; for (i = 0; i < SIG_LEN; i++) { int q1 = base64_decode(sig1[i]); int q2 = base64_decode(sig2[i]); /* A difference of one quantisation level could be because two values * which were originally close by straddled a quantisation boundary. * A difference of two quantisation levels is a significant deviation. */ if (abs(q1 - q2) > 1) return false; correct++; } return ((float)correct / SIG_LEN) > 0.95; } static void check_hash(ALLEGRO_CONFIG const *cfg, char const *testname, ALLEGRO_BITMAP *bmp, BmpType bmp_type) { char const *bt = bmp_type_to_string(bmp_type); char hash[16]; char sig[SIG_LENZ]; char const *exp; char const *sigexp; exp = al_get_config_value(cfg, testname, "hash"); sigexp = al_get_config_value(cfg, testname, "sig"); if (exp && streq(exp, "off")) { printf("OK %s [%s] - hash check off\n", testname, bt); passed_tests++; return; } sprintf(hash, "%08x", hash_bitmap(bmp)); compute_signature(bmp, sig); if (verbose) { printf("hash=%s\n", hash); printf("sig=%s\n", sig); } if (!exp && !sigexp) { printf("NEW %s [%s] - hash=%s; sig=%s\n", testname, bt, hash, sig); return; } if (exp && streq(hash, exp)) { printf("OK %s [%s]\n", testname, bt); passed_tests++; return; } if (sigexp && strlen(sigexp) != SIG_LEN) { printf("WARNING: ignoring bad signature: %s\n", sigexp); sigexp = NULL; } if (sigexp && similar_signatures(sig, sigexp)) { printf("OK %s [%s] - by signature\n", testname, bt); passed_tests++; return; } printf("FAIL %s [%s] - hash=%s\n", testname, bt, hash); failed_tests++; } static double bitmap_dissimilarity(ALLEGRO_BITMAP *bmp1, ALLEGRO_BITMAP *bmp2) { ALLEGRO_LOCKED_REGION *lr1; ALLEGRO_LOCKED_REGION *lr2; int x, y, w, h; double sqerr = 0.0; lr1 = al_lock_bitmap(bmp1, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); lr2 = al_lock_bitmap(bmp2, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); w = al_get_bitmap_width(bmp1); h = al_get_bitmap_height(bmp1); for (y = 0; y < h; y++) { char const *data1 = ((char const *)lr1->data) + y*lr1->pitch; char const *data2 = ((char const *)lr2->data) + y*lr2->pitch; for (x = 0; x < w*4; x++) { double err = (double)data1[x] - (double)data2[x]; sqerr += err*err; } } al_unlock_bitmap(bmp1); al_unlock_bitmap(bmp2); return sqrt(sqerr / (w*h*4.0)); } static void check_similarity(ALLEGRO_CONFIG const *cfg, char const *testname, ALLEGRO_BITMAP *bmp1, ALLEGRO_BITMAP *bmp2, BmpType bmp_type, bool reliable) { char const *bt = bmp_type_to_string(bmp_type); double rms = bitmap_dissimilarity(bmp1, bmp2); double tolerance; char const *value; if (bmp_type == HW) { char const *exp = al_get_config_value(cfg, testname, "hash_hw"); char hash[16]; sprintf(hash, "%08x", hash_bitmap(bmp1)); if (exp && streq(hash, exp)) { printf("OK %s [%s]\n", testname, bt); passed_tests++; return; } } /* The default cutoff is "empirically determined" only. */ if ((value = al_get_config_value(cfg, testname, "tolerance"))) tolerance = atof(value); else tolerance = 17.5; if (rms <= tolerance) { if (reliable) printf("OK %s [%s]\n", testname, bt); else printf("OK? %s [%s]\n", testname, bt); passed_tests++; } else { char const *exp = al_get_config_value(cfg, testname, "hash"); char hash[16]; char sig[SIG_LENZ]; sprintf(hash, "%08x", hash_bitmap(bmp1)); if (exp && streq(hash, exp)) { printf("OK %s [%s]\n", testname, bt); passed_tests++; return; } printf("FAIL %s [%s] - RMS error is %g\n", testname, bt, rms); printf("hash_hw=%s\n", hash); compute_signature(bmp1, sig); printf("sig_hw=%s\n", sig); failed_tests++; } } static void do_test(ALLEGRO_CONFIG *cfg, char const *testname, ALLEGRO_BITMAP *target, int bmp_type, bool reliable) { #define MAXBUF 80 const char *section = testname; int op; char const *stmt; char buf[MAXBUF]; char arg[14][MAXBUF]; char lval[MAXBUF]; int i; if (verbose) { /* So in case it segfaults, we know which test to re-run. */ printf("\nRunning %s [%s].\n", testname, bmp_type_to_string(bmp_type)); fflush(stdout); } set_target_reset(target); for (op = 0; ; op++) { sprintf(buf, "op%d", op); stmt = al_get_config_value(cfg, testname, buf); if (!stmt) { /* Check for a common mistake. */ sprintf(buf, "op%d", op+1); stmt = al_get_config_value(cfg, testname, buf); if (!stmt) break; printf("WARNING: op%d skipped, continuing at op%d\n", op, op+1); op++; } if (verbose > 1) printf("# %s\n", stmt); if (streq(stmt, "")) continue; if (SCAN("al_set_target_bitmap", 1)) { al_set_target_bitmap(B(0)); continue; } if (SCAN("al_set_clipping_rectangle", 4)) { al_set_clipping_rectangle(I(0), I(1), I(2), I(3)); continue; } if (SCAN("al_set_blender", 3)) { al_set_blender( get_blender_op(V(0)), get_blend_factor(V(1)), get_blend_factor(V(2))); continue; } if (SCAN("al_set_separate_blender", 6)) { al_set_separate_blender( get_blender_op(V(0)), get_blend_factor(V(1)), get_blend_factor(V(2)), get_blender_op(V(3)), get_blend_factor(V(4)), get_blend_factor(V(5))); continue; } if (SCAN("al_clear_to_color", 1)) { al_clear_to_color(C(0)); continue; } if (SCAN("al_draw_bitmap", 4)) { al_draw_bitmap(B(0), F(1), F(2), get_draw_bitmap_flag(V(3))); continue; } if (SCAN("al_draw_tinted_bitmap", 5)) { al_draw_tinted_bitmap(B(0), C(1), F(2), F(3), get_draw_bitmap_flag(V(4))); continue; } if (SCAN("al_draw_bitmap_region", 8)) { al_draw_bitmap_region(B(0), F(1), F(2), F(3), F(4), F(5), F(6), get_draw_bitmap_flag(V(7))); continue; } if (SCAN("al_draw_tinted_bitmap_region", 9)) { al_draw_tinted_bitmap_region(B(0), C(1), F(2), F(3), F(4), F(5), F(6), F(7), get_draw_bitmap_flag(V(8))); continue; } if (SCAN("al_draw_rotated_bitmap", 7)) { al_draw_rotated_bitmap(B(0), F(1), F(2), F(3), F(4), F(5), get_draw_bitmap_flag(V(6))); continue; } if (SCAN("al_draw_tinted_rotated_bitmap", 8)) { al_draw_tinted_rotated_bitmap(B(0), C(1), F(2), F(3), F(4), F(5), F(6), get_draw_bitmap_flag(V(7))); continue; } if (SCAN("al_draw_scaled_bitmap", 10)) { al_draw_scaled_bitmap(B(0), F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), get_draw_bitmap_flag(V(9))); continue; } if (SCAN("al_draw_tinted_scaled_bitmap", 11)) { al_draw_tinted_scaled_bitmap(B(0), C(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), F(9), get_draw_bitmap_flag(V(10))); continue; } if (SCAN("al_draw_scaled_rotated_bitmap", 9)) { al_draw_scaled_rotated_bitmap(B(0), F(1), F(2), F(3), F(4), F(5), F(6), F(7), get_draw_bitmap_flag(V(8))); continue; } if (SCAN("al_draw_tinted_scaled_rotated_bitmap", 10)) { al_draw_tinted_scaled_rotated_bitmap(B(0), C(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), get_draw_bitmap_flag(V(9))); continue; } if (SCAN("al_draw_tinted_scaled_rotated_bitmap_region", 14)) { al_draw_tinted_scaled_rotated_bitmap_region(B(0), F(1), F(2), F(3), F(4), C(5), F(6), F(7), F(8), F(9), F(10), F(11), F(12), get_draw_bitmap_flag(V(13))); continue; } if (SCAN("al_draw_pixel", 3)) { al_draw_pixel(F(0), F(1), C(2)); continue; } if (SCAN("al_put_pixel", 3)) { al_put_pixel(I(0), I(1), C(2)); continue; } if (SCAN("al_put_blended_pixel", 3)) { al_put_blended_pixel(I(0), I(1), C(2)); continue; } if (SCANLVAL("al_create_bitmap", 2)) { ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); (*bmp) = al_create_bitmap(I(0), I(1)); continue; } if (SCANLVAL("al_create_sub_bitmap", 5)) { ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); (*bmp) = al_create_sub_bitmap(B(0), I(1), I(2), I(3), I(4)); continue; } if (SCANLVAL("al_load_bitmap", 1)) { ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); (*bmp) = load_relative_bitmap(V(0)); continue; } if (SCAN("al_save_bitmap", 2)) { if (!al_save_bitmap(V(0), B(1))) { error("failed to save %s", V(0)); } continue; } if (SCAN("al_hold_bitmap_drawing", 1)) { al_hold_bitmap_drawing(get_bool(V(0))); continue; } /* Transformations */ if (SCAN("al_copy_transform", 2)) { al_copy_transform(get_transform(V(0)), get_transform(V(1))); continue; } if (SCAN("al_use_transform", 1)) { al_use_transform(get_transform(V(0))); continue; } if (SCAN("al_build_transform", 6)) { al_build_transform(get_transform(V(0)), F(1), F(2), F(3), F(4), F(5)); continue; } if (SCAN("al_translate_transform", 3)) { al_translate_transform(get_transform(V(0)), F(1), F(2)); continue; } if (SCAN("al_scale_transform", 3)) { al_scale_transform(get_transform(V(0)), F(1), F(2)); continue; } if (SCAN("al_rotate_transform", 2)) { al_rotate_transform(get_transform(V(0)), F(1)); continue; } if (SCAN("al_compose_transform", 2)) { al_compose_transform(get_transform(V(0)), get_transform(V(1))); continue; } /* Locking */ if (SCAN("al_lock_bitmap", 3)) { ALLEGRO_BITMAP *bmp = B(0); lock_region.x = 0; lock_region.y = 0; lock_region.w = al_get_bitmap_width(bmp); lock_region.h = al_get_bitmap_height(bmp); lock_region.lr = al_lock_bitmap(bmp, get_pixel_format(V(1)), get_lock_bitmap_flags(V(2))); continue; } if (SCAN("al_lock_bitmap_region", 7)) { ALLEGRO_BITMAP *bmp = B(0); lock_region.x = I(1); lock_region.y = I(2); lock_region.w = I(3); lock_region.h = I(4); lock_region.lr = al_lock_bitmap_region(bmp, lock_region.x, lock_region.y, lock_region.w, lock_region.h, get_pixel_format(V(5)), get_lock_bitmap_flags(V(6))); continue; } if (SCAN("al_unlock_bitmap", 1)) { al_unlock_bitmap(B(0)); lock_region.lr = NULL; continue; } if (SCAN("fill_lock_region", 2)) { fill_lock_region(&lock_region, F(0), get_bool(V(1))); continue; } /* Fonts */ if (SCAN("al_draw_text", 6)) { al_draw_text(get_font(V(0)), C(1), F(2), F(3), get_font_align(V(4)), V(5)); continue; } if (SCAN("al_draw_justified_text", 8)) { al_draw_justified_text(get_font(V(0)), C(1), F(2), F(3), F(4), F(5), get_font_align(V(6)), V(7)); continue; } if (SCANLVAL("al_get_text_width", 2)) { int w = al_get_text_width(get_font(V(0)), V(1)); set_config_int(cfg, testname, lval, w); continue; } if (SCANLVAL("al_get_font_line_height", 1)) { int h = al_get_font_line_height(get_font(V(0))); set_config_int(cfg, testname, lval, h); continue; } if (SCANLVAL("al_get_font_ascent", 1)) { int as = al_get_font_ascent(get_font(V(0))); set_config_int(cfg, testname, lval, as); continue; } if (SCANLVAL("al_get_font_descent", 1)) { int de = al_get_font_descent(get_font(V(0))); set_config_int(cfg, testname, lval, de); continue; } if (SCAN("al_get_text_dimensions", 6)) { int bbx, bby, bbw, bbh; al_get_text_dimensions(get_font(V(0)), V(1), &bbx, &bby, &bbw, &bbh); set_config_int(cfg, testname, V(2), bbx); set_config_int(cfg, testname, V(3), bby); set_config_int(cfg, testname, V(4), bbw); set_config_int(cfg, testname, V(5), bbh); continue; } /* Primitives */ if (SCAN("al_draw_line", 6)) { al_draw_line(F(0), F(1), F(2), F(3), C(4), F(5)); continue; } if (SCAN("al_draw_triangle", 8)) { al_draw_triangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6), F(7)); continue; } if (SCAN("al_draw_filled_triangle", 7)) { al_draw_filled_triangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6)); continue; } if (SCAN("al_draw_rectangle", 6)) { al_draw_rectangle(F(0), F(1), F(2), F(3), C(4), F(5)); continue; } if (SCAN("al_draw_filled_rectangle", 5)) { al_draw_filled_rectangle(F(0), F(1), F(2), F(3), C(4)); continue; } if (SCAN("al_draw_rounded_rectangle", 8)) { al_draw_rounded_rectangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6), F(7)); continue; } if (SCAN("al_draw_filled_rounded_rectangle", 7)) { al_draw_filled_rounded_rectangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6)); continue; } if (SCAN("al_draw_pieslice", 7)) { al_draw_pieslice(F(0), F(1), F(2), F(3), F(4), C(5), F(6)); continue; } if (SCAN("al_draw_filled_pieslice", 6)) { al_draw_filled_pieslice(F(0), F(1), F(2), F(3), F(4), C(5)); continue; } if (SCAN("al_draw_ellipse", 6)) { al_draw_ellipse(F(0), F(1), F(2), F(3), C(4), F(5)); continue; } if (SCAN("al_draw_filled_ellipse", 5)) { al_draw_filled_ellipse(F(0), F(1), F(2), F(3), C(4)); continue; } if (SCAN("al_draw_circle", 5)) { al_draw_circle(F(0), F(1), F(2), C(3), F(4)); continue; } if (SCAN("al_draw_filled_circle", 4)) { al_draw_filled_circle(F(0), F(1), F(2), C(3)); continue; } if (SCAN("al_draw_arc", 7)) { al_draw_arc(F(0), F(1), F(2), F(3), F(4), C(5), F(6)); continue; } if (SCAN("al_draw_elliptical_arc", 8)) { al_draw_elliptical_arc(F(0), F(1), F(2), F(3), F(4), F(5), C(6), F(7)); continue; } if (SCAN("al_draw_spline", 3)) { float pt[8]; if (sscanf(V(0), "%f, %f, %f, %f, %f, %f, %f, %f", pt+0, pt+1, pt+2, pt+3, pt+4, pt+5, pt+6, pt+7) == 8) { al_draw_spline(pt, C(1), F(2)); continue; } } if (SCAN("al_draw_prim", 6)) { fill_vertices(cfg, V(0)); /* decl arg is ignored */ al_draw_prim(vertices, NULL, B(2), I(3), I(4), get_prim_type(V(5))); continue; } error("statement didn't scan: %s", stmt); } al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); if (bmp_type == SW) { al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); check_hash(cfg, testname, target, bmp_type); } else { al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); check_similarity(cfg, testname, target, membuf, bmp_type, reliable); } total_tests++; if (save_outputs) { ALLEGRO_USTR *filename = al_ustr_newf("%s [%s].png", testname, bmp_type_to_string(bmp_type)); al_save_bitmap(al_cstr(filename), target); al_ustr_free(filename); } if (!quiet) { if (target != al_get_backbuffer(display)) { set_target_reset(al_get_backbuffer(display)); al_draw_bitmap(target, 0, 0, 0); } al_flip_display(); al_rest(delay); } /* Ensure we don't target a bitmap which is about to be destroyed. */ al_set_target_bitmap(display ? al_get_backbuffer(display) : NULL); /* Destroy local bitmaps. */ for (i = num_global_bitmaps; i < MAX_BITMAPS; i++) { if (bitmaps[i].name) { al_ustr_free(bitmaps[i].name); bitmaps[i].name = NULL; al_destroy_bitmap(bitmaps[i].bitmap[bmp_type]); bitmaps[i].bitmap[bmp_type] = NULL; } } /* Free transform names. */ for (i = 0; i < MAX_TRANS; i++) { al_ustr_free(transforms[i].name); transforms[i].name = NULL; } #undef MAXBUF } static void sw_hw_test(ALLEGRO_CONFIG *cfg, char const *testname) { int old_failed_tests = failed_tests; bool reliable; al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_NO_PREMULTIPLIED_ALPHA); do_test(cfg, testname, membuf, SW, true); reliable = (failed_tests == old_failed_tests); if (display) { al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PREMULTIPLIED_ALPHA); do_test(cfg, testname, al_get_backbuffer(display), HW, reliable); } } static bool section_exists(ALLEGRO_CONFIG const *cfg, char const *section) { ALLEGRO_CONFIG_ENTRY *iter; return al_get_first_config_entry(cfg, section, &iter) != NULL; } static void merge_config_sections( ALLEGRO_CONFIG *targ_cfg, char const *targ_section, ALLEGRO_CONFIG const *src_cfg, char const *src_section) { char const *key; char const *value; ALLEGRO_CONFIG_ENTRY *iter; value = al_get_config_value(src_cfg, src_section, "extend"); if (value) { if (streq(value, src_section)) { error("section cannot extend itself: %s " "(did you forget to rename a section?)", src_section); } merge_config_sections(targ_cfg, targ_section, src_cfg, value); } key = al_get_first_config_entry(src_cfg, src_section, &iter); if (!key) { error("missing section: %s", src_section); } for (; key != NULL; key = al_get_next_config_entry(&iter)) { value = al_get_config_value(src_cfg, src_section, key); al_set_config_value(targ_cfg, targ_section, key, value); } } static void run_test(ALLEGRO_CONFIG const *cfg, char const *section) { char const *extend; ALLEGRO_CONFIG *cfg2; if (!section_exists(cfg, section)) { error("section not found: %s", section); } cfg2 = al_create_config(); al_merge_config_into(cfg2, cfg); extend = al_get_config_value(cfg, section, "extend"); if (extend) { merge_config_sections(cfg2, section, cfg, section); } sw_hw_test(cfg2, section); al_destroy_config(cfg2); } static void run_matching_tests(ALLEGRO_CONFIG const *cfg, const char *prefix) { ALLEGRO_CONFIG_SECTION *iter; char const *section; for (section = al_get_first_config_section(cfg, &iter); section != NULL; section = al_get_next_config_section(&iter)) { if (0 == strncmp(section, prefix, strlen(prefix))) { run_test(cfg, section); } } } static void partial_tests(ALLEGRO_CONFIG const *cfg, int n) { ALLEGRO_USTR *name = al_ustr_new(""); while (n > 0) { /* Automatically prepend "test" for convenience. */ if (0 == strncmp(argv[0], "test ", 5)) { al_ustr_assign_cstr(name, argv[0]); } else { al_ustr_truncate(name, 0); al_ustr_appendf(name, "test %s", argv[0]); } /* Star suffix means run all matching tests. */ if (al_ustr_has_suffix_cstr(name, "*")) { al_ustr_truncate(name, al_ustr_size(name) - 1); run_matching_tests(cfg, al_cstr(name)); } else { run_test(cfg, al_cstr(name)); } argc--; argv++; n--; } al_ustr_free(name); } static bool has_suffix(char const *s, char const *suf) { return (strlen(s) >= strlen(suf)) && streq(s + strlen(s) - strlen(suf), suf); } static void process_ini_files(void) { ALLEGRO_CONFIG *cfg; int n; while (argc > 0) { if (!has_suffix(argv[0], ".ini")) error("expected .ini argument: %s\n", argv[0]); cfg = al_load_config_file(argv[0]); if (!cfg) error("failed to load config file %s", argv[0]); if (verbose) printf("Running %s\n", argv[0]); argc--; argv++; al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_NO_PREMULTIPLIED_ALPHA); load_bitmaps(cfg, "bitmaps", SW); if (display) { al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PREMULTIPLIED_ALPHA); load_bitmaps(cfg, "bitmaps", HW); } load_fonts(cfg, "fonts"); for (n = 0; n < argc; n++) { if (has_suffix(argv[n], ".ini")) break; } if (n == 0) run_matching_tests(cfg, "test "); else partial_tests(cfg, n); unload_data(); al_destroy_config(cfg); } } int main(int _argc, char *_argv[]) { argc = _argc; argv = _argv; if (argc == 1) { error("requires config file argument"); } argc--; argv++; if (!al_init()) { error("failed to initialise Allegro"); } al_init_image_addon(); al_init_font_addon(); al_init_ttf_addon(); al_init_primitives_addon(); for (; argc > 0; argc--, argv++) { char const *opt = argv[0]; if (streq(opt, "-d") || streq(opt, "--delay")) { delay = 1.0; } else if (streq(opt, "-s") || streq(opt, "--save")) { save_outputs = true; } else if (streq(opt, "-q") || streq(opt, "--quiet")) { quiet = true; } else if (streq(opt, "-n") || streq(opt, "--no-display")) { want_display = false; quiet = true; } else if (streq(opt, "-v") || streq(opt, "--verbose")) { verbose++; } else if (streq(opt, "--force-opengl-1.2")) { ALLEGRO_CONFIG *cfg = al_get_system_config(); al_set_config_value(cfg, "opengl", "force_opengl_version", "1.2"); al_set_new_display_flags(ALLEGRO_OPENGL); } else if (streq(opt, "--force-opengl-2.0")) { ALLEGRO_CONFIG *cfg = al_get_system_config(); al_set_config_value(cfg, "opengl", "force_opengl_version", "2.0"); al_set_new_display_flags(ALLEGRO_OPENGL); } else if (streq(opt, "--force-opengl")) { al_set_new_display_flags(ALLEGRO_OPENGL); } else if (streq(opt, "--force-d3d")) { /* Don't try this at home. */ al_set_new_display_flags(ALLEGRO_DIRECT3D_INTERNAL); } else { break; } } if (want_display) { display = al_create_display(640, 480); if (!display) { error("failed to create display"); } } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); if (want_display) { membuf = al_create_bitmap( al_get_display_width(display), al_get_display_height(display)); } else { membuf = al_create_bitmap(640, 480); } process_ini_files(); printf("\n"); printf("total tests: %d\n", total_tests); printf("passed tests: %d\n", passed_tests); printf("failed tests: %d\n", failed_tests); printf("\n"); return !!failed_tests; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/tests/test_locking2.ini0000644000175000001440000000604611721433063017026 0ustar tjadenusers[texture rw] op0= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op1= op2= bmp = al_create_bitmap(640, 480) op3= al_set_target_bitmap(bmp) op4= al_clear_to_color(#554321) op5= al_lock_bitmap_region(bmp, 133, 65, 381, 327, format, flags) op6= fill_lock_region(alphafactor, true) op7= al_unlock_bitmap(bmp) op8= op9= al_set_target_bitmap(target) op10=al_clear_to_color(#00ff00) # Don't assume the screen has an alpha channel, it may be 24 bit. op11=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) op12=al_draw_bitmap(bmp, 0, 0, 0) flags=ALLEGRO_LOCK_READWRITE alphafactor=1.0 [test texture rw 32b ARGB_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ARGB_8888 hash=d4866407 sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF [test texture rw 32b RGBA_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGBA_8888 hash=d4866407 sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF [test texture rw 16b ARGB_4444] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ARGB_4444 hash=32b551c9 [test texture rw 24b RGB_888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGB_888 hash=dc5525e2 [test texture rw 16b RGB_565] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGB_565 hash=a51f89f0 [test texture rw 15b RGB_555] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGB_555 hash=200647c4 [test texture rw 16b RGBA_5551] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGBA_5551 hash=c42fb611 # NOTE: the correct output for this is all green except for one pixel column # on the right. [test texture rw 16b ARGB_1555] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ARGB_1555 hash=c42fb611 # NOTE: the correct output for this is all green except for one pixel column # on the right. [test texture rw 32b ABGR_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ABGR_8888 hash=d4866407 sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF [test texture rw 32b XBGR_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_XBGR_8888 hash=dc5525e2 [test texture rw 24b BGR_888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_BGR_888 hash=dc5525e2 [test texture rw 16b BGR_565] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_BGR_565 hash=a51f89f0 [test texture rw 15b BGR_555] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_BGR_555 hash=200647c4 [test texture rw 32b RGBX_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGBX_8888 hash=dc5525e2 [test texture rw 32b XRGB_8888] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_XRGB_8888 hash=dc5525e2 [test texture rw f32 ABGR_F32] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ABGR_F32 hash=d4866407 sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF [test texture rw 32b ABGR_8888_LE] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE hash=d4866407 sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF [test texture rw 16b RGBA_4444] extend=texture rw format=ALLEGRO_PIXEL_FORMAT_RGBA_4444 hash=32b551c9 allegro-5.0.10/tests/test_driver.txt0000644000175000001440000000712611771526157016665 0ustar tjadenusersUsage ===== test_driver [OPTIONS] config1.ini [TESTS ...] [config2.ini [TESTS...]] ... where options are: -d, --delay delay between tests -s, --save save output images as .png -q, --quiet don't display graphical output -v, --verbose print extra output -v -v extra extra verbose --force-opengl select OpenGL driver --force-opengl-1.2 restrict Allegro to OpenGL 1.2 --force-opengl-2.0 restrict Allegro to OpenGL 2.0 --force-d3d select Direct3D driver If the list of tests is omitted then every test in the config file will be run. Otherwise each test named on the command line is run. For convenience, you may drop the "test " prefix on test names. If a test name ends with an asterisk, then all tests which match that prefix will be run, e.g. ./test_driver -d test_bitmaps.ini 'scaled rotate*' Every test is run with both memory and video bitmaps. The software rendered result is checked against an expected hash code. The hardware rendered result is checked for similarity with the software result. Config file format ================== Each [test ...] section defines a single test, containing one or more operations named by the keys op0, op1, ... opN. The value of each op key is a call to an Allegro function, or empty. Each argument of the call must be a literal of the correct type, or a variable name. A variable name is just another key in the section, whose value is taken as a _literal_ to be substituted in place of the variable. A test may inherit the keys of another section using the 'extend' key. Keys in the child section override keys in the parent. The [bitmaps] section defines a list of bitmaps to load, relative to the tests directory. Each key name is then a valid bitmap literal. The name 'target' refers to the default target bitmap. ALLEGRO_COLOR literals may be written as #rrggbb, #rrggbbaa or a named color (e.g. purple). Integer, float and enumeration literals are written as per C. (Note that "ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL" must be written without whitespace, because we don't have a proper parser.) String literals are not supported, but you can use a variable whose value is treated as the string contents (no quotes). Transformations are automatically created the first time they are mentioned, and set to the identity matrix. Each test section contains a key called 'hash', containing the hash code of the expected output for that test. When writing a test you should check (visually) that the output looks correct, then add the hash code computed hash code to the test section. Some tests produce slightly different (but still acceptable) output depending on the hardware, compiler or optimisation settings. As an alternative to 'hash', which will only pass if the result is exactly the same, you can use the 'sig' key. This will perform a loose comparison on "signatures" which are computed from the average intensity levels (greyscale) at 81 points on the image. Hopefully it is still strict enough to catch any major regressions. You can supply both 'hash' and 'sig' keys. Finally, 'hash=off' will disable hash checking entirely. For example, TTF rendering depends on the FreeType configuration, and the differences are big enough to show up even in the thumbnails. The hardware implementation is compared against the software implementation, with some tolerance. The tolerance is arbitrary but you can set it if necessary with the 'tolerance' key. In case the HW results is supposed to look different, a separate hash can be specifeid with 'hw_hash' instead of the similarity comparison. allegro-5.0.10/tests/test_fonts.ini0000644000175000001440000001161311777546527016470 0ustar tjadenusers[fonts] bmpfont=al_load_font(bmp_filename, 24, flags) builtin=al_create_builtin_font() ttf=al_load_font(ttf_filename, 24, flags) ttf_tall=al_load_ttf_font_stretch(ttf_filename, 24, 48, flags) ttf_wide=al_load_ttf_font_stretch(ttf_filename, 48, 24, flags) ttf_px1=al_load_font(ttf_filename, -32, flags) ttf_px2=al_load_ttf_font_stretch(ttf_filename, 0, -32, flags) ttf_px3=al_load_ttf_font_stretch(ttf_filename, -24, -32, flags) # arguments bmp_filename=../examples/data/a4_font.tga ttf_filename=../examples/data/DejaVuSans.ttf flags=ALLEGRO_NO_PREMULTIPLIED_ALPHA [text] en=Welcome to Allegro gr=Καλώς ήρθατε στο Allegro latin1=aábdðeéfghiíjkprstuúvxyýþæö [test font bmp] extend=text op0=al_clear_to_color(rosybrown) op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op2= op3=al_draw_text(font, darkred, 320, 100, ALLEGRO_ALIGN_LEFT, en) op4=al_draw_text(font, white, 320, 150, ALLEGRO_ALIGN_CENTRE, en) op5=al_draw_text(font, blue, 320, 200, ALLEGRO_ALIGN_RIGHT, en) op6= font=bmpfont hash=68f73534 [test font bmp hold] extend=test font bmp op2=al_hold_bitmap_drawing(true) op6=al_hold_bitmap_drawing(false) [test font builtin] extend=text op0=al_clear_to_color(rosybrown) op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op2=al_draw_text(font, darkred, 320, 100, ALLEGRO_ALIGN_LEFT, en) op3=al_draw_text(font, white, 320, 150, ALLEGRO_ALIGN_CENTRE, latin1) font=builtin hash=502aa12f [test font ttf] extend=test font bmp op6=al_draw_text(font, khaki, 320, 300, ALLEGRO_ALIGN_CENTRE, gr) font=ttf # Result changes with the FreeType configuration of the system. hash=off [test font ttf hold] extend=test font ttf op2=al_hold_bitmap_drawing(true) op7=al_hold_bitmap_drawing(false) [test font ttf tall] extend=test font ttf font=ttf_tall [test font ttf wide] extend=test font ttf font=ttf_wide [test font ttf pixelsize 1] extend=test font ttf font=ttf_px1 [test font ttf pixelsize 2] extend=test font ttf font=ttf_px2 [test font ttf pixelsize 3] extend=test font ttf font=ttf_px3 [test font bmp justify] extend=text op0=al_clear_to_color(#886655) op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op2=al_draw_justified_text(bmpfont, black, 100, 540, 100, 0, 0, en) op3=al_draw_justified_text(bmpfont, black, 100, 540, 150, 1000, 0, en) hash=6a402079 [test font ttf justify] extend=test font bmp justify op4=al_draw_justified_text(ttf, black, 100, 540, 300, 0, 0, gr) op5=al_draw_justified_text(ttf, black, 100, 540, 350, 1000, 0, gr) # Result changes with the FreeType configuration of the system. hash=off [test font complex] extend=text op0=al_clear_to_color(#665544) op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op2=al_build_transform(T, cx, cy, 2.0, 2.0, -0.3) op3=al_use_transform(T) op4=al_draw_text(ttf, #aabbcc80, 0, 0, ALLEGRO_ALIGN_CENTRE, en) op5=al_build_transform(T, cx, cy, 2.0, 2.0, 0.3) op6=al_use_transform(T) op7=al_draw_text(ttf, #eebbaa80, 0, 0, ALLEGRO_ALIGN_CENTRE, gr) op8=al_build_transform(T2, cx, 360, 20, 20, 0) op9=al_use_transform(T2) op10=al_draw_text(bmpfont, #88888855, 0, 0, ALLEGRO_ALIGN_CENTRE, yeah) cx=320 cy=200 yeah=yeah! # Result changes with the FreeType configuration of the system. hash=off [test font dimensions ttf en] op0= al_clear_to_color(#665544) op1= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op2= al_translate_transform(T, 100, 100) op3= al_use_transform(T) op4= al_get_text_dimensions(font, str, bbx, bby, bbw, bbh) # We can't actually draw it without introducing arithmetic. #op5=al_draw_rectangle(bbx, bby, bbx+bbw, bby+bbh, black, 0) op5= op6= al_draw_text(font, #aabbcc80, 0, 0, ALLEGRO_ALIGN_LEFT, str) op7= op8= al_translate_transform(T, 0, 100) op9= al_use_transform(T) op10=w = al_get_text_width(font, str) op11=h = al_get_font_line_height(font) op12=as = al_get_font_ascent(font) op13=de = al_get_font_descent(font) # Note: the hw version blurs the lines because we can't add 0.5 offsets. op14=al_draw_rectangle(0, 0, w, h, black, 0) op15=al_draw_line(0, as, w, as, black, 0) op16=al_draw_line(0, de, w, de, black, 0) op17=al_draw_text(font, #aabbcc80, 0, 0, ALLEGRO_ALIGN_LEFT, str) font=ttf str=Welcome to Allegro hash=off [test font dimensions ttf gr] extend=test font dimensions ttf en str=Καλώς ήρθατε στο Allegro hash=off [test font dimensions bmp] extend=test font dimensions ttf en font=bmpfont hash=4284d74d # Not a font test but requires a font. [test d3d cache state bug] op0=image = al_create_bitmap(20, 20) op1=al_set_target_bitmap(image) op2=al_clear_to_color(white) op3=al_set_target_bitmap(target) op4=al_clear_to_color(#00000000) op5=al_draw_text(bmpfont, red, 0, 0, ALLEGRO_ALIGN_LEFT, str) op6=al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ALPHA, ALLEGRO_ONE) op7=al_draw_rectangle(45, 45, 75, 75, #ffffff40, 1) op8=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) op9=al_draw_tinted_bitmap(image, #ffffffff, 50, 50, 0) str=Hello hash=249efe55 allegro-5.0.10/tests/test_prim.ini0000644000175000001440000004313012006013546016255 0ustar tjadenusers[bitmaps] bkg=../examples/data/bkg.png texture=../examples/data/texture.tga obp=../examples/data/obp.jpg [ll] op0= al_draw_bitmap(bkg, 0, 0, 0) op1= al_build_transform(trans, 320, 240, 1, 1, 1.0) op2= op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op4= al_use_transform(trans) op5= al_draw_prim(verts, 0, tex, 0, 4, ALLEGRO_PRIM_LINE_LIST) op6= al_draw_prim(verts, 0, tex, 4, 9, ALLEGRO_PRIM_LINE_STRIP) op7= al_draw_prim(verts, 0, tex, 9, 13, ALLEGRO_PRIM_LINE_LOOP) verts=vtx_ll tex=0 [test ll notex blend] extend=ll hash=3e2bdb71 [test ll notex opaque] extend=ll op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) hash=8e491071 [test ll tex blend] extend=ll tex=texture hash=002007ce [test ll tex blend white] extend=ll verts=vtx_ll_white tex=texture hash=cccd8111 [test ll tex opaque] extend=ll op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) tex=texture hash=be2f916a [test ll tex opaque white] extend=ll op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) verts=vtx_ll_white tex=texture hash=92099701 [hl] op0= al_draw_bitmap(bkg, 0, 0, 0) op1= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) op2= op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op4= al_use_transform(trans) op5= al_draw_line(-300, -200, 300, 200, #008080ff, thickness) op6= al_draw_triangle(-150, -250, 0, 250, 150, -250, #800080ff, thickness) op7= al_draw_rectangle(-300, -200, 300, 200, #800000ff, thickness) op8= al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, #333300ff, thickness) op9= al_draw_ellipse(0, 0, 300, 150, #008080ff, thickness) op10=al_draw_arc(0, 0, 200, -1.5707, 3.1415, #803f00ff, thickness) op11= op12= op13=al_draw_spline(points, #193380ff, thickness) points=-300,-200, 700,200, -700,200, 300,-200 theta=0.5 thickness=1 [hl2] # hl2 is like hl but the spline is not rotated. # We received a report on i386 where the rotated spline is drawn with # a single pixel difference, but still acceptable. extend=hl op11=al_build_transform(trans, 320, 240, 0.75, 0.75, 0) op12=al_use_transform(trans) [test hl thick-0] extend=hl thickness=0 hash=d62736a8 sig=766666666769966A66656659677676767A66866697567669A6556766786676665767A876776666766 [test hl thick-1] extend=hl thickness=1 sig=766666666769966966656659677676767A66866697566669965567667866766657679876776666766 [test hl thick-2] extend=hl thickness=2 hash=2d8b8da2 [test hl thick-10] extend=hl thickness=10 hash=6f8b689d [test hl2 thick-50] extend=hl2 thickness=50 hash=70941b3e [test hl2 thick-50 clip] extend=test hl2 thick-50 op2=al_set_clipping_rectangle(220, 140, 420, 340) hash=8509c589 [test hl2 thick-50 nolight] extend=test hl2 thick-50 op3= hash=85099dca [test hl2 thick-50 nolight clip] extend=test hl2 thick-50 clip op3= hash=a9cd853f [test hl fill] op0= al_draw_bitmap(bkg, 0, 0, 0) op1= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) op2= op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op4= al_use_transform(trans) op5= op6= al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, #80b24c) op7= al_draw_filled_rectangle(20, -50, 200, 50, #4c3399) op8= al_draw_filled_ellipse(-250, 0, 100, 150, #4c4c4c) op9= al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, #333300) theta=0.5 hash=effa21ee sig=76N6666667PP6667666OP657EF76QPd67EFF7P6c6UDFE66cb6TS6F66cc66766657677576776666766 [test hl fill clip] extend=test hl fill op2=al_set_clipping_rectangle(220, 140, 420, 340) hash=e66f9bb4 [test hl fill nolight] extend=test hl fill op3= hash=fd9ec0e9 [test hl fill subbmp dest] op0= subbmp = al_create_sub_bitmap(target, 60, 60, 540, 380) op1= al_set_target_bitmap(subbmp) op2= al_draw_bitmap(bkg, 0, 0, 0) op3= op4= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op5= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) op6= al_use_transform(trans) op7= al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, #80b24c) op8= al_draw_filled_rectangle(20, -50, 200, 50, #4c3399) op9= al_draw_filled_ellipse(-250, 0, 100, 150, #4c4c4c) op10=al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, #333300) theta=0.5 hash=457ddb11 sig=00000000075666667677QP7757676PP665F97APQY56FE75P7c76EE766bbTSUF776db77777666c7666 [test hl fill subbmp dest clip] extend=test hl fill subbmp dest op3=al_set_clipping_rectangle(220, 140, 300, 200) hash=3b5b2b93 [test circle] op0=al_clear_to_color(#884444) op1=al_draw_circle(200, 150, 100, #66aa0080, 10) op2=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE) op3=al_draw_circle(350, 250, 200, #00aaaa80, 50) op4=al_draw_filled_circle(250, 175, 75, #aa660080) hash=484ad11f [test small arc crash] op0=al_build_transform(t, 100, 100, scale, scale, 0.0) scale=0.005 op1=al_use_transform(t) op2=al_draw_ellipse(0, 0, 32, 16, red, 2) op3=al_draw_rounded_rectangle(50.5, 0.5, 100.5, 50.5, 5, 5, green, 3) op4=al_draw_filled_rounded_rectangle(0, 100, 50, 150, 5, 5, blue) op5=al_draw_arc(100, 100, 50, 0, 1.7, yellow, 4) hash=f2391dc5 [test filled notex blend] op0= op1=al_draw_bitmap(bkg, 0, 0, 0) op2=al_build_transform(t, 320, 240, 1, 1, 1.0) op3=al_use_transform(t) op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op5=al_draw_prim(vtx_notex, 0, 0, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) op6=al_draw_prim(vtx_notex, 0, 0, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) op7=al_draw_prim(vtx_notex, 0, 0, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) hash=1312b9c9 sig=766666666766P66766656657K776767676667666975I5666LK556766KPJ6766657NJ7576776666766 [test filled notex opaque] extend=test filled notex blend op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) hash=2ac96499 sig=766666666766I66766656657E776767676667666775B5666FE556766EID6766657GC7576776666766 [test filled textured blend] op0= op1=al_draw_bitmap(bkg, 0, 0, 0) op2=al_build_transform(t, 320, 240, 1, 1, 1.0) op3=al_use_transform(t) op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op5=al_draw_prim(vtx_tex, 0, tex, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) op6=al_draw_prim(vtx_tex, 0, tex, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) op7=al_draw_prim(vtx_tex, 0, tex, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) tex=texture hash=04d0ae2f sig=766666666766B66766656657977676767666766687585666NP556766RXS6766657fR7576776666766 [test filled textured blend clip] extend=test filled textured blend op0=al_set_clipping_rectangle(150, 80, 340, 280) hash=4b485162 sig=000000000006B66700006657900006767600006687500006NP550000RXS6700000000000000000000 [test filled textured opaque] extend=test filled textured blend op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) hash=67cc8955 sig=766666666766466766656657377676767666766677515666IK556766LTN6766657cK7576776666766 [test filled textured opaque clip] extend=test filled textured opaque op0=al_set_clipping_rectangle(150, 80, 340, 280) hash=42db2b52 sig=000000000006466700006657300006767600006677500006IK550000LTN6700000000000000000000 [test filled subtexture blend] # Note: sub-bitmap textures may not repeat/tile. op0=tex = al_create_sub_bitmap(obp, 70, 60, 322, 303) op1=al_draw_bitmap(bkg, 0, 0, 0) op2=al_build_transform(t, 320, 240, 1, 1, 1.0) op3=al_use_transform(t) op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) op5=al_draw_prim(vtx_tex2, 0, tex, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) op6=al_draw_prim(vtx_tex2, 0, tex, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) op7=al_draw_prim(vtx_tex2, 0, tex, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) hash=891747fe sig=766666666766J66766656657D776767676667666A75G5666ML556766NNK6766657MM7576776666766 [test filled subtexture opaque] extend=test filled subtexture blend op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) hash=325bf4a2 sig=766666666766C66766656657777676767666766687595666GF556766GHE6766657GE7576776666766 [test filled textured solid non-white tint] op0= op1=al_draw_bitmap(bkg, 0, 0, 0) op2=al_build_transform(t, 320, 240, 1, 1, 1.0) op3=al_use_transform(t) op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op5=al_draw_prim(vtx_tex3, 0, texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) hash=e16da3fc sig=7666666667666667666566576776767676667666675656669A556766ACA6766657FA7576776666766 [test filled textured subbmp dest] op0=al_clear_to_color(gray) op1=sub = al_create_sub_bitmap(target, 30, 150, 400, 300) op2=al_set_target_bitmap(sub) op3=al_clear_to_color(orange) op4= op5=al_build_transform(Tsub, 300, 10, 5, 4, 1.0) op6=al_use_transform(Tsub) op7=al_draw_prim(vtx_tex, 0, texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) hash=19fb34dc sig=WWWWWWWWWWWWWWWWWWWWWWWWWWWZZZZgZWWWZZY7bZWWWZgEM5ZWWWgUaHAeWWWP8gUf7WWWCUEgNgWWW [test filled textured subbmp dest clip] extend=test filled textured subbmp dest op4=al_set_clipping_rectangle(50, 50, 300, 200) hash=49c3d736 [test div-by-zero] # This test used to cause a division-by-zero. op0=al_build_transform(t, 320, 240, 1, 1, theta) op1=al_use_transform(t) op2=al_draw_prim(vtx_divbyzero, 0, texture, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN) theta=4.84207964 hash=a95ea313 sig=0000000000000Ca000000EgW00000bBgSK0000TWPYa0000NMgEX00000gbX000000MM0000000000000 [test pieslice] # 5.1 additions scheduled to be backported to 5.0.6 op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op1=al_draw_pieslice(160, 240, 100, 1.0, 6.0, blue, 10) op2=al_draw_pieslice(160, 240, 100, 1.0, 6.0, yellow, 1) op3=al_draw_filled_pieslice(480, 240, 200, 1.0, 1.5, #aa333388) op4=al_draw_filled_pieslice(480, 240, 200, 2.0, 1.5, #33aa3399) op5=al_draw_filled_pieslice(480, 240, 200, 3.0, 1.5, #3333aa88) hash=64ef5e16 sig=00000000000000C6000OO0CCC005002ICC00C00IIII0030O1DDI300NN0DICC000000ICC0000000CC0 [test elliptical arc] # 5.1 addition scheduled to be backported to 5.0.6 op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) op1=al_draw_elliptical_arc(160, 240, 50, 100, -1.5, 4.5, #ff5555aa, 50) op2=al_draw_elliptical_arc(160, 240, 50, 100, 2.0, 4.5, #55ff55aa, 40) op3=al_draw_elliptical_arc(160, 240, 50, 100, 2.0, 4.5, yellow, 0) op4=al_draw_elliptical_arc(440, 240, 100, 50, -1.5, 4.5, #ff5555aa, 10) op5=al_draw_elliptical_arc(440, 240, 100, 50, 2.0, 4.5, #55ff55aa, 20) op6=al_draw_elliptical_arc(440, 240, 100, 50, 2.0, 4.5, yellow, 1) hash=6a88fcfc [vtx_ll] v0 = 200.000000, 0.000000, 0.000000; 128.000000, 0.000000; #408000 v1 = 177.091202, 92.944641, 0.000000; 113.338371, 59.484570; #800040 v2 = 113.612938, 164.596771, 0.000000; 72.712280, 105.341934; #004080 v3 = 24.107338, 198.541779, 0.000000; 15.428697, 127.066742; #408000 v4 = -70.920990, 187.003250, 0.000000; -45.389435, 119.682083; #800040 v5 =-149.702148, 132.624527, 0.000000; -95.809372, 84.879700; #004080 v6 =-194.188370, 47.863136, 0.000000; -124.280556, 30.632408; #408000 v7 =-194.188354, -47.863167, 0.000000; -124.280548, -30.632427; #800040 v8 =-149.702133, -132.624557, 0.000000; -95.809364, -84.879715; #004080 v9 = -70.920914, -187.003265, 0.000000; -45.389385, -119.682091; #408000 v10= 24.107349, -198.541779, 0.000000; 15.428703, -127.066742; #800040 v11= 113.612984, -164.596741, 0.000000; 72.712311, -105.341911; #004080 v12= 177.091202, -92.944641, 0.000000; 113.338371, -59.484570; #408000 [vtx_ll_white] v0 = 200.000000, 0.000000, 0.000000; 128.000000, 0.000000; #ffffff v1 = 177.091202, 92.944641, 0.000000; 113.338371, 59.484570; #ffffff v2 = 113.612938, 164.596771, 0.000000; 72.712280, 105.341934; #ffffff v3 = 24.107338, 198.541779, 0.000000; 15.428697, 127.066742; #ffffff v4 = -70.920990, 187.003250, 0.000000; -45.389435, 119.682083; #ffffff v5 =-149.702148, 132.624527, 0.000000; -95.809372, 84.879700; #ffffff v6 =-194.188370, 47.863136, 0.000000; -124.280556, 30.632408; #ffffff v7 =-194.188354, -47.863167, 0.000000; -124.280548, -30.632427; #ffffff v8 =-149.702133, -132.624557, 0.000000; -95.809364, -84.879715; #ffffff v9 = -70.920914, -187.003265, 0.000000; -45.389385, -119.682091; #ffffff v10= 24.107349, -198.541779, 0.000000; 15.428703, -127.066742; #ffffff v11= 113.612984, -164.596741, 0.000000; 72.712311, -105.341911; #ffffff v12= 177.091202, -92.944641, 0.000000; 113.338371, -59.484570; #ffffff [vtx_notex] v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #408000 v1 = 190.211304, 61.803402, 0.000000; 0.000000, 0.000000; #804040 v2 = 121.352547, 88.167786, 0.000000; 0.000000, 0.000000; #000080 v3 = 117.557053, 161.803406, 0.000000; 0.000000, 0.000000; #408000 v4 = 46.352547, 142.658478, 0.000000; 0.000000, 0.000000; #804040 v5 = -0.000009, 200.000000, 0.000000; 0.000000, 0.000000; #000080 v6 = -46.352554, 142.658478, 0.000000; 0.000000, 0.000000; #408000 v7 = -117.557037, 161.803406, 0.000000; 0.000000, 0.000000; #804040 v8 = -121.352547, 88.167778, 0.000000; 0.000000, 0.000000; #000080 v9 = -190.211304, 61.803406, 0.000000; 0.000000, 0.000000; #408000 v10= -150.000000, -0.000013, 0.000000; 0.000000, 0.000000; #804040 v11= -190.211304, -61.803394, 0.000000; 0.000000, 0.000000; #000080 v12= -121.352539, -88.167801, 0.000000; 0.000000, 0.000000; #408000 v13= -117.557083, -161.803360, 0.000000; 0.000000, 0.000000; #804040 v14= -46.352562, -142.658478, 0.000000; 0.000000, 0.000000; #000080 v15= 0.000002, -200.000000, 0.000000; 0.000000, 0.000000; #408000 v16= 46.352570, -142.658478, 0.000000; 0.000000, 0.000000; #804040 v17= 117.557098, -161.803360, 0.000000; 0.000000, 0.000000; #000080 v18= 121.352539, -88.167793, 0.000000; 0.000000, 0.000000; #408000 v19= 190.211304, -61.803391, 0.000000; 0.000000, 0.000000; #804040 v20= 150.000000, 0.000026, 0.000000; 0.000000, 0.000000; #000080 [vtx_tex] v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #ffffff v1 = 190.211304, 61.803402, 0.000000; 121.735237, 39.554176; #ffffff v2 = 121.352547, 88.167786, 0.000000; 77.665627, 56.427383; #ffffff v3 = 117.557053, 161.803406, 0.000000; 75.236511, 103.554176; #ffffff v4 = 46.352547, 142.658478, 0.000000; 29.665630, 91.301422; #ffffff v5 = -0.000009, 200.000000, 0.000000; -0.000006, 128.000000; #ffffff v6 = -46.352554, 142.658478, 0.000000; -29.665634, 91.301422; #ffffff v7 = -117.557037, 161.803406, 0.000000; -75.236504, 103.554176; #ffffff v8 = -121.352547, 88.167778, 0.000000; -77.665627, 56.427380; #ffffff v9 = -190.211304, 61.803406, 0.000000; -121.735237, 39.554180; #ffffff v10= -150.000000, -0.000013, 0.000000; -96.000000, -0.000008; #804040 v11= -190.211304, -61.803394, 0.000000; -121.735237, -39.554173; #000080 v12= -121.352539, -88.167801, 0.000000; -77.665627, -56.427391; #408000 v13= -117.557083, -161.803360, 0.000000; -75.236534, -103.554153; #804040 v14= -46.352562, -142.658478, 0.000000; -29.665640, -91.301422; #000080 v15= 0.000002, -200.000000, 0.000000; 0.000002, -128.000000; #408000 v16= 46.352570, -142.658478, 0.000000; 29.665644, -91.301422; #804040 v17= 117.557098, -161.803360, 0.000000; 75.236542, -103.554153; #000080 v18= 121.352539, -88.167793, 0.000000; 77.665627, -56.427387; #408000 v19= 190.211304, -61.803391, 0.000000; 121.735237, -39.554169; #804040 v20= 150.000000, 0.000026, 0.000000; 96.000000, 0.000017; #000080 [vtx_tex2] v0 = 0.000000, 0.000000, 0.000000; 161.000000, 151.500000; #ffffff v1 = 190.211304, 61.803402, 0.000000; 314.120087, 198.316071; #ffffff v2 = 121.352547, 88.167786, 0.000000; 258.688812, 218.287094; #ffffff v3 = 117.557053, 161.803406, 0.000000; 255.633423, 274.066071; #ffffff v4 = 46.352547, 142.658478, 0.000000; 198.313797, 259.563782; #ffffff v5 = -0.000009, 200.000000, 0.000000; 161.000000, 303.000000; #ffffff v6 = -46.352554, 142.658478, 0.000000; 123.686195, 259.563782; #ffffff v7 = -117.557037, 161.803406, 0.000000; 66.366585, 274.066071; #ffffff v8 = -121.352547, 88.167778, 0.000000; 63.311199, 218.287094; #ffffff v9 = -190.211304, 61.803406, 0.000000; 7.879900, 198.316086; #ffffff v10= -150.000000, -0.000013, 0.000000; 40.250000, 151.499985; #804040 v11= -190.211304, -61.803394, 0.000000; 7.879900, 104.683929; #000080 v12= -121.352539, -88.167801, 0.000000; 63.311207, 84.712891; #408000 v13= -117.557083, -161.803360, 0.000000; 66.366547, 28.933954; #804040 v14= -46.352562, -142.658478, 0.000000; 123.686188, 43.436203; #000080 v15= 0.000002, -200.000000, 0.000000; 161.000000, 0.000000; #408000 v16= 46.352570, -142.658478, 0.000000; 198.313812, 43.436203; #804040 v17= 117.557098, -161.803360, 0.000000; 255.633469, 28.933954; #000080 v18= 121.352539, -88.167793, 0.000000; 258.688782, 84.712898; #408000 v19= 190.211304, -61.803391, 0.000000; 314.120087, 104.683929; #804040 v20= 150.000000, 0.000026, 0.000000; 281.750000, 151.500015; #000080 [vtx_tex3] # All vertices have same non-white colour. v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #ff883366 v1 = 190.211304, 61.803402, 0.000000; 121.735237, 39.554176; #ff883366 v2 = 121.352547, 88.167786, 0.000000; 77.665627, 56.427383; #ff883366 v3 = 117.557053, 161.803406, 0.000000; 75.236511, 103.554176; #ff883366 v4 = 46.352547, 142.658478, 0.000000; 29.665630, 91.301422; #ff883366 v5 = -0.000009, 200.000000, 0.000000; -0.000006, 128.000000; #ff883366 v6 = -46.352554, 142.658478, 0.000000; -29.665634, 91.301422; #ff883366 [vtx_divbyzero] v0= 200.000000, 0.000000, 0.000000; 128.00, 0.0; #ffffff v1= 0.000000, 200.000000, 0.000000; 0.0, 128.0; #ffffff v2= -200.000000, 0.000000, 0.000000; -128.0, 0.0; #ffffff v3= 0.000000, -200.000000, 0.000000; 0.0, -128.0; #ffffff allegro-5.0.10/tests/test_backbuffer.ini0000644000175000001440000000461711721436075017420 0ustar tjadenusers[bitmaps] allegro=../examples/data/allegro.pcx mysha=../examples/data/mysha.pcx # Test backbuffer to backbuffer. # Self-blitting support is not scheduled for 5.0.0. #[test bb2bb] #op0=al_draw_bitmap(allegro, 0, 0, 0) #op1=al_draw_bitmap_region(target, 0, 0, 320, 200, 100, 100, flags) #flags=0 #hash=BROKEN #[test bb2bb hflip] #extend=test bb2bb #flags=ALLEGRO_FLIP_HORIZONTAL #hash=BROKEN #[test bb2bb vflip] #extend=test bb2bb #flags=ALLEGRO_FLIP_VERTICAL #hash=BROKEN #[test bb2bb vhflip] #extend=test bb2bb #flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL #hash=BROKEN # Test drawing backbuffer to non-backbuffer bitmaps. [test bbsrc] op0=al_draw_bitmap(mysha, 0, 0, 0) op1=bmp = al_create_bitmap(400, 300) op2=al_set_target_bitmap(bmp) op3=al_clear_to_color(yellow) op4=al_draw_bitmap(target, 0, 0, flags) op5=al_set_target_bitmap(target) op6=al_draw_bitmap(bmp, 200, 150, 0) flags=0 hash=a22aae19 [test bbsrc translate] extend=test bbsrc op4=al_draw_bitmap(target, 160, 100, flags) hash=9cf6fa5d [test bbsrc outside] extend=test bbsrc op4=al_draw_bitmap(target, -160, -100, flags) hash=882edf64 # In Allegro 5.0.0, tinting as well as blending is ignored when the # source bitmap is the screen (and locking is not used). [test bbsrc tint] extend=test bbsrc op4=al_draw_tinted_bitmap(target, #008000, 0, 0, flags) hash=a47a96d4 hash_hw=a22aae19 # Support for transforming the back-buffer is not on the feature list # for 5.0.0. #[test bbsrc hflip] #extend=test bbsrc #flags=ALLEGRO_FLIP_HORIZONTAL #[test bbsrc vflip] #extend=test bbsrc #flags=ALLEGRO_FLIP_VERTICAL #[test bbsrc vhflip] #extend=test bbsrc #flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL #[test bbsrc scale] #extend=test bbsrc #op4=al_draw_scaled_bitmap(target, 0, 0, 320, 200, 0, 0, 640, 480, flags) #[test bbsrc scale hflip] #extend=test bbsrc scale #flags=ALLEGRO_FLIP_HORIZONTAL #[test bbsrc scale vflip] #extend=test bbsrc scale #flags=ALLEGRO_FLIP_VERTICAL #[test bbsrc scale vhflip] #extend=test bbsrc scale #flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL #[test bbsrc rotate] #extend=test bbsrc #op4=al_draw_rotated_bitmap(target, 0, 0, 0, 0, 0.2, flags) #[test bbsrc rotate hflip] #extend=test bbsrc rotate #flags=ALLEGRO_FLIP_HORIZONTAL #[test bbsrc rotate vflip] #extend=test bbsrc rotate #flags=ALLEGRO_FLIP_VERTICAL #[test bbsrc rotate vhflip] #extend=test bbsrc rotate #flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL allegro-5.0.10/cmake/0000755000175000001440000000000012157230720013465 5ustar tjadenusersallegro-5.0.10/cmake/Toolchain-mingw.cmake0000644000175000001440000000602612027214721017531 0ustar tjadenusers# Use this command to build the Windows port of Allegro # with a mingw cross compiler: # # cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-mingw.cmake . # # or for out of source: # # cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw.cmake .. # # You will need at least CMake 2.6.0. # # Adjust the following paths to suit your environment. # # This file was based on http://www.cmake.org/Wiki/CmakeMingw # the name of the target operating system set(CMAKE_SYSTEM_NAME Windows) # Assume the target architecture. # XXX for some reason the value set here gets cleared before we reach the # main CMakeLists.txt; see that file for a workaround. # set(CMAKE_SYSTEM_PROCESSOR i686) # Which compilers to use for C and C++, and location of target # environment. if(EXISTS /usr/i586-mingw32msvc) # First look in standard location as used by Debian/Ubuntu/etc. set(CMAKE_C_COMPILER i586-mingw32msvc-gcc) set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) set(CMAKE_RC_COMPILER i586-mingw32msvc-windres) set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc) elseif(EXISTS /usr/i686-w64-mingw32) # First look in standard location as used by Debian/Ubuntu/etc. set(CMAKE_C_COMPILER i686-w64-mingw32-gcc) set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) set(CMAKE_AR:FILEPATH /usr/bin/i686-w64-mingw32-ar) elseif(EXISTS /opt/mingw) # You can get a MinGW environment using the script at . # It downloads and builds MinGW and most of the dependencies for you. # You can use the toolchain file generated by MXE called `mxe-conf.cmake' # or you can use this file by adjusting the above and following paths. set(CMAKE_C_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-gcc) set(CMAKE_CXX_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-g++) set(CMAKE_RC_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-windres) set(CMAKE_FIND_ROOT_PATH /opt/mingw/usr/i686-pc-mingw32) else() # Else fill in local path which the user will likely adjust. # This is the location assumed by set(CMAKE_C_COMPILER /usr/local/cross-tools/bin/i386-mingw32-gcc) set(CMAKE_CXX_COMPILER /usr/local/cross-tools/bin/i386-mingw32-g++) set(CMAKE_RC_COMPILER /usr/local/cross-tools/bin/i386-mingw32-windres) set(CMAKE_FIND_ROOT_PATH /usr/local/cross-tools) endif() # Adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Tell pkg-config not to look at the target environment's .pc files. # Setting PKG_CONFIG_LIBDIR sets the default search directory, but we have to # set PKG_CONFIG_PATH as well to prevent pkg-config falling back to the host's # path. set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig) set(ENV{PKG_CONFIG_PATH} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig) set(ENV{MINGDIR} ${CMAKE_FIND_ROOT_PATH}) allegro-5.0.10/cmake/FileList.cmake0000644000175000001440000001365212132132453016206 0ustar tjadenusersset(ALLEGRO_SRC_FILES src/allegro.c src/bitmap.c src/bitmap_draw.c src/bitmap_io.c src/bitmap_lock.c src/bitmap_pixel.c src/blenders.c src/config.c src/convert.c src/debug.c src/display.c src/display_settings.c src/drawing.c src/dtor.c src/events.c src/evtsrc.c src/exitfunc.c src/file.c src/file_slice.c src/file_stdio.c src/fshook.c src/fshook_stdio.c src/fullscreen_mode.c src/inline.c src/joynu.c src/keybdnu.c src/libc.c src/math.c src/memblit.c src/memdraw.c src/memory.c src/monitor.c src/mousenu.c src/mouse_cursor.c src/path.c src/pixels.c src/system.c src/threads.c src/timernu.c src/tls.c src/transformations.c src/tri_soft.c src/utf8.c src/misc/aatree.c src/misc/bstrlib.c src/misc/list.c src/misc/vector.c ) set(ALLEGRO_SRC_WIN_FILES src/win/wjoydrv.c src/win/wjoydxnu.c src/win/wkeyboard.c src/win/wmcursor.c src/win/wmouse.c src/win/wsystem.c src/win/wthread.c src/win/wtime.c src/win/wunicode.c src/win/wwindow.c src/win/wxthread.c ) set(ALLEGRO_SRC_D3D_FILES src/win/d3d_bmp.cpp src/win/d3d_disp.cpp src/win/d3d_display_formats.cpp ) set(ALLEGRO_SRC_OPENGL_FILES src/opengl/extensions.c src/opengl/ogl_bitmap.c src/opengl/ogl_draw.c src/opengl/ogl_display.c ) set(ALLEGRO_SRC_WGL_FILES src/win/wgl_disp.c ) set(ALLEGRO_SRC_UNIX_FILES src/unix/udrvlist.c src/unix/ufdwatch.c src/unix/ugfxdrv.c src/unix/ujoydrv.c src/unix/ukeybd.c src/unix/umouse.c src/unix/upath.c src/unix/utime.c src/unix/uxthread.c ) set(ALLEGRO_SRC_X_FILES src/x/xcursor.c src/x/xdisplay.c src/x/xevents.c src/x/xfullscreen.c src/x/xglx_config.c src/x/xkeyboard.c src/x/xmousenu.c src/x/xrandr.c src/x/xsystem.c src/x/xwindow.c src/linux/ljoynu.c ) set(ALLEGRO_SRC_MACOSX_FILES src/macosx/hidjoy.m src/macosx/hidjoy-10.4.m src/macosx/hidman.m src/macosx/keybd.m src/macosx/qzmouse.m src/macosx/system.m src/macosx/osxgl.m src/macosx/osx_app_delegate.m src/unix/utime.c src/unix/uxthread.c ) set(ALLEGRO_SRC_GP2XWIZ_FILES src/gp2xwiz/wiz_display_opengl.c src/gp2xwiz/wiz_display_fb.c src/gp2xwiz/wiz_system.c src/gp2xwiz/wiz_joystick.c src/optimized.c src/linux/ljoynu.c ) set(ALLEGRO_SRC_IPHONE_FILES src/iphone/allegroAppDelegate.m src/iphone/EAGLView.m src/iphone/iphone_display.c src/iphone/iphone_joystick.m src/iphone/iphone_keyboard.c src/iphone/iphone_main.m src/iphone/iphone_mouse.m src/iphone/iphone_path.m src/iphone/iphone_system.c src/unix/utime.c src/unix/uxthread.c ) set(ALLEGRO_INCLUDE_ALLEGRO_FILES include/allegro5/allegro5.h include/allegro5/allegro.h include/allegro5/alcompat.h include/allegro5/alinline.h include/allegro5/altime.h include/allegro5/base.h include/allegro5/bitmap.h include/allegro5/bitmap_draw.h include/allegro5/bitmap_io.h include/allegro5/bitmap_lock.h include/allegro5/blender.h include/allegro5/color.h include/allegro5/config.h include/allegro5/debug.h include/allegro5/display.h include/allegro5/drawing.h include/allegro5/error.h include/allegro5/events.h include/allegro5/file.h include/allegro5/fixed.h include/allegro5/fmaths.h include/allegro5/fshook.h include/allegro5/fullscreen_mode.h include/allegro5/joystick.h include/allegro5/keyboard.h include/allegro5/keycodes.h include/allegro5/memory.h include/allegro5/monitor.h include/allegro5/mouse.h include/allegro5/mouse_cursor.h include/allegro5/path.h include/allegro5/allegro_opengl.h include/allegro5/allegro_direct3d.h include/allegro5/system.h include/allegro5/threads.h include/allegro5/tls.h include/allegro5/timer.h include/allegro5/transformations.h include/allegro5/utf8.h ) set(ALLEGRO_INCLUDE_ALLEGRO_INLINE_FILES include/allegro5/inline/fmaths.inl ) set(ALLEGRO_INCLUDE_ALLEGRO_INTERNAL_FILES # Only files which need to be installed. include/allegro5/internal/alconfig.h ) set(ALLEGRO_INCLUDE_ALLEGRO_OPENGL_FILES include/allegro5/opengl/gl_ext.h ) set(ALLEGRO_INCLUDE_ALLEGRO_OPENGL_GLEXT_FILES include/allegro5/opengl/GLext/gl_ext_alias.h include/allegro5/opengl/GLext/gl_ext_defs.h include/allegro5/opengl/GLext/glx_ext_alias.h include/allegro5/opengl/GLext/glx_ext_defs.h include/allegro5/opengl/GLext/wgl_ext_alias.h include/allegro5/opengl/GLext/wgl_ext_defs.h include/allegro5/opengl/GLext/gl_ext_api.h include/allegro5/opengl/GLext/gl_ext_list.h include/allegro5/opengl/GLext/glx_ext_api.h include/allegro5/opengl/GLext/glx_ext_list.h include/allegro5/opengl/GLext/wgl_ext_api.h include/allegro5/opengl/GLext/wgl_ext_list.h ) set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES # Only files which need to be installed. include/allegro5/platform/albcc32.h include/allegro5/platform/aliphone.h include/allegro5/platform/aliphonecfg.h include/allegro5/platform/almngw32.h include/allegro5/platform/almsvc.h include/allegro5/platform/alosx.h include/allegro5/platform/alosxcfg.h include/allegro5/platform/alucfg.h include/allegro5/platform/alunix.h include/allegro5/platform/alwatcom.h include/allegro5/platform/alwin.h include/allegro5/platform/astdbool.h include/allegro5/platform/astdint.h ) set(ALLEGRO_INCLUDE_ALLEGRO_WINDOWS_FILES include/allegro5/allegro_windows.h ) set(ALLEGRO_INCLUDE_ALLEGRO_MACOSX_FILES include/allegro5/allegro_osx.h ) set(ALLEGRO_INCLUDE_ALLEGRO_IPHONE_FILES include/allegro5/allegro_iphone.h ) set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES_GENERATED include/allegro5/platform/alplatf.h ) allegro-5.0.10/cmake/FindDXGuid.cmake0000644000175000001440000000121111621646216016415 0ustar tjadenusers# - Find dxguid # Find the dxguid libraries # # DXGUID_LIBRARIES - List of libraries # DXGUID_FOUND - True if dxguid found. find_library(DXGUID_LIBRARY NAMES dxguid HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" ) # Handle the QUIETLY and REQUIRED arguments and set DXGUID_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DXGUID DEFAULT_MSG DXGUID_LIBRARY) if(DXGUID_FOUND) set(DXGUID_LIBRARIES ${DXGUID_LIBRARY}) else(DXGUID_FOUND) set(DXGUID_LIBRARIES) endif(DXGUID_FOUND) mark_as_advanced(DXGUID_INCLUDE_DIR DXGUID_LIBRARY) allegro-5.0.10/cmake/FindDSound.cmake0000644000175000001440000000167411621646216016502 0ustar tjadenusers# - Find DirectSound # Find the DirectSound includes and libraries # # DSOUND_INCLUDE_DIR - where to find dsound.h # DSOUND_LIBRARIES - List of libraries when using dsound. # DSOUND_FOUND - True if dsound found. if(DSOUND_INCLUDE_DIR) # Already in cache, be silent set(DSOUND_FIND_QUIETLY TRUE) endif(DSOUND_INCLUDE_DIR) find_path(DSOUND_INCLUDE_DIR dsound.h HINTS "$ENV{DXSDK_DIR}/Include" ) find_library(DSOUND_LIBRARY NAMES dsound HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" ) # Handle the QUIETLY and REQUIRED arguments and set DSOUND_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DSOUND DEFAULT_MSG DSOUND_INCLUDE_DIR DSOUND_LIBRARY) if(DSOUND_FOUND) set(DSOUND_LIBRARIES ${DSOUND_LIBRARY}) else(DSOUND_FOUND) set(DSOUND_LIBRARIES) endif(DSOUND_FOUND) mark_as_advanced(DSOUND_INCLUDE_DIR DSOUND_LIBRARY) allegro-5.0.10/cmake/FindDInput.cmake0000644000175000001440000000167511621646216016512 0ustar tjadenusers# - Find DirectSound # Find the DirectSound includes and libraries # # DINPUT_INCLUDE_DIR - where to find dinput.h # DINPUT_LIBRARIES - List of libraries when using dinput. # DINPUT_FOUND - True if dinput found. if(DINPUT_INCLUDE_DIR) # Already in cache, be silent set(DINPUT_FIND_QUIETLY TRUE) endif(DINPUT_INCLUDE_DIR) find_path(DINPUT_INCLUDE_DIR dinput.h HINTS "$ENV{DXSDK_DIR}/Include" ) find_library(DINPUT_LIBRARY NAMES dinput8 HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" ) # Handle the QUIETLY and REQUIRED arguments and set DINPUT_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DINPUT DEFAULT_MSG DINPUT_INCLUDE_DIR DINPUT_LIBRARY) if(DINPUT_FOUND) set(DINPUT_LIBRARIES ${DINPUT_LIBRARY}) else(DINPUT_FOUND) set(DINPUT_LIBRARIES) endif(DINPUT_FOUND) mark_as_advanced(DINPUT_INCLUDE_DIR DINPUT_LIBRARY) allegro-5.0.10/cmake/FindD3D9.cmake0000644000175000001440000000160711621646216015745 0ustar tjadenusers# - Find Direct3D 9 # Find the Direct3D9 includes and libraries # # D3D9_INCLUDE_DIR - where to find d3d9.h # D3D9_LIBRARIES - List of libraries when using D3D9. # D3D9_FOUND - True if D3D9 found. if(D3D9_INCLUDE_DIR) # Already in cache, be silent set(D3D9_FIND_QUIETLY TRUE) endif(D3D9_INCLUDE_DIR) find_path(D3D9_INCLUDE_DIR d3d9.h HINTS "$ENV{DXSDK_DIR}/Include" ) find_library(D3D9_LIBRARY NAMES d3d9 HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" ) # Handle the QUIETLY and REQUIRED arguments and set D3D9_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(D3D9 DEFAULT_MSG D3D9_INCLUDE_DIR D3D9_LIBRARY) if(D3D9_FOUND) set(D3D9_LIBRARIES ${D3D9_LIBRARY}) else(D3D9_FOUND) set(D3D9_LIBRARIES) endif(D3D9_FOUND) mark_as_advanced(D3D9_INCLUDE_DIR D3D9_LIBRARY) allegro-5.0.10/cmake/FindDUMB.cmake0000644000175000001440000000157411356273250016033 0ustar tjadenusers# - Find DUMB # Find the native DUMB includes and libraries # # DUMB_INCLUDE_DIR - where to find DUMB headers. # DUMB_LIBRARIES - List of libraries when using libDUMB. # DUMB_FOUND - True if libDUMB found. if(DUMB_INCLUDE_DIR) # Already in cache, be silent set(DUMB_FIND_QUIETLY TRUE) endif(DUMB_INCLUDE_DIR) find_path(DUMB_INCLUDE_DIR dumb.h) find_library(DUMB_LIBRARY NAMES dumb) if(NOT ${DUMB_LIBRARY}) find_library(DUMB_LIBRARY NAMES libdumb) endif(NOT ${DUMB_LIBRARY}) # Handle the QUIETLY and REQUIRED arguments and set DUMB_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DUMB DEFAULT_MSG DUMB_INCLUDE_DIR DUMB_LIBRARY) if(DUMB_FOUND) set(DUMB_LIBRARIES ${DUMB_LIBRARY}) else(DUMB_FOUND) set(DUMB_LIBRARIES) endif(DUMB_FOUND) mark_as_advanced(DUMB_INCLUDE_DIR DUMB_LIBRARY) allegro-5.0.10/cmake/Toolchain-iphone.cmake0000644000175000001440000000011611655352637017703 0ustar tjadenusersSET (IPHONE 1) SET (SDKROOT "iphoneos") SET (CMAKE_OSX_SYSROOT "${SDKROOT}") allegro-5.0.10/cmake/FindTremor.cmake0000644000175000001440000000156312027210262016540 0ustar tjadenusers# - Find Tremor # # TREMOR_INCLUDE_DIR - where to find Tremor headers. # TREMOR_LIBRAY - List of libraries when using libTremor. # TREMOR_FOUND - True if Tremor found. if(TREMOR_INCLUDE_DIR) # Already in cache, be silent set(TREMOR_FIND_QUIETLY TRUE) endif(TREMOR_INCLUDE_DIR) find_path(TREMOR_INCLUDE_DIR tremor/ivorbisfile.h) find_library(TREMOR_LIBRARY NAMES vorbisidec) # Handle the QUIETLY and REQUIRED arguments and set TREMOR_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(TREMOR DEFAULT_MSG TREMOR_INCLUDE_DIR TREMOR_LIBRARY) mark_as_advanced(TREMOR_INCLUDE_DIR TREMOR_LIBRARY) if(TREMOR_FOUND) set(TREMOR_LIBRARIES ${TREMOR_LIBRARY} ${OGG_LIBRARY}) else(TREMOR_FOUND) set(TREMOR_LIBRARIES) endif(TREMOR_FOUND) mark_as_advanced(TREMOR_INCLUDE_DIR TREMOR_LIBRARY) allegro-5.0.10/cmake/FindVorbis.cmake0000644000175000001440000000321111721433553016536 0ustar tjadenusers# - Find vorbis # Find the native vorbis includes and libraries # # VORBIS_INCLUDE_DIR - where to find vorbis.h, etc. # VORBIS_LIBRARIES - List of libraries when using vorbis(file). # VORBIS_FOUND - True if vorbis found. if(VORBIS_INCLUDE_DIR) # Already in cache, be silent set(VORBIS_FIND_QUIETLY TRUE) endif(VORBIS_INCLUDE_DIR) if(NOT GP2XWIZ) find_package(Ogg) if(OGG_FOUND) find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h) # MSVC built vorbis may be named vorbis_static # The provided project files name the library with the lib prefix. find_library(VORBIS_LIBRARY NAMES vorbis vorbis_static libvorbis libvorbis_static) find_library(VORBISFILE_LIBRARY NAMES vorbisfile vorbisfile_static libvorbisfile libvorbisfile_static) # Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND # to TRUE if all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(VORBIS DEFAULT_MSG VORBIS_INCLUDE_DIR VORBIS_LIBRARY VORBISFILE_LIBRARY) endif(OGG_FOUND) else(NOT GP2XWIZ) find_path(VORBIS_INCLUDE_DIR tremor/ivorbisfile.h) find_library(VORBIS_LIBRARY NAMES vorbis_dec) find_package_handle_standard_args(VORBIS DEFAULT_MSG VORBIS_INCLUDE_DIR VORBIS_LIBRARY) endif(NOT GP2XWIZ) if(VORBIS_FOUND) if(NOT GP2XWIZ) set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY}) else(NOT GP2XWIZ) set(VORBIS_LIBRARIES ${VORBIS_LIBRARY}) endif(NOT GP2XWIZ) else(VORBIS_FOUND) set(VORBIS_LIBRARIES) endif(VORBIS_FOUND) mark_as_advanced(VORBIS_INCLUDE_DIR) mark_as_advanced(VORBIS_LIBRARY VORBISFILE_LIBRARY) allegro-5.0.10/cmake/FindOgg.cmake0000644000175000001440000000152111721433553016010 0ustar tjadenusers# - Find ogg # Find the native ogg includes and libraries # # OGG_INCLUDE_DIR - where to find ogg.h, etc. # OGG_LIBRARIES - List of libraries when using ogg. # OGG_FOUND - True if ogg found. if(OGG_INCLUDE_DIR) # Already in cache, be silent set(OGG_FIND_QUIETLY TRUE) endif(OGG_INCLUDE_DIR) find_path(OGG_INCLUDE_DIR ogg/ogg.h) # MSVC built ogg may be named ogg_static. # The provided project files name the library with the lib prefix. find_library(OGG_LIBRARY NAMES ogg ogg_static libogg libogg_static) # Handle the QUIETLY and REQUIRED arguments and set OGG_FOUND # to TRUE if all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(OGG DEFAULT_MSG OGG_INCLUDE_DIR OGG_LIBRARY) set(OGG_LIBRARIES ${OGG_LIBRARY}) mark_as_advanced(OGG_INCLUDE_DIR) mark_as_advanced(OGG_LIBRARY) allegro-5.0.10/cmake/FindD3DX9.cmake0000644000175000001440000000147511621646262016101 0ustar tjadenusers# - Find Direct3D 9 Extensions # Find the Direct3D9 Extensions includes and libraries # # D3DX9_INCLUDE_DIR - where to find d3d9x.h # D3DX9_LIBRARIES - List of libraries when using D3DX9. # D3DX9_FOUND - True if D3DX9 found. if(D3DX9_INCLUDE_DIR) # Already in cache, be silent set(D3DX9_FIND_QUIETLY TRUE) endif(D3DX9_INCLUDE_DIR) find_path(D3DX9_INCLUDE_DIR d3dx9.h HINTS "$ENV{DXSDK_DIR}/Include" ) find_library(D3DX9_LIBRARY NAMES d3dx9 HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" ) # Handle the QUIETLY and REQUIRED arguments and set D3D9X_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(D3DX9 DEFAULT_MSG D3DX9_INCLUDE_DIR D3DX9_LIBRARY) mark_as_advanced(D3DX9_INCLUDE_DIR D3DX9_LIBRARY) allegro-5.0.10/cmake/AllegroFindOSS.cmake0000644000175000001440000000432711062755053017255 0ustar tjadenusers# - Find Open Sound System # # OSS_FOUND - True if OSS headers found. # This file is Allegro-specific and requires the following variables to be # set elsewhere: # ALLEGRO_HAVE_MACHINE_SOUNDCARD_H # ALLEGRO_HAVE_LINUX_SOUNDCARD_H # ALLEGRO_HAVE_SYS_SOUNDCARD_H # ALLEGRO_HAVE_SOUNDCARD_H if(OSS_INCLUDE_DIR) # Already in cache, be silent set(OSS_FIND_QUIETLY TRUE) endif(OSS_INCLUDE_DIR) set(CMAKE_REQUIRED_DEFINITIONS) if(ALLEGRO_HAVE_SOUNDCARD_H OR ALLEGRO_HAVE_SYS_SOUNDCARD_H OR ALLEGRO_HAVE_MACHINE_SOUNDCARD_H OR ALLEGRO_LINUX_SYS_SOUNDCARD_H) if(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) set(CMAKE_REQUIRED_DEFINITIONS -DALLEGRO_HAVE_MACHINE_SOUNDCARD_H) endif(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) if(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DALLEGRO_HAVE_LINUX_SOUNDCARD_H) endif(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) if(ALLEGRO_HAVE_SYS_SOUNDCARD_H) set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DALLEGRO_HAVE_SYS_SOUNDCARD_H) endif(ALLEGRO_HAVE_SYS_SOUNDCARD_H) if(ALLEGRO_HAVE_SOUNDCARD_H) set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DALLEGRO_HAVE_SOUNDCARD_H) endif(ALLEGRO_HAVE_SOUNDCARD_H) check_c_source_compiles(" #ifdef ALLEGRO_HAVE_SOUNDCARD_H #include #endif #ifdef ALLEGRO_HAVE_SYS_SOUNDCARD_H #include #endif #ifdef ALLEGRO_HAVE_LINUX_SOUNDCARD_H #include #endif #ifdef ALLEGRO_HAVE_MACHINE_SOUNDCARD_H #include #endif int main(void) { audio_buf_info abi; return 0; }" OSS_COMPILES ) set(CMAKE_REQUIRED_DEFINITIONS) endif(ALLEGRO_HAVE_SOUNDCARD_H OR ALLEGRO_HAVE_SYS_SOUNDCARD_H OR ALLEGRO_HAVE_MACHINE_SOUNDCARD_H OR ALLEGRO_LINUX_SYS_SOUNDCARD_H) # Handle the QUIETLY and REQUIRED arguments and set OSS_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(OSS DEFAULT_MSG OSS_COMPILES) mark_as_advanced(OSS_COMPILES) allegro-5.0.10/cmake/Common.cmake0000644000175000001440000002425612114120561015722 0ustar tjadenusersfunction(set_our_header_properties) foreach(file ${ARGN}) # Infer which subdirectory this header file should be installed. set(loc ${file}) string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" loc ${loc}) string(REGEX REPLACE "^include/" "" loc ${loc}) string(REGEX REPLACE "/[-A-Za-z0-9_]+[.](h|inl)$" "" loc ${loc}) # If we have inferred correctly then it should be under allegro5. string(REGEX MATCH "^allegro5" matched ${loc}) if(matched STREQUAL "allegro5") # MACOSX_PACKAGE_LOCATION is also used in install_our_headers. set_source_files_properties(${file} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/${loc} ) else() message(FATAL_ERROR "Could not infer where to install ${file}") endif() endforeach(file) endfunction(set_our_header_properties) function(append_lib_type_suffix var) string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_TOLOWER) if(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug") set(${var} "${${var}}-debug" PARENT_SCOPE) endif(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug") if(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile") set(${var} "${${var}}-profile" PARENT_SCOPE) endif(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile") endfunction(append_lib_type_suffix) function(append_lib_linkage_suffix var) if(NOT BUILD_SHARED_LIBS) set(${var} "${${var}}-static" PARENT_SCOPE) endif(NOT BUILD_SHARED_LIBS) endfunction(append_lib_linkage_suffix) # Oh my. CMake really is bad for this - but I couldn't find a better # way. function(sanitize_cmake_link_flags ...) SET(return) foreach(lib ${ARGV}) # Watch out for -framework options (OS X) IF (NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework") # Remove absolute path. string(REGEX REPLACE "/.*/(.*)" "\\1" lib ${lib}) # Remove .a/.so/.dylib. string(REGEX REPLACE "lib(.*)\\.a" "\\1" lib ${lib}) string(REGEX REPLACE "lib(.*)\\.so" "\\1" lib ${lib}) string(REGEX REPLACE "lib(.*)\\.dylib" "\\1" lib ${lib}) # Remove -l prefix if it's there already. string(REGEX REPLACE "-l(.*)" "\\1" lib ${lib}) # Make sure we don't include our own libraries. # FIXME: Use a global list instead of a very unstable regexp. IF(NOT lib MATCHES "allegro_.*" AND NOT lib STREQUAL "allegro" AND NOT lib STREQUAL "allegro_audio") set(return "${return} -l${lib}") ENDIF() ENDIF(NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework") endforeach(lib) set(return ${return} PARENT_SCOPE) endfunction(sanitize_cmake_link_flags) function(add_our_library target sources extra_flags link_with) # BUILD_SHARED_LIBS controls whether this is a shared or static library. add_library(${target} ${sources}) if(NOT BUILD_SHARED_LIBS) set(static_flag "-DALLEGRO_STATICLINK") endif(NOT BUILD_SHARED_LIBS) set_target_properties(${target} PROPERTIES COMPILE_FLAGS "${extra_flags} ${static_flag} -DALLEGRO_LIB_BUILD" VERSION ${ALLEGRO_VERSION} SOVERSION ${ALLEGRO_SOVERSION} ) # Construct the output name. set(output_name ${target}) append_lib_type_suffix(output_name) append_lib_linkage_suffix(output_name) set_target_properties(${target} PROPERTIES OUTPUT_NAME ${output_name} ) # Put version numbers on DLLs but not on import libraries nor static # archives. Make MinGW not add a lib prefix to DLLs, to match MSVC. if(WIN32 AND SHARED) set_target_properties(${target} PROPERTIES PREFIX "" SUFFIX -${ALLEGRO_SOVERSION}.dll IMPORT_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX} ) endif() # Suppress errors about _mangled_main_address being undefined on Mac OS X. if(MACOSX) set_target_properties(${target} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress" ) endif(MACOSX) # Specify a list of libraries to be linked into the specified target. # Library dependencies are transitive by default. Any target which links # with this target will therefore pull in these dependencies automatically. target_link_libraries(${target} ${link_with}) # Set list of dependencies that the user would need to explicitly link with # if static linking. sanitize_cmake_link_flags(${link_with}) set_target_properties(${target} PROPERTIES static_link_with "${return}" ) endfunction(add_our_library) function(set_our_framework_properties target nm) if(WANT_FRAMEWORKS) if(WANT_EMBED) set(install_name_dir "@executable_path/../Frameworks") else() set(install_name_dir "${FRAMEWORK_INSTALL_PREFIX}") endif(WANT_EMBED) set_target_properties(${target} PROPERTIES FRAMEWORK on OUTPUT_NAME ${nm} INSTALL_NAME_DIR "${install_name_dir}" ) endif(WANT_FRAMEWORKS) endfunction(set_our_framework_properties) function(install_our_library target) install(TARGETS ${target} LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}" FRAMEWORK DESTINATION "${FRAMEWORK_INSTALL_PREFIX}" RUNTIME DESTINATION "bin" # Doesn't work, see below. # PUBLIC_HEADER DESTINATION "include" ) endfunction(install_our_library) # Unfortunately, CMake's PUBLIC_HEADER support doesn't install into nested # directories well, otherwise we could rely on install(TARGETS) to install # header files associated with the target. Instead we use the install(FILES) # to install headers. We reuse the MACOSX_PACKAGE_LOCATION property, # substituting the "Headers" prefix with "include". function(install_our_headers) if(NOT WANT_FRAMEWORKS) foreach(hdr ${ARGN}) get_source_file_property(LOC ${hdr} MACOSX_PACKAGE_LOCATION) string(REGEX REPLACE "^Headers" "include" LOC ${LOC}) install(FILES ${hdr} DESTINATION ${LOC}) endforeach() endif() endfunction(install_our_headers) function(fix_executable nm) if(IPHONE) string(REPLACE "_" "" bundle_nm ${nm}) set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.${bundle_nm}") # FIXME:We want those as project attributes, not target attributes, but I don't know how set_target_properties(${nm} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer") # We have to add an icon to every executable on IPhone else # cmake won't create a resource copy build phase for us. # And re-creating those by hand would be a major pain. set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_ICON_FILE icon.png) set_source_files_properties("${CMAKE_SOURCE_DIR}/misc/icon.png" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) endif(IPHONE) endfunction(fix_executable) # Arguments after nm should be source files, libraries, or defines (-D). # Source files must end with .c or .cpp. If no source file was explicitly # specified, we assume an implied C source file. # # Free variable: EXECUTABLE_TYPE # function(add_our_executable nm) set(srcs) set(libs) set(defines) set(regex "[.](c|cpp)$") set(regexd "^-D") foreach(arg ${ARGN}) if("${arg}" MATCHES "${regex}") list(APPEND srcs ${arg}) else("${arg}" MATCHES "${regex}") if ("${arg}" MATCHES "${regexd}") string(REGEX REPLACE "${regexd}" "" arg "${arg}") list(APPEND defines ${arg}) else("${arg}" MATCHES "${regexd}") list(APPEND libs ${arg}) endif("${arg}" MATCHES "${regexd}") endif("${arg}" MATCHES "${regex}") endforeach(arg ${ARGN}) if(NOT srcs) set(srcs "${nm}.c") endif(NOT srcs) if(IPHONE) set(EXECUTABLE_TYPE MACOSX_BUNDLE) set(srcs ${srcs} "${CMAKE_SOURCE_DIR}/misc/icon.png") endif(IPHONE) add_executable(${nm} ${EXECUTABLE_TYPE} ${srcs}) target_link_libraries(${nm} ${libs}) if(WANT_POPUP_EXAMPLES AND SUPPORT_NATIVE_DIALOG) list(APPEND defines ALLEGRO_POPUP_EXAMPLES) endif() if(NOT BUILD_SHARED_LIBS) list(APPEND defines ALLEGRO_STATICLINK) endif(NOT BUILD_SHARED_LIBS) foreach(d ${defines}) set_property(TARGET ${nm} APPEND PROPERTY COMPILE_DEFINITIONS ${d}) endforeach(d ${defines}) if(MINGW) if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) set_target_properties(${nm} PROPERTIES LINK_FLAGS "-Wl,-subsystem,windows") endif(NOT CMAKE_BUILD_TYPE STREQUAL Debug) endif(MINGW) fix_executable(${nm}) endfunction(add_our_executable) # Recreate data directory for out-of-source builds. # Note: a symlink is unsafe as make clean will delete the contents # of the pointed-to directory. # # Files are only copied if they don't are inside a .svn folder so we # won't end up with read-only .svn folders in the build folder. function(copy_data_dir_to_build target name destination) if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") return() endif() file(GLOB_RECURSE allfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${name}/*) set(files) # Filter out files inside .svn folders. foreach(file ${allfiles}) string(REGEX MATCH .*\\.svn.* is_svn ${file}) if("${is_svn}" STREQUAL "") list(APPEND files ${file}) endif() endforeach(file) add_custom_target(${target} ALL DEPENDS ${files}) foreach(file ${files}) add_custom_command( OUTPUT "${destination}/${file}" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${file}" COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${file}" ${file} ) endforeach(file) endfunction(copy_data_dir_to_build) #-----------------------------------------------------------------------------# # vim: set ft=cmake sts=4 sw=4 et: allegro-5.0.10/cmake/FindGDIPLUS.cmake0000644000175000001440000000212111452605425016400 0ustar tjadenusers# - Find GDI+ # Find the GDI+ includes and libraries # # GDIPLUS_INCLUDE_DIR - where to find gdiplus.h # GDIPLUS_LIBRARIES - List of libraries when using GDI+. # GDIPLUS_FOUND - True if GDI+ found. if(GDIPLUS_INCLUDE_DIR) # Already in cache, be silent set(GDIPLUS_FIND_QUIETLY TRUE) endif(GDIPLUS_INCLUDE_DIR) find_path(GDIPLUS_INCLUDE_DIR NAMES GdiPlus.h gdiplus.h) if(EXISTS ${GDIPLUS_INCLUDE_DIR}/GdiPlus.h) set(GDIPLUS_LOWERCASE 0 CACHE INTERNAL "Is GdiPlus.h spelt with lowercase?") else() set(GDIPLUS_LOWERCASE 1 CACHE INTERNAL "Is GdiPlus.h spelt with lowercase?") endif() find_library(GDIPLUS_LIBRARY NAMES gdiplus) # Handle the QUIETLY and REQUIRED arguments and set GDIPLUS_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GDIPLUS DEFAULT_MSG GDIPLUS_INCLUDE_DIR GDIPLUS_LIBRARY) if(GDIPLUS_FOUND) set(GDIPLUS_LIBRARIES ${GDIPLUS_LIBRARY}) else(GDIPLUS_FOUND) set(GDIPLUS_LIBRARIES) endif(GDIPLUS_FOUND) mark_as_advanced(GDIPLUS_INCLUDE_DIR GDIPLUS_LIBRARY GDIPLUS_LOWERCASE) allegro-5.0.10/cmake/Toolchain-openwiz.cmake0000644000175000001440000000052011234331176020077 0ustar tjadenusersSET(GP2XWIZ on) SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_C_COMPILER arm-openwiz-linux-gnu-gcc) SET(CMAKE_CXX_COMPILER arm-openwiz-linux-gnu-g++) SET(CMAKE_FIND_ROOT_PATH /home/trent/arm-openwiz-linux-gnu) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) allegro-5.0.10/cmake/FindFLAC.cmake0000644000175000001440000000222211621646317016003 0ustar tjadenusers# - Find FLAC # Find the native FLAC includes and libraries # # FLAC_INCLUDE_DIR - where to find FLAC headers. # FLAC_LIBRARIES - List of libraries when using libFLAC. # FLAC_FOUND - True if libFLAC found. if(FLAC_INCLUDE_DIR) # Already in cache, be silent set(FLAC_FIND_QUIETLY TRUE) endif(FLAC_INCLUDE_DIR) find_path(FLAC_INCLUDE_DIR FLAC/stream_decoder.h) # MSVC built libraries can name them *_static, which is good as it # distinguishes import libraries from static libraries with the same extension. find_library(FLAC_LIBRARY NAMES FLAC libFLAC libFLAC_dynamic libFLAC_static) find_library(OGG_LIBRARY NAMES ogg ogg_static libogg libogg_static) # Handle the QUIETLY and REQUIRED arguments and set FLAC_FOUND to TRUE if # all listed variables are TRUE. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FLAC DEFAULT_MSG FLAC_INCLUDE_DIR OGG_LIBRARY FLAC_LIBRARY) if(FLAC_FOUND) set(FLAC_LIBRARIES ${FLAC_LIBRARY} ${OGG_LIBRARY}) if(WIN32) set(FLAC_LIBRARIES ${FLAC_LIBRARIES} wsock32) endif(WIN32) else(FLAC_FOUND) set(FLAC_LIBRARIES) endif(FLAC_FOUND) mark_as_advanced(FLAC_INCLUDE_DIR FLAC_LIBRARY) allegro-5.0.10/python/0000755000175000001440000000000012157230745013735 5ustar tjadenusersallegro-5.0.10/python/CMakeLists.txt0000644000175000001440000000207711617372671016510 0ustar tjadenusersinclude(FindPythonInterp) if(WIN32) add_custom_command( OUTPUT python_protos DEPENDS ${ALL_SRC} COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/python/checkdocs.py -c ${CMAKE_C_COMPILER} -p python_protos -b ${CMAKE_BINARY_DIR} -s ${CMAKE_SOURCE_DIR} -w ) else(WIN32) add_custom_command( OUTPUT python_protos DEPENDS ${ALL_SRC} COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/python/checkdocs.py -p python_protos -b ${CMAKE_BINARY_DIR} -s ${CMAKE_SOURCE_DIR} ) endif(WIN32) SET(release "") append_lib_type_suffix(release) append_lib_linkage_suffix(release) SET(version "${ALLEGRO_SOVERSION}") add_custom_command( OUTPUT allegro.py DEPENDS python_protos COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/python/generate_python_ctypes.py -p python_protos -o allegro.py -t \"${release}\" -v \"${version}\" ) add_custom_target(python ALL DEPENDS allegro.py ) allegro-5.0.10/python/generate_python_ctypes.py0000755000175000001440000003775512152730216021106 0ustar tjadenusers#!/usr/bin/env python import sys import re import optparse from ctypes import * """ This script will use the prototypes from "checkdocs.py -s" to concoct a 1:1 Python wrapper for Allegro. """ class _AL_UTF8String: pass class Allegro: def __init__(self): self.types = {} self.functions = {} self.constants = {} def add_struct(self, name): x = type(name, (Structure, ), {}) self.types[name] = x def add_union(self, name): x = type(name, (Union, ), {}) self.types[name] = x def get_type(self, ptype): conversion = { "bool": c_bool, "_Bool": c_bool, "char": c_byte, "unsignedchar": c_ubyte, "int": c_int, "unsigned": c_uint, "unsignedint": c_uint, "int16_t": c_int16, "int32_t": c_int32, "uint32_t": c_uint32, "int64_t": c_int64, "uint64_t": c_uint64, "uintptr_t": c_void_p, "intptr_t": c_void_p, "GLuint": c_uint, "unsignedlong": c_ulong, "long": c_long, "size_t": c_size_t, "off_t": c_int64, "time_t": c_int64, "va_list": c_void_p, "float": c_float, "double": c_double, "al_fixed": c_int, "HWND": c_void_p, "char*": _AL_UTF8String, # hack: this probably shouldn't be in the public docs "postprocess_callback_t": c_void_p, } ptype = re.sub(r"\bconst\b", "", ptype) ptype = re.sub(r"\extern\b", "", ptype) ptype = re.sub(r"\__inline__\b", "", ptype) ptype = re.sub(r"\s+", "", ptype) if ptype.endswith("*"): if ptype in conversion: return conversion[ptype] t = ptype[:-1] if t in self.types: return POINTER(self.types[t]) return c_void_p elif ptype in self.types: return self.types[ptype] else: try: return conversion[ptype] except KeyError: print("Error:" + str(ptype)) return None def parse_funcs(self, funcs): """ Go through all documented functions and add their prototypes as Python functions. The file should have been generated by Allegro's documentation generation scripts. """ for func in funcs: name, proto = func.split(":", 1) if not name.startswith("al_"): continue proto = proto.strip() name = name[:-2] if proto.startswith("enum"): continue if proto.startswith("typedef"): continue if "=" in proto: continue if proto.startswith("#"): continue funcstart = proto.find(name) funcend = funcstart + len(name) ret = proto[:funcstart].rstrip() params = proto[funcend:].strip(" ;") if params[0] != "(" or params[-1] != ")": print("Error:") print(params) continue params2 = params[1:-1] # remove callback argument lists balance = 0 params = "" for c in params2: if c == ")": balance -= 1 if balance == 0: params += c if c == "(": balance += 1 params = params.split(",") plist = [] for param in params: param = re.sub(r"\bconst\b", "", param) param = param.strip() if param == "void": continue if param == "": continue if param == "...": continue # treat arrays as a void pointer, for now if param.endswith("]") or param.endswith("*"): plist.append(c_void_p) continue # treat callbacks as a void pointer, for now if param.endswith(")"): plist.append(c_void_p) continue mob = re.match("^.*?(\w+)$", param) if mob: pnamepos = mob.start(1) if pnamepos == 0: # Seems the parameter is not named pnamepos = len(param) else: print(params) print(proto) print("") continue ptype = param[:pnamepos] ptype = self.get_type(ptype) plist.append(ptype) f = type("", (object, ), {"restype": c_int}) if not ret.endswith("void"): f.restype = self.get_type(ret) try: f.argtypes = plist except TypeError, e: print(e) print(name) print(plist) self.functions[name] = f def parse_protos(self, filename): protos = [] unions = [] funcs = [] # first pass: create all structs, but without fields for line in open(filename): name, proto = line.split(":", 1) proto = proto.lstrip() if name.endswith("()"): funcs.append(line) continue # anonymous structs have no name at all if name and not name.startswith("ALLEGRO_"): continue if name == "ALLEGRO_OGL_EXT_API": continue if proto.startswith("union") or\ proto.startswith("typedef union"): self.add_union(name) unions.append((name, proto)) elif proto.startswith("struct") or\ proto.startswith("typedef struct"): self.add_struct(name) protos.append((name, proto)) elif proto.startswith("enum") or\ proto.startswith("typedef enum"): if name: self.types[name] = c_int protos.append(("", proto)) elif proto.startswith("#define"): if not name.startswith("_") and not name.startswith("GL_"): i = eval(proto.split(None, 2)[2]) self.constants[name] = i else: # actual typedef mob = re.match("typedef (.*) " + name, proto) if mob: t = mob.group(1) self.types[name] = self.get_type(t.strip()) else: # Probably a function pointer self.types[name] = c_void_p # Unions must come last because they finalize the fields. protos += unions # second pass: fill in fields for name, proto in protos: bo = proto.find("{") if bo == -1: continue bc = proto.rfind("}") braces = proto[bo + 1:bc] if proto.startswith("enum") or \ proto.startswith("typedef enum"): fields = braces.split(",") i = 0 for field in fields: if "=" in field: fname, val = field.split("=", 1) fname = fname.strip() try: i = int(eval(val, globals(), self.constants)) except NameError: i = val else: fname = field.strip() if not fname: continue self.constants[fname] = i try: i += 1 except TypeError: pass continue balance = 0 fields = [""] for c in braces: if c == "{": balance += 1 if c == "}": balance -= 1 if c == ";" and balance == 0: fields.append("") else: fields[-1] += c flist = [] for field in fields: if not field: continue # add function pointer as void pointer mob = re.match(".*?\(\*(\w+)\)", field) if mob: flist.append((mob.group(1), "c_void_p")) continue # add any pointer as void pointer mob = re.match(".*?\*(\w+)$", field) if mob: flist.append((mob.group(1), "c_void_p")) continue # add an array mob = re.match("(.*)( \w+)\[(.*?)\]$", field) if mob: # this is all a hack n = 0 ftype = mob.group(1) if ftype.startswith("struct"): if ftype == "struct {float axis[3];}": t = "c_float * 3" else: print("Error: Can't parse " + ftype + " yet.") t = None else: n = mob.group(3) # something in A5 uses a 2d array if "][" in n: n = n.replace("][", " * ") # something uses a division expression if "/" in n: n = "(" + n.replace("/", "//") + ")" t = self.get_type(ftype).__name__ + " * " + n fname = mob.group(2) flist.append((fname, t)) continue vars = field.split(",") mob = re.match("\s*(.*?)\s+(\w+)\s*$", vars[0]) t = self.get_type(mob.group(1)) flist.append((mob.group(2), t.__name__)) for v in vars[1:]: flist.append((v.strip(), t.__name__)) try: self.types[name].my_fields = flist except AttributeError: print(name, flist) self.parse_funcs(funcs) def main(): p = optparse.OptionParser() p.add_option("-o", "--output", help="location of generated file") p.add_option("-p", "--protos", help="A file with all " + "prototypes to generate Python wrappers for, one per line. " "Generate it with docs/scripts/checkdocs.py -p") p.add_option("-t", "--type", help="the library type to " + "use, e.g. debug") p.add_option("-v", "--version", help="the library version to " + "use, e.g. 5.1") options, args = p.parse_args() if not options.protos: p.print_help() return al = Allegro() al.parse_protos(options.protos) f = open(options.output, "w") if options.output else sys.stdout release = options.type version = options.version f.write(r"""# Generated by generate_python_ctypes.py. import os, platform, sys from ctypes import * from ctypes.util import * # You must adjust this function to point ctypes to the A5 DLLs you are # distributing. _dlls = [] def _add_dll(name): release = "%(release)s" if os.name == "nt": release = "%(release)s-%(version)s" # Under Windows, DLLs are found in the current directory, so this # would be an easy way to keep all your DLLs in a sub-folder. # os.chdir("dlls") path = find_library(name + release) if not path: if os.name == "mac": path = name + release + ".dylib" elif os.name == "nt": path = name + release + ".dll" elif os.name == "posix": if platform.mac_ver()[0]: path = name + release + ".dylib" else: path = "lib" + name + release + ".so" else: sys.stderr.write("Cannot find library " + name + "\n") # In most cases, you actually don't want the above and instead # use the exact filename within your game distribution, possibly # even within a .zip file. # if not os.path.exists(path): # path = "dlls/" + path try: # RTLD_GLOBAL is required under OSX for some reason (?) _dlls.append(CDLL(path, RTLD_GLOBAL)) except OSError: # No need to fail here, might just be one of the addons. pass # os.chdir("..") _add_dll("allegro") _add_dll("allegro_acodec") _add_dll("allegro_audio") _add_dll("allegro_primitives") _add_dll("allegro_color") _add_dll("allegro_font") _add_dll("allegro_ttf") _add_dll("allegro_image") _add_dll("allegro_dialog") _add_dll("allegro_memfile") _add_dll("allegro_physfs") _add_dll("allegro_main") # We don't have information ready which A5 function is in which DLL, # so we just try them all. def _dll(func, ret, params): for dll in _dlls: try: f = dll[func] f.restype = ret f.argtypes = params return f except AttributeError: pass sys.stderr.write("Cannot find function " + func + "\n") return lambda *args: None # In Python3, all Python strings are unicode so we have to convert to # UTF8 byte strings before passing to Allegro. if sys.version_info[0] > 2: class _AL_UTF8String: def from_param(x): return x.encode("utf8") else: _AL_UTF8String = c_char_p """ % locals()) for name, val in sorted(al.constants.items()): if isinstance(val, str): val = int(eval(val, globals(), al.constants)) f.write(name + " = " + str(val) + "\n") for name, x in sorted(al.types.items()): if not name: continue base = x.__bases__[0] if base != Structure and base != Union: f.write(name + " = " + x.__name__ + "\n") for kind in Structure, Union: for name, x in sorted(al.types.items()): if not x: continue base = x.__bases__[0] if base != kind: continue f.write("class " + name + "(" + base.__name__ + "): pass\n") pt = POINTER(x) f.write("%s = POINTER(%s)\n" % (pt.__name__, name)) for name, x in sorted(al.types.items()): base = x.__bases__[0] if base != kind: continue if hasattr(x, "my_fields"): f.write(name + "._fields_ = [\n") for fname, ftype in x.my_fields: f.write(" (\"" + fname + "\", " + ftype + "),\n") f.write(" ]\n") for name, x in sorted(al.functions.items()): try: line = name + " = _dll(\"" + name + "\", " line += x.restype.__name__ + ", " line += "[" + (", ".join([a.__name__ for a in x.argtypes])) +\ "])\n" f.write(line) except AttributeError as e: print("Ignoring " + name + " because of errors (" + str(e) + ").") # some stuff the automated parser doesn't pick up f.write(r""" ALLEGRO_VERSION_INT = \ ((ALLEGRO_VERSION << 24) | (ALLEGRO_SUB_VERSION << 16) | \ (ALLEGRO_WIP_VERSION << 8) | ALLEGRO_RELEASE_NUMBER) """) f.write(r""" # work around bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36834 if os.name == "nt": def al_map_rgba_f(r, g, b, a): return ALLEGRO_COLOR(r, g, b, a) def al_map_rgb_f(r, g, b): return ALLEGRO_COLOR(r, g, b, 1) def al_map_rgba(r, g, b, a): return ALLEGRO_COLOR(r / 255.0, g / 255.0, b / 255.0, a / 255.0) def al_map_rgb(r, g, b): return ALLEGRO_COLOR(r / 255.0, g / 255.0, b / 255.0, 1) """) f.write(""" def al_main(real_main, *args): def python_callback(argc, argv): real_main(*args) return 0 cb = CFUNCTYPE(c_int, c_int, c_void_p)(python_callback) al_run_main(0, 0, cb); """) f.close() main() allegro-5.0.10/python/ex_draw_bitmap.py0000755000175000001440000002464111776322362017311 0ustar tjadenusers#!/usr/bin/env python from __future__ import division import sys, os from random import * from math import * from ctypes import * # Get path to examples data. p = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "examples")) from allegro import * def abort_example(text): sys.stderr.write(text) sys.exit(1) FPS = 60 MAX_SPRITES = 1024 class Sprite: def __init__(self): self.x, self.y, self.dx, self.dy = 0, 0, 0, 0 text = [ "Space - toggle use of textures", "B - toggle alpha blending", "Left/Right - change bitmap size", "Up/Down - change bitmap count", "F1 - toggle help text" ] class Example: sprites = [Sprite() for i in range(MAX_SPRITES)] use_memory_bitmaps = False blending = False display = None mysha = None bitmap = None bitmap_size = 0 sprite_count = 0 show_help = True font = None mouse_down = False last_x, last_y = 0, 0 white = None half_white = None dark = None red = None direct_speed_measure = 1.0 ftpos = 0 frame_times = [0.0] * FPS example = Example() def add_time(): example.frame_times[example.ftpos] = al_get_time() example.ftpos += 1 if example.ftpos >= FPS: example.ftpos = 0 def get_fps(): prev = FPS - 1 min_dt = 1 max_dt = 1 / 1000000 av = 0 for i in range(FPS): if i != example.ftpos: dt = example.frame_times[i] - example.frame_times[prev] if dt < min_dt and dt > 0: min_dt = dt if dt > max_dt: max_dt = dt av += dt prev = i av /= FPS - 1 average = ceil(1 / av) d = 1 / min_dt - 1 / max_dt minmax = floor(d / 2) return average, minmax def add_sprite(): if example.sprite_count < MAX_SPRITES: w = al_get_display_width(example.display) h = al_get_display_height(example.display) i = example.sprite_count example.sprite_count += 1 s = example.sprites[i] a = randint(0, 359) s.x = randint(0, w - example.bitmap_size - 1) s.y = randint(0, h - example.bitmap_size - 1) s.dx = cos(a) * FPS * 2 s.dy = sin(a) * FPS * 2 def add_sprites(n): for i in range(n): add_sprite() def remove_sprites(n): example.sprite_count -= n if example.sprite_count < 0: example.sprite_count = 0 def change_size(size): if size < 1: size = 1 if size > 1024: size = 1024 if example.bitmap: al_destroy_bitmap(example.bitmap) al_set_new_bitmap_flags( ALLEGRO_MEMORY_BITMAP if example.use_memory_bitmaps else 0) example.bitmap = al_create_bitmap(size, size) example.bitmap_size = size al_set_target_bitmap(example.bitmap) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white) al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)) bw = al_get_bitmap_width(example.mysha) bh = al_get_bitmap_height(example.mysha) al_draw_scaled_bitmap(example.mysha, 0, 0, bw, bh, 0, 0, size, size, 0) al_set_target_backbuffer(example.display) def sprite_update(s): w = al_get_display_width(example.display) h = al_get_display_height(example.display) s.x += s.dx / FPS s.y += s.dy / FPS if s.x < 0: s.x = -s.x s.dx = -s.dx if s.x + example.bitmap_size > w: s.x = -s.x + 2 * (w - example.bitmap_size) s.dx = -s.dx if s.y < 0: s.y = -s.y s.dy = -s.dy if s.y + example.bitmap_size > h: s.y = -s.y + 2 * (h - example.bitmap_size) s.dy = -s.dy if example.bitmap_size > w: s.x = w / 2 - example.bitmap_size / 2 if example.bitmap_size > h: s.y = h / 2 - example.bitmap_size / 2 def update(): for i in range(example.sprite_count): sprite_update(example.sprites[i]) def redraw(): w = al_get_display_width(example.display) h = al_get_display_height(example.display) fh = al_get_font_line_height(example.font) info = ["textures", "memory buffers"] binfo = ["alpha", "additive", "tinted", "solid"] tint = example.white if example.blending == 0: al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) tint = example.half_white elif example.blending == 1: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) tint = example.dark elif example.blending == 2: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) tint = example.red elif example.blending == 3: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white) for i in range(example.sprite_count): s = example.sprites[i] al_draw_tinted_bitmap(example.bitmap, tint, s.x, s.y, 0) al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) if example.show_help: for i in range(5): al_draw_text(example.font, example.white, 0, h - 5 * fh + i * fh, 0, text[i]) al_draw_textf(example.font, example.white, 0, 0, 0, "count: %d", example.sprite_count) al_draw_textf(example.font, example.white, 0, fh, 0, "size: %d", example.bitmap_size) al_draw_textf(example.font, example.white, 0, fh * 2, 0, "%s", info[example.use_memory_bitmaps].encode("utf8")) al_draw_textf(example.font, example.white, 0, fh * 3, 0, "%s", binfo[example.blending].encode("utf8")) f1, f2 = get_fps() al_draw_textf(example.font, example.white, w, 0, ALLEGRO_ALIGN_RIGHT, "%s", ("FPS: %4d +- %-4d" % (f1, f2)).encode("utf8")) al_draw_textf(example.font, example.white, w, fh, ALLEGRO_ALIGN_RIGHT, "%s", ("%4d / sec" % int(1.0 / example.direct_speed_measure)).encode("utf8")) def main(): w, h = 640, 480 done = False need_redraw = True example.show_help = True if not al_install_system(ALLEGRO_VERSION_INT, None): abort_example("Failed to init Allegro.\n") sys.exit(1) if not al_init_image_addon(): abort_example("Failed to init IIO addon.\n") sys.exit(1) al_init_font_addon() al_get_num_video_adapters() info = ALLEGRO_MONITOR_INFO() al_get_monitor_info(0, byref(info)) if info.x2 - info.x1 < w: w = info.x2 - info.x1 if info.y2 - info.y1 < h: h = info.y2 - info.y1 example.display = al_create_display(w, h) if not example.display: abort_example("Error creating display.\n") if not al_install_keyboard(): abort_example("Error installing keyboard.\n") if not al_install_mouse(): abort_example("Error installing mouse.\n") example.font = al_load_font(p + "/data/fixed_font.tga", 0, 0) if not example.font: abort_example("Error loading data/fixed_font.tga\n") example.mysha = al_load_bitmap(p + "/data/mysha256x256.png") if not example.mysha: abort_example("Error loading data/mysha256x256.png\n") example.white = al_map_rgb_f(1, 1, 1) example.half_white = al_map_rgba_f(1, 1, 1, 0.5) example.dark = al_map_rgb(15, 15, 15) example.red = al_map_rgb_f(1, 0.2, 0.1) change_size(256) add_sprite() add_sprite() timer = al_create_timer(1.0 / FPS) queue = al_create_event_queue() al_register_event_source(queue, al_get_keyboard_event_source()) al_register_event_source(queue, al_get_mouse_event_source()) al_register_event_source(queue, al_get_timer_event_source(timer)) al_register_event_source(queue, al_get_display_event_source(example.display)) al_start_timer(timer) while not done: event = ALLEGRO_EVENT() if need_redraw and al_is_event_queue_empty(queue): t = -al_get_time() add_time() al_clear_to_color(al_map_rgb_f(0, 0, 0)) redraw() t += al_get_time() example.direct_speed_measure = t al_flip_display() need_redraw = False al_wait_for_event(queue, byref(event)) if event.type == ALLEGRO_EVENT_KEY_CHAR: if event.keyboard.keycode == ALLEGRO_KEY_ESCAPE: done = True elif event.keyboard.keycode == ALLEGRO_KEY_UP: add_sprites(1) elif event.keyboard.keycode == ALLEGRO_KEY_DOWN: remove_sprites(1) elif event.keyboard.keycode == ALLEGRO_KEY_LEFT: change_size(example.bitmap_size - 1) elif event.keyboard.keycode == ALLEGRO_KEY_RIGHT: change_size(example.bitmap_size + 1) elif event.keyboard.keycode == ALLEGRO_KEY_F1: example.show_help ^= 1 elif event.keyboard.keycode == ALLEGRO_KEY_SPACE: example.use_memory_bitmaps ^= 1 change_size(example.bitmap_size) elif event.keyboard.keycode == ALLEGRO_KEY_B: example.blending += 1 if example.blending == 4: example.blending = 0 elif event.type == ALLEGRO_EVENT_DISPLAY_CLOSE: done = True elif event.type == ALLEGRO_EVENT_TIMER: update() need_redraw = True elif event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: example.mouse_down = True example.last_x = event.mouse.x example.last_y = event.mouse.y elif event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP: fh = al_get_font_line_height(example.font) example.mouse_down = False if event.mouse.x < 40 and event.mouse.y >= h - fh * 5: button = (event.mouse.y - (h - fh * 5)) // fh if button == 0: example.use_memory_bitmaps ^= 1 change_size(example.bitmap_size) if button == 1: example.blending += 1 if example.blending == 4: example.blending = 0 if button == 4: example.show_help ^= 1 elif event.type == ALLEGRO_EVENT_MOUSE_AXES: if example.mouse_down: dx = event.mouse.x - example.last_x dy = event.mouse.y - example.last_y if dy > 4: add_sprites(int(dy / 4)) if dy < -4: remove_sprites(-int(dy / 4)) if dx > 4: change_size(example.bitmap_size + dx - 4) if dx < -4: change_size(example.bitmap_size + dx + 4) example.last_x = event.mouse.x example.last_y = event.mouse.y al_destroy_bitmap(example.bitmap) al_uninstall_system() al_main(main) allegro-5.0.10/python/readme.txt0000644000175000001440000000647711440003621015732 0ustar tjadenusers# Python wrapper This wrapper is not a proper Python-Allegro, but a simple 1:1 export of all Allegro functions and constants using ctypes. ## Building Enable WANT_PYTHON_WRAPPER in cmake and you should end up with a single file called allegro.py in the python folder of your build directory. You also need to build the shared version so you end up with either: Windows: liballegro*.dll OSX: liballegro*.dylib Unix: liballegro*.so For simplicity we will simply call those files "DLL files". ## Using it Distribute the allegro.py as well as the required DLL files along with your project. If you want you can modify it to directly point to the DLL files so you can be sure they are found. By default, it will try several system specific locations. E.g. in linux it will find .so files as long as they are in LD_LIBRARY_PATH or in ldconfig paths. For distribution build of your game, this usually means that the .so files are found within your distributions /usr/lib directory. For a standalone distribution, you may provide a shell script which modifies LD_LIBRARY_PATH to point to your game's library folder then runs the python executable. To run the included Python example something like this will work under Linux, starting within the Allegro source distribution folder: mkdir build cd build cmake -D WANT_PYTHON_WRAPPER=1 .. make export PYTHONPATH=python/ export LD_LIBRARY_PATH=lib/ python ../python/ex_draw_bitmap.py We use PYTHONPATH to specify the location of the allegro.py module and LD_LIBRARY_PATH to specify the location of the .so files. For OSX, this should work: mkdir build cd build cmake -D WANT_PYTHON_WRAPPER=1 .. make export PYTHONPATH=python/ export DYLD_LIBRARY_PATH=lib/ python ../python/ex_draw_bitmap.py For Windows: Make sure to have WANT_PYTHON_WRAPPER enabled when building. It doesn't matter whether you use mingw or MSVC, but Python must be installed on your system. Then run ex_draw_bitmap.py. The DLLs as well as allegro.py must be found, easiest is to just have them all in the same directory. Or you can also edit allegro.py and specify a directory from which to load the DLLs - see the comments in there. ## Limitations Right now this is only a proof-of concept implementation, some important things still have to be fixed: ### Variable arguments not parsed properly yet For example, if C code has: al_draw_textf(font, x, y, flags, "%d, %d", x, y); You have to do it like this in Python right now: al_draw_textf(font, x, y, flags, "%s", "%d, %d" % (x, y)) ### No reference counting or garbage collection For example, if you call al_load_bitmap, a C pointer is returned. If it goes out of scope you end up with a memory leak - very unpythonic. Therefore you should do something like this: class Bitmap: def __init__(self, filename): self.c_pointer = al_load_bitmap(filename) def __del__(self): al_destroy_bitmap(self.c_pointer) def draw(self, x, y, flags): al_draw_bitmap(self.c_pointer, x, y, flags); In other words, make a proper Python wrapper. ### No docstrings Even though the documentation system provides the description of each functions it's not copied into allegro.py right now. You will need to use the C documentation until this is fixed. ### Need more examples Or a demo game. It should test that at least each addon can be used. allegro-5.0.10/python/checkdocs.py0000755000175000001440000002303211776331360016241 0ustar tjadenusers#!/usr/bin/env python import optparse import subprocess import sys import os import re import glob links = {} symbols = {} structs = {} types = {} anonymous_enums = {} functions = {} constants = {} def check_references(): """ Check if each [link] in the reference manual actually exists. Also fills in global variable "links". """ print("Checking References...") html_refs = os.path.join(options.build, "docs", "html_refs") for line in open(html_refs): mob = re.match(r"\[(.*?)\]", line) if mob: links[mob.group(1)] = True docs = glob.glob("docs/src/refman/*.txt") for doc in docs: text = file(doc).read() text = re.compile(".*?", re.S).sub("", text) for link in re.findall(r" \[(.*?)\][^(]", text): if not link in links: print("Missing: %s: %s" % (doc, link)) def add_struct(line): if options.protos: kind = re.match("\s*(\w+)", line).group(1) if kind in ["typedef", "struct", "enum", "union"]: mob = None if kind != "typedef": mob = re.match(kind + "\s+(\w+)", line) if not mob: mob = re.match(".*?(\w+);$", line) if not mob and kind == "typedef": mob = re.match("typedef.*?\(\s*\*\s*(\w+)\)", line) if not mob: anonymous_enums[line] = 1 else: sname = mob.group(1) if sname.startswith("_ALLEGRO_gl"): return if kind == "typedef": types[sname] = line else: structs[sname] = line def parse_header(lines, filename): """ Minimal C parser which extracts most symbols from a header. Fills them into the global variable "symbols". """ n = 0 ok = False brace = 0 lines2 = [] cline = "" for line in lines: line = line.strip() if not line: continue if line.startswith("#"): if line.startswith("#define"): if ok: name = line[8:] match = re.match("#define ([a-zA-Z_]+)", line) name = match.group(1) symbols[name] = "macro" simple_constant = line.split() if len(simple_constant) == 3 and\ not "(" in simple_constant[1] and\ simple_constant[2][0].isdigit(): constants[name] = simple_constant[2] n += 1 elif line.startswith("#undef"): pass else: ok = False match = re.match(r'# \d+ "(.*?)"', line) if match: name = match.group(1) if name == "" or name.startswith(options.build) or \ name.startswith("include") or \ name.startswith("addons") or\ name.startswith(options.source): ok = True continue if not ok: continue sublines = line.split(";") for i, subline in enumerate(sublines): if i < len(sublines) - 1: subline += ";" brace -= subline.count("}") brace -= subline.count(")") brace += subline.count("{") brace += subline.count("(") if brace == 0 and subline.endswith(";") or subline.endswith("}"): cline += subline lines2.append(cline.strip()) cline = "" else: cline += subline for line in lines2: line = line.replace("__attribute__((__stdcall__))", "") if line.startswith("enum"): add_struct(line) elif line.startswith("typedef"): match = None if not match: match = re.match(r".*?(\w+);$", line) if not match: match = re.match(r".*?(\w*)\[", line) if not match: match = re.match(r".*?\(\s*\*\s*(\w+)\s*\).*?", line) if match: name = match.group(1) symbols[name] = "typedef" n += 1 else: print("? " + line) add_struct(line) elif line.startswith("struct"): add_struct(line) elif line.startswith("union"): add_struct(line) else: try: parenthesis = line.find("(") if parenthesis < 0: match = re.match(r".*?(\w+)\s*=", line) if not match: match = re.match(r".*?(\w+)\s*;$", line) if not match: match = re.match(r".*?(\w+)", line) symbols[match.group(1)] = "variable" n += 1 else: match = re.match(r".*?(\w+)\s*\(", line) fname = match.group(1) symbols[fname] = "function" if not fname in functions: functions[fname] = line n += 1 except AttributeError, e: print("Cannot parse in " + filename) print("Line is: " + line) print(e) return n def parse_all_headers(): """ Call parse_header() on all of Allegro's public include files. """ p = options.source includes = " -I " + p + "/include -I " + os.path.join(options.build, "include") includes += " -I " + p + "/addons/acodec" headers = [p + "/include/allegro5/allegro.h", p + "/addons/acodec/allegro5/allegro_acodec.h", p + "/include/allegro5/allegro_opengl.h"] if options.windows: headers += [p + "/include/allegro5/allegro_windows.h"] for addon in glob.glob(p + "/addons/*"): name = addon[len(p + "/addons/"):] header = os.path.join(p, "addons", name, "allegro5", "allegro_" + name + ".h") if os.path.exists(header): headers.append(header) includes += " -I " + os.path.join(p, "addons", name) for header in headers: p = subprocess.Popen(options.compiler + " -E -dD - " + includes, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) p.stdin.write("#include \n" + open(header).read()) p.stdin.close() text = p.stdout.read() parse_header(text.splitlines(), header) #print("%d definitions in %s" % (n, header)) def check_undocumented_functions(): """ Cross-compare the documentation links with public symbols found in headers. """ print("Checking if each documented function exists...") parse_all_headers() for link in links: if not link in symbols: print("Missing: " + link) print("") print("Checking if each function is documented...") others = [] for link in symbols: if not link in links: if symbols[link] == "function": print("Missing: " + link) else: if link and not link.startswith("GL") and \ not link.startswith("gl") and \ not link.startswith("_al_gl") and \ not link.startswith("_ALLEGRO_gl") and \ not link.startswith("_ALLEGRO_GL") and \ not link.startswith("ALLEGRO_"): others.append(link) print("Also leaking:") others.sort() print(", ".join(others)) def list_all_symbols(): parse_all_headers() for name in sorted(symbols.keys()): print(name) def main(argv): global options p = optparse.OptionParser() p.description = """\ When run from the toplevel A5 directory, this script will parse the include, addons and cmake build directory for global definitions and check against all references in the documentation - then report symbols which are not documented. """ p.add_option("-b", "--build", help="Path to the build directory.") p.add_option("-c", "--compiler", help="Path to gcc.") p.add_option("-s", "--source", help="Path to the source directory.") p.add_option("-l", "--list", action="store_true", help="List all symbols.") p.add_option("-p", "--protos", help="Write all public " + "prototypes to the given file.") p.add_option("-w", "--windows", action="store_true", help="Include windows specific symbols.") options, args = p.parse_args() if not options.source: options.source = "." if not options.compiler: options.compiler = "gcc" if not options.build: sys.stderr.write("Build path required (-p).\n") p.print_help() sys.exit(-1) if options.protos: parse_all_headers() f = open(options.protos, "w") for name, s in structs.items(): f.write(name + ": " + s + "\n") for name, s in types.items(): f.write(name + ": " + s + "\n") for e in anonymous_enums.keys(): f.write(": " + e + "\n") for fname, proto in functions.items(): f.write(fname + "(): " + proto + "\n") for name, value in constants.items(): f.write(name + ": #define " + name + " " + value + "\n") elif options.list: list_all_symbols() else: check_references() print("") check_undocumented_functions() if __name__ == "__main__": main(sys.argv) allegro-5.0.10/README_pkgconfig.txt0000644000175000001440000000343512123164502016134 0ustar tjadenusersUsing pkg-config with Allegro ============================= On Unix-like operating systems, we use the pkg-config tool to simplify the process of linking with Allegro. To print the list of Allegro libraries installed, you can run: pkg-config --list-all | grep allegro You may need to set the PKG_CONFIG_PATH environment variable appropriately if you installed to a non-standard location. To print the command line options required to link with the core Allegro library and the image addon, you would run: pkg-config --libs allegro-5 allegro_image-5 which outputs something like: -L/usr/lib -lallegro_image -lallegro This can be combined with shell command substitution: gcc mygame.c -o mygame $(pkg-config --libs allegro-5 allegro_image-5) If Allegro is installed to a non-standard location, the compiler will need command line options to find the header files. The pkg-config `--cflags` option provides that information. You can combine it with `--libs` as well: pkg-config --cflags --libs allegro-5 allegro_image-5 Most build systems will allow you to call pkg-config in a similar way to the shell. For example, a very basic Makefile might look like this: ALLEGRO_LIBRARIES := allegro-5 allegro_image-5 ALLEGRO_FLAGS := $(shell pkg-config --cflags --libs $(ALLEGRO_LIBRARIES)) mygame: mygame.c $(CC) -o $@ $^ $(ALLEGRO_FLAGS) Historical note --------------- Prior to Allegro 5.0.9 the .pc files were named allegro-5.0.pc and so on. To ease transitioning to future versions of Allegro the minor version number was dropped, leaving allegro-5.pc and so on. The old names are deprecated but will remain available in 5.0.x releases. Configuration scripts should look for Allegro using the new pkg-config names first, then the old names, for greater compatibility. allegro-5.0.10/misc/0000755000175000001440000000000012157230751013344 5ustar tjadenusersallegro-5.0.10/misc/utod.sh0000755000175000001440000000164211004511615014650 0ustar tjadenusers#!/bin/sh # # Convert LF line endings to CR/LF line endings, preserving timestamps and # permissions on the file. # with_unix_tools() { for file in "$@" do echo "$file" tmpfile=`dirname "$file"`/__dtou_tmp.$RANDOM || exit 1 trap 'rm -f "$tmpfile"' 1 2 3 13 15 # We go through a slightly convoluted sequence of commands in order to # preserve both the timestamp and permissions on the file. { perl -p -e "s/([^\r]|^)\n/\1\r\n/" "$file" > "$tmpfile" && touch -r "$file" "$tmpfile" && cat "$tmpfile" > "$file" && touch -r "$tmpfile" "$file" && rm -f "$tmpfile" } || exit 1 done } with_cygwin() { for file in "$@" do unix2dos $file || exit 1 done } if test -z "$1" then echo "$0 filename" exit fi if test "$ALLEGRO_USE_CYGWIN" = "1" then with_cygwin "$@" else with_unix_tools "$@" fi # vi: sts=3 sw=3 et allegro-5.0.10/misc/dtou.sh0000755000175000001440000000161611004511615014651 0ustar tjadenusers#!/bin/sh # # Convert CR/LF line endings to LF line endings, preserving timestamps and # permissions on the file. # with_unix_tools() { for file in "$@" do echo "$file" tmpfile=`dirname "$file"`/__dtou_tmp.$RANDOM || exit 1 trap 'rm -f "$tmpfile"' 1 2 3 13 15 # We go through a slightly convoluted sequence of commands in order to # preserve both the timestamp and permissions on the file. { tr -d '\015' < "$file" > "$tmpfile" && touch -r "$file" "$tmpfile" && cat "$tmpfile" > "$file" && touch -r "$tmpfile" "$file" && rm -f "$tmpfile" } || exit 1 done } with_cygwin() { for file in "$@" do dos2unix $file || exit 1 done } if test -z "$1" then echo "$0 filename" exit fi if test "$ALLEGRO_USE_CYGWIN" = "1" then with_cygwin "$@" else with_unix_tools "$@" fi # vi: sts=3 sw=3 et allegro-5.0.10/misc/gl_mkalias.sh0000755000175000001440000000102711244236510016001 0ustar tjadenusers#!/bin/sh # This script createi '*_ext_alias.h' from '*_ext_api.h' in # include/allegro5/opengl/GLext/ dir prefix="glx wgl gl" for name in $prefix; do src="include/allegro5/opengl/GLext/"$name"_ext_api.h" out="include/allegro5/opengl/GLext/"$name"_ext_alias.h" prfx=`echo $name | sed 's/glx/glX/'` cat $src | sed -e '/^[ ]*#/!s/[ ]//g' | awk -F"," "BEGIN{print\"/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/\"} {if (\$0 ~ /^AGL_API/) printf \"#define $prfx%s _al_$prfx%s\n\",\$2,\$2; else print \$0}" > $out done allegro-5.0.10/misc/make_scanline_drawers.py0000755000175000001440000003173412146021714020244 0ustar tjadenusers#!/usr/bin/env python # # Generate the routines to draw each scanline of a primitive. # Run: # python misc/make_scanline_drawers.py | indent -kr -i3 -l0 > src/scanline_drawers.inc import sys, re # http://code.activestate.com/recipes/502257/ def interp(string): locals = sys._getframe(1).f_locals globals = sys._getframe(1).f_globals for item in re.findall(r'#\{([^}]*)\}', string): string = string.replace('#{%s}' % item, str(eval(item, globals, locals))) return string def make_drawer(name): global texture, grad, solid, shade, opaque, white texture = "_texture_" in name grad = "_grad_" in name solid = "_solid_" in name shade = "_shade" in name opaque = "_opaque" in name white = "_white" in name if grad and solid: raise Exception("grad and solid") if grad and white: raise Exception("grad and white") if shade and opaque: raise Exception("shade and opaque") print interp("static void #{name} (uintptr_t state, int x1, int y, int x2) {") if not texture: if grad: print """\ state_grad_any_2d *gs = (state_grad_any_2d *)state; state_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; """ else: print """\ state_solid_any_2d *s = (state_solid_any_2d *)state; ALLEGRO_COLOR cur_color = s->cur_color; """ else: if grad: print """\ state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *)state; state_texture_solid_any_2d *s = &gs->solid; ALLEGRO_COLOR cur_color = s->cur_color; """ else: print """\ state_texture_solid_any_2d *s = (state_texture_solid_any_2d *)state; """ print """\ float u = s->u; float v = s->v; """ # XXX still don't understand why y-1 is required print """\ ALLEGRO_BITMAP *target = s->target; if (target->parent) { x1 += target->xofs; x2 += target->xofs; y += target->yofs; target = target->parent; } x1 -= target->lock_x; x2 -= target->lock_x; y -= target->lock_y; y--; if (y < 0 || y >= target->lock_h) { return; } if (x1 < 0) { """ if texture: print """\ u += s->du_dx * -x1; v += s->dv_dx * -x1; """ if grad: print """\ cur_color.r += gs->color_dx.r * -x1; cur_color.g += gs->color_dx.g * -x1; cur_color.b += gs->color_dx.b * -x1; cur_color.a += gs->color_dx.a * -x1; """ print """\ x1 = 0; } if (x2 > target->lock_w - 1) { x2 = target->lock_w - 1; } """ print "{" if shade: print """\ int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); """ print "{" if texture: print """\ const int offset_x = s->texture->parent ? s->texture->xofs : 0; const int offset_y = s->texture->parent ? s->texture->yofs : 0; ALLEGRO_BITMAP* texture = s->texture->parent ? s->texture->parent : s->texture; const int src_format = texture->locked_region.format; const int src_size = texture->locked_region.pixel_size; /* Ensure u in [0, s->w) and v in [0, s->h). */ while (u < 0) u += s->w; while (v < 0) v += s->h; u = fmodf(u, s->w); v = fmodf(v, s->h); ASSERT(0 <= u); ASSERT(u < s->w); ASSERT(0 <= v); ASSERT(v < s->h); """ print "{" print """\ const int dst_format = target->locked_region.format; uint8_t *dst_data = (uint8_t *)target->locked_region.data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; """ if shade: make_if_blender_loop( op='ALLEGRO_ADD', src_mode='ALLEGRO_ONE', src_alpha='ALLEGRO_ONE', op_alpha='ALLEGRO_ADD', dst_mode='ALLEGRO_INVERSE_ALPHA', dst_alpha='ALLEGRO_INVERSE_ALPHA', if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', alpha_only=True ) print "else" make_if_blender_loop( op='ALLEGRO_ADD', src_mode='ALLEGRO_ALPHA', src_alpha='ALLEGRO_ALPHA', op_alpha='ALLEGRO_ADD', dst_mode='ALLEGRO_INVERSE_ALPHA', dst_alpha='ALLEGRO_INVERSE_ALPHA', if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', alpha_only=True ) print "else" make_if_blender_loop( op='ALLEGRO_ADD', src_mode='ALLEGRO_ONE', src_alpha='ALLEGRO_ONE', op_alpha='ALLEGRO_ADD', dst_mode='ALLEGRO_ONE', dst_alpha='ALLEGRO_ONE', if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', alpha_only=True ) print "else" if opaque and white: make_loop(copy_format=True, src_size='4') print "else" make_loop(copy_format=True, src_size='3') print "else" make_loop(copy_format=True, src_size='2') print "else" else: make_loop( if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888' ) print "else" make_loop() print """\ } } } } """ def make_if_blender_loop( op='op', src_mode='src_mode', dst_mode='dst_mode', op_alpha='op_alpha', src_alpha='src_alpha', dst_alpha='dst_alpha', src_format='src_format', dst_format='dst_format', if_format=None, alpha_only=False ): print interp("""\ if (op == #{op} && src_mode == #{src_mode} && src_alpha == #{src_alpha} && op_alpha == #{op_alpha} && dst_mode == #{dst_mode} && dst_alpha == #{dst_alpha}) { """) if texture and if_format: make_loop( op=op, src_mode=src_mode, src_alpha=src_alpha, op_alpha=op_alpha, dst_mode=dst_mode, dst_alpha=dst_alpha, if_format=if_format, alpha_only=alpha_only ) print "else" make_loop( op=op, src_mode=src_mode, src_alpha=src_alpha, op_alpha=op_alpha, dst_mode=dst_mode, dst_alpha=dst_alpha, alpha_only=alpha_only) print "}" def make_loop( op='op', src_mode='src_mode', dst_mode='dst_mode', op_alpha='op_alpha', src_alpha='src_alpha', dst_alpha='dst_alpha', src_format='src_format', dst_format='dst_format', src_size='src_size', if_format=None, copy_format=False, alpha_only=False ): if if_format: src_format = if_format dst_format = if_format print interp("if (dst_format == #{dst_format}") if texture: print interp("&& src_format == #{src_format}") print ")" elif copy_format: assert opaque and white print interp("if (dst_format == src_format && src_size == #{src_size})") print "{" if texture: print """\ uint8_t *lock_data = texture->locked_region.data; const int src_pitch = texture->locked_region.pitch; const al_fixed du_dx = al_ftofix(s->du_dx); const al_fixed dv_dx = al_ftofix(s->dv_dx); """ if opaque: # If texture coordinates never wrap around then we can simplify the # innermost loop. It doesn't seem to have so great an impact when the # loop is complicated by blending. print """\ const float steps = x2 - x1 + 1; const float end_u = u + steps * s->du_dx; const float end_v = v + steps * s->dv_dx; if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { """ make_innermost_loop( op=op, src_mode=src_mode, dst_mode=dst_mode, op_alpha=op_alpha, src_alpha=src_alpha, dst_alpha=dst_alpha, src_format=src_format, dst_format=dst_format, src_size=src_size, copy_format=copy_format, tiling=False, alpha_only=alpha_only ) print "} else" make_innermost_loop( op=op, src_mode=src_mode, dst_mode=dst_mode, op_alpha=op_alpha, src_alpha=src_alpha, dst_alpha=dst_alpha, src_format=src_format, dst_format=dst_format, src_size=src_size, copy_format=copy_format, alpha_only=alpha_only ) print "}" def make_innermost_loop( op='op', src_mode='src_mode', dst_mode='dst_mode', op_alpha='op_alpha', src_alpha='src_alpha', dst_alpha='dst_alpha', src_format='src_format', dst_format='dst_format', src_size='src_size', copy_format=False, tiling=True, alpha_only=True ): print "{" if texture: # In non-tiling mode we can hoist offsets out of the loop. if tiling: print """\ al_fixed uu = al_ftofix(u); al_fixed vv = al_ftofix(v); const int uu_ofs = offset_x - texture->lock_x; const int vv_ofs = offset_y - texture->lock_y; const al_fixed w = al_ftofix(s->w); const al_fixed h = al_ftofix(s->h); """ uu_ofs = "uu_ofs" vv_ofs = "vv_ofs" else: print """\ al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); """ uu_ofs = vv_ofs = "0" print "for (; x1 <= x2; x1++) {" if not texture: print """\ ALLEGRO_COLOR src_color = cur_color; """ else: print interp("""\ const int src_x = (uu >> 16) + #{uu_ofs}; const int src_y = (vv >> 16) + #{vv_ofs}; uint8_t *src_data = lock_data + src_y * src_pitch + src_x * #{src_size}; """) if copy_format: pass else: print interp("""\ ALLEGRO_COLOR src_color; _AL_INLINE_GET_PIXEL(#{src_format}, src_data, src_color, false); """) if grad: print """\ SHADE_COLORS(src_color, cur_color); """ elif not white: print """\ SHADE_COLORS(src_color, s->cur_color); """ if copy_format: print interp("""\ switch (#{src_size}) { case 4: memcpy(dst_data, src_data, 4); dst_data += 4; break; case 3: memcpy(dst_data, src_data, 3); dst_data += 3; break; case 2: *dst_data++ = *src_data++; *dst_data++ = *src_data; break; case 1: *dst_data++ = *src_data; break; } """) elif shade: blend = "_al_blend_inline" if alpha_only: blend = "_al_blend_alpha_inline" print interp("""\ { ALLEGRO_COLOR dst_color; ALLEGRO_COLOR result; _AL_INLINE_GET_PIXEL(#{dst_format}, dst_data, dst_color, false); #{blend}(&src_color, &dst_color, #{op}, #{src_mode}, #{dst_mode}, #{op_alpha}, #{src_alpha}, #{dst_alpha}, &result); _AL_INLINE_PUT_PIXEL(#{dst_format}, dst_data, result, true); } """) else: print interp("""\ _AL_INLINE_PUT_PIXEL(#{dst_format}, dst_data, src_color, true); """) if texture: print """\ uu += du_dx; vv += dv_dx; """ if tiling: print """\ if (_AL_EXPECT_FAIL(uu < 0)) uu += w; else if (_AL_EXPECT_FAIL(uu >= w)) uu -= w; if (_AL_EXPECT_FAIL(vv < 0)) vv += h; else if (_AL_EXPECT_FAIL(vv >= h)) vv -= h; """ if grad: print """\ cur_color.r += gs->color_dx.r; cur_color.g += gs->color_dx.g; cur_color.b += gs->color_dx.b; cur_color.a += gs->color_dx.a; """ print """\ } }""" if __name__ == "__main__": print """\ // Warning: This file was created by make_scanline_drawers.py - do not edit. #if __GNUC__ #define _AL_EXPECT_FAIL(expr) __builtin_expect((expr), 0) #else #define _AL_EXPECT_FAIL(expr) (expr) #endif """ make_drawer("shader_solid_any_draw_shade") make_drawer("shader_solid_any_draw_opaque") make_drawer("shader_grad_any_draw_shade") make_drawer("shader_grad_any_draw_opaque") make_drawer("shader_texture_solid_any_draw_shade") make_drawer("shader_texture_solid_any_draw_shade_white") make_drawer("shader_texture_solid_any_draw_opaque") make_drawer("shader_texture_solid_any_draw_opaque_white") make_drawer("shader_texture_grad_any_draw_shade") make_drawer("shader_texture_grad_any_draw_opaque") # vim: set sts=3 sw=3 et: allegro-5.0.10/misc/msvchelp.c0000644000175000001440000000257410601373421015333 0ustar tjadenusers#define WIN32_LEAN_AND_MEAN #include #include #include #define MAKEFILE_HELPER_FILENAME "makefile.helper" int main(int argc, char *argv[]) { char shortfilename[MAX_PATH]; char *longfilename; int ret; FILE *fout; if (argc != 2) { fprintf(stderr, "msvchelp: No argument given!\n"); return 1; } longfilename = getenv(argv[1]); if (longfilename == NULL) { fprintf(stderr, "msvchelp: Given argument does not correspond to any enviroment variable name!\n"); return 2; } ret = GetShortPathName(longfilename, shortfilename, MAX_PATH); if (ret == 0 || ret > MAX_PATH) { fprintf(stderr, "msvchelp: Cannot convert to short name!\n"); return 3; } fout = fopen(MAKEFILE_HELPER_FILENAME, "wt"); if (fout == NULL) { fprintf(stderr, "msvchelp: Cannot create output file '%s'!\n", MAKEFILE_HELPER_FILENAME); return 4; } ret = fprintf(fout, "%s = %s\n", argv[1], shortfilename); if (ret < 0) { fprintf(stderr, "msvchelp: Cannot write to the output file '%s'!\n", MAKEFILE_HELPER_FILENAME); return 5; } ret = fclose(fout); if (ret != 0) { fprintf(stderr, "msvchelp: Cannot close the output file '%s'!\n", MAKEFILE_HELPER_FILENAME); return 6; } return EXIT_SUCCESS; } allegro-5.0.10/misc/allegro_memfile.pc.in0000644000175000001440000000063712062774155017434 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_memfile Description: Allegro game programming library, memory files addon Version: ${version} Libs: -L${libdir} -lallegro_memfile${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/mkunixdists.sh0000755000175000001440000001132311162422066016262 0ustar tjadenusers#!/bin/sh ################################################################ # mkunixdists.sh -- shell script to generate Unix distributions # # Usage: mkunixdists.sh [.zip] [tmpdir] # # This generates all the Unix-specific distributions. The # existing ZIP format is fine on Unix too, but we'll generate # here a .tar.gz in Unix format (no `fix.sh unix' necessary) and # also an end-user distribution which just creates and installs # the library, without examples, documentation, etc. I suppose # there's a danger that people will download this as a cut-down # development version, but if we shoot those people then this # problem will be solved. This script might need a lot of disk # space, but no more than the existing zipup.sh needs. :) ################################################################ # First process the arguments if [ $# -lt 1 -o $# -gt 2 ]; then echo "Usage: mkunixdists.sh [.zip] [tmpdir]" exit 1 fi # Sort out `dir', adding a trailing `/' if necessary if [ $# -gt 1 ]; then dir=$(echo "$2" | sed -e 's/\([^/]\)$/\0\//').tmp else dir=.tmp fi ################################################################ # Error reporter error() { echo "Error occured, aborting" ; rm -rf $dir ; exit 1 } ################################################################ # Unzip the archive and convert line endings mkdir $dir || error echo "Unzipping $1 to $dir" unzip -qq $1 -d $dir || error echo "Running 'convert_line_endings.sh --dtou'" (cd $dir/allegro && rm -f makefile && sh misc/convert_line_endings.sh --dtou >/dev/null ) || error echo "Checking version number" # Derive version number from the archive name, as the number in # CMakeLists.txt won't reflect the fourth version digit. version=$( echo $1 | sed -e 's/^allegro-// ; s/\.zip$//' ) test -n "$version" || error basename="allegro-$version" basename2="allegro-enduser-$version" echo "Renaming 'allegro' to '$basename'" mv $dir/allegro $dir/$basename || error ################################################################ # Make .tar.gz distributions mktargz() { echo "Creating $1.tar" (cd $dir && tar -cf - $basename) > $1.tar || error echo "gzipping to $1.tar.gz" gzip $1.tar || error } # Create the developers' archive mktargz $basename # Hack'n'slash # XXX end-user distribution is useless while we are in WIP mode # This code is outdated anyway. if false then echo "Stripping to form end-user distribution" (cd $dir/$basename && { (cd src && rm -rf beos qnx dos mac ppc win) (cd obj && rm -rf bcc32 beos qnx djgpp mingw32 msvc watcom) (cd lib && rm -rf bcc32 beos qnx djgpp mingw32 msvc watcom) (cd include && rm -f bealleg.h qnxalleg.h winalleg.h) (cd misc && rm -f cmplog.pl dllsyms.lst findtext.sh fixpatch.sh fixver.sh) (cd misc && rm -f allegro-config-qnx.sh zipup.sh zipwin.sh *.bat *.c) mkdir .saveme cp readme.txt docs/build/unix.txt docs/build/linux.txt .saveme rm -rf demo docs examples resource setup tests tools rm -f AUTHORS CHANGES THANKS *.txt fix* indent* readme.* allegro.mft rm -f makefile.all makefile.be makefile.qnx makefile.bcc makefile.dj rm -f makefile.mgw makefile.mpw makefile.vc makefile.wat makefile.tst rm -f xmake.sh rm -f keyboard.dat language.dat mv .saveme/* . rmdir .saveme { # Tweak makefile.in cp makefile.in makefile.old && cat makefile.old | sed -e "s/INSTALL_TARGETS = .*/INSTALL_TARGETS = mini-install/" | sed -e "s/DEFAULT_TARGETS = .*/DEFAULT_TARGETS = lib modules/" | cat > makefile.in && rm -f makefile.old } }) # Create the end users' archive mktargz $basename2 fi # false ################################################################ # Create SRPM distribution # # We don't actually create the binary RPMs here, since that # will really need to be done on many different machines. # Instead we'll build the source RPM. # # This requires you to have Red Hat's default RPM build system # properly set up, so we'll skip it if that's not the case. # XXX SRPMs disabled because they must be broken by now # Also, they are useless. if false then rpmdir= [ -d /usr/src/redhat ] && rpmdir=/usr/src/redhat [ -d /usr/src/packages ] && rpmdir=/usr/src/packages [ -d /usr/src/RPM ] && rpmdir=/usr/src/RPM [ -d /usr/src/rpm ] && rpmdir=/usr/src/rpm if [ -n "$rpmdir" ]; then echo "Creating SRPM" echo "Enter your root password if prompted" su -c "(\ cp -f $basename.tar.gz $rpmdir/SOURCES ;\ cp -f $dir/$basename/misc/icon.xpm $rpmdir/SOURCES ;\ rpm -bs $dir/$basename/misc/allegro.spec ;\ mv -f $rpmdir/SRPMS/allegro-*.rpm . ;\ rm -f $rpmdir/SOURCES/icon.xpm ;\ rm -f $rpmdir/SOURCES/$basename.tar.gz ;\ )" fi fi # false ################################################################ # All done! rm -rf $dir echo "All done!" allegro-5.0.10/misc/convert_line_endings.sh0000755000175000001440000000321411004511615020070 0ustar tjadenusers#!/bin/sh # # This file is only used now to convert file line endings by misc/zipup.sh. # We used to do this in fix.sh/fix.bat but those files have been removed # in the 4.9.x series as running them could confuse the CMake and Scons builds, # plus the old build system is not being maintained. # proc_filelist() { # common files. This must not include any shell scripts or batch files. AL_FILELIST=`find . -type f "(" ! -path "*/.*" ")" -a "(" \ -name "*.c" -o -name "*.cfg" -o -name "*.cpp" -o -name "*.def" -o \ -name "*.h" -o -name "*.hin" -o -name "*.in" -o -name "*.inc" -o \ -name "*.m" -o -name "*.m4" -o -name "*.mft" -o -name "*.s" -o \ -name "*.rc" -o -name "*.rh" -o -name "*.spec" -o -name "*.pl" -o \ -name "*.txt" -o -name "*._tx" -o -name "makefile*" -o \ -name "*.inl" -o -name "CHANGES" -o \ -name "AUTHORS" -o -name "THANKS" ")" \ -a ! -path "*.dist*" \ ` # touch unix shell scripts? if [ "$1" != "omit_sh" ]; then AL_FILELIST="$AL_FILELIST `find . -type f -name '*.sh' -o \ -name 'configure' -a ! -path "*addons*"`" fi # touch DOS batch files? if [ "$1" != "omit_bat" ]; then AL_FILELIST="$AL_FILELIST `find . -type f -name '*.bat' -a \ ! -path "*addons*"`" fi } proc_utod() { echo "Converting files from Unix to DOS/Win32 ..." proc_filelist "omit_sh" /bin/sh misc/utod.sh $AL_FILELIST } proc_dtou() { echo "Converting files from DOS/Win32 to Unix ..." proc_filelist "omit_bat" /bin/sh misc/dtou.sh $AL_FILELIST } trap 'exit $?' 1 2 3 13 15 case "$1" in "--utod" ) proc_utod ;; "--dtou" ) proc_dtou ;; esac echo "Done!" allegro-5.0.10/misc/make_converters.py0000755000175000001440000003064112110414116017100 0ustar tjadenusers#!/usr/bin/env python import optparse, re, sys formats_by_name = {} formats_list = [] def read_color_h(filename): """ Read in the list of formats. """ formats = [] inside_enum = False for line in open(filename): line = line.strip() if line == "{": continue if line == "typedef enum ALLEGRO_PIXEL_FORMAT": inside_enum = True elif inside_enum: match = re.match(r"\s*ALLEGRO_PIXEL_FORMAT_(\w+)", line) if match: formats.append(match.group(1)) else: break return formats def parse_format(format): """ Parse the format name into an info structure. """ if format.startswith("ANY"): return None separator = format.find("_") class Info: pass class Component: pass pos = 0 info = Info() info.components = {} info.name = format info.little_endian = "LE" in format if "F32" in format: info.float = True info.size = 128 info.name = format return info for i in range(separator): c = Component() c.color = format[i] c.size = int(format[separator + 1 + i]) c.position_from_left = pos info.components[c.color] = c pos += c.size size = pos for c in info.components.values(): c.position = size - c.position_from_left - c.size info.size = size info.float = False return info def macro_lines(info_a, info_b): """ Write out the lines of a conversion macro. """ r = "" names = info_b.components.keys() names.sort() if info_a.float: lines = [] for name in names: if name == "X": continue c = info_b.components[name] mask = (1 << c.size) - 1 lines.append( "((uint32_t)((x)." + name.lower() + " * " + str(mask) + ") << " + str(c.position) + ")") r += " (" r += " | \\\n ".join(lines) r += ")\n" return r if info_b.float: lines = [] for name in "RGBA": if name not in info_a.components: break c = info_a.components[name] mask = (1 << c.size) - 1 line = "((x) >> " + str(c.position) + ") & " + str(mask) if c.size < 8: line = "_al_rgb_scale_" + str(c.size) + "[" + line + "]" lines.append(line) r += " al_map_rgba(" if len(lines) == 4 else " al_map_rgb(" r += ",\\\n ".join(lines) r += ")\n" return r # Generate a list of (mask, shift, add) tuples for all components. ops = {} for name in names: if name == "X": continue # We simply ignore X components. c_b = info_b.components[name] if name not in info_a.components: # Set A component to all 1 bits if the source doesn't have it. if name == "A": add = (1 << c_b.size) - 1 add <<= c_b.position ops[name] = (0, 0, add, 0, 0, 0) continue c_a = info_a.components[name] mask = (1 << c_b.size) - 1 shift_right = c_a.position mask_pos = c_a.position shift_left = c_b.position bitdiff = c_a.size - c_b.size if bitdiff > 0: shift_right += bitdiff mask_pos += bitdiff else: shift_left -= bitdiff mask = (1 << c_a.size) - 1 mask <<= mask_pos shift = shift_left - shift_right ops[name] = (mask, shift, 0, c_a.size, c_b.size, mask_pos) # Collapse multiple components if possible. common_shifts = {} for name, (mask, shift, add, size_a, size_b, mask_pos) in ops.items(): if not add: if shift in common_shifts: common_shifts[shift].append(name) else: common_shifts[shift] = [name] for newshift, colors in common_shifts.items(): if len(colors) == 1: continue newname = "" newmask = 0 colors.sort() for name in colors: names.remove(name) newname += name newmask |= ops[name][0] names.append(newname) ops[newname] = (newmask, shift, 0, size_a, size_b, mask_pos) # Write out a line for each remaining operation. lines = [] add_format = "0x%0" + str(info_b.size >> 2) + "x" mask_format = "0x%0" + str(info_a.size >> 2) + "x" for name in names: if not name in ops: continue mask, shift, add, size_a, size_b, mask_pos = ops[name] if add: line = "(" + (add_format % add) + ")" lines.append((line, name, 0, size_a, size_b, mask_pos)) continue mask_string = "((x) & " + (mask_format % mask) + ")" if (size_a != 8 and size_b == 8): line = "(_al_rgb_scale_" + str(size_a) + "[" + mask_string + " >> %2d" % mask_pos + "]" else: if (shift > 0): line = "(" + mask_string + " << %2d" % shift + ")" elif (shift < 0): line = "(" + mask_string + " >> %2d" % -shift + ")" else: line = mask_string + " " lines.append((line, name, shift, size_a, size_b, mask_pos)) # Concoct the macro. for i in range(len(lines)): line, name, shift, size_a, size_b, mask_pos = lines[i] if i == 0: start = " (" else: start = " " if i == len(lines) - 1: cont = ") " else: cont = " | \\" if (size_a != 8 and size_b == 8): shift = shift+(mask_pos-(8-size_a)) if (shift > 0): backshift = " << %2d)" % shift elif (shift < 0): backshift = " >> %2d)" % -shift else: backshift = " )" else: backshift = " " r += start + line + backshift + " /* " + name + " */" + cont + "\n" return r def converter_macro(info_a, info_b): """ Create a conversion macro. """ if not info_a or not info_b: return None name = "ALLEGRO_CONVERT_" + info_a.name + "_TO_" + info_b.name r = "" if info_a.little_endian or info_b.little_endian: r += "#ifdef ALLEGRO_BIG_ENDIAN\n" r += "#define " + name + "(x) \\\n" if info_a.name == "ABGR_8888_LE": r += macro_lines(formats_by_name["RGBA_8888"], info_b) elif info_b.name == "ABGR_8888_LE": r += macro_lines(info_a, formats_by_name["RGBA_8888"]) else: r += "#error Conversion %s -> %s not understood by make_converts.py" % ( info_a.name, info_b.name) r += "#else\n" r += "#define " + name + "(x) \\\n" r += macro_lines(info_a, info_b) r += "#endif\n" else: r += "#define " + name + "(x) \\\n" r += macro_lines(info_a, info_b) return r def write_convert_h(filename): """ Create the file with all the conversion macros. """ f = open(filename, "w") f.write("""\ // Warning: This file was created by make_converters.py - do not edit. #ifndef __al_included_allegro5_aintern_convert_h #define __al_included_allegro5_aintern_convert_h #include "allegro5/allegro.h" #include "allegro5/internal/aintern_pixels.h" """) for a in formats_list: for b in formats_list: if b == a: continue macro = converter_macro(a, b) if macro: f.write(macro) f.write("""\ #endif // Warning: This file was created by make_converters.py - do not edit. """) def converter_function(info_a, info_b): """ Create a string with one conversion function. """ name = info_a.name.lower() + "_to_" + info_b.name.lower() params = "void *src, int src_pitch,\n" params += " void *dst, int dst_pitch,\n" params += " int sx, int sy, int dx, int dy, int width, int height" declaration = "static void " + name + "(" + params + ")" macro_name = "ALLEGRO_CONVERT_" + info_a.name + "_TO_" + info_b.name types_and_sizes = { 8 : ("uint8_t", "", 1), 15 : ("uint16_t", "", 2), 16 : ("uint16_t", "", 2), 24: ("uint8_t", " * 3", 1), 32 : ("uint32_t", "", 4), 128 : ("ALLEGRO_COLOR", "", 16)} a_type, a_count, a_size = types_and_sizes[info_a.size] b_type, b_count, b_size = types_and_sizes[info_b.size] if a_count == "" and b_count == "": conversion = """\ *dst_ptr = %(macro_name)s(*src_ptr); dst_ptr++; src_ptr++;""" % locals() else: if a_count != "": s_conversion = """\ #ifdef ALLEGRO_BIG_ENDIAN int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); #else int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); #endif """ % locals() if b_count != "": d_conversion = """\ #ifdef ALLEGRO_BIG_ENDIAN dst_ptr[0] = dst_pixel >> 16; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel; #else dst_ptr[0] = dst_pixel; dst_ptr[1] = dst_pixel >> 8; dst_ptr[2] = dst_pixel >> 16; #endif """ % locals() if a_count != "" and b_count != "": conversion = s_conversion + ("""\ int dst_pixel = %(macro_name)s(src_pixel); """ % locals()) + d_conversion elif a_count != "": conversion = s_conversion + ("""\ *dst_ptr = %(macro_name)s(src_pixel); """ % locals()) else: conversion = ("""\ int dst_pixel = %(macro_name)s(*src_ptr); """ % locals()) + d_conversion conversion += """\ src_ptr += 1%(a_count)s; dst_ptr += 1%(b_count)s;""" % locals() r = declaration + "\n" r += "{\n" r += """\ int y; %(a_type)s *src_ptr = (void *)((char *)src + sy * src_pitch); %(b_type)s *dst_ptr = (void *)((char *)dst + dy * dst_pitch); int src_gap = src_pitch / %(a_size)d - width%(a_count)s; int dst_gap = dst_pitch / %(b_size)d - width%(b_count)s; src_ptr += sx%(a_count)s; dst_ptr += dx%(b_count)s; for (y = 0; y < height; y++) { %(b_type)s *dst_end = dst_ptr + width%(b_count)s; while (dst_ptr < dst_end) { %(conversion)s } src_ptr += src_gap; dst_ptr += dst_gap; } """ % locals() r += "}\n" return r def write_convert_c(filename): """ Write out the file with the conversion functions. """ f = open(filename, "w") f.write("""\ // Warning: This file was created by make_converters.py - do not edit. #include "allegro5/allegro.h" #include "allegro5/internal/aintern_bitmap.h" #include "allegro5/internal/aintern_convert.h" """) for a in formats_list: for b in formats_list: if b == a: continue if not a or not b: continue function = converter_function(a, b) f.write(function) f.write("""\ void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] [ALLEGRO_NUM_PIXEL_FORMATS])(void *, int, void *, int, int, int, int, int, int, int) = { """) for a in formats_list: if not a: f.write(" {NULL},\n") else: f.write(" {") was_null = False for b in formats_list: if b and a != b: name = a.name.lower() + "_to_" + b.name.lower() f.write("\n " + name + ",") was_null = False else: if not was_null: f.write("\n ") f.write(" NULL,") was_null = True f.write("\n },\n") f.write("""\ }; // Warning: This file was created by make_converters.py - do not edit. """) def main(argv): global options p = optparse.OptionParser() p.description = """\ When run from the toplevel A5 folder, this will re-create the convert.h and convert.c files containing all the low-level color conversion macros and functions.""" options, args = p.parse_args() # Read in color.h to get the available formats. formats = read_color_h("include/allegro5/color.h") print(formats) # Parse the component info for each format. for f in formats: info = parse_format(f) formats_by_name[f] = info formats_list.append(info) # Output a macro for each possible conversion. write_convert_h("include/allegro5/internal/aintern_convert.h") # Output a function for each possible conversion. write_convert_c("src/convert.c") if __name__ == "__main__": main(sys.argv) # vim: set sts=4 sw=4 et: allegro-5.0.10/misc/coverage.sh0000755000175000001440000000224511451570150015475 0ustar tjadenusers#!/bin/sh -e # Produce test coverage results using lcov. # Run this from a dedicated build directory unless you don't mind your build # flags being changed. BUILDDIR=$(dirname $PWD) JOBS=${JOBS:-4} if ! test ../LICENSE.txt then echo "Run this in a build subdirectory." 1>&2 exit 1 fi if ! which lcov 2>&1 >/dev/null then echo "lcov is required." 1>&2 exit 1 fi # ccache can interfere with gcov by causing profiling data to end up in the # ~/.ccache directory. export CCACHE_DISABLE=1 cmake \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_C_FLAGS=--coverage \ -DCMAKE_CXX_FLAGS=--coverage \ -DCMAKE_EXE_LINKER_FLAGS=--coverage \ -DWANT_POPUP_EXAMPLES=no \ .. lcov -d $BUILDDIR --zerocounters make -j${JOBS} ex_blend_test make -j${JOBS} ex_config make -j${JOBS} ex_dir make -j${JOBS} ex_path_test make -j${JOBS} ex_utf8 make -j${JOBS} copy_example_data copy_demo_data ( cd examples ./ex_blend_test ./ex_config ./ex_dir ./ex_path_test ./ex_utf8 ) || true ( cd tests make -j${JOBS} run_tests ) || true lcov -d $BUILDDIR --capture --output allegro_auto.info genhtml --legend allegro_auto.info --output-directory coverage allegro-5.0.10/misc/allegro_acodec.pc.in0000644000175000001440000000064212062774155017230 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_acodec Description: Allegro game programming library, audio codec addon Version: ${version} Libs: -L${libdir} -lallegro_acodec${suffix} Libs.private: @link_with@ Requires: allegro_audio${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/allegro_color.pc.in0000644000175000001440000000062512062774155017131 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_color Description: Allegro game programming library, colors addon Version: ${version} Libs: -L${libdir} -lallegro_color${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/allegro_main.pc.in0000644000175000001440000000062712062774155016741 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_main Description: Allegro game programming library, magic main addon Version: ${version} Libs: -L${libdir} -lallegro_main${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/icon.xpm0000644000175000001440000000511410655103021015011 0ustar tjadenusers/* XPM */ static char * alex_xpm[] = { "48 48 6 1", " c None", ". c #080808", "+ c #FCFCFC", "@ c #486028", "# c #587834", "$ c #A4C47C", " .... .... ", " .... .... ", " .++++.. .++++.. ", " .++++.. .++++.. ", " ...... ...++.......++... ", " ...... ...++.......++... ", "..@@####............@@###....##@.. ", "..@@####............@@###....##@.. ", "..###########################..#@@.. ", "..###########################..#@@.. ", ".............................#####.. ", ".............................#####.. ", " ...#########@@.. ", " ......#####..#######.. ", " ......#####..#######.. ", " .....######.....$$#######.. ", " .....######.....$$#######.. ", " .....#####...... ..$$#######.. ", " .....#####...... ..$$#######.. ", " ..#####..... .$$##..###@@.. ", " ..#####..... .$$##..###@@.. ", " ..... .......###@@.. ", " ..... .......###@@.. ", " ..#########.@@.. ", " ..##.......@##.. ", " ..##.......@##.. ", " ...$$$$#####.. ", " ...$$$$#####.. ", " .$$$$#####.. .. ", " .$$$$#####.. .. ", " .$$$$#####.. ..@@.", " .$$$$#####.. ..@@.", " .$$..#####@@.. ..@@.", " .$$..#####@@.. ..@@.", " ..####@..##.. ..##@@.", " ..####@..##.. ..##@@.", " ..####@..####...##@@$$.", " .####@@.$$#######@@$$.. ", " .####@@.$$#######@@$$.. ", " .##@@.....$$$$$$$$$.. ", " .##@@.....$$$$$$$$$.. ", " ..##@@............ ", " ..##@@............ ", " ...######.@@.. ", " ...######.@@.. ", " ..#####@@###..@@.. ", " ..#####@@###..@@.. ", " .................. "}; allegro-5.0.10/misc/askq.c0000644000175000001440000000107507461566347014471 0ustar tjadenusers/* * ASKQ - asks a yes/no question, returning an exit status to the caller. * This is used by the msvcmake installation batch file. */ #include #include int main(int argc, char *argv[]) { int i; puts("\n"); for (i=1; i 1) putc(' ', stdout); puts(argv[i]); } puts("? [y/n] "); for (;;) { i = getc(stdin); if ((tolower(i) == 'y') || (tolower(i) == 'n')) { putc(i, stdout); puts("\n\n"); return (tolower(i) == 'y') ? 0 : 1; } else putc(7, stdout); } } allegro-5.0.10/misc/allegro_audio.pc.in0000644000175000001440000000062412062774155017113 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_audio Description: Allegro game programming library, audio addon Version: ${version} Libs: -L${libdir} -lallegro_audio${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/allegro_image.pc.in0000644000175000001440000000063012062774155017071 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_image Description: Allegro game programming library, image I/O addon Version: ${version} Libs: -L${libdir} -lallegro_image${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/zipup.sh0000755000175000001440000002176411467730662015075 0ustar tjadenusers#! /bin/sh # # Shell script to create a distribution zip, generating the manifest # file and optionally building diffs against a previous version. This # should be run from the allegro directory, but will leave the zip # files in the parent directory. # # This script tries to generate dependencies for all the supported # compilers, which involves considerable skulduggery to make sure it # will work on any Unix-like platform, even if the compilers are not # available themselves. # # Note: if you write datestamp in the archive_name field, then the # resulting archive will be datestamped. This is in particular useful # for making SVN snapshots. # # This script does not try to clean up your workspace so when making # a release, do so from a freshly checked out workspace. if [ $# -lt 1 -o $# -gt 2 ]; then echo "Usage: zipup archive_name [previous_archive]" 1>&2 exit 1 fi if [ -n "$2" ] && [ ! -r ../"$2" ]; then echo "Previous archive $2 not in parent directory, aborting" exit 1 fi # strip off the path and extension from our arguments name=$(echo "$1" | sed -e 's/.*[\\\/]//; s/\.zip//') prev=$(echo "$2" | sed -e 's/.*[\\\/]//; s/\.zip//') # make a datestamped archive if specified if test $name = datestamp; then date=`date '+%Y%m%d'` name=allegro_$date fi # make sure all the makefiles are in Unix text format # for file in makefile.*; do # mv $file _tmpfile # tr -d \\\r < _tmpfile > $file # touch -r _tmpfile $file # rm _tmpfile # done # delete all generated files # echo "Cleaning the Allegro tree..." # # sed -n -e "/CLEAN_FILES/,/^$/p; /^ALLEGRO_.*_EXES/,/^$/p" makefile.lst | \ # sed -e "/CLEAN_FILES/d; /ALLEGRO_.*_EXES/d; s/\\\\//g" | \ # xargs -n 1 echo | \ # sed -e "s/\(.*\)/-c \"rm -f \1\"/" | \ # xargs -l sh # # find . -name '*~' -exec rm -f {} \; # emulation of the djgpp utod utility program (Unix to DOS text format) utod() { for file in $*; do if echo $file | grep "^\.\.\./" >/dev/null; then # files like .../*.c recurse into directories (emulating djgpp libc) spec=$(echo $file | sed -e "s/^\.\.\.\///") find . -type f -name "$spec" -exec perl -p -i -e 's/([^\r]|^)\n/\1\r\n/' {} \; else perl -p -e "s/([^\r]|^)\n/\1\r\n/" $file > _tmpfile touch -r $file _tmpfile mv _tmpfile $file fi done } # generate dependencies for DJGPP # echo "Generating DJGPP dependencies..." # # ./fix.sh djgpp --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for Watcom # echo "Generating Watcom dependencies..." # # ./fix.sh watcom --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for MSVC # echo "Generating MSVC dependencies..." # # ./fix.sh msvc --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for MinGW # echo "Generating MinGW dependencies..." # # ./fix.sh mingw --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for Borland C++ # echo "Generating BCC32 dependencies..." # # ./fix.sh bcc32 --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for BeOS # echo "Generating BeOS dependencies..." # # ./fix.sh beos --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for QNX # echo "Generating QNX dependencies..." # # ./fix.sh qnx --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate dependencies for MacOS X # echo "Generating MacOS X dependencies..." # # ./fix.sh macosx --quick # # make depend UNIX_TOOLS=1 CC=gcc # generate the DLL export definition files for Windows compilers # misc/fixdll.sh # running autoconf # echo "Running autoconf to generate configure script..." # autoconf || exit 1 # touch stamp-h.in so the user doesn't need autoheader to compile # touch stamp-h.in # convert documentation from the ._tx source files # echo "Converting documentation..." # # gcc -o _makedoc.exe docs/src/makedoc/*.c # # ./_makedoc.exe -ascii readme.txt docs/src/readme._tx # ./_makedoc.exe -ascii CHANGES docs/src/changes._tx # ./_makedoc.exe -part -ascii AUTHORS docs/src/thanks._tx # ./_makedoc.exe -part -ascii THANKS docs/src/thanks._tx # for base in abi ahack allegro const faq help mistakes; do # ./_makedoc.exe -ascii docs/txt/$base.txt docs/src/$base._tx # done # for base in bcc32 beos darwin djgpp linux macosx mingw32 msvc qnx unix watcom; do # ./_makedoc.exe -ascii docs/build/$base.txt docs/src/build/$base._tx # done # # # rm _makedoc.exe # convert documentation from pandoc-format source files if which cmake >/dev/null && which pandoc >/dev/null then echo "Generating documentation from Pandoc source files..." builddir=,,zipup_builddir.$$ trap 'rm -rf $builddir' 0 1 2 3 13 15 mkdir $builddir ( cd $builddir cmake .. make -j4 docs html man mv docs/txt/changes-5.0.txt ../CHANGES-5.0.txt test -d ../docs/html || mkdir -p ../docs/html rm -rf ../docs/html/refman mv docs/html/refman ../docs/html/refman rm -rf ../docs/man mv docs/man ../docs/man ) || exit 1 rm -rf $builddir else echo "WARNING: CMake or Pandoc not found, skipping step" 1>&2 fi # generate NaturalDocs documentation # if which NaturalDocs >/dev/null # then # echo "Generating NaturalDocs..." # ( cd docs/naturaldocs # make clean # make public # ) || exit 1 # else # echo "WARNING: NaturalDocs not found, skipping step" 1>&2 # fi # create language.dat and keyboard.dat files # misc/mkdata.sh || exit 1 # convert files to djgpp format for distribution # ./fix.sh djgpp --utod # convert line endings to CR/LF ./misc/convert_line_endings.sh --utod || exit 1 # recursive helper to fill any empty directories with a tmpfile.txt scan_for_empties() { if [ -f $1/tmpfile.txt ]; then rm $1/tmpfile.txt; fi files=`echo $1/*` if [ "$files" = "$1/CVS" -o "$files" = "$1/cvs" -o "$files" = "$1/*" ]; then echo "This file is needed because some unzip programs skip empty directories." > $1/tmpfile.txt else for file in $files; do if [ -d $file ]; then scan_for_empties $file fi done fi } #echo "Filling empty directories with tmpfile.txt..." scan_for_empties "." # build the main zip archive echo "Creating $name.zip..." if [ -f .dist/$name.zip ]; then rm .dist/$name.zip; fi rm -rf ./autom4te* mkdir -p .dist/allegro # Note: we use -print0 and xargs -0 to handle file names with spaces. find . -type f "(" -path "*/.*" -prune -o -iname "*.rej" \ -prune -o -iname "*.orig" -prune -o -print0 ")" | \ xargs -0 cp -a --parents -t .dist/allegro # from now on, the scripts runs inside .dist cd .dist # If 7za is available, use that to produce .7z files. # I used to produce .zip files with it as well but I noticed upon extraction # files with timestamps 10 hours into the future (I'm at UTC+10). .7z files # seem to be unaffected. This was with p7zip 4.65. if 7za > /dev/null ; then rm -f $name.7z if [ -n "$FAST_ZIPUP" ]; then 7za a -mx0 $name.7z allegro else 7za a -mx9 -ms=on $name.7z allegro fi fi rm -f $name.zip if [ -n "$FAST_ZIPUP" ]; then zip -0 -r $name.zip allegro else zip -9 -r $name.zip allegro fi # generate the manifest file echo "Generating allegro.mft..." unzip -Z1 $name.zip | sort > allegro/allegro.mft echo "allegro/allegro.mft" >> allegro/allegro.mft utod allegro/allegro.mft zip -9 $name.zip allegro/allegro.mft if [ -r $name.7z ]; then 7za a $name.7z allegro/allegro.mft fi # if we are building diffs as well, do those if [ $# -eq 2 ]; then echo "Inflating current version ($name.zip)..." mkdir current unzip -q $name.zip -d current echo "Inflating previous version ($2)..." mkdir previous unzip -q ../../"$2" -d previous || exit 1 echo "Generating diffs..." diff -U 3 -N --recursive previous/ current/ > $name.diff echo "Deleting temp files..." rm -r previous rm -r current # generate the .txt file for the diff archive echo "This is a set of diffs to upgrade from $prev to $name." > $name.txt echo >> $name.txt echo "Date: $(date '+%A %B %d, %Y, %H:%M')" >> $name.txt echo >> $name.txt echo "To apply this patch, copy $name.diff into the same directory where you" >> $name.txt echo "installed Allegro (this should be one level up from the allegro/ dir, eg." >> $name.txt echo "if your Allegro installation lives in c:/djgpp/allegro/, you should be in" >> $name.txt echo "c:/djgpp/). Then type the command:" >> $name.txt echo >> $name.txt echo " patch -p1 < $name.diff" >> $name.txt echo >> $name.txt echo "Change into the allegro directory, run make, and enjoy!" >> $name.txt utod $name.txt # zip up the diff archive echo "Creating ${name}_diff.zip..." if [ -f ${name}_diff.zip ]; then rm ${name}_diff.zip; fi zip -9 ${name}_diff.zip $name.diff $name.txt # find if we need to add any binary files as well bin=$(sed -n -e "s/Binary files previous\/\(.*\) and current.* differ/\1/p" $name.diff) if [ "$bin" != "" ]; then echo "Adding binary diffs..." zip -9 ${name}_diff.zip $bin fi rm $name.diff $name.txt fi # convert line endings to back to LF cd .. ./misc/convert_line_endings.sh --dtou || exit 1 allegro-5.0.10/misc/gcc-uni.sh0000755000175000001440000000506710650601744015240 0ustar tjadenusers#!/bin/sh # gcc-uni.sh # ---------- # By Matthew Leverton # # Builds a universal binary by a multi-step process to allow for individual # options for both architectures. Its primary use is to be used as a wrapper # for makefile based projects. # # Although untested, it should be able to build OS X 10.2 compatible builds. # Note that you may need to install the various OS SDKs before this will # work. gcc-3.3 is used for the PPC build. The active version of gcc is used # for the Intel build. (Note that it must be at least version 4.) # # If the makefile has a CC variable, this is all that should be necessary: # # CC=/usr/bin/gcc-uni.sh # # set up defaults mode=link output= cmd= # check whether to use gcc or g++ # (using a symlink with g++ in name is recommended) case "$0" in *g++*) gcc=g++ ;; *) gcc=gcc ;; esac # which OSX to target (used for PPC) OSX_TARGET=10.2 # which SDK to use (unused with PPC because gcc-3.3 doesn't know about it)) SDK_i386=/Developer/SDKs/MacOSX10.4u.sdk SDK_PPC= # i386 flags CFLAGS_i386=" -isysroot $SDK_i386" LDFLAGS_i386=" -isysroot $SDK_i386 -Wl,-syslibroot,$SDK_i386" # ppc flags CFLAGS_PPC= LDFLAGS_PPC= # Parse options: # -arch switches are ignored # looks for -c to enable the CFLAGS # looks for -o to determine the name of the output if [ $# -eq 0 ]; then echo "This is a wrapper around gcc that builds universal binaries." echo "It can only be used to compile or link." exit 1 fi # remember the arguments in case there's no output files args=$* while [ -n "$1" ]; do case "$1" in -arch) shift ;; -c) mode=compile cmd="$cmd -c" ;; -o) shift output="$1" ;; *) cmd="$cmd $1" ;; esac shift done # if no output file, just pass the original command as-is and hope for the best if [ -z "$output" ]; then exec $gcc $args fi # figure out if we are compiling or linking case "$mode" in link) FLAGS_i386="$LDFLAGS_i386" FLAGS_PPC="$LDFLAGS_PPC" ;; compile) FLAGS_i386="$CFLAGS_i386" FLAGS_PPC="$CFLAGS_PPC" ;; *) echo "internal error in gcc-uni.sh script" exit 1 ;; esac # TODO: use trap to cleanup # build the i386 version $gcc $cmd $FLAGS_i386 -arch i386 -o $output.i386 if [ $? -ne 0 ]; then exit 1 fi # build the PPC version MACOSX_DEPLOYMENT_TARGET=$OSX_TARGET /usr/bin/$gcc-3.3 $cmd $FLAGS_PPC -arch ppc -o $output.ppc if [ $? -ne 0 ]; then rm -f $output.i386 exit 1 fi # create the universal version lipo -create $output.i386 $output.ppc -output $output if [ $? -ne 0 ]; then rm -f $output.i386 $output.ppc exit 1 fi # cleanup rm -f $output.i386 $output.ppc allegro-5.0.10/misc/allegro_dialog.pc.in0000644000175000001440000000063612062774155017254 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_dialog Description: Allegro game programming library, native dialog addon Version: ${version} Libs: -L${libdir} -lallegro_dialog${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/zipwin.sh0000755000175000001440000002346412132123562015226 0ustar tjadenusers#! /bin/sh # # Shell script to create a Windows binary distribution. This will # compile the DLL files using MSVC or Cygwin, generate the batch file and # associated helpers needed for end users to build the example programs, # and finally zip up the results. # # Note! If you use Cygwin to generate the DLLs make sure you have set up # your MINGDIR and ALLEGRO_USE_CYGWIN environment variables correctly. # # It should be run from the root of the Allegro directory, eg. # bash misc/zipwin.sh, so that it can find misc/vcvars.c and misc/askq.c. # check we have a filename, and strip off the path and extension from it if [ $# -ne 1 ]; then echo "Usage: zipwin " 1>&2 exit 1 fi name=$(echo "$1" | sed -e 's/.*[\\\/]//; s/\.zip//') # check that MSVC or Cygwin is available if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then if [ "$MINGDIR" = "" ]; then echo "You need to set up Cygwin before running this script" 1>&2 exit 1 fi else if [ "$MSVCDIR" = "" ]; then echo "You need to set up MSVC (run vcvars32.bat) before running this script" 1>&2 exit 1 fi fi # check that we are in the Allegro dir if [ ! -f include/allegro5/allegro.h ]; then echo "Oops, you don't appear to be in the root of the Allegro directory" 1>&2 exit 1 fi # convert Allegro to MSVC or Cygwin format if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then ./fix.sh mingw --dtou else ./fix.sh msvc --utod fi # delete all generated files echo "Cleaning the Allegro tree..." make.exe -s veryclean # generate DLL export definition files misc/fixdll.sh # generate dependencies echo "Generating dependencies..." make.exe depend # build all three libs make.exe lib make.exe lib DEBUGMODE=1 make.exe lib PROFILEMODE=1 # find what library version (DLL filename) the batch file should build ver=`sed -n -e "s/LIBRARY_VERSION = \(.*\)/\1/p" makefile.ver` # compile vcvars echo "Compiling vcvars.exe..." if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then gcc -Wl,--subsystem,console -o vcvars.exe misc/vcvars.c -ladvapi32 else cl -nologo misc/vcvars.c advapi32.lib rm vcvars.obj fi # compile askq echo "Compiling askq.exe..." if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then gcc -Wl,--subsystem,console -o askq.exe misc/askq.c else cl -nologo misc/askq.c rm askq.obj fi # generate the setup code for msvcmake.bat (this bit checks for vcvars32, # and builds the import libs) echo "Generating msvcmake.bat..." cat > msvcmake.bat << END_OF_BATCH @echo off rem Batch file for installing the precompiled Allegro DLL files, rem and building the MSVC example and test programs. rem Generated by misc/zipwin.sh if not exist include\\allegro.h goto no_allegro if not "%MSVCDIR%" == "" goto got_msvc if "%VCVARS%" == "" goto no_vcvars call "%VCVARS%" goto got_msvc :no_vcvars echo MSVC environment variables not found: running vcvars.exe to look for them vcvars.exe msvcmake.bat goto the_end :got_msvc call fix.bat msvc --quick echo Generating release mode import library copy lib\\msvc\\allegro.def lib\\msvc\\alleg$ver.def > nul lib /nologo /machine:ix86 /def:lib\\msvc\\alleg$ver.def /out:lib\\msvc\\alleg.lib echo Generating debug mode import library copy lib\\msvc\\allegro.def lib\\msvc\\alld$ver.def > nul lib /nologo /machine:ix86 /def:lib\\msvc\\alld$ver.def /out:lib\\msvc\\alld.lib /debugtype:cv echo Generating profile mode import library copy lib\\msvc\\allegro.def lib\\msvc\\allp$ver.def > nul lib /nologo /machine:ix86 /def:lib\\msvc\\allp$ver.def /out:lib\\msvc\\allp.lib echo Compiling test and example programs END_OF_BATCH # If running Cygwin, we need to do some trickery if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then ./fix.sh msvc --utod export MSVCDIR="MSVCDIR" make.exe depend UNIX_TOOLS=1 echo "Fooling the MSVC makefile ..." cp lib/mingw32/*.dll lib/msvc/ make.exe -t lib fi # SED script for converting make -n output into a funky batch file cat > _fix1.sed << END_OF_SED # remove any echo messages from the make output /^echo/d # strip out references to runner.exe s/obj\/msvc\/runner.exe // # turn program name slashes into DOS format s/\\//\\\\/g # make sure were are using command.com copy, rather than cp s/^.*cat tools.*msvc.plugins.h/copy \/B tools\\\\plugins\\\\*.inc tools\\\\plugins\\\\plugins.h/ # add blank lines, to make the batch output more readable s/^\([^@]*\)$/\\ \1/ # turn any @ argfile references into an echo+tmpfile sequence s/\(.*\) @ \(.*\)/\\ echo \2 > _tmp.arg\\ \1 @_tmp.arg\\ del _tmp.arg/ END_OF_SED # second SED script, for splitting long echos into multiple segments cat > _fix2.sed << END_OF_SED s/echo \(................................................[^ ]*\) \(........*\) \(>>*\) _tmp\.arg/echo \1 \3 _tmp.arg\\ echo \2 >> _tmp.arg/ END_OF_SED # run make -n, to see what commands are needed for building this thing echo "Running make -n, to generate the command list..." make.exe -n | \ sed -f _fix1.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed | \ sed -f _fix2.sed \ >> msvcmake.bat rm _fix1.sed _fix2.sed if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then unset MSVCDIR fi # finish writing msvcmake.bat (this bit asks whether to install the headers, # libs, and DLL files) cat >> msvcmake.bat << END_OF_BATCH askq.exe Would you like to copy the headers and libs to your MSVC directories if errorlevel 1 goto no_lib_copy if not "%MSVCDIR%" == "" set _VC_DIR_=%MSVCDIR% echo Copying libraries copy lib\\msvc\\*.lib "%_VC_DIR_%\\lib" echo Copying allegro.h copy include\\allegro.h "%_VC_DIR_%\\include" echo Copying winalleg.h copy include\\winalleg.h "%_VC_DIR_%\\include" echo Copying module headers md "%_VC_DIR_%\\include\\allegro" copy include\\allegro\\*.h "%_VC_DIR_%\\include\\allegro" echo Copying inline headers md "%_VC_DIR_%\\include\\allegro\\inline" copy include\\allegro\\inline\\*.inl "%_VC_DIR_%\\include\\allegro\\inline" echo Copying internal headers md "%_VC_DIR_%\\include\\allegro\\internal" copy include\\allegro\\internal\\*.h "%_VC_DIR_%\\include\\allegro\\internal" echo Copying platform headers md "%_VC_DIR_%\\include\\allegro\\platform" copy include\\allegro\\platform\\aintwin.h "%_VC_DIR_%\\include\\allegro\\platform" copy include\\allegro\\platform\\almsvc.h "%_VC_DIR_%\\include\\allegro\\platform" copy include\\allegro\\platform\\alplatf.h "%_VC_DIR_%\\include\\allegro\\platform" copy include\\allegro\\platform\\alwin.h "%_VC_DIR_%\\include\\allegro\\platform" set _VC_DIR_= goto lib_copy_done :no_lib_copy echo Library and header files were not installed. echo You can find the headers in the allegro\\include directory, echo and the libs in allegro\\lib\\msvc\\ :lib_copy_done askq.exe Would you like to copy the DLL files to your Windows system directory if errorlevel 1 goto no_dll_copy if "%OS%" == "Windows_NT" set _WIN_DIR_=%SYSTEMROOT%\\system32 if "%OS%" == "" set _WIN_DIR_=%windir%\\system echo Copying DLL files to %_WIN_DIR_% copy lib\\msvc\\*.dll %_WIN_DIR_% set _WIN_DIR_= goto dll_copy_done :no_dll_copy echo DLL files were not installed. echo You can find them in allegro\\lib\\msvc\\ :dll_copy_done echo. echo All done: Allegro is now installed on your system! goto the_end :no_allegro echo Can't find the Allegro library source files! To install this binary echo distribution, you must also have a copy of the library sources, so echo that I can compile the support programs and convert the documentation. :the_end END_OF_BATCH # generate the readme cat > $name.txt << END_OF_README ______ ___ ___ /\\ _ \\ /\\_ \\ /\\_ \\ \\ \\ \\L\\ \\\\//\\ \\ \\//\\ \\ __ __ _ __ ___ \\ \\ __ \\ \\ \\ \\ \\ \\ \\ /'__\`\\ /'_ \`\\/\\\`'__\\/ __\`\\ \\ \\ \\/\\ \\ \\_\\ \\_ \\_\\ \\_/\\ __//\\ \\L\\ \\ \\ \\//\\ \\L\\ \\ \\ \\_\\ \\_\\/\\____\\/\\____\\ \\____\\ \\____ \\ \\_\\\\ \\____/ \\/_/\\/_/\\/____/\\/____/\\/____/\\/___L\\ \\/_/ \\/___/ /\\____/ \\_/__/ Windows binary distribution. This package contains precompiled copies of the Windows DLL files for the Allegro library, to save you having to compile it yourself. This is not a complete distribution of Allegro, as it does not contain any of the documentation, example programs, headers, etc. You need to download the full source version, and then just unzip this package over the top of it. To install, run the batch file msvcmake.bat, either from a command prompt or by double-clicking on it from the Windows explorer. This will hopefully be able to autodetect all the details of where to find your compiler, and will automatically compile the various support programs that come with Allegro. At the end of the install process you will be asked whether to copy libs and headers into your compiler directories, and whether to install the DLL files into the Windows system directory. You should normally say yes here, but if you prefer, you can leave these files in the Allegro directory, and then specify the paths to them later on, when you come to compile your own programs using Allegro. There are three versions of the DLL included in this zip: alleg$ver.dll is the normal optimised version alld$ver.dll is the debugging build, and should be used during development allp$ver.dll is a profiling build, for collecting performance info For more general information about using Allegro, see the readme.txt and docs/build/msvc.txt files from the source distribution. END_OF_README # build the main zip archive echo "Creating $name.zip..." cd .. if [ -f $name.zip ]; then rm $name.zip; fi if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then unix2dos allegro/$name.txt unix2dos allegro/msvcmake.bat fi zip -9 $name.zip allegro/$name.txt allegro/msvcmake.bat allegro/vcvars.exe allegro/askq.exe allegro/lib/msvc/*.dll # clean up after ourselves cd allegro rm $name.txt msvcmake.bat vcvars.exe askq.exe echo "Done!" allegro-5.0.10/misc/sf-cf.py0000755000175000001440000000751710601373421014723 0ustar tjadenusers#!/usr/bin/env python import os, sys, optparse, threading, time # Put here any hosts you want to compile on. hosts = [ "x86-linux2", #: Fedora Linux FC2 running Linux 2.6 kernel "x86-openbsd1", #: OpenBSD 3.4 "x86-solaris1", #: Sun Solaris 9 "x86-linux1", #: Debian GNU/Linux 3.0 running Linux 2.4 kernel "x86-freebsd1", #: FreeBSD 4.8 "x86-netbsd1", #: NetBSD 1.6.1 "amd64-linux1", #: Fedora Core release 3 running Linux 2.6 kernel "amd64-linux2", #: Fedora Core release 3 running Linux 2.6 kernel "alpha-linux1", #: Debian GNU/Linux 3.0 running Linux 2.2 kernel "ppc-osx1", #: Apple Mac OS X 10.1 Server with Fink running on an Apple Mac G4 "ppc-osx2", #: Apple Mac OS X 10.2 Server with Fink running on an Apple Mac G4 "ppc-osx3", "sparc-solaris1", "sparc-solaris2", #: Sun Solaris 9, running on two Sun Enterprise 220R systems "openpower-linux1", #: SuSE Enterprise Linux 9, running on an IBM OpenPower 720 (e-Series) host. ] # The name of a directory containing the sources to be compiled. source_folder = "allegro" def exe(c): print ">>>" + c + "\n" r = os.popen(c).read() print r parser = optparse.OptionParser() parser.set_usage( """ python %s [options] To use this script, you must have ssh access to the SourceForge compile farm, and your home directory must contain a directory called "allegro". The existence of .txt files with the name of the various hosts controls which systems are tested - by default all for which no .txt file exists yet. """.strip() % sys.argv[0]) hostname = os.popen("hostname").read().strip() parser.add_option("-s", "--ssh", action = "store_true", dest = "ssh", help = "Connect to all hosts for which no .txt files exists and " + "try to compile there, pasting the results back to a .txt file.") parser.add_option("-c", "--compile", action = "store", dest = "compile", help = "Internal command to directly compile on the current host. Do not use.") parser.add_option("-o", "--one", action = "store", dest = "one", help = "Compile only on the given host, and overwrite the .txt " + "file for it if it exists already.") parser.add_option("-u", "--user", help = "The SourceForge compile farm username to use.") options, args = parser.parse_args() user = options.user def compile(host): print ">>>Running on %s [%s].\n" % (host, time.asctime()) make = "make" if host.find("bsd") >= 0: make = "gmake" name = user[:1] + "/" + user[:2] + "/" + user + "/" + host configure = "./configure --prefix=/home/users/%s/local" % name if host.find("osx") >= 0: configure = "./fix.sh macosx" commands = " ".join([ "rm -r %s ;" % host, "mkdir %s ; mkdir %s/local ; " % (host, host), "cd %s &&" % host, #"gunzip -c ../allegro-4.2.1.tar.gz | tar xf - && cd allegro-4.2.1 && ", "cp -r ../%s . && cd %s && " % (source_folder, source_folder), "%s && " % configure, "%s &&" % make, "%s install" % make]) connect_command = r'''ssh %s "'%s'"''' % (host, commands) sshcommand = "ssh cf-shell.sf.net %s" % connect_command print sshcommand stdin, stdout = os.popen4(sshcommand, bufsize=1) print stdout.read() def run(host): print "Connecting to %s..\n" % host print os.popen( "python -u compile.py --compile %s 2>&1 | tee %s.txt" % (host, host)).read() if options.ssh: threads = [] for host in hosts: # Delete previous result .txt to try again! if not os.path.exists("%s.txt" % host): threads.append(threading.Thread(None, run, None, (host, ))) for t in threads: t.start() for t in threads: t.join() elif options.compile: compile(options.compile) elif options.one: run(options.one) else: print "Need either --ssh or --compile argument. -h or --help for help." print parser.print_help() allegro-5.0.10/misc/make_mixer_helpers.py0000755000175000001440000002227112020407417017562 0ustar tjadenusers#!/usr/bin/env python # # Run: # python misc/make_resamplers.py | indent -kr -i3 -l0 import sys, re # http://code.activestate.com/recipes/502257/ def interp(string): locals = sys._getframe(1).f_locals globals = sys._getframe(1).f_globals for item in re.findall(r'#\{([^}]*)\}', string): string = string.replace('#{%s}' % item, str(eval(item, globals, locals))) return string class Depth: def index(self, fmt): if fmt == "f32": return self.index_f32 if fmt == "s16": return self.index_s16 class Depth_f32(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_FLOAT32" def index_f32(self, buf, index): return interp("#{buf}.f32[ #{index} ]") def index_s16(self, buf, index): return interp("(int16_t) (#{buf}.f32[ #{index} ] * 0x7FFF)") class Depth_int24(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_INT24" def index_f32(self, buf, index): return interp("(float) #{buf}.s24[ #{index} ] / ((float)0x7FFFFF + 0.5f)") def index_s16(self, buf, index): return interp("(int16_t) (#{buf}.s24[ #{index} ] >> 9)") class Depth_uint24(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_UINT24" def index_f32(self, buf, index): return interp("(float) #{buf}.u24[ #{index} ] / ((float)0x7FFFFF + 0.5f) - 1.0f") def index_s16(self, buf, index): return interp("(int16_t) ((#{buf}.u24[ #{index} ] - 0x800000) >> 9)") class Depth_int16(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_INT16" def index_f32(self, buf, index): return interp("(float) #{buf}.s16[ #{index} ] / ((float)0x7FFF + 0.5f)") def index_s16(self, buf, index): return interp("#{buf}.s16[ #{index} ]") class Depth_uint16(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_UINT16" def index_f32(self, buf, index): return interp("(float) #{buf}.u16[ #{index} ] / ((float)0x7FFF + 0.5f) - 1.0f") def index_s16(self, buf, index): return interp("(int16_t) (#{buf}.u16[ #{index} ] - 0x8000)") class Depth_int8(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_INT8" def index_f32(self, buf, index): return interp("(float) #{buf}.s8[ #{index} ] / ((float)0x7F + 0.5f)") def index_s16(self, buf, index): return interp("(int16_t) #{buf}.s8[ #{index} ] << 7") class Depth_uint8(Depth): def constant(self): return "ALLEGRO_AUDIO_DEPTH_UINT8" def index_f32(self, buf, index): return interp("(float) #{buf}.u8[ #{index} ] / ((float)0x7F + 0.5f) - 1.0f") def index_s16(self, buf, index): return interp("(int16_t) (#{buf}.u8[ #{index} ] - 0x80) << 7") depths = [ Depth_f32(), Depth_int24(), Depth_uint24(), Depth_int16(), Depth_uint16(), Depth_int8(), Depth_uint8() ] def make_point_interpolator(name, fmt): print interp("""\ static INLINE const void * #{name} (SAMP_BUF *samp_buf, const ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int maxc) { unsigned int i0 = spl->pos*maxc; unsigned int i; switch (spl->spl_data.depth) { """) for depth in depths: buf_index = depth.index(fmt)("spl->spl_data.buffer", "i0 + i") print interp("""\ case #{depth.constant()}: for (i = 0; i < maxc; i++) { samp_buf-> #{fmt} [i] = #{buf_index}; } break; """) print interp("""\ } return samp_buf-> #{fmt} ; }""") def make_linear_interpolator(name, fmt): assert fmt == "f32" or fmt == "s16" print interp("""\ static INLINE const void * #{name} (SAMP_BUF *samp_buf, const ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int maxc) { int p0 = spl->pos; int p1 = spl->pos+1; switch (spl->loop) { case ALLEGRO_PLAYMODE_ONCE: if (p1 >= spl->spl_data.len) p1 = p0; break; case ALLEGRO_PLAYMODE_LOOP: if (p1 >= spl->loop_end) p1 = spl->loop_start; break; case ALLEGRO_PLAYMODE_BIDIR: if (p1 >= spl->loop_end) { p1 = spl->loop_end - 1; if (p1 < spl->loop_start) p1 = spl->loop_start; } break; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR:""" + # For audio streams, sample i+1 may be in the next buffer fragment, # which may not even be generated yet. So we lag by one sample and # interpolate between sample i-1 and sample i. # # We arrange the buffers in memory such that indexing i-1 is always # valid, even after wrapping around from the last buffer fragment to # the first buffer fragment. See _al_kcm_refill_stream. """ p0--; p1--; break; } p0 *= maxc; p1 *= maxc; switch (spl->spl_data.depth) { """) for depth in depths: x0 = depth.index(fmt)("spl->spl_data.buffer", "p0 + i") x1 = depth.index(fmt)("spl->spl_data.buffer", "p1 + i") print interp("""\ case #{depth.constant()}: {""") if fmt == "f32": print interp("""\ const float t = (float)spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int)maxc; i++) { const float x0 = #{x0}; const float x1 = #{x1}; const float s = (x0 * (1.0f - t)) + (x1 * t); samp_buf->f32[i] = s; }""") elif fmt == "s16": print interp("""\ const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; int i; for (i = 0; i < (int)maxc; i++) { const int32_t x0 = #{x0}; const int32_t x1 = #{x1}; const int32_t s = ((x0 * (256 - t))>>8) + ((x1 * t)>>8); samp_buf->s16[i] = (int16_t)s; }""") print interp("""\ } break; """) print interp("""\ } return samp_buf-> #{fmt}; }""") def make_cubic_interpolator(name, fmt): assert fmt == "f32" print interp("""\ static INLINE const void * #{name} (SAMP_BUF *samp_buf, const ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int maxc) { int p0 = spl->pos-1; int p1 = spl->pos; int p2 = spl->pos+1; int p3 = spl->pos+2; switch (spl->loop) { case ALLEGRO_PLAYMODE_ONCE: if (p0 < 0) p0 = 0; if (p2 >= spl->spl_data.len) p2 = spl->spl_data.len - 1; if (p3 >= spl->spl_data.len) p3 = spl->spl_data.len - 1; break; case ALLEGRO_PLAYMODE_LOOP: case ALLEGRO_PLAYMODE_BIDIR: /* These positions should really wrap/bounce instead of clamping * but it's probably unnoticeable. */ if (p0 < spl->loop_start) p0 = spl->loop_end - 1; if (p2 >= spl->loop_end) p2 = spl->loop_start; if (p3 >= spl->loop_end) p3 = spl->loop_start; break; case _ALLEGRO_PLAYMODE_STREAM_ONCE: case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: /* Lag by three samples in total. */ p0 -= 2; p1 -= 2; p2 -= 2; p3 -= 2; break; } p0 *= maxc; p1 *= maxc; p2 *= maxc; p3 *= maxc; switch (spl->spl_data.depth) { """) for depth in depths: value0 = depth.index(fmt)("spl->spl_data.buffer", "p0 + i") value1 = depth.index(fmt)("spl->spl_data.buffer", "p1 + i") value2 = depth.index(fmt)("spl->spl_data.buffer", "p2 + i") value3 = depth.index(fmt)("spl->spl_data.buffer", "p3 + i") # 4-point, cubic Hermite interpolation # Code transcribed from "Polynomial Interpolators for High-Quality # Resampling of Oversampled Audio" by Olli Niemitalo # http://yehar.com/blog/?p=197 print interp("""\ case #{depth.constant()}: { const float t = (float)spl->pos_bresenham_error / spl->step_denom; signed int i; for (i = 0; i < (signed int)maxc; i++) { float x0 = #{value0}; float x1 = #{value1}; float x2 = #{value2}; float x3 = #{value3}; float c0 = x1; float c1 = 0.5f * (x2 - x0); float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; samp_buf->f32[i] = s; } } break; """) print interp("""\ } return samp_buf-> #{fmt} ; }""") if __name__ == "__main__": print "// Warning: This file was created by make_resamplers.py - do not edit." print "// vim: set ft=c:" make_point_interpolator("point_spl32", "f32") make_point_interpolator("point_spl16", "s16") make_linear_interpolator("linear_spl32", "f32") make_linear_interpolator("linear_spl16", "s16") make_cubic_interpolator("cubic_spl32", "f32") # vim: set sts=3 sw=3 et: allegro-5.0.10/misc/regenerate.sh0000755000175000001440000000053312020337543016021 0ustar tjadenusers#!/bin/sh -ex # Recreate the automatically generated source files in the tree. python misc/make_scanline_drawers.py | \ indent -kr -i3 -l0 > src/scanline_drawers.inc python misc/make_converters.py misc/gl_mkalias.sh python misc/make_mixer_helpers.py | \ indent -kr -i3 -l0 > addons/audio/kcm_mixer_helpers.inc # vim: set sts=3 sw=3 et: allegro-5.0.10/misc/allegro_font.pc.in0000644000175000001440000000062112062774155016755 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_font Description: Allegro game programming library, font addon Version: ${version} Libs: -L${libdir} -lallegro_font${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/vcvars.c0000644000175000001440000000702407107604636015025 0ustar tjadenusers/* * VCVARS - sets up a command prompt with suitable options for using MSVC. * * This program tries to locate the vcvars32.bat file, first by looking in * the registry, and then if that fails, by asking the user. It then sets * the environment variable VCVARS to the full path of this file. * * If it was given a commandline argument, it then runs that program, * or otherwise it opens up a new command prompt. In either case it will * adjust the environment size to make sure there is enough space for * setting the compiler variables. */ #define WIN32_LEAN_AND_MEAN #include #include #include #include /* try to read a value from the registry */ int read_registry(char *path, char *var, char *val, int size) { HKEY key; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &key) != ERROR_SUCCESS) return 0; if (RegQueryValueEx(key, var, NULL, NULL, val, &size) != ERROR_SUCCESS) { RegCloseKey(key); return 0; } RegCloseKey(key); return 1; } /* locate vcvars32.bat */ void find_vcvars() { char data[256], name[256]; int i; /* look in the registry (try VC versions 4 through 9, just in case :-) */ for (i=9; i>=4; i--) { sprintf(name, "Software\\Microsoft\\DevStudio\\%d.0\\Products\\Microsoft Visual C++", i); if (read_registry(name, "ProductDir", data, sizeof(data))) { strcat(data, "\\bin\\vcvars32.bat"); if (access(data, 4) == 0) { printf("Found %s\n", data); break; } } data[0] = 0; } /* oh dear, have to ask the user where they put it */ if (!data[0]) { printf("\n Unable to find MSVC ProductDir information in your registry!\n\n"); printf(" To install Allegro, I need to know the path where your compiler is\n"); printf(" installed. Somewhere in your MSVC installation directory there will\n"); printf(" be a file called vcvars32.bat, which contains this information.\n"); printf(" Please enter the full path to where I can find that file, for example\n"); printf(" c:\\Program Files\\Microsoft Visual Studio\\VC98\\bin\\vcvars32.bat\n"); for (;;) { printf("\n> "); fflush(stdout); if (gets(data)) { i = strlen(data) - 12; if (i < 0) i = 0; if (stricmp(data+i, "vcvars32.bat") != 0) printf("\nError: that path doesn't end in vcvars32.bat!\n"); else if (access(data, 4) != 0) printf("\nError: can't find a vcvars32.bat file there!\n"); else { printf("\nUsing %s\n", data); break; } } data[0] = 0; } } /* put it in the environment */ strcpy(name, "VCVARS="); strcat(name, data); putenv(name); } /* the main program */ int main(int argc, char *argv[]) { char cmd[256]; int i; find_vcvars(); if ((getenv("OS")) && (stricmp(getenv("OS"), "Windows_NT") == 0)) { if (argc > 1) { /* run program using cmd.exe */ strcpy(cmd, "cmd.exe /e:8192 /c"); } else { /* TSR using cmd.exe */ sprintf(cmd, "cmd.exe /e:8192 /k \"%s\"", getenv("VCVARS")); } } else { if (argc > 1) { /* run program using command.com */ strcpy(cmd, "command.com /e:8192 /c"); } else { /* TSR using command.com */ sprintf(cmd, "command.com /e:8192 /k \"%s\"", getenv("VCVARS")); } } /* what program do we want to invoke? */ for (i=1; i ChangeLog sed -i -re'/-+$/d;s/r[0-9]+ \| ([^ ]+).*/
  • \n\1/;/^$/d;s/([A-Z].*)/ \1/' ChangeLog Use the generated ChangeLog file to update the docs/changes._tx and docs/thanks._tx files. Remove the ChangeLog file after use or move it to some other place. 3. Commit docs/changes._tx and docs/thanks._tx to the SVN repository. 4. Update the DLL symbol definitions: *only* for WIP releases: rm misc/dllsyms.lst chmod +x misc/fixdll.sh [problem in the CVS repository] misc/fixdll.sh --update-symbol-list 5. Commit misc/dllsyms.lst to the SVN repository. 6. In the allegro root directory, run `python misc/genexamp.py'. If the output looks good, applye the output adding ` | patch -p0' to the previous command and commit docs/src/allegro._tx. 7. Tag SVN repository: svn cp https://svn.sourceforge.net/svnroot/alleg/allegro/branches/4.2 https://svn.sourceforge.net/svnroot/alleg/allegro/tags/v4-2-1 * NOTE: svn doesn't retain timestamps when you use svn up or svn co. IMHO it's best for files to keep the timestamp of the last change that was made in SVN -- a little bit of history. You might want to do the next few steps from an `svn export'ed directory, which does preserve timestamps. 8. Set the locale to en_US or en_UK: export LC_ALL=en_US 9. Fix version number: 'misc/fixver.sh 4 2 1' 10. Make sure demo.dat is present in the 'demo' sub-directory. 11. Make sure the working directory is called 'allegro'. 12. Make sure the installed version of GNU autoconf is the right one. 13. Make .zip distro. Have the previous archive in parent directory. You will need to have the dat tool in your path. misc/zipup.sh all421.zip all420.zip The generated zip archive will be in the .dist subdirectory. 14. Make Unix distros. From the top level directory: cd .dist unzip all421.zip allegro/misc allegro/misc/mkunixdists.sh all421.zip 15. Check that the RPM file can be installed and compiled without problems. Also check if the patch applies ok (all421_diff.zip). To verify that the RPM .spec file is updated, you can build the package on a RedHat system, which verifies if the .spec file includes all the files of the package. You can use SourceForge's compile farm to do this, they have Red Hat Linux 9 running Linux 2.4 kernel on x86 architecture. 16. Use misc/zipwin.sh to make Windows binary distro. This script must be run under djgpp Bash having MSVC installed. If you do not have these installed, create a new windows binary distro based on the old one, update all text files and scripts and update the dlls with some you make with MinGW using the newly created .zip distro. (all421.zip) 17. Upload all packages to Sourceforge using the FRS (File Release System). Use CHANGES as the basis for the release notes. 18. Announce the new release to the Allegro mailinglist: , make sure you add URLs to both the Allegro homepage and the Allegro sourceforge download page. Also include the release notes and anything else you wish to add. 19. Convert local files back to Unix format, bump version number, and commit changed files. ./fix.sh unix --dtou misc/fixver.sh 4 2 2 SVN svn commit -m "Bumped version to 4.2.2 (SVN)" 20. Webmasters watch the mailing lists for annoucements and then update the web pages accordingly. If you are interested in this process yourself, you are free to do it following the instructions at: http://alleg.sourceforge.net/docs/webmaster_instructions.html ---------------------------------------------------------------------- By: Henrik Stokseth, October, 2001. E-mail:hstokset@tiscali.no Modified by: Eric Botcazou, April 2003. E-mail:ebotcazou@libertysurf.fr Posterior modifications in CVS log, file allegro/misc/release.txt allegro-5.0.10/misc/allegro.pc.in0000644000175000001440000000050512062774155015730 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro Description: Allegro game programming library Version: ${version} Libs: -L${libdir} -lallegro${suffix} Libs.private: @link_with@ Cflags: -I${includedir} allegro-5.0.10/misc/allegro_primitives.pc.in0000644000175000001440000000064312062774155020206 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_primitives Description: Allegro game programming library, primitives addon Version: ${version} Libs: -L${libdir} -lallegro_primitives${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/allegro_ttf.pc.in0000644000175000001440000000063612062774155016612 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_ttf Description: Allegro game programming library, TrueType fonts addon Version: ${version} Libs: -L${libdir} -lallegro_ttf${suffix} Libs.private: @link_with@ Requires: allegro_font${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/icon.png0000644000175000001440000000100610655103021014765 0ustar tjadenusersPNG  IHDR00WIDAThY+r0]u { (((r 4((!|14Y}lcIMFA$-}mQ!kB~4,&) թK ȮiM /]Pڇݭzit8G)1)lwk^EQ`JHj*S`.+,s.e"}{1%e< g`0_\iS-$ֺٝ/hj)mus^b~aׅB x^4E(,[!)JL5 E:SϰNsA)zc9e"M Q)xAg I,ӛ3K1`/. 1*}|6lJDtN% 6DeN%.lI[1_lpIENDB`allegro-5.0.10/misc/allegro_physfs.pc.in0000644000175000001440000000063212062774155017325 0ustar tjadenusersprefix=@prefix@ exec_prefix=${prefix} libdir=@libdir@ includedir=@includedir@ version=@ALLEGRO_VERSION@ suffix=@lib_type@@lib_linkage@ versuffix=@versuffix@ Name: allegro_physfs Description: Allegro game programming library, PhysicsFS addon Version: ${version} Libs: -L${libdir} -lallegro_physfs${suffix} Libs.private: @link_with@ Requires: allegro${suffix}-${versuffix} >= ${version} Cflags: -I${includedir} allegro-5.0.10/misc/embedman.bat0000755000175000001440000000323110601373421015600 0ustar tjadenusers@ECHO OFF REM *** embedman.bat is a helper tool for MSVC8. REM It embeds all XML manifest files into its corresponding executable. REM ======== DISPATCHING ======== IF "%1" == "" GOTO usage IF "%1" == "all" IF "%2" == "" GOTO search IF "%2" == "" GOTO bad_usage IF NOT EXIST "%1" GOTO file_not_found IF NOT EXIST "%1.manifest" GOTO no_manifest REM ======== EMBED MANIFEST ======== mt -nologo -manifest %1.manifest -outputresource:%1;%2 IF NOT "%ERRORLEVEL%" == "0" GOTO mt_fail del %1.manifest GOTO end REM ======== SEARCH AND EMBED ======== :search FOR /R %%v IN (*.exe) DO CALL %0 %%v 1 -silent FOR /R %%v IN (*.scr) DO CALL %0 %%v 1 -silent FOR /R %%v IN (*.dll) DO CALL %0 %%v 2 -silent GOTO end REM ======== ERRORS ======== :usage ECHO. ECHO Running embedman.bat with "all" as the first and only parameter causes it to ECHO search for all executables and DLLs with manifest files, and embed them. ECHO. ECHO %0 all ECHO. ECHO Alternatively, you can specify an exact file: ECHO. ECHO %0 file.exe 1 ECHO %0 file.dll 2 ECHO. ECHO In every case, the manifest file must exist in the same folder with the same ECHO name as the executable for it to work. The manifest file is then deleted. GOTO end :bad_usage ECHO. ECHO You must specify whether the file is an executable or DLL via the second ECHO parameter. ECHO. ECHO 1 = Executable ECHO 2 = DLL GOTO end :file_not_found ECHO. ECHO The file "%1" was not found. GOTO end :mt_fail ECHO Unable to embed %1.manifest! Make sure mt.exe is in the path. GOTO end :no_manifest IF NOT "%3" == "-silent" ECHO No manifest found for %1 REM ======== THE END ======== :endallegro-5.0.10/misc/fixver.sh0000755000175000001440000000563211347077756015232 0ustar tjadenusers#! /bin/sh -e # # Shell script to adjust the version numbers and dates in files. # # Note: if you pass "datestamp" as the only argument, then the version # digits will remain unchanged and the comment will be set to the date. # This is in particular useful for making SVN snapshots. if [ $# -eq 1 -a $1 == "datestamp" ]; then # Uses GNU grep -o. ver=$( grep -o "ALLEGRO_VERSION [0-9.]*" CMakeLists.txt | cut -d' ' -f2 ) major_num=$( echo $ver | cut -d. -f1 ) sub_num=$( echo $ver | cut -d. -f2 ) wip_num=$( echo $ver | cut -d. -f3 ) $0 $major_num $sub_num $wip_num `date '+%Y%m%d'` exit 0 fi case $# in 3|4|5) ;; *) echo "Usage: fixver major_num sub_num wip_num [n] [comment]" 1>&2 echo " or: fixver datestamp" 1>&2 echo "Example: fixver 4 9 14 SVN" 1>&2 echo " fixver 4 9 14 WIP" 1>&2 echo " fixver 4 9 14 1 WIP" 1>&2 echo " fixver 5 0 0" 1>&2 exit 1 ;; esac # get the version and date strings in a nice format case $# in 3) # Proper release. fourth=1 comment= ;; 4) case $4 in WIP) # Proper release fourth=1 comment=WIP ;; [0-9]) # Proper release fourth=$(( $4 + 1 )) comment= ;; *) fourth=0 comment=$4 ;; esac ;; 5) fourth=$(( $4 + 1 )) comment=$5 ;; esac if [ -z "$comment" ]; then verstr="$1.$2.$3" else verstr="$1.$2.$3 ($comment)" fi year=$(date +%Y) month=$(date +%m) day=$(date +%d) datestr="$(date +%b) $day, $year" # patch allegro/base.h echo "s/\#define ALLEGRO_VERSION .*/\#define ALLEGRO_VERSION $1/" > fixver.sed echo "s/\#define ALLEGRO_SUB_VERSION .*/\#define ALLEGRO_SUB_VERSION $2/" >> fixver.sed echo "s/\#define ALLEGRO_WIP_VERSION .*/\#define ALLEGRO_WIP_VERSION $3/" >> fixver.sed echo "s/\#define ALLEGRO_RELEASE_NUMBER .*/\#define ALLEGRO_RELEASE_NUMBER $fourth/" >> fixver.sed echo "s/\#define ALLEGRO_VERSION_STR .*/\#define ALLEGRO_VERSION_STR \"$verstr\"/" >> fixver.sed echo "s/\#define ALLEGRO_DATE_STR .*/\#define ALLEGRO_DATE_STR \"$year\"/" >> fixver.sed echo "s/\#define ALLEGRO_DATE .*/\#define ALLEGRO_DATE $year$month$day \/\* yyyymmdd \*\//" >> fixver.sed echo "Patching include/allegro5/base.h..." cp include/allegro5/base.h fixver.tmp sed -f fixver.sed fixver.tmp > include/allegro5/base.h # patch the OSX package readme echo "s/\\_\/__\/ Version .*/\\_\/__\/ Version $verstr/" > fixver.sed echo "s/By Shawn Hargreaves, .*\./By Shawn Hargreaves, $datestr\./" >> fixver.sed # patch CMakeLists.txt echo "Patching CMakeLists.txt..." cp CMakeLists.txt fixver.tmp sed -e "s/set(ALLEGRO_VERSION [^)]*)/set(ALLEGRO_VERSION $1.$2.$3)/" fixver.tmp > CMakeLists.txt # clean up after ourselves rm fixver.sed fixver.tmp echo "Done!" allegro-5.0.10/README_macosx.txt0000644000175000001440000000152111520362452015455 0ustar tjadenusersMac OS X-specific notes ======================= Building Allegro on Mac OS X is the same as on other Unix-like operating systems. See README_make.txt. You may also use Xcode but that is not covered there. Using the Clang compiler (OS X 10.6+) ------------------------------------- It is possible to build Allegro using the Clang compiler that ships with OS X 10.6 (Snow Leopard). Clang is installed in /Developer/usr/bin. To use it, you have to tell Cmake to use Clang instead of gcc. From the terminal, this is most easily accomplished by the commands export PATH=/Developer/usr/bin:$PATH export CC=clang before you run Cmake. If you use the graphical version of Cmake, you will be given the option of selecting the C compiler to use. Simply select /Developer/usr/bin/clang. The installation otherwise continues as usual. allegro-5.0.10/CHANGES-5.0.txt0000644000175000001440000041316312157230670014532 0ustar tjadenusersAllegro changelog for 5.0.x series ********************************** See `changes._tx' for changes in earlier versions of Allegro. These lists serve as summaries; the full histories are in the Subversion repository. Changes from 5.0.9 to 5.0.10 (June 2013) **************************************** The main developers this time were: Trent Gamblin, Paul Suntsov, Peter Wang. Core: * Register system interface even if no display driver available on Windows. Displays: * Don't crash in al_create_display if there is no display driver. * Don't crash at shutdown if there is no display driver (Windows). * Don't fail init if both D3D, GL drivers unavailable (Windows). * Run fullscreen toggle on main thread (OS X). * Destroy the backbuffer bitmap when destroying the display (OS X). * Switch to new NSTrackingArea API (OS X). * Check availability of fullscreen button on window frame at run-time (OS X). Graphics: * Add ALLEGRO_SRC_COLOR, ALLEGRO_DEST_COLOR, ALLEGRO_INVERSE_SRC_COLOR, ALLEGRO_INVERSE_DEST_COLOR blending modes (initially by Jon Rafkind and Elias Pschernig). * Let al_destroy_bitmap implicitly untarget the bitmap on the calling thread. * Use memory bitmap drawing when either bitmap is locked (OpenGL). * Add const qualifiers to glUniform*v() functions (Aaron Bolyard). Input: * al_set_mouse_xy on Windows resulted in the mouse getting set to the wrong position in windowed modes. * Scale the user supplied mouse cursor if it's too big (Windows). * Fix mouse warping on OS X. * Fix mouse warping in Linux evdev mouse driver. Audio addon: * pulseaudio: Use smaller buffer size by default, and make it configurable. * pulseaudio: Clean up state transitions. * Fix looping in Ogg Vorbis stream (Todd Cope). * Enable the use of the unpatched DirectX SDK to build Allegro with MinGW. Color addon: * Fix al_color_rgb_to_html blue component (Jeff Bernard). Font addons: * Make al_init_ttf_addon return true for subsequent calls. Primitives addon: * Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. * Check that the vertex declaration is valid before creating it. * Respect filter settings of textures in the D3D backend. Build system: * Do not install most internal header files. * Do not search for and link with unneeded X libraries. Examples: * ex_audio_timer: New example. Other: * Minor fixes. * Various documentation updates. * A lot of code refactoring. Changes from 5.0.8 to 5.0.9 (February 2013) ******************************************* The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Core: * Clean up logging subsystem at shutdown (muhkuh). * Fix a problem with creating a display after Allegro is shut down then re-initialised on X11. * Fix use of clobbered return value from setlocale() on X11. * Fix use of double math functions for float arguments (Nick Trout). Displays: * Fix al_set/get_window position on Windows so getting/setting to the same position continuosly doesn't move the window. (Michael Swiger) * Add al_set_display_icons (plural). Implemented on X11 and Windows. * Made al_get_display_mode return the closest thing to a pixel format possible with the WGL driver (tobing). * Move WGL context destruction out of the message pump thread and into the user/main thread. * Allow command-tab to work in fullscreen window mode on OS X. Graphics: * Avoid null pointer dereference when setting a target bitmap after its video_texture has already been released (D3D). * Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap failed, likely because the device was lost. * Set device_lost flag immediately when d3d_display_thread_proc finds the device is lost. * Sync bitmaps before resizing display to prevent changes being lost after the resize (D3D). * Revert a faulty FBO rebinding optimisation in al_set_target_bitmap. * Fix OpenGL extensions being completely ignored on OS X. * Support stencil buffer on iOS. Input: * Partially fix mouse buttons "sticking" on Mac, e.g. holding the mouse and toggling fullscreen window. Filesystem: * Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to the working directory do not affect the interpretation of the path. * Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. * Make sure stat mode bits are cleared in default implementation of al_update_fs_entry. * Support Unicode paths on Windows. * Change description of al_get_fs_entry_name about not returning absolute path if created from relative path; no longer true for either the default or Physfs implementations. Audio addons: * Shut down threads properly when when destroying FLAC and modaudio streams. * Fix PulseAudio driver trying to connect to a non-existent server forever. Image I/O addon: * Fixed loading interlaced .png files with libpng. * Use Allegro built-in loaders in preference to OS X loaders for BMP/TGA/PCX. The OS X TGA loader doesn't support alpha and this is also more consistent. * Restored ability of the native OSX image loader to load grayscale pictures. Native dialog addon: * Add al_init_native_dialog_addon and al_shutdown_native_dialog_addon. Build system: * Rename allegro*-5.0.pc files to allegro*-5.pc. The old names are deprecated but retained on the 5.0 branch for backwards compatibility. * Only generate and install pkg-config files for libraries that we build. * Install iPhone internals headers (Nick Trout). Examples: * ex_icon2: New example. * speed: Use builtin font. Other: * Documentation updates. * A lot of code refactoring. Changes from 5.0.7 to 5.0.8 (November 2012) ******************************************* The main developers this time were: Dennis Busch, Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Core: * Added alternate spelling: ALLEGRO_ALIGN_CENTER. Displays: * Rewrite D3D display format listing code, which was broken. This should re-enable multi-sampling and fix ex_depth_mask being slow with D3D. * Fixed a case where changing fullscreen mode in D3D via al_resize_display caused a crash and loss of loaded bitmaps information. * Fixed a case where changing fullscreen mode in OpenGL (on Windows) via al_resize_display cause nothing to be rendered after the mode change. * Fix crashes when resizing a WGL fullscreen window. * Fixed missing/incorrect resize events under Windows. * Fix al_set_new_display_adapter on OS X. * Fix use of invalidated pointers in D3D driver when the first format fails. * Fix bug where setting the mouse cursor had no effect when the mouse was captured (mouse button held down). * Fix windows not having a minimise button when set to windowed state from fullscreen window state. * Respect ALLEGRO_FRAMELESS flag properly when toggling from fullscreen window state to windowed state (Windows). * Don't generate DISPLAY_LOST events when resizing a fullscreen display. * Scale window icon to sizes returned by GetSystemMetrics (Windows). * Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. * Added al_osx_get_window function (Dennis Gooden). Graphics: * al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. * Fix a potential crash when drawing the screen to a bitmap with D3D. * Avoid null pointer dereference when setting a target bitmap after its video_texture has already been released (D3D). * Lock bitmap to prevent slowness when creating a cursor from a non-memory bitmap on Windows. * Conditionally lock bitmap when creating cursor on X11 (previously it did so even if already locked). * Don't use NSOpenGLPFAAccelerated unnecessarily (OS X). Input: * Fix incorrect keyboard modifier flags after leaving and re-entering a window (Windows). * Fixed a bug with mouse enter/leave events for resized windows under OSX (Dennis Gooden). * Temporary fix for delay after mouse warp on OS X. File I/O: * Fix al_fputc on big-endian. Reported by Andreas Rönnquist and Tobias Hansen. * Make al_fputc return value like fputc when out of range. * Fix al_read_directory crash on 64-bit Windows (simast). Image addon: * Don't include native image loader source files in builds with the native image loaders disabled (OSX, iOS). * Added a missing autorelease-pool to the OSX bitmap saving function (sleepywind). * Fix OSX native image loader for loading not-premultiplied RGB data. Previously the data was "de-multiplied", with possibly all information lost. * Fix OSX native image loader for loading bitmaps without an alpha channel. They appeared completely black previously. Font addons: * Add builtin font creation function. * Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). * Made TTF addon include padding on the top and left edges of pages (Todd Cope). Audio addon: * Use programmatically generated interpolators. They cover an additional case which was missed and should be slightly more efficient. * Support linear interpolation for 16-bit mixers. * Add cubic interpolation for mixers (off by default). * Fix potential deadlock in stop_voice for OpenAL. * Fix potential deadlock in stop_voice for DirectSound. * Improve buffer filling behaviour for DirectSound, reducing pops and crackles significantly on slower machines. * Increase default buffer size for DirectSound to 8192 samples. * Fix setting the speed of an audio stream after it was attached to the mixer. Native dialogs addon: * Do not unload of rich edit module when closing one text log window while another exists. Reported by URB753. * Use default colours for Windows text log implementation, avoiding problems when the previous custom colours failed, leading to black text on a nearly black background. Build system: * Install pkg-config files when cross-compiling on Unix. Examples: * ex_synth: Add button to save waveform to a file. * ex_multisample: Demonstrate using moving bitmaps. * speed: Avoid poor performance due to needless redraws. * Renamed a5teroids to Cosmic Protector Other: * Many minor bug fixes. * Various documentation updates. Changes from 5.0.6 to 5.0.7 (June 2012) *************************************** The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Core: * Fix ALLEGRO_STATIC_ASSERT collisions from different files included in the same translation unit. Reported by tobing. * Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const ALLEGRO_USTR* instead of just an ALLEGRO_USTR* (Paul Suntsov). * Make al_ustr_empty_string const correct. * Fix many memory leak/warnings on MacOS X (Pär Arvidsson). * Fix typo preventing get_executable_name from using System V procfs correctly. Reported by Max Savenkov. Displays: * Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing ALLEGRO_NOFRAME flag. * Rename al_toggle_display_flag to al_set_display_flag, retaining the older name for compatibility. * Set WM_NAME for some window managers (X11). Graphics: * Force al_create_bitmap to not create oversized bitmaps, to mitigate integer overflow problems. * Removed initial black frame on all Allegro programs. OpenGL: * Texture should be 'complete' (min/mag and wrap set) before glTexImage2D. * Fixed a bug in al_unlock_bitmap where the pixel alignment mistakenly was used as row length. * Fixed typo in names of some OpenGL extension functions. * Display list of OpenGL extensions in allegro.log also for OpenGL 3.0. Direct3D: * Fixed a bug in the D3D driver where separate alpha blending was being tested for when it shouldn't have been (Max Savenkov). Input: * Monitor /dev/input instead of /dev on Linux for hotplugging joysticks (Jon Rafkind). * Do not permanently change the locale for the X11 keyboard driver. Set LC_CTYPE only, not LC_ALL. Audio addon: * Fix desychronization due to inaccurate sample positions when resampling. Thanks to _Bnu for discovering the issue and Paul Suntsov for devising the correct solution. * Fix linear interpolation across audio stream buffer fragments. * Fix two minor memory leaks in the PulseAudio driver. Image I/O addon: * Improve compatibility of BMP loader. In particular, support bitmaps with V2-V5 headers and certain alpha bit masks. * Fix TGA loader using more memory than necessary. Reported by Max Savenkov. Font addon: * Use user set pixel format for fonts. Native dialogs addon: * Clear mouse state after dialogs or else it gets messed up (OSX). * Fix some warnings in gtk_dialog.c. * Wrap use of NSAlert so it can be run on the main thread with return value. Examples: * Add ex_resample_test. * ex_audio_props: Add bidir button. * ex_joystick_events: Support hotplugging and fix display of 3-axis sticks. * Add test_driver -no-display flag. (Tobias Hansen) Other: * Various documentation updates. * Other minor bug fixes. * Fix whatis entries of man pages. (Tobias Hansen) Changes from 5.0.5 to 5.0.6 (March 2012) **************************************** The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Paul Suntsov, Peter Wang. Core: * Added al_register_assert_handler. Graphics: * Added al_draw_tinted_scaled_rotated_bitmap_region. * Added al_reset_clipping_rectangle convenience function. * Added al_get_parent_bitmap. * Fixed a bug in the OpenGL driver when drawing the backbuffer outside the clipping rectangle of the target bitmap. * Make blitting from backbuffer work when using multisampling on Windows/D3D. Displays: * Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). * Don't generate bogus resize events after restoring minimised window on Windows. * Fixed bug on Windows where two SWITCH_IN events were fired when window was minimized/restored (Michael Swiger). * Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under Windows as well as a bug where repeatedly setting the flag to on would make the window grow bigger and bigger (Michael Swiger). * Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in X11. * Prevent a deadlock during display creation on X. * Fallback to the 'old' visual selection method on X instead of crashing if the 'new' visual selection doesn't work. Input: * Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was used for FULLSCREEN. (Max OS X) Filesystem: * Added al_fopen_slice. * Added al_set_exe_name which allows overriding Allegro's idea of the path to the current executable. * Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat the value of TMPDIR et al. as a directory name even without a trailing slash. (Unix) * Make stdio al_fopen implementation set proper errno on failure. Audio addons: * Add mixer gain property and functions. * Improve code to check that DLL symbols are loaded in the acodec addon. The old method was hacky and broke under -O2 using GCC 4.6.1. Image I/O addon: * Improved accuracy of un-alpha-premultiplying in the native OSX bitmap loader. Primitives addon: * Added al_draw_filled_pieslice and al_draw_pieslice. * Added al_draw_elliptical_arc. TTF addon: * Added al_load_ttf_font_stretch functions (tobing). * Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto Hinter which is enabled by default in newer version of FreeType (Michał Cichoń). * Clear locked region so pixel borders aren't random garbage that can be seen sometimes with linear filtering on. * Unlock glyph cache page at end of text_length and get_text_dimensions (jmasterx). Examples: * Added new examples: ex_audio_chain, ex_display_events, ex_file_slice. * ex_ogre3d: Make it work under Windows (AMCerasoli). * a5teroids: Support gamepads that report small non-zero values for sticks that are at rest. Other: * Added index to HTML version of the reference manual (Jon Rafkind). * Various documentation updates. * Other minor bug fixes. Changes from 5.0.4 to 5.0.5 (November 2011) ******************************************* The main developers this time were: Elias Pschernig and Trent Gamblin. Graphics: * Fixed several instances of windows being positioned wrong on Windows: regular windows, WGL FULLSCREEN_WINDOW, and ALLEGRO_NOFRAME windows. * Don't re-bind the FBO in al_set_target_bitmap if the new target bitmap shares the parent bitmap with the new target bitmap (Paul Suntsov). * Zero out fake refresh rate information from the nvidia proprietary driver on X11 (Peter Wang). * Implemented the ALLEGRO_FULLSCREEN_WINDOW flag for iOS. Input: * Make al_set_mouse_xy work in fullscreen on Windows. * Fixed a race condition in al_init_joystick. * Fixed problem on OS X where having two identical gamepads attached would cause joystick initialization to hang (Thanks to Todd Cope for pointing it out.) * Fixed iphone joystick events (it assumed a call to al_get_joystick but that's not required when using events). TTF fonts: * Save new bitmap flags and bitmap format at time of loading font and use them when creating pages. Primitives addon: * Very thin arcs/pieslices were not drawn due to an overzealous check (Paul Suntsov). Native dialogs addon: * Implemented al_show_native_message_box for iOS. Other: * Use .../Library/Application Support for ALLEGRO_USER_SETTINGS_PATH and ALLEGRO_USER_DATA_PATH on iOS. * Listen for applicationDidBecomeActive and applicationWillResignActive instead of applicationWillEnterForeground and applicationDidEnterBackground on iOS. This makes all of the common situations where you want to pause your game work, such as the lock button. * Fix some memory leaks on iOS. Documentation: * Various documentation updates. * Generate multiple copies of a man page for all the API entries that it documents. Changes from 5.0.3 to 5.0.4 (August 2011) ***************************************** The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang and torhu. Core: * Restore searching of directories on PATH for DLLs to load on Windows. * Fix crash on shutdown in headless Unix environment (no X11 display). * Change all instances of al_malloc + memset(0) to al_calloc. Graphics: * Save memory in OpenGL case by freeing bitmap memory after uploading a texture. Use a temporary buffer when converting lock buffer back to native texture format. * Don't release or refresh memory or sub-bitmaps when D3D device gets lost/found. * Do not set D3D sub bitmaps to modified when first creating them. This can cause major slowdowns when creating a lot of sub-bitmaps and is likely responsible for slow font performance/startup when using D3D. * Fix incorrect number of display formats in D3D (tobing). * Honor ALLEGRO_VSYNC in the WGL driver. * Make titlebar icons the right size on Windows. * Fix typo causing weird results of al_get_monitor_info on X. * Don't setup FBO for a sub-bitmap whose parent is locked. * Specialise ADD/ONE/INVERSE_ALPHA blend mode software scanline drawers. * Toggle ALLEGRO_VIDEO_BITMAP flag off when creating a memory bitmap (both bits were previously on). * Add null bitmap assertion to al_clone_bitmap. Input: * New system for mapping extended keys in Windows keyboard driver. Mainly for getting the same keycode for numpad keys independently of the state of Num Lock. * More reliable updating of the toggle modifiers in Windows keyboard driver (Num Lock, Caps Lock, and Scroll Lock). Timers: * Fix race conditions when starting timers from different threads. Audio addons: * Don't mix into a global temporary sample buffer, causing noise when two separate mixers are trying to run in parallel. * Make it possible to start/stop an audio stream which is attached to a voice. * ALSA voices could not be resumed after being stopped, because the update threads quit as soon as a voice is stopped. * OpenAL backend did not handle the case where _al_voice_update returns less than a full buffer. * Attempt to load FLAC and Vorbis DLLs only once to avoid Windows popping up too many error windows. Native dialogs addon: * al_show_native_messagebox() on Windows: add UTF-8 support; show heading; show information icon by default. TTF addon: * Reduce memory usage. * Don't make multiple passes over strings when computing text dimensions. Build system: * Make sure static builds on Windows never use DLL_TLS (Zac Evans). * Made compilation possible with different combinations of Xinerama, XF86VidMode, or Randr being present. * cmake: Use find_path HINTS instead of PATHS in our DirectX SDK scripts. * cmake: Search for D3DX9 once instead of multiple times (John-Kim Murphy). * cmake: Find FLAC/Ogg/Vorbis libraries under the names generated by the official MSVC project files. * Include zlib.h explicitly for libpng 1.5. Examples: * Add multisampling to SPEED example. Change examples to use ALLEGRO_SUGGEST for multisampling. * Include the font for speed.app under OSX within the bundle so it can be run by double clicking. * Use default blending/pre-multiplied alpha in ex_blend2. Other: * Various documentation updates. * Fix minor memory leaks. Bindings: * Better way to make the Python wrapper work with both Python 2 and 3. * Include Windows-specific functions in the Python wrapper. Changes from 5.0.2.1 to 5.0.3 (May 2011) **************************************** Input: * Fixed keyboard repeat for extended keys on Windows. Added ALLEGRO_KEY_MENU. (torhu) * Make Delete key in Windows send KEY_CHAR event with unichar code 127 (Peter Wang). Filesystem: * al_remove_filename returned false even if successful (reported by xpolife). Graphics: * On OpenGL ES 1.1, glReadPixels can only read 4 byte pixels (Trent Gamblin). Font addon: * Fix a small memory leak when unregistering a handler with al_register_font_loader (Trent Gamblin). Primitives addon: * Fix assertion failures when drawing al_draw_ellipse, al_draw_arc, al_draw_rounded_rectangle, al_draw_filled_rounded_rectangle at very small scales (reported by Carl Olsson). Native dialogs addon: * gtk: Fix truncated string if the final button contained a non-ASCII character (Peter Wang). Other: * Minor build fixes and documentation updates. Changes from 5.0.2 to 5.0.2.1 (April 2011) ****************************************** * Fix regression on Windows where the keyboard state was not updated unless the keyboard event source is registered to an event queue. Changes from 5.0.1 to 5.0.2 (April 2011) **************************************** Input: * Fix inverted mouse wheel on X11. * Make unicode field in KEY_CHAR events zero for Fn, arrow keys, etc. for OS X (jmasterx, Peter Hull). * Support ALLEGRO_KEY_PAD_ENTER and detect left/right Alt and Ctrl keys independently on Windows (torhu, Matthew Leverton). Changes from 5.0.0 to 5.0.1 (March 2011) **************************************** The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Other contributions noted in-line. Graphics: * Automatically destroy framebuffer objects (FBOs) created for non-memory bitmaps after a while. This solves the problem of running out of resources if you set many different target bitmaps. * Make al_get_opengl_fbo attempt to create an FBO if one doesn't exist. * Avoid very small textures in Direct3D. * Do not sync from memory when first creating/uploading a bitmap (D3D). * Try to fix the problem of the taskbar appearing above fullscreen windows on Windows. * Center the window after toggling fullscreen on Windows. Input: * Support 4-way mouse-wheel and up to 32 mouse buttons in X11. Audio addons: * Avoid buffer overrun while reading from vorbis files. * Added optional support for Tremor in place of libvorbis on any platform. * Do not prefer DirectSound with OpenAL. This can cause problems and also will override user config. * Play silence where needed in DirectSound driver. TTF addon: * Do not hold bitmap drawing when changing target bitmap, which is invalid and caused transformations to be misapplied. * Remove FBO for a cache bitmap once we are no longer adding glyphs to it. Build system: * Force "default" visibility of _al_mangled_main on OS X, otherwise the dynamic linker cannot find the symbol if building with XCode4 (Owen Anderson and Peter Hull). * Generated pkg-config files should take into account LIB_SUFFIX variable (Cristian Morales Vega). * Update allegro_font pkg-config file to not require allegro_primitives. Documentation: * Various documentation updates. * Add copy of DejaVu font licence. Bindings: * Add allegro_main addon to the Python wrapper. Make the wrapper work with Python 3, which has a different string representation. Add parameter type checking for custom types. Changes from 5.0.0 RC5 to 5.0.0 (February 2011) *********************************************** Color addon: * Use colour names from CSS. This is the same as the previous list but with all grey/gray alternatives. Documentation: * Minor documentation updates. Changes from 5.0.0 RC4 to 5.0.0 RC5 (February 2011) *************************************************** The main developers this time were: Thomas Fjellstrom, Trent Gamblin, Peter Hull, Matthew Leverton and Peter Wang. Other contributions noted in-line. System: * Load allegro5.cfg from the directory containing the executable, not the initial working directory. Graphics: * Make al_get_monitor_info return success code. * Replace al_set_new_display_adaptor(-1) with a named constant ALLEGRO_DEFAULT_DISPLAY_ADAPTER. * Fix numerous bugs in X mode setting and multi monitor related code, and introduce new xrandr code. * Generate ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY when mouse leaves OS X window (Evert Glebbeek). * Hide OS X window during exiting fullscreen window mode, to prevent the hideous misaligned animation from showing. * Fix erroneous assertions in OpenGL backend. * Added a hack which makes OpenGL mode work under Wine for me (Elias Pschernig). * Add support for some al_get_display_options in D3D port. Keyboard: * Don't send KEY_CHAR events for modifier and dead keys (with contributions from torhu). * Don't send KEY_DOWN events for non-physical key events. * osx: Allow unicode entry (single keypresses only). * x11: Set the keycode field in KEY_CHAR events to the code of the last key pressed, as stated in the documentation, even if the char is due to a compose sequence. * x11: Get rid of historic behaviour where the unicode field is always zero when Alt is held down. * Rename ALLEGRO_KEY_EQUALS_PAD to ALLEGRO_KEY_PAD_EQUALS for consistency. Mouse: * Add al_grab_mouse and al_ungrab_mouse. Implemented on X11 and Windows. * Allow the user configure a key binding to toggle mouse grabbing on a window. * Support horizontal mouse wheel on Windows (jmasterx). * Calculate Y position for al_set_mouse_xy correctly in OS X windowed mode (X-G). * Use more appropriate CURSOR_LINK cursor on OS X (X-G). * Assign different button IDs for separate touches on iPhone (Michał Cichoń). * iphone: Remove fake mouse move events as they're unncessary and can cause problems with user input tracking. Filesystem: * Clean up al_get_standard_path(): remove SYSTEM_DATA, SYSTEM_SETTINGS, PROGRAM paths; add RESOURCES and USER_DOCUMENTS paths. Use system API calls if possible. * Implement ALLEGRO_USER_DATA_PATH under Linux. Honor XDG_DATA/CONFIG_HOME environment variables. * Fix al_make_directory on Windows due to problems with calls to stat() with trailing slashes. Native dialogs addon: * Use string arguments to al_create_native_file_dialog() and al_get_native_file_dialog_path() instead of ALLEGRO_PATH. * Enhance the Windows file selector (initial patch by Todd Cope): * Use Windows' folder selector for ALLEGRO_FILECHOOSER_FOLDER. * Implement patterns. * Display the title of the dialog that the user specified. Primitives addon: * Fix changing the D3D blender state without updating the cached state. TTF addon: * Align glyphs in ttf font sheets so as to work around problems with forced S3TC compression with some OpenGL drivers (Elias Pschernig). Examples: * SPEED: add full screen flag, use standard paths for highscores and data. Build system: * Check PulseAudio backend will compile before enabling support. * Give a louder warning if FLAC/Vorbis/DUMB compile tests fail. Other: * Many leaks fixed on OS X. * Minor bug fixes and documentation updates. Changes from 5.0.0 RC3 to 5.0.0 RC4 (December 2010) *************************************************** The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Peter Wang. Graphics: * d3d: Don't generate intermediate resize events during modal resize loop. * Optimize D3D9 driver by caching blender state and scissor rectangle so redundant calls to D3D9 functions are avoided (Michał Cichoń). * gl: Use glGenerateMipmapEXT to generate mipmaps when FBOs are used. * x11: Don't restore display mode if another fullscreen display is active. Input: * iphone: Reverse button/axis events that were swapped at some point. File I/O: * Change the way user code implements new ALLEGRO_FILE structures. This adds al_create_file_handle and al_get_file_userdata. * Implement default ungetc behavior - used if the interface does not supply its own. * Add al_fopen_interface. Memfile addon: * Implement ungetc. * Add rw file modes. * Rename header to allegro_memfile.h. * Add documentation. Image I/O addon: * Fix endian issues in TGA and Mac OS X image loaders. Other: * Use _NSGetExecutablePath for al_get_standard_path(ALLEGRO_EXENAME_PATH) on OS X (Jeff Connelly). * Minor bug fixes and documentation updates. Changes from 5.0.0 RC2 to 5.0.0 RC3 (December 2010) *************************************************** The main developers this time were: Michał Cichoń, Trent Gamblin, Peter Wang. Graphics: * Honour subbitmap clipping rectangle under OpenGL (Elias Pschernig). * Fix an error in the Direct3D primitives blending. * al_set_new_window_position() did not have an effect for resizable windows on X11. * Fix windows only showing up on first monitor on X11 (Thomas Fjellstrom). * Implement al_get_monitor_info() for iDevices. Input: * Separate character inputs from physical key down events. This removes unichar and modifiers fields from ALLEGRO_EVENT_KEY_DOWN, and replaces ALLEGRO_EVENT_KEY_REPEAT by ALLEGRO_EVENT_KEY_CHAR. We decided this design flaw was better fixed now than later. * Make Mac OS X keyboard driver properly distinguish key down and key repeat events. TTF addon: * Respect ALLEGRO_NO_PREMULTIPLIED_ALPHA flag when loading TTF fonts. Other: * Fix returning a garbage pointer in maybe_load_library_at_cwd (Vadik Mironov). * Remove dependency on dxguid. * Minor compilation fixes and documentation updates. Changes from 5.0.0 RC1 to 5.0.0 RC2 (December 2010) *************************************************** The developers this time were: Trent Gamblin, Elias Pschernig and Peter Wang. System: * Add al_is_system_installed and hide al_get_system_driver. * Prevent 'DLL hijacking' security issue on Windows. Graphics: * Change to using premultiplied alpha by default. The new bitmap flag ALLEGRO_NO_PREMULTIPLIED_ALPHA was added. * Change the value of ALLEGRO_VIDEO_BITMAP to non-zero. * Change al_get_opengl_version to return a packed integer. * Made al_get_opengl_version return an OpenGL ES version (if using OpenGL ES) rather than an attempted estimate at a desktop GL version. * Added function al_get_opengl_variant that returns either ALLEGRO_DESKTOP_OPENGL or ALLEGRO_OPENGL_ES. * Make al_have_opengl_extension return bool. * Fix OpenGL graphics mode height value on Windows. * Only try to create one Direct3D display at a time. * Make screensaver activate on Windows Vista and above unless inhibited. * Avoid potential divide-by-zeroes when computing the refresh rate in X11 video modes. Events: * Delete an incorrect mutex destroy in al_unregister_event_source. Input: * Revert the joystick driver used on OS X 10.4 to the pre-hotplugging version, rather than one which contained an earlier attempt at implementing hotplugging. Select the 10.4 or greater joystick driver at runtime. iPhone: * Added two iPhone-specific functions: al_iphone_override_screen_scale and al_iphone_program_has_halted. Image I/O addon: * Made the iPhone and OSX image loaders not try and correct colors to some arbitrary color space, but instead use the values directly from the image. Native dialogs addon: * Tolerate null display in al_show_native_file_dialog on Windows. * Make GTK native dialog implementation only call GTK from a single thread. * Define al_show_native_message_box to be usable without installing Allegro. Primitives addon: * Make primitives addon compilable again without OpenGL. Examples: * ex_ttf: Test the monochrome flag. * Work around problems with MSVC and UTF-8 string literals. ex_utf8 is now not built under MSVC. * Don't use WIN32 executable type on examples that require the console (David Capello). Other: * Minor bug fixes and documentation updates. Changes from 4.9.22 to 5.0.0 RC1 (November 2010) ************************************************ The developers this time were: Trent Gamblin, Evert Glebbeek, Elias Pschernig, Paul Suntsov, Peter Wang. Graphics: * Make al_resize_display keep the original resolution (or change back) if it can't set the users request, on Windows. * Do not emit ALLEGRO_DISPLAY_RESIZE events from the Windows and X11 display drivers when using al_resize_display. * [X11] Make al_get_num_display_modes and al_get_display_mode work if the adapter is set to default. Right now there was no way to query the modes of the default monitor. * [X11] Use _NET_WM_STATE_FULLSCREEN hint for "true" fullscreen displays. Enable mouse grabbing in fullscreen modes. * Added ALLEGRO_EVENT_DISPLAY_ORIENTATION and implement it on iOS. * Dennis Busch fixed a problem with displays not showing up on the primary display by default in some dual head setups, on Windows. * Increase the precision of texture coordinate deltas in the software triangle renderer, from floats to doubles. * Remove al_get_frontbuffer(). It wasn't implemented anywhere. * Implement min/mag filter and mipmap flags for Direct3D. Input: * Report correct initial mouse position if a display is created with the mouse pointer inside, or if the mouse routines are installed after a display is created (X11, Windows). * John Murphy fixed improperly mapped axes on the Windows joystick driver. Events: * Do not register user event sources with the destructor system as it cannot work reliably. User event sources must be destroyed manually. Filesystem: * Make al_get_fs_entry_name and al_get_current_directory return strings instead of ALLEGRO_PATH. * Make al_make_directory create parent directories as needed. * Fix al_create_fs_entry to not trim the root path "/" down to the empty string with the stdio backend. Path routines: * Remove al_make_path_absolute and replace it by al_rebase_path. * Remove undocumented behavior of setting a default organization name of "allegro" for all apps. * Correctly return standard paths as directories on OS X. Threads: * Rename al_wait_cond_timed to al_wait_cond_until to match al_wait_cond_until. Config routines: * Add a blank line between sections when writing out a config file. Other core: * Move the Windows event loops back into the same thread as the D3D event loop. It's a requirement of D3D, else you can get crashes as I was when resetting the device (like tabbing away from a fullscreen app). * Add some missing standard entries to the OS X menu bar (the "hide", "hide others" and the window list, mainly). Audio addon: * Automatically stop sample instances which point to a buffer of a sample which is about to be destroyed with al_destroy_sample. * alsa: Resume properly after suspending. Image I/O addon: * Make GDI+ support compile cleanly with the headers that come with MinGW package w32api-3.15. * Speed up PNG and BMP saving, and NSImageFromAllegroBitmap loading. TTF addon: * Add a flag for loading TTFs without anti-aliasing (ALLEGRO_TTF_MONOCHROME). Primitives addon: * Fix several failed sub-bitmap related unit tests on Windows. * Made thick outlined triangles look nicer when the triangles are very thin. * Add a debug-only check for primitives addon initialization to aid in code portability. Examples: * Added example demonstrating the effect of premultiplied alpha. * Make 'F' toggle fullscreen window in SPEED (in-game). * Minor improvements to the a5teroids demo. Documentation: * Many documentation updates. * Add list of contributors and a readme for packagers. * Make make_doc tool build cleanly on MSVC, and work around a problem with recent version of Pandoc on Windows. * Improve styling of PDF output. * Add generated man pages to archives. Bindings: * Implemented array types in the Python wrapper. Changes from 4.9.21 to 4.9.22 (September 2010) ********************************************** The developers this time included: Michał Cichoń, Trent Gamblin, Evert Glebbeek, Angelo Mottola, Elias Pschernig, Paul Suntsov and Peter Wang. System: * Allow the X11 port to initialise without an X server connection. Graphics: * Fix many bugs with bitmap locking. * Fix many bugs to do with transformations, flipping and clipping. * Fix many bugs to do with sub-bitmaps as source and destination. * Renamed al_draw_[tinted_]rotated_scaled_bitmap to al_draw_[tinted_]scaled_rotated_bitmap to match the parameter order. * Reimplemented bitmap software rendering routines using newly optimised software triangle renderer, formerly in the primitives addon. * Add pixel_size field to ALLEGRO_LOCKED_REGION. * Fix bugs to do with pixel alignment on OpenGL. * Fix OpenGL pixel transfer of 15 bpp formats, where Allegro does not Allegro does not care whether the unused bit is set or not, but when transferring to OpenGL it will be interpreted as an alpha bit. * Disabled support for drawing a bitmap into itself. * Changed specification of al_draw_*bitmap to not allow transformation and ignore blending/tinting when the screen itself is being drawn (except when drawn into a memory bitmap). * Allow bitmap regions to be outside the bitmap area in drawing routines. * Added al_add_new_bitmap_flag convenience function. * Added three new bitmaps flags ALLEGRO_MAG_LINEAR, ALLEGRO_MIN_LINEAR, ALLEGRO_MIPMAP. Removed the config settings for linear/anisotropic min/mag filtering. DirectX side not yet updated. * Register destructors for bitmaps, so they will be implicitly destroyed when Allegro is shut down. This was only true for some bitmaps previously. * Don't allocate memory buffers for video bitmaps when using OpenGL. * Make al_get_opengl_extension_list() return NULL if called on a non-GL display. * Fix al_create_display for OpenGL forward compatible contexts. * Add al_set_current_opengl_context as an explicit way to set the OpenGL context. * Rename al_is_opengl_extension_supported to al_have_opengl_extension. * Produce more accurate/correct color when going from less to more bits per component. * Fix al_set_new_window_position() everywhere. * Avoid potential deadlock if resizing window to the same size on X11. * Fixed turning off vsync in X11. * Added al_is_d3d_device_lost function. * Dynamically load dinput and d3d DLLs on Windows. * Replaced PeekMessage with GetMessage in window event loops for the D3D and WGL drivers (David Capello). Input: * Added hotplugging support for joysticks on Linux, Windows and OS X. * Added al_reconfigure_joysticks function. * Merged all joystick devices under a single joystick event source. * Removed al_get_joystick_number. * Add al_is_joystick_installed. * The OS X joystick driver was rewritten; it requires OS X 10.5. The older driver still exists for OS X 10.4 and earlier but is in a semi-updated state with regards to hotplugging. * Allow user to override joystick device paths in the config file (Linux). * Fix iphone touch input and clipping for modes other than w=768,h=1024. * Fixed missing mouse movement messages on IPhone on touch-up/down. Also changed how mouse buttons are reported - always as button 1 now. Config: * Give config iterators proper types instead of void *. * Make al_get_system_config() always return non-NULL if a system driver is installed. Events: * Rename al_event_queue_is_empty to al_is_event_queue_empty (with compatibility define). Timers: * Add al_add_timer_count function. * Rename al_timer_is_started to al_get_timer_started. * Rename al_current_time to al_get_time (with compatibility define). File I/O: * Add al_open_fs_entry to open a file handle from an FS_ENTRY. * Add al_fclearerr. * Set ALLEGRO_FILEMODE_HIDDEN flag on entries for file names beginning with dot (OS X). * Remove al_is_path_present, al_fs_entry_is_directory, al_fs_entry_is_file (all trivial). Primitives addon: * Optimised most of the software rendering routines by a lot. * Triangle drawer was skipping pixels in very thin triangles. * Handle lost d3d devices better. * Fix some bugs found during testing. Image I/O addon: * Fix native image loader on Mac OS X: images that were not 72 dpi would be rescaled to a smaller size. * Added native bitmap saving support for OSX. * Fix jpeg saving when locked region has negative pitch. Native dialogs addon: * Add Windows and OS X text log implementations. * Add ALLEGRO_FILECHOOSER and ALLEGRO_TEXTLOG types instead of conflating them into ALLEGRO_NATIVE_DIALOG. * Fix race condition in al_open_native_text_log. * Rename al_destroy_native_dialog to al_destroy_native_file_dialog. * Rename al_get_native_dialog_event_source to al_get_native_text_log_event_source. * Speed up text log appending by making the reader/writers asynchronous. * Register destructors for file chooser and text log dialogs. * Fix file chooser on Windows returning multiple selections with slashes appended to filenames. If an initial path was specified then the dialog wouldn't open at all; fixed. * Let native dialog functions fail gracefully. Audio addons: * Init destructors even if audio driver fails to install. * Dynamically load dsound DLL on Windows. Font addons: * Added al_shutdown_ttf_addon. * Prevent SIGSEGV for double-closing a file in the TTF addon if it is not a valid font file. * Make al_grab_font_from_bitmap not cause a segmentation fault if the bitmap is garbage. * Some TTF fonts would not render right at small sizes; fixed. * Make al_destroy_font ignore NULL. Tests: * Added a test suite (finally). * Add a shell script to produce test coverage results using lcov. Examples: * Add ex_haiku, an example based on Mark Oates's Haiku game. Mark generously agreed to let us include it as an Allegro example. * Added a new example ex_joystick_hotplugging. * Added a new example ex_filter. * Make ex_fs_window work on MSVC. * Allow a5teroids to run without audio, or if audio data doesn't load. Build system: * Re-added CMake option that allows forced static linking of libFLAC. * Replaced the old iphone xcode project with a cmake iphone toolchain. Documentation: * Many updates to the reference manual. Bindings: * Added a workaround to the Python wrapper for a Mingw bug. Changes from 4.9.20 to 4.9.21 (July 2010) ***************************************** The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Paul Suntsov, Peter Wang. Graphics: * Fixed the mis-termed "blend color". There is no more color state. * al_set*_blender functions lose the color parameter. * Added 5 new bitmap drawing functions al_draw_tinted*_bitmap with a color parameter. The parameter is used just like the "blend color" before. * All text drawing functions gain a color parameter and use it like they used the "blend color" before. * Primitive drawing functions previously sometimes (and sometimes not) used the "blend color". Not any longer. * Make the current blending mode thread-local state instead of per-display state. * Add explicit display arguments to functions which require a display, but don't require the rendering context to be current. * Make al_set_target_bitmap change the current display as necessary. al_set_target_bitmap(NULL) releases the rendering context. * Add al_set_target_backbuffer as a convenience. * Remove al_set_current_display. * Give each bitmap its own transformation, i.e. every bitmap has a transformation, which is in effect when that bitmap is the target. * Remove sub-bitmap clip-to-parent restriction on create. Add out-of-bounds blitting support to memory bitmaps. * Merge sub-bitmap and parent bitmap clipping; clip source bitmap to (0,0)-(w,h); fix flipping to/from clipped bitmaps. * Made mouse cursors independent of displays. You may create cursors without a display, and you may use a cursor with any display. * Rename al_{set,get}_current_video_adapter to *new_display_adapter for consistency. * Move the new display video adapter and new window position to thread-local state, like other new display parameters. Make al_store_state also save those parameters with ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS. * Rename al_transform_transform to al_compose_transform. Switched the order of parameters in al_compose_transform and al_copy_transform to match the rest of the transform functions. * Made memory bitmap manipulation without a display possible (again?). * Fixed window resizing in D3D driver. Simplify resize-postponing on Windows. * Make al_create_display abort early when the new_display_adapter is greater than the screen count (X11). * Added ALLEGRO_MINIMIZED flag to the X11 port. * Fixed OpenGL version string parsing (bug #3016654). Other core: * Renamed al_install_timer to al_create_timer, and al_uninstall_timer to al_destroy_timer. * Rename al_{get,set}_{appname,orgname} to *app_name and *org_name. * Fix assertion failure in al_create_mutex_recursive on Windows (spoofle). Primitives addon: * Made the D3D driver of the primitives addon work with multiple displays. Also made it handle the display being destroyed properly. * Simplified shader recreating on thread destruction when using the primitives addon with D3D. * Avoid double free when shutting down the primitives addon multiple times. * Older Intel cards don't implement DrawIndexedPrimitiveUP correctly. Altered the D3D code to work around that. Audio addon: * Allow setting the DirectSound buffer size via allegro5.cfg. Image addon: * Make GDI+ image loader work with MinGW. Font addon: * Nicolas Martyanoff added al_get_font_descent/ascent functions which query per-font properties. Previously it was necessary to call al_get_text_dimensions (which now just reports the text dimensions as it should). Native dialogs addon: * Add text log window functions (GTK only for now). Documentation: * Many updates to the reference manual. * Improve styling and add Allegro version to HTML pages. * Separated readme_a5.txt into multiple files, and hopefully improve them. Build system: * Remove INSTALL_PREFIX. Windows users can now use CMAKE_INSTALL_PREFIX to set the install path. * Allow the user to place dependencies in a subdirectory "deps", which will be automatically searched. Examples: * Use text log windows in many examples. * Add ex_noframe: test bitmap manipulation without a display. Bindings: * Update Python bindings. Changes from 4.9.19 to 4.9.20 (May 2010) **************************************** The developers this time were: Thomas Fjellstrom, Evert Glebbeek, Matthew Leverton, Milan Mimica, Paul Suntsov, Trent Gamblin, Elias Pschernig, Peter Wang. With significant contributions from Michał Cichoń. Core: * Add al_malloc, al_free, et al. These are now used consistently throughout Allegro and its addons. * Replace al_set_memory_management_functions by a simpler function, al_set_memory_interface. * Renamed some D3D/Windows specific functions to follow the al_{verb}_{stuff} convention. Graphics: * Move image I/O framework to core, i.e. al_load_bitmap, al_save_bitmap and bitmap file type registration. Image codecs remain in allegro_image. * Added a simple display capabilities querying capability to al_get_display_option: ALLEGRO_MAX_BITMAP_SIZE, ALLEGRO_SUPPORT_NPOT_BITMAP, ALLEGRO_CAN_DRAW_INTO_BITMAP, ALLEGRO_SUPPORT_SEPARATE_ALPHA. (OpenGL only for now) * Fix in OpenGL 3.0 context creation. * Make the extensions mechanism compatible with OpenGL version >= 3. Declared symbols needed by OpenGL 3.2 and 3.3 and brought OpenGL extensions up to date. * Fix an assertion in _al_draw_bitmap_region_memory so it does not trigger when source and destination are the same bitmap. * Fix some locking issues by setting GL_PACK_ALIGNMENT and GL_UNPACK_ALIGNMENT before reading/writing pixels. * Partial implementation of ALLEGRO_FULLSCREEN_WINDOW on OS X (Snow Leopard, probably Leopard). * Started X11 fullscreen support (resolution switching). * Fix handling of X11 size hints. * Fixed a deadlock related to fullscreen windows under X11 caused by using a nested lock for a condition variable. * Use _NET_WM_ICON to set icon on X11 instead of XSetWMHints. * Get the iPhone OpenGL version more properly. Only use separate blending on iPhone with OpenGL ES 2.0+. * Release the splash view and windows on iPhone, which makes backgrounding Allegro apps on OS 4.0 work. * Updated iphone port for IPad (only tested in the simulator). Input: * Disabled Raw Input code in Windows. Mouse events now reflect system cursor movements even in fullscreen mode. * Prevent late WM_MOUSELEAVE notifications from overriding mouse state display field (Windows). * Update pollable mouse state with axes events as well as button events on iPhone. Filesystem: * Made the filesystem entry functions work under Windows even if the name passed to al_create_fs_entry has a trailing slash or backslash. Config routines: * Add al_{load,save}_config_file_f. * Reorder al_save_config_file* arguments to match al_save_bitmap and al_save_sample. * Optimise config routines to work well for thousands of keys/sections. Image addon: * Added a GDI+ implementation of the image codecs, which will be used in favour of libjpeg/libpng if Allegro is compiled with MSVC. Then allegro_image will not require JPEG/PNG DLLs at runtime. * Removed format specific image functions. * Fixed bug in native png loader on iphone: was using the source color space instead of the target color space which made it fail whenever they differed (alpha-less paletted pictures). * Add an autorelease pool around iphone native image loading to stop memory leaks. Font addons: * Sever the tie between allegro_font and allegro_image. The user needs to initialise the image addon separately now. * Rename al_load_ttf_font_entry to al_load_ttf_font_f. * Fixed problem with glyph precision after applying transformations in the ttf addon. Primitives addon: * Added al_init_primitives addon function. This is now required. * Removed ALLEGRO_PRIM_COLOR; ALLEGRO_COLOR can now be used where it was required. * v textures coordinates were off for OpenGL non-power-of-two textures. * Free the vertex cache in al_destroy_display on X11. * Added the dummy vertex shader support to D3D driver of the primitives addon. Without this, custom vertices either resulted in warnings or outright crashes on some systems. * Bring D3D driver up to speed a little bit: transformations now work properly with sub-bitmap targets; the half-pixel offset now properly interacts with transformations; al_set_target_bitmap does not clear the transformation; the proper transformation is set at display creation. * Cull the primitives that are completely outside the clipping region. * Scale the numbers of vertices for the curvy primitives with the scale of the current transformation. Audio addon: * Remove driver parameter from al_install_audio. * Rename al_get_depth_size to al_get_audio_depth_size. * Rename al_get_audio_stream_buffer to al_get_audio_stream_fragment. * Many improvements to AQueue driver. Audio codecs: * Add MOD/S3M/XM/IT file support, using the DUMB library. * Revert to a monolithic allegro_acodec addon, i.e. remove separate allegro_flac, allegro_vorbis addons. WAV file support is in allegro_acodec. * Implement DLL loading for FLAC/Vorbis/DUMB on Windows. allegro_acodec will load the DLL at runtime to enable support for that format. If your program does not require said format, you don't need to distribute the DLL. * Remove format-specific loader/saver audio codec functions. * Make acodec loaders have consistent file closing behaviour. * Optimised wave file loading. Examples: * Make SPEED port run acceptably on graphics drivers without FBOs. Documentation: * Added documentation for the public Direct3D specific functions. * Documented ALLEGRO_OPENGL_3_0 and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. Other: * Many bug and documentation fixes. Changes from 4.9.18 to 4.9.19 (April 2010) ****************************************** The main developers this time were: Milan Mimica, Trent Gamblin, Paul Suntsov, Peter Wang. Other contributions from: Evert Glebbeek and Shawn Hargreaves. Graphics: * Implemented support for transformations for memory bitmaps. * Transformations now work properly when the target bitmap is a sub-bitmap in OpenGL (still broken in D3D). Also fixed OpenGL bitmap drawing in the same scenario (it used to always revert to software drawing). * Use the memory drawers when the source bitmap is the backbuffer with the rotated/scaled bitmaps. * Make al_put_pixel clip even if the bitmap is locked, which was the reason why software primitives were not clipping. * Added al_put_blended_pixel, the blended version of al_put_pixel. * Sub bitmaps of sub bitmaps must be clipped to the first parent. * Don't clear the transformation when setting the target bitmap in OpenGL. * Implemented ALLEGRO_NOFRAME and ALLEGRO_FULLSCREEN_WINDOW in WGL. * Set the ALLEGRO_DISPLAY->refresh_rate variable for fullscreen modes under D3D. * Make d3d_clear return immediately if the display is in a lost state. * Rewrote the function that reads the OpenGL version so it works for previously unrecognised versions, and future versions. * Check for framebuffer extension on iPhone properly. * Fixed locking bugs on iPhone. allegro_ttf works now. Input: * Removed al_set_mouse_range. * Don't call al_get_mouse_state if the mouse driver isn't installed (Windows). * Send events even when the mouse cursor leaves the window, while any buttons are held down (Windows and Mac OS X; X11 already did this). * Allow mouse presses and accelerometer data simultaneously. (iPhone) File I/O: * Optimise al_fread{16,32}* by using only one call to al_fread each. * Optimise al_fgetc() for stdio backend. Path: * Fix an infinite loop in _find_executable_file when searching for the executable on the PATH (Alan Coopersmith). Primitives addon: * Made the software driver for the primitives addon check for blending properly. Also, fixed two line shaders. * Made the D3D driver thread-safe. The whole addon should be thread-safe now. * The addon now officially supports 3D vertices, even though the software component can't draw them yet. * Changed the way the primitives addon handles the OpenGL state (fixes a few bugs and makes life easier for raw-OpenGL people) Image addon: * Optimised BMP, PCX, TGA loaders. * Fix loading 16-bit BMP files. * Fix loading grayscale TGA images. * Nial Giacomelli fixed a bug where images could be corrupt using the native Apple image loader (iPhone). Audio addon: * Add al_is_audio_installed. * Fix al_attach_sample_instance_to_mixer for int16 mixers. * Implement attaching an INT16 mixer to another INT16 mixer. * Handle conversion when an INT16 mixer is attached to a UINT16 voice. Build system: * Add an option to disable Apple native image loader (iPhone and OS X). * Add ttf addon target to iPhone xcode project. Examples: * Special contribution from Shawn "the Progenitor" Hargreaves. Changes from 4.9.17 to 4.9.18 (March 2010) ****************************************** The main developers this time were: Trent Gamblin, Elias Pschernig, Evert Glebbeek, Peter Wang. Other contributions from: Milan Mimica, Paul Suntsov, Peter Hull. Graphics: * Fixed broken drawing into memory bitmaps as access to the global transformation required an active display. Now both transformation and current blending mode are stored in the display but provisions are made for them to also work if the current thread has no display. * Fixed a bunch of clipping problems with OpenGL, especially with sub-bitmaps. * Fix bug in OpenGL FBO setup when the target bitmap is the sub-bitmap of a bitmap with an FBO. * Fixed crash in al_get_num_display_modes under OSX 10.5. * Fixed some problems in _al_convert_to_display_bitmap that caused problems in WGL FS display resize. * Fixed al_set_current_display(NULL) on WGL. * Added subtractive blending. al_set_blender() takes another parameter. * Added ALLEGRO_FULLSCREEN_WINDOW display flag (X11 and D3D for now). * Allow changing ALLEGRO_FULLSCREEN_WINDOW with al_toggle_display_flag. * Figured out how to switch display modes using Carbon on OS X 10.6. * Stop the OpenGL driver on iPhone from changing the currently bound FBO behind our back when locking a bitmap. * Prevent screen flicker at app startup by simulating the splash screen (iPhone). Input: * Added "pressure" field to the mouse event struct and mouse state, which can be used with pressure sensitive pointing devices, i.e. tablets/stylus (currently OS X only). * Report scroll ball "w" position in mouse event struct, on OS X. * Removed OS X 10.1 specific code from mouse driver. We don't support OS X 10.1 any more. * Fix building of Linux joystick driver on some systems. Threads: * Fix a problem when al_join_thread() is called immediately after al_start_thread(). The thread could be joined before the user's thread function starts at all. * Fix a possible deadlock with al_join_thread() on Windows (thanks to Michał Cichoń for the report). * Fix some error messages running threading examples on OS X. Other core: * Added version check to al_install_system. * Rename al_free_path to al_destroy_path for consistency. * Make it possible to have an empty organization name with al_set_org_name(). * Changed implementation of AL_ASSERT to use POSIX-standard assert instead. * Removed al_register_assert_handler. * Fix timer macros which did not parenthesize their arguments. * Make stricmp, strlwr, strupr macros conditionally defined. Audio addon: * Rename al_attach_sample_to_mixer to al_attach_sample_instance_to_mixer. * Fix a premature free() when detaching samples and other audio objects. * Fix mixers attaching to mixers. * Pass correct number of samples to mixer postprocess callback. * AudioQueue code was not compiled even though version requirements may have been met (OS X). Primitives addon: * Make high-level primitives functions thread safe. (note: the DirectX driver is not yet thread safe) * Fix a bug causing crashes on Windows 7 when using the primitives addon and Direct3D (Invalid vertex declarations were being used). * Fixed another issue with primitives drawing to memory bitmaps. * Hopefully fix the bitmap clipping bugs, and make the D3D and OGL/Software outputs to be near-identical again. Image addon: * Added a "native loader" for MacOS X that uses the NSImage bitmap loading functions. In addition to .png and .jpg, this allows us to read a whole zoo of image formats (listed in allegro.log). * Add native support for tif, jpg, gif, png, BMPf, ico, cur, xbm formats to under IPhone. * Fixed an over-zealous ASSERT() that disallowed passing NULL to al_register_bitmap_loader() despite this being an allowed value. * Avoid using a field which is deprecated in libpng 1.4. Color addon: * Make al_color_name_to_rgb return a bool. Native dialogs addon: * Fixed some erratic behaviour and crashes on OS X. Build system: * Set VERSION and SOVERSION properties on targets to give Unix shared libraries proper sonames. e.g. liballegro[_addon].so.4.9, liballegro[_addon].4.9.dylib * Static libraries are now named without version number suffixes to minimise the differences with the shared libraries, which no longer have the versions in their base names. e.g. liballegro[_addon]-static.a, allegro[_addon]-static.lib * Windows import libraries are also named without version suffixes, e.g. liballegro[_addon].a, allegro[_addon].lib * DLLs are named with a short version suffix, not the full version. e.g. allegro-4.9.dll instead of allegro-4.9.18.dll * Add support for Mac OS X frameworks (untested), which are enabled with WANT_FRAMEWORKS and WANT_EMBED. There is one framework per addon. * Search for static OGG/Vorbis libraries built with MSVC named libogg_static.lib, etc. * Updated iPhone XCode project. Examples: * ex_mixer_pp: New example to test mixer postprocessing callbacks. * ex_threads: Make it more visually interesting and test out per-display transformations. * ex_ogre3d: New example demonstrating use of Ogre graphics rendering alongside Allegro (currently GLX only). Commented out in the build system for now. * ex_fs_window: New example to test ALLEGRO_FULLSCREEN_WINDOW flag and al_toggle_display_flag. * ex_blend2: Updated to test subtractive blending, including scaled/rotated blits and the primitives addon. * ex_mouse_events: Show "w" field. * ex_prim: Added possibility to click the mouse to advance screens (for iPhone). * ex_vsync: Display config parameters and warning. * ex_gldepth: Make the textures appear again though we're not sure why they disappeared. Documentation: * Many documentation updates. * Add which header file and which library to link with for each page of the reference manual. * Minor improvements to HTML styling and man page output. Changes from 4.9.16 to 4.9.17 (February 2010) ********************************************* The main developers this time were: Trent Gamblin, Elias Pschernig, Evert Glebbeek, Paul Suntsov, Peter Wang. Core: * Removed END_OF_MAIN() everywhere. For MSVC, we pass a linker option through a #pragma. On Mac OS X, we rename main() and call it from a real main() function in the allegro-main addon. The prototype for main() for C++ applications should be "int main(int, char **)", or the code will not compile on OS X. For C, either of the normal ANSI forms is fine. #define ALLEGRO_NO_MAGIC_MAIN disables the #pragma or name mangling, so you can write a WinMain() or use al_run_main() yourself. Graphics: * Fixed a bug in the OpenGL driver where al_draw_bitmap() wouldn't handle blitting from the back buffer. * Changing the blending color now works with deferred drawing (Todd Cope). * Avoid some problems with window resizing in Windows/D3D. * Added al_get_d3d_texture_position. * Fixed bug under X11 where al_create_display() would always use the display options from the first al_create_display() call. * Properly implemented osx_get_opengl_pixelformat_attributes(). * Fixed automatic detection of colour depth on OS X. * Fixed al_get_num_display_modes() on Mac OS X 10.6. * Removed al_get_num_display_formats, al_get_display_format_option, al_set_new_display_format functions as they can't be implemented on OSX/iPhone/GPX ports (and were awkward to use). * Replaced al_toggle_window_frame function with a new function al_toggle_display_flags. * al_load_bitmap() and al_convert_mask_to_alpha() no longer reset the current transformation. * Add a minimize button to all non-resizable windows on Windows. * The wgl display switch-in/out vtable entries were swapped (Milan Mimica). Input: * Some keycodes were out of order in src/win/wkeyboard.c * Fixed mouse range after resizing window on Windows. * Fixed (or worked around) a joystick axis detection problem on Mac OS X. * Change timer counts from 'long' to 'int64_t'. File I/O: * Remove `ret_success' arguments from al_fread32be/le. allegro-main addon: * Added an "allegro-main" addon to hold the main() function that is required on Mac OS X. This way the user can opt out of it. Primitives addon: * Added support for sub-bitmap textures in OpenGL driver. * Added support for sub-bitmap textures in D3D driver. Made D3D sub-bitmaps work better with user D3D code. Audio addons: * Changed the _stream suffix to _f in the audio loading functions. * Added the stream versions of loading functions for wav, ogg and flac. * Rename audio I/O functions to al_load_{format}, al_save_{format}, al_load_{format}_f and al_save_{format}_f. * Added al_load_sample_f, al_save_sample_f, al_load_audio_stream_f and the related functions. * Fixed a bug where al_save_sample was improperly handling the extension. * al_drain_audio_stream would hang on an audio stream in the 'playing' state (the default) which wasn't attached to anything. * Fixed a potential deadlock on destroying audio streams by shutting down the audio driver. * Comment out PA_SINK_SUSPENDED check, which breaks the PulseAudio driver, at least on Ubuntu 9.10. * Replace unnecessary uses of `long' in audio interfaces. Image addons: * Fixed return values of al_save_bmp_f and al_save_pcx_f being ignored. * Changed the _stream suffix to _f in the image loading functions. TTF addon: * Drawing TTF fonts no longer resets the current transformation. Build system: * Add the CMake option FLAC_STATIC, required when using MSVC with a static FLAC library. * Link with zlib if linking with PhysicsFS is not enough. * Updated iPhone project files. Documentation: * Many documentation updates. Examples: * ex_display_options: Added mouse support, query current display settings, display error if a mode can't be set. Bindings: * Made the Python wrapper work under OSX. * Added a CMake option to build the Python wrapper. * Added al_run_main() mainly to support the Python wrapper on OSX. Changes from 4.9.15.1 to 4.9.16 (November 2009) *********************************************** The main developers this time were: Trent Gamblin and Paul Suntsov. Graphics: * Fixed clipping of the right/bottom edges for the software primitives. * Enable sub-pixel accuracy for rotated blitting in software. * Made the D3D output look closer to the OGL/Software output. * OpenGL driver now respects the 'linear' texture filtering configuration option. Anisotropic is interpreted as linear at this time. * Added deferred bitmap drawing (al_hold_bitmap_drawing). * Made the font addons use deferred bitmap drawing instead of the primitives addon, removing the link between the two addons. * Changed al_transform_vertex to al_transform_coordinates to make the function more versatile. * Transfered transformations from the primitives addon into the core. Added documentation for that, as well as a new example, ex_transform. Transformations work for hardware accelerated bitmap drawing (including fonts) but the software component is not implemented as of yet. Also fixed some bugs inside the code of the transformations. * Increase performance of screen->bitmap blitting in the D3D driver. * Fixed a strange bug with textured primitives (u/v repeat flags were being ignored on occasion). * Added ALLEGRO_VIDEO_BITMAP for consistency. Input: * Work around a memory leak in iPhone OS that occurs when the accelerometer is on during touch input. Other core: * Don't #define true/false/bool macros in C++. Audio addon: * Some minor cleanups to the Audio Queue driver. Changes from 4.9.15 to 4.9.15.1 (October 2009) ********************************************** * Fixed a problem building on MinGW (dodgy dinput.h). Changes from 4.9.14 to 4.9.15 (October 2009) ******************************************** The main developers this time were: Trent Gamblin, Elias Pschernig, Matthew Leverton, Paul Suntsov, Peter Wang. Core: * Set the initial title of new windows to the app name. * Add al_set/get_event_source_data. * Make locking work on bitmaps that didn't have an FBO prior to the call on iPhone. * Make al_get_opengl_fbo work on iPhone. * Made iPhone port properly choose a visual (so depth buffer creation works). Font addon: * Improved drawing speed for longish strings. The font addon now depends on the primitives addon. Primitives addon: * Made the ribbon drawer handle the case of extremely sharp corners more gracefully. * Make al_draw_pixel use blend color in the D3D driver. * Added POINT_LIST to the primitive types. * Various fixes for the D3D driver: fixed line loop drawing; made the indexed primitives a little faster; added workabouts for people with old/Intel graphics cards. * Fall back to software if given a memory bitmap as a texture. * Removed OpenGL state saving code, it was causing massive slowdown when drawing. Also removed glFlush for the same reason. Audio addon: * Added PulseAudio driver. * Support AudioQueue driver on Mac OS X. * Add al_uninstall_audio exit function. * Added ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event to signify when non-looping streams made with al_load_audio_stream reach the end of the file. * Fixed a deadlock when destroying voices. * Handle underruns in the r/w ALSA updater. * Minor change to the ALSA driver to improve compatibility with PulseAudio. Documentation: * Replaced awk/sh documentation scripts with C programs. Changes from 4.9.13 to 4.9.14 (September 2009) ********************************************** The main developers this time were: Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Evert Glebbeek, Matthew Leverton. Ports: * Elias Pschernig and Trent Gamblin started a iPhone port. Graphics: * Added al_get_opengl_texture_size and al_get_opengl_texture_position functions. * Try to take into account GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT when locking OpenGL bitmaps. * Fixed all (hopefully) conversion mistakes in the color conversion macros. * Sped up memory blitting, which was using conversion even with identical formats (in some cases). * Make al_set_current_display(NULL); unset the current display. * Added ALLEGRO_LOCK_READWRITE flag for al_lock_bitmap (in place of 0). * Fixed window titles which contain non-ASCII characters in X11. * Added OES_framebuffer_object extension. Input: * Added a lot more system mouse cursors. * Renamed al_get_cursor_position to al_get_mouse_cursor_position. * Prevent Windows from intercepting ALT for system menus. Filesystem: * Make the path returned by al_get_entry_name() owned by the filesystem entry so the user doesn't need to free it manually. * Renamed the filesystem entry functions, mainly to include "fs_entry" in their names instead of just "entry". * Reordered and renamed ALLEGRO_FS_INTERFACE members. * Make al_read_directory() not return . and .. directory entries. * Renamed al_create_path_for_dir to al_create_path_for_directory. * Added al_set_standard_file_interface, al_set_standard_fs_interface. Events: * Exported ALLEGRO_EVENT_TYPE_IS_USER. Threads: * Added a new function al_run_detached_thread. Other core: * Put prefixes on register_assert_handler, register_trace_handler. * Added functions to return the compiled Allegro version and addon versions. * Added al_ prefix to fixed point routines and document them. * Added al_get_system_config(). * Renamed al_system_driver() to al_get_system_driver(). * Added 64-bit intptr_t detection for Windows. * Added work-around to make OS X port compile in 64 bit mode. Addons: * Renamed addons from a5_* to allegro_*. Image addon: * Renamed the IIO addon to "allegro_image". * Renamed *_entry functions that take ALLEGRO_FILE * arguments to *_stream. * Fixed off-by-one error in greyscale JPEG loader. Audio addons: * Renamed the kcm_audio addon to "allegro_audio". * Renamed ALLEGRO_STREAM and stream functions to ALLEGRO_AUDIO_STREAM and al_*audio_stream*. * Renamed al_stream_from_file to al_load_audio_stream * Added int16 mixing and configurable frequency and depth for default mixer/voice (see configuration file). * Fixed FLAC decoding and added FLAC streaming support. * Changed the function signature of al_get_stream_fragment() to be more straightforward. * Fixed bug in kcm audio that caused data to be deleted that was still used. * Made ALSA audio driver work when the driver does not support mmap (commonly because the ALSA really is PulseAudio). * Removed al_is_channel_conf function. Font addons: * Optimized font loading by converting the mask color on a memory copy instead of have to lock a texture. * Made the ttf addon read from file streams. Primitives addon: * Fixed the direction of the last segment in software line loop, and fixed the offsets in the line drawer. * Fixed the thick ribbon code in the primitives addon, was broken for straight segments. * Various fixes/hacks for the D3D driver of the primitives addon: hack to make the indexed primitives work and a fix for the textured primitives. * Various enhancements to the transformations API: const correctness, transformation inverses and getting the current transformation. * Added support for custom vertex formats. * Flipped the v axis of texture coordinates for primitives. Now (u=0, v=0) correspond to (x=0, y=0) on the texture bitmap. * Added a way to use texture coordinates measured in pixels. Changed ALLEGRO_VERTEX to use them by default. PhysicsFS: * PhysFS readdir didn't prepend the parent directory name to the returned entry's path. * Set execute bit on PhysFS directory entries. Examples: * Made examples report errors using the native dialogs addon if WANT_POPUP_EXAMPLES is enabled in CMake (default). * Added new example ex_draw_bitmap, which simply measures FPS when drawing a bunch of bitmaps (similar to exaccel in A4). Documentation: * Many documentation updates and clarifications. * Fixed up Info and PDF documentation. Bindings: * Added a script to generate a 1:1 Python wrapper (see `python' directory). Changes from 4.9.12 to 4.9.13 (August 2009) ******************************************* The main developers this time were: Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Todd Cope, Evert Glebbeek, Michael Harrington, Matthew Leverton. Ports: * Trent Gamblin started a port to the GP2X Wiz handheld console. Graphics: * Some OpenGL bitmap routines were not checking whether the target bitmap was locked. * Scaled bitmap drawer was not setting the blend mode. * Fixed a bug where al_map_rgb followed by al_unmap_rgb would return different values. * Fixed problems with sub-sub-bitmaps. * Fixed window placement on OS X, which did not properly translate the coordinates specified by the user with al_set_new_window_position(). * Made is_wgl_extension_supported() fail gracefuly. * Added ALLEGRO_ALPHA_TEST bitmap flag. * Minor optimizations in some memory blitting routines. Input: * Replaced (ALLEGRO_EVENT_SOURCE *) casting with type-safe functions, namely al_get_keyboard_event_source, al_get_mouse_event_source, al_get_joystick_event_source, al_get_display_event_source, al_get_timer_event_source, etc. * Made it so that users can derive their own structures from ALLEGRO_EVENT_SOURCE. al_create_user_event_source() is replaced by al_init_user_event_source(). * Fixed a problem on Windows where the joystick never regains focus when tabbing away from a window. * Fixed a problem with missing key repeat with broken X.Org drivers. * Implemented ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY for X11. Image I/O addon: * Changed return type of al_save_bitmap() to bool. * Separated al_add_image_handler into al_register_bitmap_loader, al_register_bitmap_saver, etc. * Made JPEG and PNG loaders handle al_create_bitmap() failing. * Speed up JPEG loading and saving. * Fixed a reinitialisation issue in iio. Audio addons: * Moved basic sample loading/saving routines to kcm_audio from acodec and added file type registration functions. * Moved WAV support into kcm_audio. * Made WAV loader not choke on extra chunks in the wave. * Separated acodec into a5_flac, a5_vorbis addons. You need to initialise them explicitly. Removed sndfile support. * Renamed al_*_oggvorbis to al_*_ogg_vorbis. * Changed argument order in al_save_sample and al_stream_from_file. * Reordered parameters in al_attach_* functions to follow the word order. * Renamed a few streaming functions to refer to fragments/buffers as fragments consistently. * Added missing getters for ALLEGRO_SAMPLE fields. * Fixed mutex locking problems with kcm_audio objects. * Avoid underfilling a stream when it is fed with a short looping stream. Other addons: * Added glyph advance caching for the TTF addon. * Renamed al_register_font_extension to al_register_font_loader. Match the file name extension case insensitively. Documentation: * Lots of documentation updates. * Added a short "Getting started guide" to the reference manual. Examples: * Added another example for kcm_audio streaming: ex_synth. Build system: * Fix pkg-config .pc files generated for static linking. * DLL symbols are now exported by name, not ordinals. Changes from 4.9.11 to 4.9.12 (July 2009) ***************************************** * Fixed bugs in Windows keyboard driver (Todd Cope). * Fixed problems with ALLEGRO_MOUSE_STATE buttons on Windows (Milan Mimica). * Fixed problems with PhysicsFS addon DLL on MSVC (Peter Wang). * Set the D3D texture address mode to CLAMP (Todd Cope). * Fixed hang if Allegro was initialized more than once on Windows (Michael Harrington). * Added a CMake option to force the use of DllMain style TLS on Windows, for use with C# bindings (Michael Harrington). * Fixed a bug where drawing circles with a small radius would crash (Elias Pschernig). * Fixed several memory leaks throughout the libraries (Trent Gamblin). * Fixed some compilation warnings on Mac OS X (Evert Glebbeek). * Small documentation updates. Changes from 4.9.10.1 to 4.9.11 (June 2009) ******************************************* The main developers this time were: Trent Gamblin, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Christopher Bludau, David Capello, Todd Cope, Evert Glebbeek, Peter Hull. Graphics: * Changed rotation direction in memory blitting routines to match D3D/OpenGL routines. * Made al_set_target_bitmap not create an FBO if the bitmap is locked. * Added explicit FBO handling functions al_get_opengl_fbo and al_remove_opengl_fbo in case we weren't quite clever enough above and the user has to intervene manually. * Added OpenGL 3.1 support and a bunch of new OpenGL extensions. * Fixed al_inhibit_screensaver on Windows * Fixed selection of X pixel formats with WGL if a new bitmap has alpha. * Made X11 icon work regardless of the backbuffer format. Input: * Ditched DirectInput keyboard driver and replaced it with WinAPI. Fixes several issues the old driver had. * Rewrote Windows mouse driver to use WinAPI instad of DirectInput. * Added al_get_joystick_number. Filesystem: * Merged ALLEGRO_FS_HOOK_ENTRY_INTERFACE into ALLEGRO_FS_INTERFACE and made ALLEGRO_FS_INTERFACE public. * Added al_set_fs_interface and al_get_fs_interface. * Made al_opendir take an ALLEGRO_FS_ENTRY. * Removed functions which are obsolete or probably have no use. * Made al_get_standard_path(ALLEGRO_PROGRAM_PATH) return a path with an empty filename. Path routines: * Renamed functions to follow conventions. File I/O: * Fix al_fgets() returning wrong pointer value on success. Primitives addon: * Added support for textured primitives in software. * Introduced ALLEGRO_PRIM_COLOR, removed ALLEGRO_VBUFFER. * Exposed the software line and triangle drawers to the user. * Added rounded rectangles. * Fix an extraneous pixel bug in the triangle drawer. Audio addon: * Change from using generic get/set audio property functions to specific getter/setter functions. * Change return types on many functions to return true on success instead of zero. (Watch out when porting your code, the C compiler won't help.) Native dialogs: * Added a Windows implementation. * Added a title to al_show_native_message_box(). Other addons: * Implemented the filesystem interface for PhysicsFS and demonstrate its use in ex_physfs. * Fixed al_color_html_to_rgb. Examples: * Added an OpenGL pixel shader example. Build system: * Output separate pkg-config .pc files for static linking. Changes from 4.9.10 to 4.9.10.1 (May 2009) ****************************************** * Fixed uses of snprintf on MSVC. * Disabled ex_curl on Windows as it requires Winsock. Changes from 4.9.9.1 to 4.9.10 (May 2009) ***************************************** The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan Mimica, Elias Pschernig, Peter Wang. Other contributions from: Peter Hull, Paul Suntsov. Graphics: * Renamed al_clear() to al_clear_to_color(). * Renamed al_opengl_version() to al_get_opengl_version(). * Changed the direction of rotation for al_draw_rotated* from counter-clockwise to clockwise. * Added new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which guanrantees component ordering. * Added ALLEGRO_NO_PRESERVE_TEXTURE flag. * Fixed horizontal flipping in plain software blitting routines. * Fixed some blending bugs in the OpenGL driver. * Made OpenGL driver fall back to software rendering if separate alpha blending is requested but not supported. * Added a config option which allows pretending a lower OpenGL version. * Implemented al_get_num_display_formats(), al_get_display_format_option() and al_set_new_display_format() for WGL. * Fixed bug in al_get_display_format_option() with the GLX driver. * Fixed a bug in the D3D driver that made display creation crash if the first scored mode failed. * Made the OpenGL driver prefer the backbuffer format for new bitmaps. * Defer FBO creation to when first setting a bitmap as target bitmap. Input: * Renamed some joystick functions. * Account for caps lock state in OS X keyboard driver. * Made UTF-8 input work on X11. File I/O: * Separated part of fshook API into a distinct file I/O API (actually generic streams). * Make the file I/O API match stdio more closely and account for corner cases. (incomplete) * Made it possible to set a stream vtable on a per-thread basis, which affects al_fopen() for that thread. * Added al_fget_ustr() to read a line conveniently. * Change al_fputs() not to do its own CR insertion. * Add al_fopen_fd() to create an ALLEGRO_FILE from an existing file descriptor. Filesystem: * Changed al_getcwd, al_get_entry_name to return ALLEGRO_PATHs. * Renamed al_get_path to al_get_standard_path, and to return an ALLEGRO_PATH. * Changed al_readdir to return an ALLEGRO_FS_ENTRY. * Added al_path_create_dir. * Removed some filesystem querying functions which take string paths (ALLEGRO_FS_ENTRY versions will do). Config routines: * Added functions to traverse configurations structures. * Change al_save_config_file() return type to bool. * Removed an arbitrary limit on the length of config values. * Renamed configuration files to allegro5.cfg and allegro5rc. String routines: * Allegro 4-era string routines removed. * Added al_ustr_to_buffer(). Other core: * Renamed al_thread_should_stop to al_get_thread_should_stop. * Added a new internal logging mechanism with configurable debug "channels", verbosity levels and output formatting. * Cleaned up ASSERT namespace pollution. Font addons: * Renamed font and TTF addon functions to conform to conventions. * Added al_init_ttf_addon. * Implemented slightly nicer text drawing API: * functions are called "draw_text" instead of "textout" * centre/right alignment handled by a flag instead of functions * functions accepting ALLEGRO_USTR arguments provided * substring support is removed so 'count' arguments not needed in usual case, however ALLEGRO_USTR functions provide similar thing. * Removed al_font_is_compatible_font. * Sped up al_grab_font_from_bitmap() by five times. * ttf: Fixed a possible bug with kerning of unicode code points > 127. Image I/O addon: * Renamed everything in the IIO addon. * Exposed al_load_bmp/al_save_bmp etc. Audio addon: * Renamed al_mixer_set_postprocess_callback. * Added two config options to OSS driver. * Made ALSA read config settings from [alsa] section. Native dialogs: * Added al_show_native_message_box() which works like allegro_message() in A4. Implemented for GTK and OS X. PhysicsFS addon: * Added PhysicsFS addon. Primitives addon: * Removed global state flags. * Removed normals from ALLEGRO_VERTEX. * Removed read/write flags from vertex buffers. Examples: * Added an example that tests al_get_display_format_option(). * Added an example which shows playing a sample directly to a voice. * Added an example for PhysicsFS addon. * Added a (silly) example that loads an image off the network using libcurl. * Added ex_dir which demonstrates the use of al_readdir and al_get_entry_name. Other: * Many bug and documentation fixes. Changes from 4.9.9 to 4.9.9.1 (March 2009) ****************************************** * Made it compile and work with MSVC and MinGW 3.4.5. * Enabled SSE instruction set in MSVC. * Fixed X11 XIM keyboard input (partially?). * Fall back on the reference (software) rasterizer in D3D. Changes from 4.9.8 to 4.9.9 (March 2009) **************************************** The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Todd Cope, Angelo Mottola, Trezker. Graphics: * Added display options API and scoring, based on AllegroGL, for finer control over display creation. * Added API to query possible display formats (implemented on X, Mac OS X). * Changed the bitmap locking mechanism. The caller can choose a pixel format. * Added support for multisampling. * Simplified the semantics of al_update_display_region(). * Optimised software blitting routines. * Optimised al_map_rgb/al_map_rgba. * Replaced al_draw_rectangle() and al_draw_line() from core library with al_draw_rectangle_ex() and al_draw_line_ex() from the primitives addon. * Implemented al_wait_for_vsync() everywhere except WGL. * Fixed problems with sub-bitmaps with the OpenGL driver. * Fixed bugs in software scaled/rotated blit routines. * Added a new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_F32. Removed ALLEGRO_PIXEL_FORMAT_ANY_15_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_24_WITH_ALPHA. * Added support for creating OpenGL 3.0 contexts (untested; only WGL/GLX for now). Relevant display flags are ALLEGRO_OPENGL_3_0 and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. * Allow disabling any OpenGL extensions from allegro.cfg to test alternative rendering paths. * Fixed problem with windows only activating on title bar clicks (Windows). * Fixed a minimize/restore bug in D3D (with the help of Christopher Bludau). Input: * Implemented al_set_mouse_xy under X11. * Added ALLEGRO_EVENT_MOUSE_WARPED event for al_set_mouse_xy(). Path routines: * Made al_path_get_drive/filename return the empty string instead of NULL if the drive or filename is missing. * Changed al_path_set_extension/al_path_get_extension to include the leading dot. * Made al_path_get_extension(), al_path_get_basename(), al_path_to_string() return pointers to internal strings. Unicode: * Changed type of ALLEGRO_USTR; now you should use pointers to ALLEGRO_USTRs. * Added UTF-16 conversion routines. Other core: * Added ALLEGRO_GET_EVENT_TYPE for constructing integers for event type IDs. * Renamed configuration function names to conform to conventions. * Removed public MIN/MAX/ABS/MID/SGN/CLAMP/TRUE/FALSE macros. * Replaced AL_PI by ALLEGRO_PI and documented it as part of public API. Audio addons: * Added stream seeking and stream start/end loop points. * Add panning support for kcm_audio (stereo only). Font addons: * Made al_font_grab_font_from_bitmap() accept code point ranges. * Made font routines use new UTF-8 routines; lifted some arbitrary limits. * Fixed artefacts in bitmap font and TTF rendering. Image I/O addon: * Made the capability to load/save images from/to ALLEGRO_FS_ENTRYs public. * Added missing locking to .png save function. Other addons: * Added native_dialog addon, with file selector dialogs. * Fixed many bugs in the primitives addon. * Made hsv/hsl color functions accept angles outside the 0..360° range. * Fixed a bug in al_color_name_to_rgb. Examples: * New programs: ex_audio_props, ex_blend_bench, ex_blend_test, ex_blit, ex_clip, ex_draw, ex_font_justify, ex_gl_depth, ex_logo, ex_multisample, ex_native_filechooser, ex_path_test, ex_rotate, ex_stream_seek, ex_vsync, ex_warp_mouse. (ex_draw demonstrated known bugs currently.) * Updated programs: ex_joystick_events, ex_monitorinfo ex_pixelformat, ex_scale, ex_subbitmap. Build system: * Added pkg-config support. .pc files are generated and installed on Unix. * Allowed gcc to generate SSE instructions on x86 by default. For Pentium 2 (or lower) compatibility you must uncheck a CMake option before building Allegro. Other: * Many other bug fixes. Changes from 4.9.7.1 to 4.9.8 (February 2009) ********************************************* The main developers this time were: Thomas Fjellstrom, Trent Gamblin, Evert Glebbeek, Matthew Leverton, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. General: * Lots of bug fixes. File system hooks: * Rationalised file system hook functions. Failure reasons can be retrieved with al_get_errno(). * Enable large file support on 32-bit systems. * Converted the library and addons to use file system hook functions. Path functions: * Added al_path_clone(), al_path_make_canonical(), al_path_make_absolute(), al_path_set_extension(), al_{get,set}_org_name, al_{get,set}_app_name} functions. * Made al_path_get_extension() not include the leading "." of the extension, * Add AL_EXENAME_PATH, AL_USER_SETTINGS_PATH, AL_SYSTEM_SETTINGS_PATH enums for al_get_path(). String routines: * Added a new, dynamically allocating UTF-8 string API. This uses bstrlib internally, which is distributed under a BSD licence. Allegro 5 will expect all strings to be either ASCII compatible, or in UTF-8 encoding. * Removed many old Unicode string functions. (Eventually they will all be removed.) Config routines: * Clarified behaviour of al_config_add_comment, al_config_set_value with regards to whitespace and leading comment marks. Graphics: * Bug fixes on Windows and Mac OS X for resizing, switching away, setting full screens, multi-monitor, etc. * Added an al_get_opengl_texture() convenience function. * Added separate alpha blending. * Added ALLEGRO_PIXEL_FORMAT_ANY. * Honour al_set_new_window_position() in X11 port. * Made the X11 port fail to set a full screen mode if the requested resolution cannot be set rather than falling back to a windowed mode. Input: * Added a field to the mouse state struct to indicate the display the mouse is currently on. * Made DirectX enumerate all joysticks/gamepads properly by using a device type new to DirectInput 8. * Fixed a bug in wmouse.c where y was not changed in al_set_mouse_xy. * Support ALLEGRO_EVENT_MOUSE_ENTER/LEAVE_DISPLAY events in Windows. Addons: * Added a primitives addon. * Revamp interface for kcm_audio addon to make simple cases easier. * Added native .wav support and save sample routines to acodec addon. * Added a colors addon. * Added memory file addon and example. TTF addon: * Added al_ttf_get_text_dimensions() function. * Allow specifying the font size more precisely by passing a negative font size. * Guess the filenames of kerning info for Type1 fonts. Documentation: * Added a new documentation system using Pandoc. Now we can generate HTML, man, Info and PDF formats. * Added and fixed lots of documentation. Examples: * Added ex_prim, ex_mouse_focus examples. * Made ex_blend2 more comprehensive. * Updated ex_get_path example. * Made ex_ttf accept the TTF file name on the command line. Build system: * Use official CMAKE_BUILD_TYPE method of selecting which build configuration. This should work better for non-make builds, however, it's no longer possible to build multiple configurations with a single configuration step as we could previously. Removals: * Remove outdated A4 tools. * Remove icodec addon. * SCons build was unmaintained and not working. Changes from 4.9.7 to 4.9.7.1 (December 2008) ********************************************* * Scan aintern_dtor.h for export symbols, needed for MSVC. Changes from 4.9.6 to 4.9.7 (December 2008) ******************************************* The main developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Peter Wang. Graphics: * Fixed a bug where the "display" field of a bitmap was not correctly reset when it was transfered to another display on OS X. * Made al_create_display() respect al_set_new_window_position() on OS X. * Fixed the bug that caused input focus to be lost in OS X when a window was resized. * Made resizable Allegro windows respond properly to the green "+" button at the top of the screen on OS X. * Properly implemented fullscreen resize in WGL. * Made the memory blenders work the same as the hardware ones. * Made al_get_pixel()/al_draw_pixel() handle sub bitmaps in case the bitmap was locked. * In the OpenGL driver, if the bitmap is locked by the user, use memory drawing on the locked region. * Added implementations of al_inhibit_screensaver() for the X and Mac OS X ports. * Added multi-monitor support to Mac OS X port (untested!). * Other fixes. Input: * Made al_get_keyboard_state() return structures with the `display' field correctly set. * Made keyboard event member 'unichar' uppercase when Shift/CapsLock is on, in Windows. * Made mouse cursor show/hide work with Mac OS X full screen. Config routines: * Preserve comment and empty lines in config files when writing. Addons: * Add a simple interface layer for kcm_audio. * Made kcm_audio objects automatically be destroyed when it is shut down. * Renamed functions in kcm_audio to conform better with the rest of the library. * Made the TTF addon aggregate glyph cache bitmaps into larger bitmaps for faster glyph rendering (less source bitmap switching). Examples: * Add an example to test the ALLEGRO_KEYBOARD_STATE `display' field. * Add an example for testing config routines. * Add an example for checking software blending routines against hardware blending. * Add an example for the simple interface for kcm_audio. Changes from 4.9.5 to 4.9.6 (November 2008) ******************************************* The core developers this time were: Thomas Fjellstrom, Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Jon Rafkind, Peter Wang. Allegro 4.9.6 and onwards are licensed under the zlib licence (see LICENSE.txt). This is a simple permissive free software licence, close in spirit to the 'giftware' licence, but is clearer and more well-known. General: * Added filesystem hook (fshook) and path API functions. * Many minor bug fixes. Graphics: * Added allegro5/a5_opengl.h, which has to be included by programs to use OpenGL specifics. ALLEGRO_EXCLUDE_GLX and ALLEGRO_EXCLUDE_WGL can be #defined to exclude GLX and WGL OpenGL extensions respectively. * Added allegro/a5_direct3d.h, which has to be included by programs to use D3D specifics. * Fixed some drawing from and onto sub-bitmaps. * Fixed blending with the wrong color in case of sub-bitmaps. * Fixed a bug in the D3D driver where the transformation matrix was not reset after drawing a bitmap. * Added draw pixel to OpenGL driver. * Added more OpenGL extensions. * Added function to inhibit screen saver (currently Windows only). Config routines: * Added al_config_create(). * Deleted al_config_set_global(). Made empty section name equivalent to the global section. * Read system wide and home directory config files on Unix (Ryan Patterson). Events: * Added support for injecting user-defined events into event queues. Audio addon: * Made the ALSA driver read the device name from the config file (Ryan Patterson). Examples: * Added ex_subbitmap example. * Added ex_disable_screensaver example. Build system: * Rationalised library names and made CMake and SCons build systems agree on the names. Changes from 4.9.4 to 4.9.5 (October 2008) ****************************************** The core developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Elias Pschernig, Jon Rafkind, Peter Wang. Graphics: * Added fullscreen support on Mac OS X. * Added support for resizable windows on Mac OS X. * Made frameless windows respond to events on Mac OS X. * Fixed a problem with D3D blending. * Made D3D driver work on systems without hardware vertex processing. * Made WGL driver fail more gracefully. * Implemented sprite flipping for OpenGL drivers (Steven Wallace). * Added al_is_sub_bitmap() function. Input: * Fixed input with multiple windows on Windows. * Fixed keyboard autorepeat events in X11. * Added al_is_keyboard_installed(). * Fixed key shifts on Windows (ported from 4.2). * Fixed mouse button reporting on Mac OS X. * Implemented system mouse cursors on MacOS X. * Fixed mouse cursors with alpha channels on X11. * Some work on Mac OS X joystick support (incomplete). Events: * Simplified internals of events system further. At the same time, this change happens to also allow event queues to grow unboundedly. (You should still avoid letting them get too big, of course.) Audio addons: * Made ALLEGRO_STREAM objects emit events for empty fragments that need to be refilled. * Added a possiblity to drain a stream created by al_stream_from_file(). * Added a function to rewind a stream. * Added gain support to ALLEGRO_STREAM and ALLEGRO_SAMPLE objects. * Made it possible to attach a sample to a mixer that isn't already attached to something. * Fixed Ogg Vorbis loader on big-endian systems. * Made the OpenAL driver the least preferred driver, as it doesn't play stereo samples properly. Image addons: * Added JPEG support to iio addon, using libjpeg. * Fixed TGA loader on big-endian systems. * Fixed image loading in icodec addon. Font addon: * Fixed count-restricted text output functions calculations on non-ASCII strings. * Made al_textout* functions always a 'count' parameter. * Renamed al_font_text_length* to al_font_text_width*. * Harmonised the order of al_font_textout* and al_font_textprintf* arguments. Examples: * Added ex_bitmap_flip example (Steven Wallace). * Added ex_mixer_chain example. * Split ex_events into smaller examples. * Made the demo use ALLEGRO_STREAM to play music. * Build an app bundle from the demo, on Mac OS X. Build system: * Improved detection of external dependencies in CMake build. * Guess compiler locations for MinGW and MSVC (CMake). * Many improvements to scons build, including install support. General: * Many other bug fixes. Changes from 4.9.3 to 4.9.4 (September 2008) ******************************************** The core developers this time were: Trent Gamblin, Peter Hull, Milan Mimica, Elias Pschernig and Peter Wang. Ryan Dickie and Jon Rafkind also contributed. General: * Many bug fixes all around. * Added a public threads API. * Added a basic configuration API. * Added al_store_state/al_restore_state functions. * Added al_get_errno/al_set_errno (not used much yet). * Renamed some functions/structures to be more consistent. * Code formatting improvements. * Added more debugging messages. * Removed a lot of A4 code that is no longer used. Graphics: * Added support for some new OpenGL extensions. * Multihead support on Windows (preliminary support on OSX and Linux). * Many enhancements to all drivers. * Merged common parts of WGL and D3D drivers. * Borderless windows, setting window positions and titles. * Fullscreen support on OSX and Linux. * Do not clear bitmaps when they are created. * Improved compile times and DLL sizes by simplifying "memblit" functions. * Added EXPOSE, SWITCH_IN and SWITCH_OUT display events. Build system: * Many bug fixes and enhancements to SCons and CMake build systems. * Support for Turbo C++ 2006. * Support for cross-compiling on Linux to MinGW (CMake). Events: * Filled in a display field for all relevant events. * Added al_wait_for_event_until. Addons: * Added an ImageMagick addon * Added iio (Image IO) addon * Supports BMP, PCX, TGA. * Supports PNG support with libpng. * Added new audio addon, kcm_audio. (The 'audio' addon was taken in a new direction between the 4.9.3 and 4.9.4 releases, but we decided against that, so actually it's actually a continuation of the old audio addon.) * Added audio streaming functionality. * Added OSS, ALSA, DirectSound drivers. * A lot of reorganisation, internally and externally. * Added TTF font addon, using FreeType. * Made all addons use "al_" prefix. Examples: * Lots of new examples. * Wait for keypress in some examples instead of arbitrary delay. * Clean up files when done in some examples. Changes from 4.9.2 to 4.9.3 (April 2008) **************************************** Graphics: * Milan Mimica did lots of work on the OpenGL drivers, such as adding an OpenGL driver for Windows and making the OpenGL code shared between platforms. * Peter Hull added an OpenGL graphics driver for Mac OS X. * Milan Mimica made the OpenGL driver share contexts between displays. * Peter Wang and Milan Mimica made the OpenGL driver work with cards that don't support non-power-of-two (NPOT) textures. * Trent Gamblin added support for NPOT textures in the Direct3D driver. * Trent Gamblin fixed blending in memory drawing functions. * Trent Gamblin added al_draw_pixel() which obeys blending. * Trent Gamblin made al_clear() not affected by blending in D3D. * Milan Mimica added the following functions to the public API: al_opengl_version(), al_is_opengl_extension_supported(), al_get_opengl_proc_address(), al_get_opengl_extension_list(). * Milan Mimica added sub-bitmaps support for memory bitmaps and in the OpenGL display driver. * Milan Mimica made displays keep a list of bitmaps. When destroying a display its bitmaps will be managed properly, e.g. converted to memory bitmaps if necessary. All display bitmaps will be automatically destroyed on exit. * Peter Wang made X window resizing work without GLX 1.3. * Trent Gamblin fixed a bug in the Direct3D driver when windows were minimized (thanks to David McCallum). * Trent Gamblin fixed the coordinates of Direct3D primitives to match OpenGL style. * Peter Hull fixed some logic in bitmap drawing and al_load_bitmap(). Fonts: * Milan Mimica made font drawing faster, by making glyphs sub-bitmaps of a larger glyph sheet. * Milan Mimica and Peter Wang made font loading faster. * Trent Gamblin added versions of text output functions which take as an explicit argument the length of the strings. Audio: * A new audio API implementation, originally by Chris Robinson, was added (currently as an addon only). It has received additional work in the past from Milan Mimica and recently much work from Ryan Dickie. * Ryan Dickie also added an acodec addon, which has loaders for FLAC, Wave and Ogg Vorbis files, using other libraries. Timers: * Ryan Dickie changed the type of timestamps throughout the API from int expressed in milliseconds to double expressed in seconds and improved timer resolution on Windows. * Ryan Dickie added an 'error' field to the timer event, and added error and overhead statistics to exnew_timer. * Trent Gamblin made the Windows timer use QueryPerformanceCounter. * Peter Wang split al_wait_for_event() into two functions, a version that takes a timeout and a version that doesn't. * Trent Gamblin merged the Windows and Unix timer source files. Input: * Peter Wang renamed some joystick and timer functions to adhere to the `al__' convention. * Peter Wang made al_num_joysticks() more lenient if there is no joystick driver installed. Other: * David Capello added support for various different BMPs. * Elias Pschernig fixed compilation of the X port in case the XVidMode extension is unavailable (thanks to Thomas Fjellstrom). * Elias Pschernig added a exnew_timer example. * Trent Gamblin added exnew_multiwin and exnew_drawpixels. * Peter Wang added exnew_timedwait and exnew_scale. * Jon Rafkind and Elias Pschernig updated the SCons build. * Jon Rafkind added a `_s' suffix to static libraries in the SCons build. * Elias Pschernig did some work on cross-compilation with SCons and MinGW. * Milan Mimica made the CMake build work with MSVC project solutions and made the library build with MSVC 8. * Jacod Dawid added a nicer spaceship graphic for a5teroids demo. * Many more bug fixes and documentation updates. Changes from 4.9.1 to 4.9.2 (November 2007) ******************************************* _This list is still to be summarised._ * Trent Gamblin made the mouse cursor always hide when the user calls al_hide_mouse_cursor in fullscreen (D3D). * Trent Gamblin fixed some signedness warnings and implemented show/hide_mouse in the display vtable for D3D. * Elias Pschernig made show/hide cursor use the display driver instead of the 4.2 gfx_driver. * Elias Pschernig fixed missing keyboard events in exnew_mouse_events example. * Elias Pschernig wired the X11 mouse driver to the XGLX system driver. * Jon Rafkind made various fixes to get the OSX build to compile * Trent Gamblin added exnew_mouse_events. * Trent Gamblin added exnew_mouse. * Jon Rafkind made the scons build get the library name dynamically. * Jon Rafkind made the scons build link Allegro using -l instead of using the full path. * Trent Gamblin added a note about MINGDIR in readme_a5.txt. * Trent Gamblin removed -lalleg_unsharable from allegro-config.in, since assembly is not used anymore. * Jon Rafkind fixed up allegro-config. * Trent Gamblin added some documentation on ALLEGRO_MSESTATE. * Trent Gamblin listed the examples in readme_a5.txt. * Trent Gamblin improved some inline documentation. * Jon Rafkind removed /lib from install path in unix.scons. * Jon Rafkind added the new demo to the scons build and allowed addons to be built statically or shared. * Trent Gamblin made the glx line drawing function use blending. * Trent Gamblin added cmake instructions to readme_a5.txt. * Elias Pschernig added readme_a5.txt. * Trent Gamblin fixed warnings in the demo. * Trent Gamblin fixed a crash-on-exit bug in tls.c. * Trent Gamblin replaced the old demo with a temporary one. * Peter Wang fixed gcc string warnings. * Peter Wang added some assertions to display_new.c. * Peter Wang merged changes from the 4.2 branch. * Elias Pschernig removed an unnecessary import from the naturaldocs upload script. * Elias Pschernig added a script to automatically upload the naturaldocs generated documentation to the website. * Peter Wang fixed missed renamings from AL_ to ALLEGRO_ in the Linux and X code. * Elias Pschernig merged 4.9-newgfx back to 4.9. * Peter Wang fixed a "ALLEGRO__JOYSTICK" typo. * Trent Gamblin renamed AL_ to ALLEGRO_ in input, events, and timer code. * Elias Pschernig implemented outline flag and blending for draw_rectangle in the GLX driver. * Elias Pschernig added another mysha.pcx for the font example. * Elias Pschernig re-added GLX checked to scons build which went missing in the merge. * Elias Pschernig added icon.xpm which went missing in the merge. * Peter Wang replaced _al_draw_bitmap_region_memory_fast with _al_draw_bitmap_region_memory. * Trent Gamblin made memblit.c compile a little faster in debug mode. * Peter Wang mergedd changes in r7948:10859 on 4.9 branch to 4.9-newgfx branch. * Peter Wang enabled WANT_D3D by default. Only set ALLEGRO_D3D on Windows. * Trent Gamblin made al_acknowledge_resize take the display as a parameter. * Trent Gamblin fixed some warnings and made the MinGW build compilable statically with gcc 4.2.1. * Peter Wang fixed a bug in ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444. * Peter Wang renamed al_memory_management_functions() to al_set_memory_management_functions() and added some extra documenation for it. * Peter Wang removed NaturalDocs markup for Allegro 4.x display functions. * Peter Wang made OpenGL libraries link if building with X11 support. * Peter Wang fixed a signedness warning. * Peter Wang made al_destroy_bitmap return immediately when passed a null pointer instead of segfaulting. * Elias Pschernig made some cosmetic improvements to the code. * Elias Pschernig removed a bad optimization. * Elias Pschernig removed > GLX 1.1 specific code. * Trent Gamblin fixed several of the floating point unmapping functions that were doing integer division. * Elias Pschernig implemented blending in the GLX driver. * Elias Pschernig fixed GLX rotation to use radians and allow negative angles. * Elias Pschernig implemented rotated blitting in the GLX driver. * Jon Rafkind made scons install addons/font. * Jon Rafkind added a scons file for addons. * Jon Rafkind used target_scanner to find makedoc instead of using Depends. * Jon Rafkind forced makedoc to be a dependancy of the docs. * Trent Gamblin made 60hz the default refresh rate of the D3D driver. * Trent Gamblin changed al_create_mouse_cursor to accept ALLEGRO_BITMAP structures. * Trent Gamblin renamed __al_unmap_rgba to al_unmap_rgba_ex in the glx driver. * Trent Gamblin made al_(map|unmap)_rgb(a)_*_ex public. * Trent Gamblin made D3D windows show the resize cursor when resizing windows. * Jon Rafkind added allegro includes for asmdef. * Jon Rafkind erased older build demo target. * Jon Rafkind added the demo to the scons build. * Jon Rafkind made it so assembly files can be built statically. * Jon Rafkind made scons always build asmdef. * Trent Gamblin made al_acknowledge_resize and al_resize_display adjust clipping in the D3D driver. Mad eal_set_current_display * Trent Gamblin used higher compatibility flags to Direct3DCreate9, made D3D driver die more gracefully on unsupported configurations, removed flags from draw_line, and did more error checking. * Trent Gamblin turned al_init macros into an inline function. * Trent Gamblin commented out a TRACE line that was causing the entire log to be overwritten. * Peter Wang fixed an incorrect call to _al_vector_find_and_delete. * Peter Wang made various formatting fixes. * Peter Wang converted CR/LF line endings to LF. * Trent Gamblin added NaturalDocs for the graphics api. * Trent Gamblin fixed an instance where a variable could have been used uninitialized. * Trent Gamblin fixed texture coordinates in the D3D driver. * Trent Gamblin fixed formatting and an improper assertion. * Trent Gamblin removed a redundant call to al_set_target_bitmap. * Trent Gamblin fixed a bug in the DX joystick code that caused it to assert when it shouldn't. * Trent Gamblin made al_create_display call al_flip_display so the window is cleared. * Trent Gamblin made the D3D driver work where render-to-texture is not supported. * Trent Gamblin removed masking support completely. * Elias Pschernig got the font example working with the GLX driver. * Elias Pschernig renamed the font addon in the scons build. * Jon Rafkind made scons build modules in a separate directory. * Jon Rafkind bumped the version to match cmake. * Jon Rafkind fixed esd to be like the other unix modules. * Trent Gamblin changed color map and unmap functions to use the target bitmap. * Trent Gamblin added the font example to the cmake build process. * Elias Pschernig added the font example to the scons build process. * Elias Pschernig removed special handling of "src" dir, and made various cosmetic changes. * Trent Gamblin made cmake install to MINGDIR. * Trent Gamblin added a better font and example for the bitmap font addon. * Trent Gamblin removed unix header from install on other platforms. * Trent Gamblin added a bitmap font addon. * Trent Gamblin fixed a locking bug in the D3D driver. * Elias Pschernig removed masking from the GLX driver. * Trent Gamblin implemented blending for memory bitmaps (very slow unless the blend mode is ALLEGRO_ONE,ALLEGRO_ZERO with a pure white blend color). * Trent Gamblin implemented blending for the D3D driver. * Trent Gamblin added ALLEGRO_PIXEL_FORMAT_ANY_(15|16|24|32)_(WITH_ALPHA|NO_ALPHA) formats, used ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA in locking examples, and ixed some formatting. * Trent Gamblin added al_clone_bitmap which makes an exact copy of the color-data of a bitmap. * Trent Gamblin added a ALLEGRO_KEEP_BITMAP_FORMAT flag that forces Allegro to use the same format as the disk file when loading bitmaps. * Elias Pschernig implemented video bitmap masking for the GLX driver (by converting to alpha textures and drawing with alpha blending). * Elias Pschernig fixed clipping in the GLX driver. * Trent Gamblin removed ALLEGRO_MASK_SOURCE flag in favor of ALLEGRO_USE_MASKING. Mask color is now a bitmap property. Removed ALLEGRO_NO_ALPHA flag and changed the meaning of ALLEGRO_USE_ALPHA to mean do alpha blending or not. Added al_set/get_bitmap_mask_color and removed al_set/get_mask_color. New masking example added (exnew_masking). * Trent Gamblin added proper clipping to al_put_pixel. * Trent Gamblin renamed graphics stuff from AL_ to ALLEGRO_ and removed patterned drawing. * Elias Pschernig implemented clipping for the X11 GLX driver (only for screen so far). * Trent Gamblin removed unused set_bitmap_clip entry from the bitmap vtable. * Trent Gamblin made clipping always enabled and made the clipping functions operate on the current target bitamp. * Trent Gamblin removed src/compat/coblit.c. * Trent Gamblin renamed scroll_display to scroll_screen in display.c * Trent Gamblin Removed commented code from src/display.c. Removed include/allegro/display.h and src/compat/cogfx.c * Elias Pschernig renamed XDUMMY driver to XGLX. * Elias Pschernig made some cosmetic changes. * Elias Pschernig made exblend work over the compatibility screen. * Elias Pschernig implemented upload_compat_screen method in the GLX driver. * Elias Pschernig optimized al_lock_bitmap/al_unlock_bitmap slightly. * Elias Pschernig added a flags parameter to the drawing primitives methods. * Trent Gamblin added flags to primitives in display vtable and renamed draw_filled_rectangle vtable entry to draw_rectangle. * Elias Pschernig implemented AL_SINGLEBUFFER flag and fixed bug with AL_FULLSCREEN in the GLX driver. * Trent Gamblin added a mode parameter to al_set_drawing_pattern. * Trent Gamblin added AL_OUTLINED flag that is the default for primitives. * Trent Gamblin added al_set_drawing_pattern and al_get_drawing_pattern, added a flags parameters to all the primitive drawing functions that can be: AL_FILLED, AL_PATTERNED, and added hline and vline functions for memory bitmaps. * Trent Gamblin ifdefed d3d stuff in win/wnewsys.c. * Trent Gamblin removed d3dx9 library from CMakeLists.txt. * Trent Gamblin ifdefed Direct3D stuff in display.c. * Jon Rafkind made scons read win32 files from cmake file list. * Trent Gamblin added al_wait_for_vsync and made it work with the D3D driver. * Elias Pschernig implemented immediate-resize for al_resize_display, and implemented fullscreen resizing. * Trent Gamblin added al_enable_bitmap_clip and al_is_bitmap_clip_enabled, added al_create_sub_bitmap, and made it work with D3D and memory bitmaps. * Elias Pschernig improved fullscreen handling. * Elias Pschernig added shutdown_system vtable entry to the system driver, and automatically call it on program exit. This allows unsetting fullscreen modes in the X11 driver. * Trent Gamblin added al_set_bitmap_clip and al_get_bitmap_clip, and made them work with D3D and memory bitmaps. * Elias Pschernig added XF86Vidmode fullscreen modes. * Elias Pschernig added xdummy files to cmake files list. * Elias Pschernig made al_resize_display work on non-resizable windows. * Elias Pschernig fixed opengl setup being issued in wrong thread. * Elias Pschernig moved src/misc/colconv.c from windows sources to general sources. * Elias Pschernig uncommented accidentally commented out line. * Elias Pschernig made scons read the list of source files from cmake/FileList.cmake, so there's only one place to add new files. * Trent Gamblin made _al_get_pixel_value faster. * Trent Gamblin made al_unmap_rgba_i use a table instead of relying on al_unmap_rgba_f. * Peter Wang changed #includes to use file names from the root of the include hierarchy, i.e. #include "allegro/internal/foo.h" instead of #include "internal/foo.h" and likewise for allegro/platform/foo.h. * Peter Wang removed some stray CR characters. * Trent Gamblin added al_get_bitmap_width, al_get_bitmap_height, al_get_bitmap_format, and al_get_bitmap_flags. * Trent Gamblin made al_draw_rotated_(scaled_)bitmap only lock the region of the destination is needs to for memory bitmaps. * Trent Gamblin made al_draw_scaled_bitmap use the AL_FLIP_* flags. * Trent Gamblin added an example of resizing a fullscreen display. * Elias Pschernig updated xdummy driver and implemented al_resize_display for it. * Elias Pschernig added another testcase. * Trent Gamblin added al_get_display_width and al_get_display_height, made al_get_display_* work on the current display, and renamed al_notify_resize to al_acknowledge_resize. * Trent Gamblin uncommented everything in cogfx.c (removing the display parameter). * Trent Gamblin made exnew_lockscreen use pitch. * Trent Gamblin fixed scaled conversion macros (4444, 555, 565), added XRGB_8888 pixel format, made windowed mode default, moved get_num_display_modes and get_display_mode into the system vtable. * Trent Gamblin made exnew_lockbitmap use pitch. * Trent Gamblin fixed D3D unlocking bug, and used desktop format in windowed mode if not specified. * Elias Pschernig fixed a bug where events reported the wrong source display under X11. * Elias Pschernig added three simple test cases. * Elias Pschernig fixed al_lock_bitmap and al_unlock_bitmap implementation in the xdummy driver (for now it works in a slow way). * Trent Gamblin made al_notify_resize return success/failure and added al_resize_display to resize the display from code. * Elias Pschernig started implementing lock_region and unlock_region for the xdummy driver. * Elias Pschernig split xdraw.c out of xdisplay.c, used _AL_THREAD instead of pthreads in the xdummy driver, added a lock to the xdummy driver, in order to implement al_destroy_display, used the correct format. * Elias Pschernig fixed a comment typo. * Elias Pschernig fixed a typo in AL_CONVERT_PALETTE_8_TO_ABGR_8888. * Trent Gamblin improved D3D line drawing, added al_get_num_display_modes and al_get_display_mode, and cleaned up & organized some code. * Trent Gamblin removed _al_win_delete_from_vector. * Trent Gamblin added draw_memory_bitmap_region vtable hook to AL_DISPLAY. * Elias Pschernig implemented enough of the xdummy driver to run exnewap (doesn't display correctly yet though). * Elias Pschernig updated scons build files. * Elias Pschernig Removed windows specific includes from exnewapi.c. * Elias Pschernig added missing al_convert_mask_to_alpha prototype. * Peter Wang fixed src/tls.c to compile under Linux (not tested). * Trent Gamblin put TLS support back in for MSVC and UNIX. * Trent Gamblin cleaned up some code, added headers to new source files, grouped thread local variables into one structure (UNIX support is broken for now), and made mask color thread local. * Trent Gamblin added clear, filled rectangle, and line for memory bitmaps. * Trent Gamblin made it so the system driver is no longer hard coded, added switch_out method to display vtable, made the D3D window and system driver code generic. * Trent Gamblin merged 4.9-elias and 4.9-trentg into 4.9-newgfx. * Elias Pschernig adjusted prototype of _al_init to implementation. * Elias Pschernig fixed a bogus cast. * Elias Pschernig fixed typo in al_get_new_diplay_format for non-mingw. * Trent Gamblin made display and bitmap parameters local to the calling thread. * Trent Gamblin added al_draw_rotated_bitmap and al_draw_rotated_scaled_bitmap for memory bitmaps using Allegro's software rotation code as a base. * Trent Gamblin ported a stretch blit fix from 4.2, made al_init call allegro_init, made al_draw_bitmap(_region) much faster on memory bitmaps, and added al_draw_scaled_bitmap for memory bitmaps. * Trent Gamblin renamed AL_LOCKED_RECTANGLE to AL_LOCKED_REGION, and started on memory bitmaps (al_draw_bitmap and al_draw_bitmap region work). * Trent Gamblin made seperate functions for getting/setting display/bitmap parameters, made backbuffer-as-source bitmap work in D3D, and changed parameter ordering of some functions. * Trent Gamblin added al_is_compatible_bitmap removed dependancy on Allegro's 3D math functions from the D3D driver. * Trent Gamblin added al_convert_mask_to_alpha, made put/get_pixel faster if the bitmap is locked ahead of time, and brought back AL_MASK_SOURCE. * Trent Gamblin committed various bugfixes, implemented the RGB mapping/unmapping functions from Bob's API. * Trent Gamblin removed the D3DX library dependancy. * Trent Gamblin committed various bugfixes and got all of the examples working with the D3D driver. * Trent Gamblin fixed some of the compatibility conversions. * Trent Gamblin changed the examples back to autodetecting the graphics driver. * Trent Gamblin made fullscreen mode work with the D3D driver, and non-resizable windows. * Trent Gamblin finished bitmap conversion functions, improved locking, implemented get/put pixel, and made some speed improvements. * Trent Gamblin added a bitmap conversion function. * Trent Gamblin got the demo game running in D3D. * Trent Gamblin removed an unnecessary bitmap copy. * Trent Gamblin added a skeleton D3D driver. * Peter Wang fixed the generation of allegro-config under Mac OS. * Michael Jensen fixed a mistake in the documenation for is_compatible_font. * Peter Wang fixed wrong variable in example code for load_font(); * Trent Gamblin fixed some problems with the cmake build on Windows. * Peter Wang removed the second parameter in a call to _al_event_source_needs_to_generate_event() which was missed earlier. * Peter Wang exposed some internal documentation on destructors, events and event sources to NaturalDocs. * Peter Wang changed al_wait_for_event() so that a timeout value of "0" means to not wait at all. To wait an indefinite amount of time the caller should pass the AL_WAIT_FOREVER constant. * Peter Wang removed the declarations of al_event_source_set_mask and al_event_source_mask which were missed in the previous change. * Peter Wang removed event masking abilities, that is, for the user to prevent an event source from generating particular event types. This was implemented using bitfields which limited the number of event types to 32. Although the limit could be raised event masking was probably not very useful anyway. In all, the functions removed are: al_event_source_mask, al_event_source_set_mask, al_wait_for_specific_event. The al_wait_for_specific_event() API also required event types to be bitfields. * Peter Wang fixed some spelling mistakes in the examples. * Peter Wang bumped the version to 4.9.2. * Peter Wang moved allegro/branches/4.3 to allegro/branches/4.9. * Ryan Patterson clarified the documentation of stop_sample(). * Peter Wang and Trent Gamblin fixed some issues with the CMake build. The allegro-config script was not generated properly and liballeg_unsharable wasn't being installed. * Matthew Leverton changed an instance of long long to LONG_LONG and an LL suffix into a (LONG_LONG) cast, both for MSVC 6. * Matthew Leverton submitted a fix for MSVC 6 regarding MSVC's lack of a __FUNCTION__ macro. * orz, Matthew Leverton, and Peter Wang made the ALLEGRO_USE_C=1 option to work under MinGW and MSVC. * Anthony Cassidy fixed a typo. * Peter Wang removed the 'msvc' target from the fix.sh help message as it should not be used by users any more. Added a comment that it is used by zipup.sh. * Anthony 'Timorg' Cassidy made d_menu_proc fill up its assigned area with the gui_bg_color. Changes from 4.9.0 to 4.9.1 (March 2007) **************************************** _Note that 4.9.1 was called 4.3.1 when it was originally released._ * Added a new mouse and cursor API. The new functions are: al_install_mouse, al_uninstall_mouse, al_get_mouse, al_get_mouse_num_buttons, al_get_mouse_num_axes, al_set_mouse_xy, al_set_mouse_z, al_set_mouse_w, al_set_mouse_axis, al_set_mouse_range, al_get_mouse_state, al_mouse_button_down, al_mouse_state_axis al_create_mouse_cursor, al_destroy_mouse_cursor, al_set_mouse_cursor, al_set_system_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor * Added documentation for some parts of the 4.9 API using the NaturalDocs generation system. The documentation is nowhere near as good as a proper manual, but it's still better than nothing. * Added a commented example demonstating the new API (exnew_events.c). * Added CMake and SCons build systems. These are mainly for use by Allegro developers at present. * Various bug fixes and minor changes. Changes from 4.2 series to 4.9.0 (July 2006) ******************************************** _Note that 4.9.0 was called 4.3.0 when it was originally released._ Basically we're just wrapping up what we have in version control up to now. See the commit logs if you want details. This release introduces a few new subsystems. We have an event system, a new keyboard API, a new joystick API, a new timer API, and the start of a new graphics API. All of these are subject to change, as is usual for a WIP. We are maintaining a certain level of source compatibility with the 4.2 API. If it's easy to maintain compatibility then we do it, otherwise compatibility is dropped. Obscure features are more likely to be dropped. This release has had minimal testing on Linux/x86, Windows/x86 (MinGW) and Windows/x86 (MSVC). It seems to work on some Linux/x86-64 machines also. Other ports are broken or untested. The new functions are as follows (in no particular order). No real documentation exists at the moment but interesting header files are: altime.h, display.h, draw.h, events.h, joystick.h, keyboard.h, timer.h. * al_current_time al_rest * al_create_video_bitmap al_create_system_bitmap al_scroll_display al_request_scroll al_poll_scroll al_show_video_bitmap al_request_video_bitmap al_enable_triple_buffer al_create_display al_set_update_method al_destroy_display al_flip_display al_get_buffer al_get_update_method al_enable_vsync al_disable_vsync al_toggle_vsync al_vsync_is_enabled al_blit al_blit_region al_blit_scaled * al_event_source_set_mask al_event_source_mask * al_create_event_queue al_destroy_event_queue al_register_event_source al_unregister_event_source al_event_queue_is_empty al_get_next_event al_peek_next_event al_drop_next_event al_flush_event_queue al_wait_for_event al_wait_for_specific_event * al_install_joystick al_uninstall_joystick al_num_joysticks al_get_joystick al_release_joystick al_joystick_name al_joystick_num_sticks al_joystick_stick_flags al_joystick_stick_name al_joystick_num_axes al_joystick_axis_name al_joystick_button_name al_get_joystick_state * al_install_keyboard al_uninstall_keyboard al_get_keyboard al_set_keyboard_leds al_keycode_to_name al_get_keyboard_state al_key_down * al_install_timer al_uninstall_timer al_start_timer al_stop_timer al_timer_is_started al_timer_get_speed al_timer_set_speed al_timer_get_count al_timer_set_count  Local Variables: coding: utf-8 End: allegro-5.0.10/docs/0000755000175000001440000000000012157230746013345 5ustar tjadenusersallegro-5.0.10/docs/src/0000755000175000001440000000000012157230746014134 5ustar tjadenusersallegro-5.0.10/docs/src/pandoc.css0000644000175000001440000000756611461312647016126 0ustar tjadenusers/* We use this style sheet for HTML documents generated with Pandoc. */ body { background-color: #fcfcfc; padding-left: 0.1em; color: #222; font-family: sans-serif; } pre { border: 1px solid #ddd; background-color: #f3f3f8; padding: 0.6em; padding-left: 0.8em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } blockquote { border: 1px solid #ddd; background-color: #fff8e0; padding: 0.6em; padding-left: 0.8em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } blockquote p { padding: 0; margin: 0; } blockquote p em:first-child { font-style: normal; font-weight: bold; color: #400000; } code { font-family: monospace; } h1, h2, h3, h4, h5 { color: #348; margin-top: 2.5em; border-top: 1px solid #eee; padding-top: 0.8em; } h1 { font-size: 130%; } h2 { font-size: 110%; } h3 { font-size: 95%; } h4 { font-size: 90%; font-style: italic; } h5 { font-size: 90%; font-style: italic; } h1.title { font-size: 200%; font-weight: bold; margin-top: 0; padding-top: 0.2em; padding-bottom: 0.2em; text-align: left; border: none; } a { text-decoration: none; color: #348; } dl dt { font-weight: bold; } dt code { font-weight: bold; } dd p { margin-top: 0; } ul { padding-left: 1.5em; } table { background-color: #f8f8fa; border-top: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0; } table th { font-weight: bold; border-bottom: 1px solid #e0e0e0; padding: 0.5em; } /* Side bar */ div.sidebar { background-color: #f0f0fa; border: solid 1px #e0e0ea; float: left; width: 150px; margin-right: 1em; line-height: 110%; -moz-border-radius: 5px; -webkit-border-radius: 5px; } div.sidebar ul { list-style-type: none; padding: 0; margin-left: 0.5em; font-size: small; } div.sidebar ul a:hover { background: #fffff0; } div.searchbox { margin-left: 5px; margin-right: 5px; margin-bottom: 0.8em; font-size: small; } /* font-size isn't inherited (at least not in Firefox and Chrome) */ input#q { font-size: small; } /* Body of page */ div.content { margin-left: 165px; max-width: 50em; line-height: 135%; } div#TOC { display: table; border: 1px solid #ddd; background-color: #f3f3fa; padding-right: 1em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } div#TOC ul { padding-left: 1em; list-style-type: none; } p.timestamp { margin-top: 3em; border-top: solid 1px #eee; padding: 0.7em; padding-left: 0.3em; color: #999; text-align: left; } /* Below is the autosuggest.css from autosuggest.js version 2.4. */ .autosuggest-body { position: absolute; border: 1px solid black; z-index: 100; font-size: small; } .autosuggest-body iframe { display: block; position: absolute; z-index: 999; filter: alpha(opacity=0); } .autosuggest-body table { width: 100%; background-color: #FFFFF0; } .autosuggest-body tr { cursor: hand; cursor: pointer; color: black; text-align: left; } .autosuggest-body tr.up { height: 10px; background: #656291 url("arrow-up.gif") center center no-repeat; } .autosuggest-body tr.down { height: 10px; background: #656291 url("arrow-down.gif") center center no-repeat; } .autosuggest-body tr.up-disabled { height: 10px; background: #656291 url("arrow-up-d.gif") center center no-repeat; cursor: default; } .autosuggest-body tr.down-disabled { height: 10px; background: #656291 url("arrow-down-d.gif") center center no-repeat; cursor: default; } .autosuggest-body tr.selected { background-color: #D6D7E7; color: red; } .autosuggest-body td { white-space: nowrap; } .autosuggest-body span.match { font-weight: bold; } allegro-5.0.10/docs/src/custom_header.html0000644000175000001440000000017511145041774017644 0ustar tjadenusers allegro-5.0.10/docs/src/refman/0000755000175000001440000000000012157230746015404 5ustar tjadenusersallegro-5.0.10/docs/src/refman/memfile.txt0000644000175000001440000000161111505637161017560 0ustar tjadenusers# Memfile interface The memfile interface allows you to treat a fixed block of contiguous memory as a file that can be used with Allegro's I/O functions. These functions are declared in the following header file. Link with allegro_memfile. #include ## API: al_open_memfile Returns a file handle to the block of memory. All read and write operations act upon the memory directly, so it must not be freed while the file remains open. The mode can be any combination of "r" (readable) and "w" (writable). Regardless of the mode, the file always opens at position 0. The file size is fixed and cannot be expanded. It should be closed with [al_fclose]. After the file is closed, you are responsible for freeing the memory (if needed). ## API: al_get_allegro_memfile_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/time.txt0000644000175000001440000000216111476663604017111 0ustar tjadenusers# Time routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_TIMEOUT Represent a timeout value. The size of the structure is known so can be statically allocated. The contents are private. See also: [al_init_timeout] ## API: al_get_time Return the number of seconds since the Allegro library was initialised. The return value is undefined if Allegro is uninitialised. The resolution depends on the used driver, but typically can be in the order of microseconds. ## API: al_current_time Alternate spelling of [al_get_time]. ## API: al_init_timeout Set timeout value of some number of seconds after the function call. See also: [ALLEGRO_TIMEOUT], [al_wait_for_event_until] ## API: al_rest Waits for the specified number seconds. This tells the system to pause the current thread for the given amount of time. With some operating systems, the accuracy can be in the order of 10ms. That is, even al_rest(0.000001) might pause for something like 10ms. Also see the section on easier ways to time your program without using up all CPU. allegro-5.0.10/docs/src/refman/index.txt0000644000175000001440000000254512057104470017253 0ustar tjadenusers% Allegro 5.0 reference manual * [Getting started guide](getting_started.html) API === * [Configuration files](config.html) * [Displays](display.html) * [Events](events.html) * [File I/O](file.html) * [Filesystem](fshook.html) * [Fixed point math](fixed.html) * [Fullscreen modes](fullscreen_mode.html) * [Graphics routines](graphics.html) * [Joystick routines](joystick.html) * [Keyboard routines](keyboard.html) * [Memory management](memory.html) * [Monitors](monitor.html) * [Mouse routines](mouse.html) * [Path structures](path.html) * [State](state.html) * [System routines](system.html) * [Threads](threads.html) * [Time](time.html) * [Timer](timer.html) * [Transformations](transformations.html) * [UTF-8 string routines](utf8.html) * [Miscellaneous](misc.html) * [Platform-specific](platform.html) * [Direct3D integration](direct3d.html) * [OpenGL integration](opengl.html) Addons ====== * [Audio addon](audio.html) * [Audio codecs](acodec.html) * [Color addon](color.html) * [Font addons](font.html) * [Image I/O addon](image.html) * [Main addon](main.html) * [Memfile addon](memfile.html) * [Native dialogs addon](native_dialog.html) * [PhysicsFS addon](physfs.html) * [Primitives addon](primitives.html) allegro-5.0.10/docs/src/refman/latex.template0000644000175000001440000001111411522501752020245 0ustar tjadenusers%% This template is a modified version of the default pandoc latex template. %% Changes are marked with double-%% comments. %% Most of it was "inspired" by the Memoir manual. $if(legacy-header)$ $legacy-header$ $else$ %% Replacement for the book document class. \documentclass[a4paper]{memoir} %% The default layout looks too wasteful to me. \usepackage[a4paper,hmargin=2.6cm,top=2.4cm,bottom=3cm,footskip=1cm,centering]{geometry} %% ToC down to subsections \settocdepth{subsection} %% Numbering down to subsections as well \setsecnumdepth{subsection} %% Choose a nice looking chapter style. \chapterstyle{ell} %\chapterstyle{ger} %% Choose a nice font. \usepackage[T1]{fontenc} %\usepackage{mathpazo} % roman=Palatino %\usepackage{mathptmx} % roman=Times %\usepackage{newcent} % roman=New Century Schoolbook \usepackage{charter} % roman=Charter \usepackage{inconsolata} % typewriter=Inconsolata % TODO: I don't like the sans serif fonts much. %% Does this help with overlongs? \midsloppy %% The long identifiers make justified text look quite ugly. \raggedright %% In definition lists, start the description on the next line. \usepackage{enumitem} \setdescription{style=nextline} \usepackage{amssymb,amsmath} $if(xetex)$ \usepackage{ifxetex} \ifxetex \usepackage{fontspec,xltxtra,xunicode} \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} \else \usepackage[mathletters]{ucs} \usepackage[utf8x]{inputenc} \fi $else$ \usepackage[mathletters]{ucs} \usepackage[utf8x]{inputenc} $endif$ $if(lhs)$ \usepackage{listings} \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} $endif$ $endif$ %% Use `Verbatim' environments so we can offset them slightly. \usepackage{fancyvrb} \fvset{xleftmargin=8pt} $if(fancy-enums)$ % Redefine labelwidth for lists; otherwise, the enumerate package will cause % markers to extend beyond the left margin. \makeatletter\AtBeginDocument{% \renewcommand{\@listi} {\setlength{\labelwidth}{4em}} }\makeatother \usepackage{enumerate} $endif$ $if(tables)$ \usepackage{array} % This is needed because raggedright in table elements redefines \\: \newcommand{\PreserveBackslash}[1]{\let\temp=\\#1\let\\=\temp} \let\PBS=\PreserveBackslash $endif$ $if(strikeout)$ \usepackage[normalem]{ulem} $endif$ $if(subscript)$ \newcommand{\textsubscr}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}} $endif$ $if(url)$ \usepackage{url} $endif$ $if(graphics)$ \usepackage{graphicx} % We will generate all images so they have a width \maxwidth. This means % that they will get their normal width if they fit onto the page, but % are scaled down if they would overflow the margins. \makeatletter \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth \else\Gin@nat@width\fi} \makeatother \let\Oldincludegraphics\includegraphics \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=\maxwidth]{#1}} $endif$ \usepackage[breaklinks=true,unicode=true,hyperref]{hyperref} %% Generate different types of cross-reference depending on whether the %% final output is designed to be printed, or read onscreen (with hyperlinks). $if(paperref)$ \newcommand{\alref}[1]{\detokenize{#1}~(\ref{#1})} $else$ \newcommand{\alref}[1]{\nameref{#1}} $endif$ %% Nice coloured links. \usepackage{color} \definecolor{linkcolor}{rgb}{0.2,0.2,0.45} \hypersetup{ colorlinks=true, linkcolor=linkcolor, citecolor=linkcolor, filecolor=linkcolor, urlcolor=linkcolor } \setlength{\parindent}{0pt} \setlength{\parskip}{6pt plus 2pt minus 1pt} $if(numbersections)$ $else$ \setcounter{secnumdepth}{0} $endif$ $if(verbatim-in-note)$ \VerbatimFootnotes % allows verbatim text in footnotes $endif$ $for(header-includes)$ $header-includes$ $endfor$ $if(title)$ \title{$title$} $endif$ $if(author)$ \author{$for(author)$$author$$sep$\\$endfor$} $endif$ $if(date)$ \date{$date$} $endif$ \begin{document} %% Make a nice title page. \frontmatter \pagestyle{empty} % no page numbers, etc. \vspace*{\fill} \begin{center} \HUGE\textsf{The Allegro 5 Library}\par \end{center} \begin{center} \HUGE\textsf{Reference Manual}\par \end{center} \begin{center} \vspace*{\fill} \LARGE{\textcopyright{} 2008 --- 2011} \end{center} \cleardoublepage \pagestyle{ruled} %% Fiddle with the spacing in table of contents. \setlength\cftsectionindent{1.5em} \setlength\cftsubsectionindent{1.5em} \setlength\cftchapternumwidth{2em} \setlength\cftsectionnumwidth{3.7em} \setlength\cftsubsectionnumwidth{4.7em} $for(include-before)$ $include-before$ $endfor$ $if(toc)$ \tableofcontents $endif$ %% This enables page numbers, etc. \mainmatter $body$ $for(include-after)$ $include-after$ $endfor$ \end{document} %% vim: set ft=tex et: allegro-5.0.10/docs/src/refman/getting_started.txt0000644000175000001440000001626111771530216021336 0ustar tjadenusers# Getting started guide ## Introduction Welcome to Allegro 5.0! This short guide should point you at the parts of the API that you'll want to know about first. It's not a tutorial, as there isn't much discussion, only links into the manual. The rest you'll have to discover for yourself. Read the examples, and ask questions at [Allegro.cc]. There is an unofficial tutorial at [the wiki]. Be aware that, being on the wiki, it may be a little out of date, but the changes should be minor. Hopefully more will sprout when things stabilise, as they did for earlier versions of Allegro. ## Structure of the library and its addons Allegro 5.0 is divided into a core library and multiple addons. The addons are bundled together and built at the same time as the core, but they are distinct and kept in separate libraries. The core doesn't depend on anything in the addons, but addons may depend on the core and other addons and additional third party libraries. Here are the addons and their dependencies: allegro_main -> allegro allegro_image -> allegro allegro_primitives -> allegro allegro_color -> allegro allegro_font -> allegro allegro_ttf -> allegro_font -> allegro allegro_audio -> allegro allegro_acodec -> allegro_audio -> allegro allegro_memfile -> allegro allegro_physfs -> allegro allegro_native_dialog -> allegro The header file for the core library is `allegro5/allegro.h`. The header files for the addons are named `allegro5/allegro_image.h`, `allegro5/allegro_font.h`, etc. The allegro_main addon does not have a header file. ## The main function For the purposes of cross-platform compatibility Allegro puts some requirements on your main function. First, you must include the core header (`allegro5/allegro.h`) in the same file as your main function. Second, if your main function is inside a C++ file, then it must have this signature: `int main(int argc, char **argv)`. Third, if you're using C/C++ then you need to link with the allegro_main addon when building your program. ## Initialisation Before using Allegro you must call [al_init]. Some addons have their own initialisation, e.g. [al_init_image_addon], [al_init_font_addon], [al_init_ttf_addon]. To receive input, you need to initialise some subsystems like [al_install_keyboard], [al_install_mouse], [al_install_joystick]. ## Opening a window [al_create_display] will open a window and return an [ALLEGRO_DISPLAY]. To clear the display, call [al_clear_to_color]. Use [al_map_rgba] or [al_map_rgba_f] to obtain an [ALLEGRO_COLOR] parameter. Drawing operations are performed on a backbuffer. To make the operations visible, call [al_flip_display]. ## Display an image To load an image from disk, you need to have initialised the image I/O addon with [al_init_image_addon]. Then use [al_load_bitmap], which returns an [ALLEGRO_BITMAP]. Use [al_draw_bitmap], [al_draw_scaled_bitmap] or [al_draw_scaled_rotated_bitmap] to draw the image to the backbuffer. Remember to call [al_flip_display]. ## Changing the drawing target Notice that [al_clear_to_color] and [al_draw_bitmap] didn't take destination parameters: the destination is implicit. Allegro remembers the current "target bitmap" for the current thread. To change the target bitmap, call [al_set_target_bitmap]. The backbuffer of the display is also a bitmap. You can get it with [al_get_backbuffer] and then restore it as the target bitmap. Other bitmaps can be created with [al_create_bitmap], with options which can be adjusted with [al_set_new_bitmap_flags] and [al_set_new_bitmap_format]. ## Event queues and input Input comes from multiple sources: keyboard, mouse, joystick, timers, etc. Event queues aggregate events from all these sources, then you can query the queue for events. Create an event queue with [al_create_event_queue], then tell input sources to place new events into that queue using [al_register_event_source]. The usual input event sources can be retrieved with [al_get_keyboard_event_source], [al_get_mouse_event_source] and [al_get_joystick_event_source]. Events can be retrieved with [al_wait_for_event] or [al_get_next_event]. Check the event type and other fields of [ALLEGRO_EVENT] to react to the input. Displays are also event sources, which emit events when they are resized. You'll need to set the ALLEGRO_RESIZABLE flag with [al_set_new_display_flags] before creating the display, then register the display with an event queue. When you get a resize event, call [al_acknowledge_resize]. Timers are event sources which "tick" periodically, causing an event to be inserted into the queues that the timer is registered with. Create some with [al_create_timer]. [al_get_time] and [al_rest] are more direct ways to deal with time. ## Displaying some text To display some text, initialise the image and font addons with [al_init_image_addon] and [al_init_font_addon], then load a bitmap font with [al_load_font]. Use [al_draw_text] or [al_draw_textf]. For TrueType fonts, you'll need to initialise the TTF font addon with [al_init_ttf_addon] and load a TTF font with [al_load_ttf_font]. ## Drawing primitives The primitives addon provides some handy routines to draw lines ([al_draw_line]), rectangles ([al_draw_rectangle]), circles ([al_draw_circle]), etc. ## Blending To draw translucent or tinted images or primitives, change the blender state with [al_set_blender]. As with [al_set_target_bitmap], this changes Allegro's internal state (for the current thread). Often you'll want to save some part of the state and restore it later. The functions [al_store_state] and [al_restore_state] provide a convenient way to do that. ## Sound Use [al_install_audio] to initialize sound. To load any sample formats, you will need to initialise the acodec addon with [al_init_acodec_addon]. After that, you can simply use [al_reserve_samples] and pass the number of sound effects typically playing at the same time. Then load your sound effects with [al_load_sample] and play them with [al_play_sample]. To stream large pieces of music from disk, you can use [al_load_audio_stream] so the whole piece will not have to be pre-loaded into memory. If the above sounds too simple and you can't help but think about clipping and latency issues, don't worry. Allegro gives you full control over how much or little you want its sound system to do. The [al_reserve_samples] function mentioned above only sets up a default mixer and a number of sample instances but you don't need to use it. Instead, to get a "direct connection" to the sound system you would use an [ALLEGRO_VOICE] (but depending on the platform only one such voice is guaranteed to be available and it might require a specific format of audio data). Therefore all sound can be first routed through an [ALLEGRO_MIXER] which is connected to such a voice (or another mixer) and will mix together all sample data fed to it. You can then directly stream real-time sample data to a mixer or a voice using an [ALLEGRO_AUDIO_STREAM] or play complete sounds using an [ALLEGRO_SAMPLE_INSTANCE]. The latter simply points to an [ALLEGRO_SAMPLE] and will stream it for you. ## Not the end There's a heap of stuff we haven't even mentioned yet. Enjoy! [Allegro.cc]: http://www.allegro.cc/forums/ [the wiki]: http://wiki.allegro.cc/ allegro-5.0.10/docs/src/refman/graphics.txt0000644000175000001440000011415612157072165017754 0ustar tjadenusers# Graphics routines These functions are declared in the main Allegro header file: #include ## Colors ### API: ALLEGRO_COLOR An ALLEGRO_COLOR structure describes a color in a device independent way. Use [al_map_rgb] et al. and [al_unmap_rgb] et al. to translate from and to various color representations. ### API: al_map_rgb Convert r, g, b (ranging from 0-255) into an [ALLEGRO_COLOR], using 255 for alpha. See also: [al_map_rgba], [al_map_rgba_f], [al_map_rgb_f] ### API: al_map_rgb_f Convert r, g, b, (ranging from 0.0f-1.0f) into an [ALLEGRO_COLOR], using 1.0f for alpha. See also: [al_map_rgba], [al_map_rgb], [al_map_rgba_f] ### API: al_map_rgba Convert r, g, b, a (ranging from 0-255) into an [ALLEGRO_COLOR]. See also: [al_map_rgb], [al_map_rgba_f], [al_map_rgb_f] ### API: al_map_rgba_f Convert r, g, b, a (ranging from 0.0f-1.0f) into an [ALLEGRO_COLOR]. See also: [al_map_rgba], [al_map_rgb], [al_map_rgb_f] ### API: al_unmap_rgb Retrieves components of an ALLEGRO_COLOR, ignoring alpha Components will range from 0-255. See also: [al_unmap_rgba], [al_unmap_rgba_f], [al_unmap_rgb_f] ### API: al_unmap_rgb_f Retrieves components of an [ALLEGRO_COLOR], ignoring alpha. Components will range from 0.0f-1.0f. See also: [al_unmap_rgba], [al_unmap_rgb], [al_unmap_rgba_f] ### API: al_unmap_rgba Retrieves components of an [ALLEGRO_COLOR]. Components will range from 0-255. See also: [al_unmap_rgb], [al_unmap_rgba_f], [al_unmap_rgb_f] ### API: al_unmap_rgba_f Retrieves components of an [ALLEGRO_COLOR]. Components will range from 0.0f-1.0f. See also: [al_unmap_rgba], [al_unmap_rgb], [al_unmap_rgb_f] ## Locking and pixel formats ### API: ALLEGRO_LOCKED_REGION Users who wish to manually edit or read from a bitmap are required to lock it first. The ALLEGRO_LOCKED_REGION structure represents the locked region of the bitmap. This call will work with any bitmap, including memory bitmaps. typedef struct ALLEGRO_LOCKED_REGION { void *data; int format; int pitch; int pixel_size; } ALLEGRO_LOCKED_REGION; - *data* points to the leftmost pixel of the first row (row 0) of the locked region. - *format* indicates the pixel format of the data. - *pitch* gives the size in bytes of a single row (also known as the stride). The pitch may be greater than `width * pixel_size` due to padding; this is not uncommon. It is also *not* uncommon for the pitch to be negative (the bitmap may be upside down). - *pixel_size* is the number of bytes used to represent a single pixel. See also: [al_lock_bitmap], [al_lock_bitmap_region], [al_unlock_bitmap], [ALLEGRO_PIXEL_FORMAT] ### API: ALLEGRO_PIXEL_FORMAT Pixel formats. Each pixel format specifies the exact size and bit layout of a pixel in memory. Components are specified from high bits to low bits, so for example a fully opaque red pixel in ARGB_8888 format is 0xFFFF0000. > *Note:* > > The pixel format is independent of endianness. That is, in the above > example you can always get the red component with > > (pixel & 0x00ff0000) >> 16 > > But you can *not* rely on this code: > > *(pixel + 2) > > It will return the red component on little endian systems, but the > green component on big endian systems. Also note that Allegro's naming is different from OpenGL naming here, where a format of GL_RGBA8 merely defines the component order and the exact layout including endianness treatment is specified separately. Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on little endian systems, so care must be taken (note the reversal of RGBA <-> ABGR). The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will always have the components as 4 bytes corresponding to red, green, blue and alpha, in this order, independent of the endianness. * ALLEGRO_PIXEL_FORMAT_ANY - Let the driver choose a format. This is the default format at program start. * ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format without alpha. * ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - Let the driver choose a format with alpha. * ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - Let the driver choose a 15 bit format without alpha. * ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - Let the driver choose a 16 bit format without alpha. * ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - Let the driver choose a 16 bit format with alpha. * ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - Let the driver choose a 24 bit format without alpha. * ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - Let the driver choose a 32 bit format without alpha. * ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - Let the driver choose a 32 bit format with alpha. * ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit * ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit * ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit * ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit * ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit * ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit * ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit * ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit * ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit * ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit * ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit * ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE - Like the version without _LE, but the component order is guaranteed to be red, green, blue, alpha. This only makes a difference on big endian systems, on little endian it is just an alias. * ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit See also: [al_set_new_bitmap_format], [al_get_bitmap_format] ### API: al_get_pixel_size Return the number of bytes that a pixel of the given format occupies. See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_format_bits] ### API: al_get_pixel_format_bits Return the number of bits that a pixel of the given format occupies. See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_size] ### API: al_lock_bitmap Lock an entire bitmap for reading or writing. If the bitmap is a display bitmap it will be updated from system memory after the bitmap is unlocked (unless locked read only). Returns NULL if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked. Flags are: * ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card. * ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. This can be faster if the bitmap is a video texture, as no data need to be read from the video card. You are required to fill in all pixels before unlocking the bitmap again, so be careful when using this flag. * ALLEGRO_LOCK_READWRITE - The locked region can be written to and read from. Use this flag if a partial number of pixels need to be written to, even if reading is not needed. 'format' indicates the pixel format that the returned buffer will be in. To lock in the same format as the bitmap stores it's data internally, call with `al_get_bitmap_format(bitmap)` as the format or use ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster. > *Note:* While a bitmap is locked, you can not use any drawing operations on it (with the sole exception of [al_put_pixel] and [al_put_blended_pixel]). See also: [ALLEGRO_LOCKED_REGION], [ALLEGRO_PIXEL_FORMAT], [al_unlock_bitmap] ### API: al_lock_bitmap_region Like [al_lock_bitmap], but only locks a specific area of the bitmap. If the bitmap is a display bitmap, only that area of the texture will be updated when it is unlocked. Locking only the region you indend to modify will be faster than locking the whole bitmap. See also: [ALLEGRO_LOCKED_REGION], [ALLEGRO_PIXEL_FORMAT], [al_unlock_bitmap] ### API: al_unlock_bitmap Unlock a previously locked bitmap or bitmap region. If the bitmap is a display bitmap, the texture will be updated to match the system memory copy (unless it was locked read only). See also: [al_lock_bitmap], [al_lock_bitmap_region] ## Bitmap creation ### API: ALLEGRO_BITMAP Abstract type representing a bitmap (2D image). ### API: al_create_bitmap Creates a new bitmap using the bitmap format and flags for the current thread. Blitting between bitmaps of differing formats, or blitting between memory bitmaps and display bitmaps may be slow. Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created for the current display. Blitting to another display may be slow. If a display bitmap is created, there may be limitations on the allowed dimensions. For example a DirectX or OpenGL backend usually has a maximum allowed texture size - so if bitmap creation fails for very large dimensions, you may want to re-try with a smaller bitmap. Some platforms also dictate a minimum texture size, which is relevant if you plan to use this bitmap with the primitives addon. If you try to create a bitmap smaller than this, this call will not fail but the returned bitmap will be a section of a larger bitmap with the minimum size. The minimum size that will work on all platforms is 32 by 32. Some platforms do not directly support display bitmaps whose dimensions are not powers of two. Allegro handles this by creating a larger bitmap that has dimensions that are powers of two and then returning a section of that bitmap with the dimensions you requested. This can be relevant if you plan to use this bitmap with the primitives addon but shouldn't be an issue otherwise. See also: [al_set_new_bitmap_format], [al_set_new_bitmap_flags], [al_clone_bitmap], [al_create_sub_bitmap], [al_destroy_bitmap] ### API: al_create_sub_bitmap Creates a sub-bitmap of the parent, at the specified coordinates and of the specified size. A sub-bitmap is a bitmap that shares drawing memory with a pre-existing (parent) bitmap, but possibly with a different size and clipping settings. The sub-bitmap may originate off or extend past the parent bitmap. See the discussion in [al_get_backbuffer] about using sub-bitmaps of the backbuffer. The parent bitmap's clipping rectangles are ignored. If a sub-bitmap was not or cannot be created then NULL is returned. Note that destroying parents of sub-bitmaps will not destroy the sub-bitmaps; instead the sub-bitmaps become invalid and should no longer be used. See also: [al_create_bitmap] ### API: al_clone_bitmap Create a new bitmap with [al_create_bitmap], and copy the pixel data from the old bitmap across. See also: [al_create_bitmap], [al_set_new_bitmap_format], [al_set_new_bitmap_flags] ### API: al_destroy_bitmap Destroys the given bitmap, freeing all resources used by it. This function does nothing if the bitmap argument is NULL. As a convenience, if the calling thread is currently targets the bitmap then the bitmap will be untargeted first. The new target bitmap is unspecified. (since: 5.0.10, 5.1.6) Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) is the target bitmap of any thread. See also: [al_create_bitmap] ### API: al_get_new_bitmap_flags Returns the flags used for newly created bitmaps. See also: [al_set_new_bitmap_flags] ### API: al_get_new_bitmap_format Returns the format used for newly created bitmaps. See also: [ALLEGRO_PIXEL_FORMAT], [al_set_new_bitmap_format] ### API: al_set_new_bitmap_flags Sets the flags to use for newly created bitmaps. Valid flags are: ALLEGRO_VIDEO_BITMAP : Creates a bitmap that resides in the video card memory. These types of bitmaps receive the greatest benefit from hardware acceleration. [al_set_new_bitmap_flags] will implicitly set this flag unless ALLEGRO_MEMORY_BITMAP is present. ALLEGRO_MEMORY_BITMAP : Create a bitmap residing in system memory. Operations on, and with, memory bitmaps will not be hardware accelerated. However, direct pixel access can be relatively quick compared to video bitmaps, which depend on the display driver in use. *Note: Allegro's software rendering routines are currently very unoptimised.* ALLEGRO_KEEP_BITMAP_FORMAT : Only used when loading bitmaps from disk files, forces the resulting [ALLEGRO_BITMAP] to use the same format as the file. *This is not yet honoured.* ALLEGRO_FORCE_LOCKING : When drawing to a bitmap with this flag set, always use pixel locking and draw to it using Allegro's software drawing primitives. This should never be used if you plan to draw to the bitmap using Allegro's graphics primitives as it would cause severe performance penalties. However if you know that the bitmap will only ever be accessed by locking it, no unneeded FBOs will be created for it in the OpenGL drivers. ALLEGRO_NO_PRESERVE_TEXTURE : Normally, every effort is taken to preserve the contents of bitmaps, since Direct3D may forget them. This can take extra processing time. If you know it doesn't matter if a bitmap keeps its pixel data, for example its a temporary buffer, use this flag to tell Allegro not to attempt to preserve its contents. This can increase performance of your game or application, but there is a catch. See ALLEGRO_EVENT_DISPLAY_LOST for further information. ALLEGRO_ALPHA_TEST : This is a driver hint only. It tells the graphics driver to do alpha testing instead of alpha blending on bitmaps created with this flag. Alpha testing is usually faster and preferred if your bitmaps have only one level of alpha (0). This flag is currently not widely implemented (i.e., only for memory bitmaps). ALLEGRO_MIN_LINEAR : When drawing a scaled down version of the bitmap, use linear filtering. This usually looks better. You can also combine it with the MIPMAP flag for even better quality. ALLEGRO_MAG_LINEAR : When drawing a magnified version of a bitmap, use linear filtering. This will cause the picture to get blurry instead of creating a big rectangle for each pixel. It depends on how you want things to look like whether you want to use this or not. ALLEGRO_MIPMAP : This can only be used for bitmaps whose width and height is a power of two. In that case, it will generate mipmaps and use them when drawing scaled down versions. For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled down version of the original. ALLEGRO_NO_PREMULTIPLIED_ALPHA : By default, Allegro pre-multiplies the alpha channel of an image with the images color data when it loads it. Typically that would look something like this: r = get_float_byte(); g = get_float_byte(); b = get_float_byte(); a = get_float_byte(); r = r * a; g = g * a; b = b * a; set_image_pixel(x, y, r, g, b, a); The reason for this can be seen in the Allegro example ex_premulalpha, ie, using pre-multiplied alpha gives more accurate color results in some cases. To use alpha blending with images loaded with pre-multiplied alpha, you would use the default blending mode, which is set with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA). The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that images are not loaded with alpha pre-multiplied, but are loaded with color values direct from the image. That looks like this: r = get_float_byte(); g = get_float_byte(); b = get_float_byte(); a = get_float_byte(); set_image_pixel(x, y, r, g, b, a); To draw such an image using regular alpha blending, you would use al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) to set the correct blender. This has some caveats. First, as mentioned above, drawing such an image can result in less accurate color blending (when drawing an image with linear filtering on, the edges will be darker than they should be). Second, the behaviour is somewhat confusing, which is explained in the example below. // Load and create bitmaps with an alpha channel al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA); // Load some bitmap with alpha in it bmp = al_load_bitmap("some_alpha_bitmap.png"); // We will draw to this buffer and then draw this buffer to the screen tmp_buffer = al_create_bitmap(SCREEN_W, SCREEN_H); // Set the buffer as the target and clear it al_set_target_bitmap(tmp_buffer); al_clear_to_color(al_map_rgba_f(0, 0, 0, 1)); // Draw the bitmap to the temporary buffer al_draw_bitmap(bmp, 0, 0, 0); // Finally, draw the buffer to the screen // The output will look incorrect (may take close inspection // depending on the bitmap -- it may also be very obvious) al_set_target_bitmap(al_get_backbuffer(display)); al_draw_bitmap(tmp_buffer, 0, 0, 0); To explain further, if you have a pixel with 0.5 alpha, and you're using (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, the formula is: a = da * dst + sa * src Expands to: result_a = dst_a * (1-0.5) + 0.5 * 0.5; So if you draw the image to the temporary buffer, it is blended once resulting in 0.75 alpha, then drawn again to the screen, blended in the same way, resulting in a pixel has 0.1875 as an alpha value. See also: [al_get_new_bitmap_flags], [al_get_bitmap_flags] ### API: al_add_new_bitmap_flag A convenience function which does the same as al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag); See also: [al_set_new_bitmap_flags], [al_get_new_bitmap_flags], [al_get_bitmap_flags] ### API: al_set_new_bitmap_format Sets the pixel format for newly created bitmaps. The default format is 0 and means the display driver will choose the best format. See also: [ALLEGRO_PIXEL_FORMAT], [al_get_new_bitmap_format], [al_get_bitmap_format] ## Bitmap properties ### API: al_get_bitmap_flags Return the flags used to create the bitmap. See also: [al_set_new_bitmap_flags] ### API: al_get_bitmap_format Returns the pixel format of a bitmap. See also: [ALLEGRO_PIXEL_FORMAT], [al_set_new_bitmap_flags] ### API: al_get_bitmap_height Returns the height of a bitmap in pixels. ### API: al_get_bitmap_width Returns the width of a bitmap in pixels. ### API: al_get_pixel Get a pixel's color value from the specified bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. See also: [ALLEGRO_COLOR], [al_put_pixel], [al_lock_bitmap] ### API: al_is_bitmap_locked Returns whether or not a bitmap is already locked. See also: [al_lock_bitmap], [al_lock_bitmap_region], [al_unlock_bitmap] ### API: al_is_compatible_bitmap D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each [ALLEGRO_BITMAP] created with [al_create_bitmap] however is usually tied to a single ALLEGRO_DISPLAY. This function can be used to know if the bitmap is compatible with the given display, even if it is a different display to the one it was created with. It returns true if the bitmap is compatible (things like a cached texture version can be used) and false otherwise (blitting in the current display will be slow). The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both. Returns true if the bitmap is compatible with the current display, false otherwise. If there is no current display, false is returned. ### API: al_is_sub_bitmap Returns true if the specified bitmap is a sub-bitmap, false otherwise. See also: [al_create_sub_bitmap], [al_get_parent_bitmap] ### API: al_get_parent_bitmap Returns the bitmap this bitmap is a sub-bitmap of. Returns NULL if this bitmap is not a sub-bitmap. Since: 5.0.6, 5.1.2 See also: [al_create_sub_bitmap], [al_is_sub_bitmap] ## Drawing operations All drawing operations draw to the current "target bitmap" of the current thread. Initially, the target bitmap will be the backbuffer of the last display created in a thread. ### API: al_clear_to_color Clear the complete target bitmap, but confined by the clipping rectangle. See also: [ALLEGRO_COLOR], [al_set_clipping_rectangle] ### API: al_draw_bitmap Draws an unscaled, unrotated bitmap at the given position to the current target bitmap (see [al_set_target_bitmap]). `flags` can be a combination of: * ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis * ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis > *Note:* The current target bitmap must be a different bitmap. Drawing a bitmap to itself (or to a sub-bitmap of itself) or drawing a sub-bitmap to its parent (or another sub-bitmap of its parent) are not currently supported. To copy part of a bitmap into the same bitmap simply use a temporary bitmap instead. > *Note:* The backbuffer (or a sub-bitmap thereof) can not be transformed, blended or tinted. If you need to draw the backbuffer draw it to a temporary bitmap first with no active transformation (except translation). Blending and tinting settings/parameters will be ignored. This does not apply when drawing into a memory bitmap. See also: [al_draw_bitmap_region], [al_draw_scaled_bitmap], [al_draw_rotated_bitmap], [al_draw_scaled_rotated_bitmap] ### API: al_draw_tinted_bitmap Like [al_draw_bitmap] but multiplies all colors in the bitmap with the given color. For example: al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0); The above will draw the bitmap 50% transparently (r/g/b values need to be pre-multiplied with the alpha component with the default blend mode). al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0); The above will only draw the red component of the bitmap. See also: [al_draw_bitmap] ### API: al_draw_bitmap_region Draws a region of the given bitmap to the target bitmap. * sx - source x * sy - source y * sw - source width (width of region to blit) * sh - source height (height of region to blit) * dx - destination x * dy - destination y * flags - same as for [al_draw_bitmap] See also: [al_draw_bitmap], [al_draw_scaled_bitmap], [al_draw_rotated_bitmap], [al_draw_scaled_rotated_bitmap] ### API: al_draw_tinted_bitmap_region Like [al_draw_bitmap_region] but multiplies all colors in the bitmap with the given color. See also: [al_draw_tinted_bitmap] ### API: al_draw_pixel Draws a single pixel at x, y. This function, unlike [al_put_pixel], does blending and, unlike [al_put_blended_pixel], respects the transformations. This function can be slow if called often; if you need to draw a lot of pixels consider using [al_draw_prim] with ALLEGRO_PRIM_POINT_LIST from the primitives addon. * x - destination x * y - destination y * color - color of the pixel > *Note:* This function may not draw exactly where you expect it to. See the pixel-precise output section on the primitives addon documentation for details on how to control exactly where the pixel is drawn. See also: [ALLEGRO_COLOR], [al_put_pixel] ### API: al_draw_rotated_bitmap Draws a rotated version of the given bitmap to the target bitmap. The bitmap is rotated by 'angle' radians clockwise. The point at cx/cy relative to the upper left corner of the bitmap will be drawn at dx/dy and the bitmap is rotated around this point. If cx,cy is 0,0 the bitmap will rotate around its upper left corner. * cx - center x (relative to the bitmap) * cy - center y (relative to the bitmap) * dx - destination x * dy - destination y * angle - angle by which to rotate (radians) * flags - same as for [al_draw_bitmap] Example float w = al_get_bitmap_width(bitmap); float h = al_get_bitmap_height(bitmap); al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0); The above code draws the bitmap centered on x/y and rotates it 90° clockwise. See also: [al_draw_bitmap], [al_draw_bitmap_region], [al_draw_scaled_bitmap], [al_draw_scaled_rotated_bitmap] ### API: al_draw_tinted_rotated_bitmap Like [al_draw_rotated_bitmap] but multiplies all colors in the bitmap with the given color. See also: [al_draw_tinted_bitmap] ### API: al_draw_scaled_rotated_bitmap Like [al_draw_rotated_bitmap], but can also scale the bitmap. The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap is rotated and scaled around this point. * cx - center x * cy - center y * dx - destination x * dy - destination y * xscale - how much to scale on the x-axis (e.g. 2 for twice the size) * yscale - how much to scale on the y-axis * angle - angle by which to rotate (radians) * flags - same as for [al_draw_bitmap] See also: [al_draw_bitmap], [al_draw_bitmap_region], [al_draw_scaled_bitmap], [al_draw_rotated_bitmap] ### API: al_draw_tinted_scaled_rotated_bitmap Like [al_draw_scaled_rotated_bitmap] but multiplies all colors in the bitmap with the given color. See also: [al_draw_tinted_bitmap] ### API: al_draw_tinted_scaled_rotated_bitmap_region Like [al_draw_tinted_scaled_rotated_bitmap] but you specify an area within the bitmap to be drawn. You can get the same effect with a sub bitmap: al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint, cx, cy, dx, dy, xscale, yscale, angle, flags); /* This draws the same: */ sub_bitmap = al_create_sub_bitmap(bitmap, sx, sy, sw, sh); al_draw_tinted_scaled_rotated_bitmap(sub_bitmap, tint, cx, cy, dx, dy, xscale, yscale, angle, flags); Since: 5.0.6, 5.1.0 See also: [al_draw_tinted_bitmap] ### API: al_draw_scaled_bitmap Draws a scaled version of the given bitmap to the target bitmap. * sx - source x * sy - source y * sw - source width * sh - source height * dx - destination x * dy - destination y * dw - destination width * dh - destination height * flags - same as for [al_draw_bitmap] See also: [al_draw_bitmap], [al_draw_bitmap_region], [al_draw_rotated_bitmap], [al_draw_scaled_rotated_bitmap], ### API: al_draw_tinted_scaled_bitmap Like [al_draw_scaled_bitmap] but multiplies all colors in the bitmap with the given color. See also: [al_draw_tinted_bitmap] ### API: al_get_target_bitmap Return the target bitmap of the calling thread. See also: [al_set_target_bitmap] ### API: al_put_pixel Draw a single pixel on the target bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. This function is not affected by the transformations or the color blenders. See also: [ALLEGRO_COLOR], [al_get_pixel], [al_put_blended_pixel], [al_lock_bitmap] ### API: al_put_blended_pixel Like [al_put_pixel], but the pixel color is blended using the current blenders before being drawn. See also: [ALLEGRO_COLOR], [al_put_pixel] ### API: al_set_target_bitmap This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using [al_get_backbuffer]. As a convenience, you may also use [al_set_target_backbuffer]. Each video bitmap is tied to a display. When a video bitmap is set to as the target bitmap, the display that the bitmap belongs to is automatically made "current" for the calling thread (if it is not current already). Then drawing other bitmaps which are tied to the same display can be hardware accelerated. A single display cannot be current for multiple threads simultaneously. If you need to release a display, so it is not current for the calling thread, call `al_set_target_bitmap(NULL);` Setting a memory bitmap as the target bitmap will not change which display is current for the calling thread. OpenGL note: Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is very fast. When using an OpenGL display, if all of the following conditions are met an FBO will be created for use with the bitmap: * The GL_EXT_framebuffer_object OpenGL extension is available. * The bitmap is not a memory bitmap. * The bitmap is not currently locked. In Allegro 5.0.0, you had to be careful as an FBO would be kept around until the bitmap is destroyed or you explicitly called [al_remove_opengl_fbo] on the bitmap, wasting resources. In newer versions, FBOs will be freed automatically when the bitmap is no longer the target bitmap, *unless* you have called [al_get_opengl_fbo] to retrieve the FBO id. In the following example, no FBO will be created: lock = al_lock_bitmap(bitmap); al_set_target_bitmap(bitmap); al_put_pixel(x, y, color); al_unlock_bitmap(bitmap); The above allows using [al_put_pixel] on a locked bitmap without creating an FBO. In this example an FBO is created however: al_set_target_bitmap(bitmap); al_draw_line(x1, y1, x2, y2, color, 0); An OpenGL command will be used to directly draw the line into the bitmap's associated texture. See also: [al_get_target_bitmap], [al_set_target_backbuffer] ### API: al_set_target_backbuffer Same as `al_set_target_bitmap(al_get_backbuffer(display));` See also: [al_set_target_bitmap], [al_get_backbuffer] ### API: al_get_current_display Return the display that is "current" for the calling thread, or NULL if there is none. See also: [al_set_target_bitmap] ## Blending modes ### API: al_get_blender Returns the active blender for the current thread. You can pass NULL for values you are not interested in. See also: [al_set_blender], [al_get_separate_blender] ### API: al_get_separate_blender Returns the active blender for the current thread. You can pass NULL for values you are not interested in. See also: [al_set_separate_blender], [al_get_blender] ### API: al_set_blender Sets the function to use for blending for the current thread. Blending means, the source and destination colors are combined in drawing operations. Assume the source color (e.g. color of a rectangle to draw, or pixel of a bitmap to draw) is given as its red/green/blue/alpha components (if the bitmap has no alpha it always is assumed to be fully opaque, so 255 for 8-bit or 1.0 for floating point): *sr, sg, sb, sa*. And this color is drawn to a destination, which already has a color: *dr, dg, db, da*. The conceptional formula used by Allegro to draw any pixel then depends on the `op` parameter: * ALLEGRO_ADD r = dr * dst + sr * src g = dg * dst + sg * src b = db * dst + sb * src a = da * dst + sa * src * ALLEGRO_DEST_MINUS_SRC r = dr * dst - sr * src g = dg * dst - sg * src b = db * dst - sb * src a = da * dst - sa * src * ALLEGRO_SRC_MINUS_DEST r = sr * src - dr * dst g = sg * src - dg * dst b = sb * src - db * dst a = sa * src - da * dst Valid values for `src` and `dst` passed to this function are * ALLEGRO_ZERO src = 0 dst = 0 * ALLEGRO_ONE src = 1 dst = 1 * ALLEGRO_ALPHA src = sa dst = sa * ALLEGRO_INVERSE_ALPHA src = 1 - sa dst = 1 - sa * ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0) f = s.r, s.g, s.b, s.a * ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8) f = d.r, d.g, d.b, d.a * ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0) f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a * ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8) f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a Blending examples: So for example, to restore the default of using premultiplied alpha blending, you would use (pseudo code) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) If you are using non-pre-multiplied alpha, you could use al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) Additive blending would be achieved with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) Copying the source to the destination (including alpha) unmodified al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) Multiplying source and destination components al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO) See also: [al_set_separate_blender], [al_get_blender] ### API: al_set_separate_blender Like [al_set_blender], but allows specifying a separate blending operation for the alpha channel. This is useful if your target bitmap also has an alpha channel and the two alpha channels need to be combined in a different way than the color components. See also: [al_set_blender], [al_get_blender], [al_get_separate_blender] ## Clipping ### API: al_get_clipping_rectangle Gets the clipping rectangle of the target bitmap. See also: [al_set_clipping_rectangle] ### API: al_set_clipping_rectangle Set the region of the target bitmap or display that pixels get clipped to. The default is to clip pixels to the entire bitmap. See also: [al_get_clipping_rectangle], [al_reset_clipping_rectangle] ### API: al_reset_clipping_rectangle Equivalent to calling `al_set_clipping_rectangle(0, 0, w, h)' where *w* and *h* are the width and height of the target bitmap respectively. Does nothing if there is no target bitmap. See also: [al_set_clipping_rectangle] Since: 5.0.6, 5.1.0 ## Graphics utility functions ### API: al_convert_mask_to_alpha Convert the given mask color to an alpha channel in the bitmap. Can be used to convert older 4.2-style bitmaps with magic pink to alpha-ready bitmaps. See also: [ALLEGRO_COLOR] ## Deferred drawing ### API: al_hold_bitmap_drawing Enables or disables deferred bitmap drawing. This allows for efficient drawing of many bitmaps that share a parent bitmap, such as sub-bitmaps from a tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls such that the parent bitmap is the same for large number of those calls. While deferred bitmap drawing is enabled, the only functions that can be used are the bitmap drawing functions and font drawing functions. Changing the state such as the blending modes will result in undefined behaviour. One exception to this rule are the transformations. It is possible to set a new transformation while the drawing is held. No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function's usage is to enable the deferred bitmap drawing, draw as many bitmaps as possible, taking care to stagger bitmaps that share parent bitmaps, and then disable deferred drawing. As mentioned above, this function also works with bitmap and truetype fonts, so if multiple lines of text need to be drawn, this function can speed things up. See also: [al_is_bitmap_drawing_held] ### API: al_is_bitmap_drawing_held Returns whether the deferred bitmap drawing mode is turned on or off. See also: [al_hold_bitmap_drawing] ## Image I/O ### API: al_register_bitmap_loader Register a handler for [al_load_bitmap]. The given function will be used to handle the loading of bitmaps files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_bitmap_saver], [al_register_bitmap_loader_f] ### API: al_register_bitmap_saver Register a handler for [al_save_bitmap]. The given function will be used to handle the loading of bitmaps files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `saver` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_bitmap_loader], [al_register_bitmap_saver_f] ### API: al_register_bitmap_loader_f Register a handler for [al_load_bitmap_f]. The given function will be used to handle the loading of bitmaps files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `fs_loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_bitmap_loader] ### API: al_register_bitmap_saver_f Register a handler for [al_save_bitmap_f]. The given function will be used to handle the loading of bitmaps files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `saver_f` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_bitmap_saver] ### API: al_load_bitmap Loads an image file into an [ALLEGRO_BITMAP]. The file type is determined by the extension. Returns NULL on error. > *Note:* the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. See also: [al_load_bitmap_f], [al_register_bitmap_loader], [al_set_new_bitmap_format], [al_set_new_bitmap_flags], [al_init_image_addon] ### API: al_load_bitmap_f Loads an image from an [ALLEGRO_FILE] stream into an [ALLEGRO_BITMAP]. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot. Returns NULL on error. The file remains open afterwards. > *Note:* the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. See also: [al_load_bitmap], [al_register_bitmap_loader_f], [al_init_image_addon] ### API: al_save_bitmap Saves an [ALLEGRO_BITMAP] to an image file. The file type is determined by the extension. Returns true on success, false on error. > *Note:* the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. See also: [al_save_bitmap_f], [al_register_bitmap_saver], [al_init_image_addon] ### API: al_save_bitmap_f Saves an [ALLEGRO_BITMAP] to an [ALLEGRO_FILE] stream. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot. Returns true on success, false on error. The file remains open afterwards. > *Note:* the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. See also: [al_save_bitmap], [al_register_bitmap_saver_f], [al_init_image_addon] allegro-5.0.10/docs/src/refman/color.txt0000644000175000001440000001346312135504300017254 0ustar tjadenusers# Color addon These functions are declared in the following header file. Link with allegro_color. #include ## API: al_color_cmyk Return an [ALLEGRO_COLOR] structure from CMYK values (cyan, magenta, yellow, black). See also: [al_color_cmyk_to_rgb], [al_color_rgb_to_cmyk] ## API: al_color_cmyk_to_rgb Convert CMYK values to RGB values. See also: [al_color_cmyk], [al_color_rgb_to_cmyk] ## API: al_color_hsl Return an [ALLEGRO_COLOR] structure from HSL (hue, saturation, lightness) values. See also: [al_color_hsl_to_rgb], [al_color_hsv] ## API: al_color_hsl_to_rgb Convert values in HSL color model to RGB color model. Parameters: * hue - Color hue angle in the range 0..360. * saturation - Color saturation in the range 0..1. * lightness - Color lightness in the range 0..1. * red, green, blue - returned RGB values in the range 0..1. See also: [al_color_rgb_to_hsl], [al_color_hsl], [al_color_hsv_to_rgb] ## API: al_color_hsv Return an [ALLEGRO_COLOR] structure from HSV (hue, saturation, value) values. See also: [al_color_hsv_to_rgb], [al_color_hsl] ## API: al_color_hsv_to_rgb Convert values in HSV color model to RGB color model. Parameters: * hue - Color hue angle in the range 0..360. * saturation - Color saturation in the range 0..1. * value - Color value in the range 0..1. * red, green, blue - returned RGB values in the range 0..1. See also: [al_color_rgb_to_hsv], [al_color_hsv], [al_color_hsl_to_rgb] ## API: al_color_html Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0. See also: [al_color_html_to_rgb], [al_color_rgb_to_html] ## API: al_color_html_to_rgb Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0. See also: [al_color_html], [al_color_rgb_to_html] ## API: al_color_rgb_to_html Create an HTML-style string representation of an [ALLEGRO_COLOR], e.g. #00faff. Parameters: * red, green, blue - The color components in the range 0..1. * string - A pointer to a buffer of at least 8 bytes, into which the result will be written (including the NUL terminator). Example: char html[8]; al_color_rgb_to_html(1, 0, 0, html); Now html will contain "#ff0000". See also: [al_color_html], [al_color_html_to_rgb] ## API: al_color_name Return an [ALLEGRO_COLOR] with the given name. If the color is not found then black is returned. See [al_color_name_to_rgb] for the list of names. ## API: al_color_name_to_rgb Parameters: * name - The (lowercase) name of the color. * r, g, b - If one of the recognized color names below is passed, the corresponding RGB values in the range 0..1 are written. The recognized names are: > aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, purple, purwablue, red, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen They are taken from . Returns: true if a name from the list above was passed, else false. See also: [al_color_name] ## API: al_color_rgb_to_cmyk Each RGB color can be represented in CMYK with a K component of 0 with the following formula: C = 1 - R M = 1 - G Y = 1 - B K = 0 This function will instead find the representation with the maximal value for K and minimal color components. See also: [al_color_cmyk], [al_color_cmyk_to_rgb] ## API: al_color_rgb_to_hsl Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and lightness in the range 0..1. See also: [al_color_hsl_to_rgb], [al_color_hsl] ## API: al_color_rgb_to_hsv Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and value in the range 0..1. See also: [al_color_hsv_to_rgb], [al_color_hsv] ## API: al_color_rgb_to_name Given an RGB triplet with components in the range 0..1, find a color name describing it approximately. See also: [al_color_name_to_rgb], [al_color_name] ## API: al_color_rgb_to_yuv Convert RGB values to YUV color space. See also: [al_color_yuv], [al_color_yuv_to_rgb] ## API: al_color_yuv Return an [ALLEGRO_COLOR] structure from YUV values. See also: [al_color_yuv_to_rgb], [al_color_rgb_to_yuv] ## API: al_color_yuv_to_rgb Convert YUV color values to RGB color space. See also: [al_color_yuv], [al_color_rgb_to_yuv] ## API: al_get_allegro_color_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/events.txt0000644000175000001440000005166212067702071017456 0ustar tjadenusers# Event system and events These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_EVENT An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: type (ALLEGRO_EVENT_TYPE) : Indicates the type of event. any.source (ALLEGRO_EVENT_SOURCE *) : The event source which generated the event. any.timestamp (double) : When the event was generated. By examining the `type` field you can then access type-specific fields. The `any.source` field tells you which event source generated that particular event. The `any.timestamp` field tells you when the event was generated. The time is referenced to the same starting point as [al_get_time]. Each event is of one of the following types, with the usable fields given. ### API: ALLEGRO_EVENT_JOYSTICK_AXIS A joystick axis value changed. joystick.id (ALLEGRO_JOYSTICK *) : The joystick which generated the event. This is not the same as the event source `joystick.source`. joystick.stick (int) : The stick number, counting from zero. Axes on a joystick are grouped into "sticks". joystick.axis (int) : The axis number on the stick, counting from zero. joystick.pos (float) : The axis position, from -1.0 to +1.0. ### API: ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN A joystick button was pressed. joystick.id (ALLEGRO_JOYSTICK *) : The joystick which generated the event. joystick.button (int) : The button which was pressed, counting from zero. ### API: ALLEGRO_EVENT_JOYSTICK_BUTTON_UP A joystick button was released. joystick.id (ALLEGRO_JOYSTICK *) : The joystick which generated the event. joystick.button (int) : The button which was released, counting from zero. ### API: ALLEGRO_EVENT_JOYSTICK_CONFIGURATION A joystick was plugged in or unplugged. See [al_reconfigure_joysticks] for details. ### API: ALLEGRO_EVENT_KEY_DOWN A keyboard key was pressed. keyboard.keycode (int) : The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO\_KEY\_\* constants. keyboard.display (ALLEGRO_DISPLAY *) : The display which had keyboard focus when the event occurred. > *Note:* this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. ### API: ALLEGRO_EVENT_KEY_UP A keyboard key was released. keyboard.keycode (int) : The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO\_KEY\_\* constants. keyboard.display (ALLEGRO_DISPLAY *) : The display which had keyboard focus when the event occurred. ### API: ALLEGRO_EVENT_KEY_CHAR A character was typed on the keyboard, or a character was auto-repeated. keyboard.keycode (int) : The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO\_KEY\_\* constants. keyboard.unichar (int) : A Unicode code point (character). This *may* be zero or negative if the event was generated for a non-visible "character", such as an arrow or Function key. In that case you can act upon the `keycode` field. Some special keys will set the `unichar` field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the `unichar` field will have the values 1 to 26. For example Ctrl-A will set `unichar` to 1 and Ctrl-H will set it to 8. As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the `keycode` field. keyboard.modifiers (unsigned) : This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. keyboard.repeat (bool) : Indicates if this is a repeated character. keyboard.display (ALLEGRO_DISPLAY *) : The display which had keyboard focus when the event occurred. > *Note*: in many input methods, characters are *not* entered one-for-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce 'é'. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. ### API: ALLEGRO_EVENT_MOUSE_AXES One or more mouse axis values changed. mouse.x (int) : x-coordinate mouse.y (int) : y-coordinate mouse.z (int) : z-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. mouse.w (int) : w-coordinate. This usually means the horizontal axis of a mouse wheel. mouse.dx (int) : Change in the x-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. mouse.dy (int) : Change in the y-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. mouse.dz (int) : Change in the z-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. mouse.dw (int) : Change in the w-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. mouse.display (ALLEGRO_DISPLAY *) : The display which had mouse focus. > *Note:* Calling [al_set_mouse_xy] also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. > *Note:* currently mouse.display may be NULL if an event is generated in response to [al_set_mouse_axis]. ### API: ALLEGRO_EVENT_MOUSE_BUTTON_DOWN A mouse button was pressed. mouse.x (int) : x-coordinate mouse.y (int) : y-coordinate mouse.z (int) : z-coordinate mouse.w (int) : w-coordinate mouse.button (unsigned) : The mouse button which was pressed, numbering from 1. mouse.display (ALLEGRO_DISPLAY *) : The display which had mouse focus. ### API: ALLEGRO_EVENT_MOUSE_BUTTON_UP A mouse button was released. mouse.x (int) : x-coordinate mouse.y (int) : y-coordinate mouse.z (int) : z-coordinate mouse.w (int) : w-coordinate mouse.button (unsigned) : The mouse button which was released, numbering from 1. mouse.display (ALLEGRO_DISPLAY *) : The display which had mouse focus. ### API: ALLEGRO_EVENT_MOUSE_WARPED [al_set_mouse_xy] was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. ### API: ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY The mouse cursor entered a window opened by the program. mouse.x (int) : x-coordinate mouse.y (int) : y-coordinate mouse.z (int) : z-coordinate mouse.w (int) : w-coordinate mouse.display (ALLEGRO_DISPLAY *) : The display which had mouse focus. ### API: ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY The mouse cursor leave the boundaries of a window opened by the program. mouse.x (int) : x-coordinate mouse.y (int) : y-coordinate mouse.z (int) : z-coordinate mouse.w (int) : w-coordinate mouse.display (ALLEGRO_DISPLAY *) : The display which had mouse focus. ### API: ALLEGRO_EVENT_TIMER A timer counter incremented. timer.source (ALLEGRO_TIMER *) : The timer which generated the event. timer.count (int64_t) : The timer count value. ### API: ALLEGRO_EVENT_DISPLAY_EXPOSE The display (or a portion thereof) has become visible. display.source (ALLEGRO_DISPLAY *) : The display which was exposed. display.x (int) :   display.y (int) :   : The top-left corner of the display which was exposed. display.width (int) :   display.height (int) : The width and height of the rectangle which was exposed. > *Note:* The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. ### API: ALLEGRO_EVENT_DISPLAY_RESIZE The window has been resized. display.source (ALLEGRO_DISPLAY *) : The display which was resized. display.x (int) :   display.y (int) : The position of the top-level corner of the display. display.width (int) : The new width of the display. display.height (int) : The new height of the display. You should normally respond to these events by calling [al_acknowledge_resize]. Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. ### API: ALLEGRO_EVENT_DISPLAY_CLOSE The close button of the window has been pressed. display.source (ALLEGRO_DISPLAY *) : The display which was closed. ### API: ALLEGRO_EVENT_DISPLAY_LOST When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap's pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps -- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. display.source (ALLEGRO_DISPLAY *) : The display which was lost. ### API: ALLEGRO_EVENT_DISPLAY_FOUND Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. display.source (ALLEGRO_DISPLAY *) : The display which was found. ### API: ALLEGRO_EVENT_DISPLAY_SWITCH_OUT The window is no longer active, that is the user might have clicked into another window or "tabbed" away. display.source (ALLEGRO_DISPLAY *) : The display which was switched out of. ### API: ALLEGRO_EVENT_DISPLAY_SWITCH_IN The window is the active one again. display.source (ALLEGRO_DISPLAY *) : The display which was switched into. ### API: ALLEGRO_EVENT_DISPLAY_ORIENTATION Generated when the rotation or orientation of a display changes. display.source (ALLEGRO_DISPLAY *) : The display which generated the event. event.display.orientation : Contains one of the following values: - ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES - ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES - ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES - ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES - ALLEGRO_DISPLAY_ORIENTATION_FACE_UP - ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN See also: [ALLEGRO_EVENT_SOURCE], [ALLEGRO_EVENT_TYPE], [ALLEGRO_USER_EVENT], [ALLEGRO_GET_EVENT_TYPE] ## API: ALLEGRO_USER_EVENT An event structure that can be emitted by user event sources. These are the public fields: - ALLEGRO_EVENT_SOURCE *source; - intptr_t data1; - intptr_t data2; - intptr_t data3; - intptr_t data4; Like all other event types this structure is a part of the ALLEGRO_EVENT union. To access the fields in an ALLEGRO_EVENT variable `ev`, you would use: - ev.user.source - ev.user.data1 - ev.user.data2 - ev.user.data3 - ev.user.data4 To create a new user event you would do this: ALLEGRO_EVENT_SOURCE my_event_source; ALLEGRO_EVENT my_event; float some_var; al_init_user_event_source(&my_event_source); my_event.user.type = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'); my_event.user.data1 = 1; my_event.user.data2 = &some_var; al_emit_user_event(&my_event_source, &my_event, NULL); Event type identifiers for user events are assigned by the user. Please see the documentation for [ALLEGRO_GET_EVENT_TYPE] for the rules you should follow when assigning identifiers. See also: [al_emit_user_event], [ALLEGRO_GET_EVENT_TYPE] ## API: ALLEGRO_EVENT_QUEUE An event queue holds events that have been generated by event sources that are registered with the queue. Events are stored in the order they are generated. Access is in a strictly FIFO (first-in-first-out) order. See also: [al_create_event_queue], [al_destroy_event_queue] ## API: ALLEGRO_EVENT_SOURCE An event source is any object which can generate events. For example, an ALLEGRO_DISPLAY can generate events, and you can get the ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with [al_get_display_event_source]. You may create your own "user" event sources that emit custom events. See also: [ALLEGRO_EVENT], [al_init_user_event_source], [al_emit_user_event] ## API: ALLEGRO_EVENT_TYPE An integer used to distinguish between different types of events. See also: [ALLEGRO_EVENT], [ALLEGRO_GET_EVENT_TYPE], [ALLEGRO_EVENT_TYPE_IS_USER] ## API: ALLEGRO_GET_EVENT_TYPE Make an event type identifier, which is a 32-bit integer. Usually, but not necessarily, this will be made from four 8-bit character codes, for example: #define MY_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('M','I','N','E') IDs less than 1024 are reserved for Allegro or its addons. Don't use anything lower than `ALLEGRO_GET_EVENT_TYPE(0, 0, 4, 0)`. You should try to make your IDs unique so they don't clash with any 3rd party code you may be using. Be creative. Numbering from 1024 is not creative. If you need multiple identifiers, you could define them like this: #define BASE_EVENT ALLEGRO_GET_EVENT_TYPE('M','I','N','E') #define BARK_EVENT (BASE_EVENT + 0) #define MEOW_EVENT (BASE_EVENT + 1) #define SQUAWK_EVENT (BASE_EVENT + 2) /* Alternatively */ enum { BARK_EVENT = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'), MEOW_EVENT, SQUAWK_EVENT }; See also: [ALLEGRO_EVENT], [ALLEGRO_USER_EVENT], [ALLEGRO_EVENT_TYPE_IS_USER] ## API: ALLEGRO_EVENT_TYPE_IS_USER A macro which evaluates to true if the event type is not a builtin event type, i.e. one of those described in [ALLEGRO_EVENT_TYPE]. ## API: al_create_event_queue Create a new, empty event queue, returning a pointer to object if successful. Returns NULL on error. See also: [al_register_event_source], [al_destroy_event_queue], [ALLEGRO_EVENT_QUEUE] ## API: al_destroy_event_queue Destroy the event queue specified. All event sources currently registered with the queue will be automatically unregistered before the queue is destroyed. See also: [al_create_event_queue], [ALLEGRO_EVENT_QUEUE] ## API: al_register_event_source Register the event source with the event queue specified. An event source may be registered with any number of event queues simultaneously, or none. Trying to register an event source with the same event queue more than once does nothing. See also: [al_unregister_event_source], [ALLEGRO_EVENT_SOURCE] ## API: al_unregister_event_source Unregister an event source with an event queue. If the event source is not actually registered with the event queue, nothing happens. If the queue had any events in it which originated from the event source, they will no longer be in the queue after this call. See also: [al_register_event_source] ## API: al_is_event_queue_empty Return true if the event queue specified is currently empty. See also: [al_get_next_event], [al_peek_next_event] ## API: al_get_next_event Take the next event out of the event queue specified, and copy the contents into `ret_event`, returning true. The original event will be removed from the queue. If the event queue is empty, return false and the contents of `ret_event` are unspecified. See also: [ALLEGRO_EVENT], [al_peek_next_event], [al_wait_for_event] ## API: al_peek_next_event Copy the contents of the next event in the event queue specified into `ret_event` and return true. The original event packet will remain at the head of the queue. If the event queue is actually empty, this function returns false and the contents of `ret_event` are unspecified. See also: [ALLEGRO_EVENT], [al_get_next_event], [al_drop_next_event] ## API: al_drop_next_event Drop (remove) the next event from the queue. If the queue is empty, nothing happens. Returns true if an event was dropped. See also: [al_flush_event_queue], [al_is_event_queue_empty] ## API: al_flush_event_queue Drops all events, if any, from the queue. See also: [al_drop_next_event], [al_is_event_queue_empty] ## API: al_wait_for_event Wait until the event queue specified is non-empty. If `ret_event` is not NULL, the first event in the queue will be copied into `ret_event` and removed from the queue. If `ret_event` is NULL the first event is left at the head of the queue. See also: [ALLEGRO_EVENT], [al_wait_for_event_timed], [al_wait_for_event_until], [al_get_next_event] ## API: al_wait_for_event_timed Wait until the event queue specified is non-empty. If `ret_event` is not NULL, the first event in the queue will be copied into `ret_event` and removed from the queue. If `ret_event` is NULL the first event is left at the head of the queue. `timeout_msecs` determines approximately how many seconds to wait. If the call times out, false is returned. Otherwise true is returned. See also: [ALLEGRO_EVENT], [al_wait_for_event], [al_wait_for_event_until] ## API: al_wait_for_event_until Wait until the event queue specified is non-empty. If `ret_event` is not NULL, the first event in the queue will be copied into `ret_event` and removed from the queue. If `ret_event` is NULL the first event is left at the head of the queue. `timeout` determines how long to wait. If the call times out, false is returned. Otherwise true is returned. See also: [ALLEGRO_EVENT], [ALLEGRO_TIMEOUT], [al_init_timeout], [al_wait_for_event], [al_wait_for_event_timed] ## API: al_init_user_event_source Initialise an event source for emitting user events. The space for the event source must already have been allocated. One possible way of creating custom event sources is to derive other structures with ALLEGRO_EVENT_SOURCE at the head, e.g. typedef struct THING THING; struct THING { ALLEGRO_EVENT_SOURCE event_source; int field1; int field2; /* etc. */ }; THING *create_thing(void) { THING *thing = malloc(sizeof(THING)); if (thing) { al_init_user_event_source(&thing->event_source); thing->field1 = 0; thing->field2 = 0; } return thing; } The advantage here is that the THING pointer will be the same as the ALLEGRO_EVENT_SOURCE pointer. Events emitted by the event source will have the event source pointer as the `source` field, from which you can get a pointer to a THING by a simple cast (after ensuring checking the event is of the correct type). However, it is only one technique and you are not obliged to use it. The user event source will never be destroyed automatically. You must destroy it manually with [al_destroy_user_event_source]. See also: [ALLEGRO_EVENT_SOURCE], [al_destroy_user_event_source], [al_emit_user_event], [ALLEGRO_USER_EVENT] ## API: al_destroy_user_event_source Destroy an event source initialised with [al_init_user_event_source]. This does not free the memory, as that was user allocated to begin with. See also: [ALLEGRO_EVENT_SOURCE] ## API: al_emit_user_event Emit a user event. The event source must have been initialised with [al_init_user_event_source]. Returns `false` if the event source isn't registered with any queues, hence the event wouldn't have been delivered into any queues. Events are *copied* in and out of event queues, so after this function returns the memory pointed to by `event` may be freed or reused. Some fields of the event being passed in may be modified by the function. Reference counting will be performed if `dtor` is not NULL. Whenever a copy of the event is made, the reference count increases. You need to call [al_unref_user_event] to decrease the reference count once you are done with a user event that you have received from [al_get_next_event], [al_peek_next_event], [al_wait_for_event], etc. Once the reference count drops to zero `dtor` will be called with a copy of the event as an argument. It should free the resources associated with the event, but *not* the event itself (since it is just a copy). If `dtor` is NULL then reference counting will not be performed. It is safe, but unnecessary, to call [al_unref_user_event] on non-reference counted user events. See also: [ALLEGRO_USER_EVENT], [al_unref_user_event] ## API: al_unref_user_event Decrease the reference count of a user-defined event. This must be called on any user event that you get from [al_get_next_event], [al_peek_next_event], [al_wait_for_event], etc. which is reference counted. This function does nothing if the event is not reference counted. See also: [al_emit_user_event], [ALLEGRO_USER_EVENT] ## API: al_get_event_source_data Returns the abstract user data associated with the event source. If no data was previously set, returns NULL. See also: [al_set_event_source_data] ## API: al_set_event_source_data Assign the abstract user data to the event source. Allegro does not use the data internally for anything; it is simply meant as a convenient way to associate your own data or objects with events. See also: [al_get_event_source_data] allegro-5.0.10/docs/src/refman/opengl.txt0000644000175000001440000001357312134764134017440 0ustar tjadenusers# OpenGL integration These functions are declared in the following header file: #include ## API: al_get_opengl_extension_list Returns the list of OpenGL extensions supported by Allegro, for the given display. Allegro will keep information about all extensions it knows about in a structure returned by `al_get_opengl_extension_list`. For example: if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) { use it } The extension will be set to true if available for the given display and false otherwise. This means to use the definitions and functions from an OpenGL extension, all you need to do is to check for it as above at run time, after acquiring the OpenGL display from Allegro. Under Windows, this will also work with WGL extensions, and under Unix with GLX extensions. In case you want to manually check for extensions and load function pointers yourself (say, in case the Allegro developers did not include it yet), you can use the [al_have_opengl_extension] and [al_get_opengl_proc_address] functions instead. ## API: al_get_opengl_proc_address Helper to get the address of an OpenGL symbol Example: How to get the function _glMultiTexCoord3fARB_ that comes with ARB's Multitexture extension: // define the type of the function ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC, (GLenum, GLfloat, GLfloat, GLfloat)); // declare the function pointer MULTI_TEX_FUNC glMultiTexCoord3fARB; // get the address of the function glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address( "glMultiTexCoord3fARB"); If _glMultiTexCoord3fARB_ is not NULL then it can be used as if it has been defined in the OpenGL core library. > *Note:* Under Windows, OpenGL functions may need a special calling convention, so it's best to always use the ALLEGRO_DEFINE_PROC_TYPE macro when declaring function pointer types for OpenGL functions. Parameters: name - The name of the symbol you want to link to. *Return value:* A pointer to the symbol if available or NULL otherwise. ## API: al_get_opengl_texture Returns the OpenGL texture id internally used by the given bitmap if it uses one, else 0. Example: bitmap = al_load_bitmap("my_texture.png"); texture = al_get_opengl_texture(bitmap); if (texture != 0) glBindTexture(GL_TEXTURE_2D, texture); ## API: al_get_opengl_texture_size Retrieves the size of the texture used for the bitmap. This can be different from the bitmap size if OpenGL only supports power-of-two sizes or if it is a sub-bitmap. 0's are returned if the bitmap is not an OpenGL bitmap. See also: [al_get_opengl_texture_position] ## API: al_get_opengl_texture_position Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels. See also: [al_get_opengl_texture_size] ## API: al_get_opengl_fbo Returns the OpenGL FBO id internally used by the given bitmap if it uses one, otherwise returns zero. No attempt will be made to create an FBO if the bitmap is not owned by the current display. The FBO returned by this function will only be freed when the bitmap is destroyed, or if you call [al_remove_opengl_fbo] on the bitmap. > *Note:* In Allegro 5.0.0 this function only returned an FBO which had previously been created by calling [al_set_target_bitmap]. It would not attempt to create an FBO itself. This has since been changed. See also: [al_remove_opengl_fbo], [al_set_target_bitmap] ## API: al_remove_opengl_fbo Explicitly free an OpenGL FBO created for a bitmap, if it has one. Usually you do not need to worry about freeing FBOs, unless you use [al_get_opengl_fbo]. See also: [al_get_opengl_fbo], [al_set_target_bitmap] ## API: al_have_opengl_extension This function is a helper to determine whether an OpenGL extension is available on the given display or not. Example: bool packedpixels = al_have_opengl_extension("GL_EXT_packed_pixels"); If _packedpixels_ is true then you can safely use the constants related to the packed pixels extension. Returns true if the extension is available; false otherwise. ## API: al_get_opengl_version Returns the OpenGL or OpenGL ES version number of the client (the computer the program is running on), for the current display. "1.0" is returned as 0x01000000, "1.2.1" is returned as 0x01020100, and "1.2.2" as 0x01020200, etc. A valid OpenGL context must exist for this function to work, which means you may *not* call it before [al_create_display]. See also: [al_get_opengl_variant] ## API: al_get_opengl_variant Returns the variant or type of OpenGL used on the running platform. This function can be called before creating a display or setting properties for new displays. Possible values are: ALLEGRO_DESKTOP_OPENGL : Regular OpenGL as seen on desktop/laptop computers. ALLEGRO_OPENGL_ES : Trimmed down version of OpenGL used on many small consumer electronic devices such as handheld (and sometimes full size) consoles. See also: [al_get_opengl_version] ## API: al_set_current_opengl_context Make the OpenGL context associated with the given display current for the calling thread. If there is a current target bitmap which belongs to a different OpenGL context, the target bitmap will be changed to NULL. Normally you do not need to use this function, as the context will be made current when you call [al_set_target_bitmap] or [al_set_target_backbuffer]. You might need if it you created an OpenGL "forward compatible" context. Then [al_get_backbuffer] only returns NULL, so it would not work to pass that to [al_set_target_bitmap]. ## OpenGL configuration You can disable the detection of any OpenGL extension by Allegro with a section like this in allegro5.cfg: [opengl_disabled_extensions] GL_ARB_texture_non_power_of_two=0 GL_EXT_framebuffer_object=0 Any extension which appears in the section is treated as not available (it does not matter if you set it to 0 or any other value). allegro-5.0.10/docs/src/refman/path.txt0000644000175000001440000001602511520366477017111 0ustar tjadenusers# Path structures These functions are declared in the main Allegro header file: #include We define a path as an optional *drive*, followed by zero or more *directory components*, followed by an optional *filename*. The filename may be broken up into a *basename* and an *extension*, where the basename includes the start of the filename up to, but not including, the last dot (.) character. If no dot character exists the basename is the whole filename. The extension is everything from the last dot character to the end of the filename. ## API: al_create_path Create a path structure from a string. The last component, if it is followed by a directory separator and is neither "." nor "..", is treated as the last directory name in the path. Otherwise the last component is treated as the filename. The string may be NULL for an empty path. See also: [al_create_path], [al_destroy_path] ## API: al_create_path_for_directory This is the same as [al_create_path], but interprets the passed string as a directory path. The filename component of the returned path will always be empty. See also: [al_create_path], [al_destroy_path] ## API: al_destroy_path Free a path structure. Does nothing if passed NULL. See also: [al_create_path], [al_create_path_for_directory] ## API: al_clone_path Clones an ALLEGRO_PATH structure. Returns NULL on failure. See also: [al_destroy_path] ## API: al_join_paths Concatenate two path structures. The first path structure is modified. If 'tail' is an absolute path, this function does nothing. If 'tail' is a relative path, all of its directory components will be appended to 'path'. tail's filename will also overwrite path's filename, even if it is just the empty string. Tail's drive is ignored. Returns true if 'tail' was a relative path and so concatenated to 'path', otherwise returns false. See also: [al_rebase_path] ## API: al_rebase_path Concatenate two path structures, modifying the second path structure. If *tail* is an absolute path, this function does nothing. Otherwise, the drive and path components in *head* are inserted at the start of *tail*. For example, if *head* is "/anchor/" and *tail* is "data/file.ext", then after the call *tail* becomes "/anchor/data/file.ext". See also: [al_join_paths] ## API: al_get_path_drive Return the drive letter on a path, or the empty string if there is none. The "drive letter" is only used on Windows, and is usually a string like "c:", but may be something like "\\\\Computer Name" in the case of UNC (Uniform Naming Convention) syntax. ## API: al_get_path_num_components Return the number of directory components in a path. The directory components do not include the final part of a path (the filename). See also: [al_get_path_component] ## API: al_get_path_component Return the i'th directory component of a path, counting from zero. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds. See also: [al_get_path_num_components], [al_get_path_tail] ## API: al_get_path_tail Returns the last directory component, or NULL if there are no directory components. ## API: al_get_path_filename Return the filename part of the path, or the empty string if there is none. The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. See also: [al_get_path_basename], [al_get_path_extension], [al_get_path_component] ## API: al_get_path_basename Return the basename, i.e. filename with the extension removed. If the filename doesn't have an extension, the whole filename is the basename. If there is no filename part then the empty string is returned. The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. See also: [al_get_path_filename], [al_get_path_extension] ## API: al_get_path_extension Return a pointer to the start of the extension of the filename, i.e. everything from the final dot ('.') character onwards. If no dot exists, returns an empty string. The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. See also: [al_get_path_filename], [al_get_path_basename] ## API: al_set_path_drive Set the drive string on a path. The drive may be NULL, which is equivalent to setting the drive string to the empty string. See also: [al_get_path_drive] ## API: al_append_path_component Append a directory component. See also: [al_insert_path_component] ## API: al_insert_path_component Insert a directory component at index i. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index i which is not within these bounds: 0 <= i <= al_get_path_num_components(path). See also: [al_append_path_component], [al_replace_path_component], [al_remove_path_component] ## API: al_replace_path_component Replace the i'th directory component by another string. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds. See also: [al_insert_path_component], [al_remove_path_component] ## API: al_remove_path_component Delete the i'th directory component. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds. See also: [al_insert_path_component], [al_replace_path_component], [al_drop_path_tail] ## API: al_drop_path_tail Remove the last directory component, if any. See also: [al_remove_path_component] ## API: al_set_path_filename Set the optional filename part of the path. The filename may be NULL, which is equivalent to setting the filename to the empty string. See also: [al_set_path_extension], [al_get_path_filename] ## API: al_set_path_extension Replaces the extension of the path with the given one, i.e. replaces everything from the final dot ('.') character onwards, including the dot. If the filename of the path has no extension, the given one is appended. Usually the new extension you supply should include a leading dot. Returns false if the path contains no filename part, i.e. the filename part is the empty string. See also: [al_set_path_filename], [al_get_path_extension] ## API: al_path_cstr Convert a path to its string representation, i.e. optional drive, followed by directory components separated by 'delim', followed by an optional filename. To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP for 'delim'. The returned pointer is valid only until the path is modified in any way, or until the path is destroyed. ## API: al_make_path_canonical Removes any leading '..' directory components in absolute paths. Removes all '.' directory components. Note that this does *not* collapse "x/../y" sections into "y". This is by design. If "/foo" on your system is a symlink to "/bar/baz", then "/foo/../quux" is actually "/bar/quux", not "/quux" as a naive removal of ".." components would give you. allegro-5.0.10/docs/src/refman/primitives.txt0000644000175000001440000006203712117032252020334 0ustar tjadenusers# Primitives addon These functions are declared in the following header file. Link with allegro_primitives. #include ## General ### API: al_get_allegro_primitives_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. ### API: al_init_primitives_addon Initializes the primitives addon. *Returns:* True on success, false on failure. See also: [al_shutdown_primitives_addon] ### API: al_shutdown_primitives_addon Shut down the primitives addon. This is done automatically at program exit, but can be called any time the user wishes as well. See also: [al_init_primitives_addon] ## High level drawing routines High level drawing routines encompass the most common usage of this addon: to draw geometric primitives, both smooth (variations on the circle theme) and piecewise linear. Outlined primitives support the concept of thickness with two distinct modes of output: hairline lines and thick lines. Hairline lines are specifically designed to be exactly a pixel wide, and are commonly used for drawing outlined figures that need to be a pixel wide. Hairline thickness is designated as thickness less than or equal to 0. Unfortunately, the exact rasterization rules for drawing these hairline lines vary from one video card to another, and sometimes leave gaps where the lines meet. If that matters to you, then you should use thick lines. In many cases, having a thickness of 1 will produce 1 pixel wide lines that look better than hairline lines. Obviously, hairline lines cannot replicate thicknesses greater than 1. Thick lines grow symmetrically around the generating shape as thickness is increased. ### Pixel-precise output While normally you should not be too concerned with which pixels are displayed when the high level primitives are drawn, it is nevertheless possible to control that precisely by carefully picking the coordinates at which you draw those primitives. To be able to do that, however, it is critical to understand how GPU cards convert shapes to pixels. Pixels are not the smallest unit that can be addressed by the GPU. Because the GPU deals with floating point coordinates, it can in fact assign different coordinates to different parts of a single pixel. To a GPU, thus, a screen is composed of a grid of squares that have width and length of 1. The top left corner of the top left pixel is located at (0, 0). Therefore, the center of that pixel is at (0.5, 0.5). The basic rule that determines which pixels are associated with which shape is then as follows: a pixel is treated to belong to a shape if the pixel's center is located in that shape. The figure below illustrates the above concepts: ![*Diagram showing a how pixel output is calculated by the GPU given the mathematical description of several shapes.*](images/primitives1.png) This figure depicts three shapes drawn at the top left of the screen: an orange and green rectangles and a purple circle. On the left are the mathematical descriptions of pixels on the screen and the shapes to be drawn. On the right is the screen output. Only a single pixel has its center inside the circle, and therefore only a single pixel is drawn on the screen. Similarly, two pixels are drawn for the orange rectangle. Since there are no pixels that have their centers inside the green rectangle, the output image has no green pixels. Here is a more practical example. The image below shows the output of this code: /* blue vertical line */ al_draw_line(0.5, 0, 0.5, 6, color_blue, 1); /* red horizontal line */ al_draw_line(2, 1, 6, 1, color_red, 2); /* green filled rectangle */ al_draw_filled_rectangle(3, 4, 5, 5, color_green); /* purple outlined rectangle */ al_draw_rectangle(2.5, 3.5, 5.5, 5.5, color_purple, 1); ![*Diagram showing a practical example of pixel output resulting from the invocation of several primitives addon functions.*](images/primitives2.png) It can be seen that lines are generated by making a rectangle based on the dashed line between the two endpoints. The thickness causes the rectangle to grow symmetrically about that generating line, as can be seen by comparing the red and blue lines. Note that to get proper pixel coverage, the coordinates passed to the `al_draw_line` had to be offset by 0.5 in the appropriate dimensions. Filled rectangles are generated by making a rectangle between the endpoints passed to the `al_draw_filled_rectangle`. Outlined rectangles are generated by symmetrically expanding an outline of a rectangle. With a thickness of 1, as depicted in the diagram, this means that an offset of 0.5 is needed for both sets of endpoint coordinates to exactly line up with the pixels of the display raster. The above rules only apply when multisampling is turned off. When multisampling is turned on, the area of a pixel that is covered by a shape is taken into account when choosing what color to draw there. This also means that shapes no longer have to contain the pixel's center to affect its color. For example, the green rectangle in the first diagram may in fact be drawn as two (or one) semi-transparent pixels. The advantages of multisampling is that slanted shapes will look smoother because they will not have jagged edges. A disadvantage of multisampling is that it may make vertical and horizontal edges blurry. While the exact rules for multisampling are unspecified, and may vary from GPU to GPU it is usually safe to assume that as long as a pixel is either completely covered by a shape or completely not covered, then the shape edges will be sharp. The offsets used in the second diagram were chosen so that this is the case: if you use those offsets, your shapes (if they are oriented the same way as they are on the diagram) should look the same whether multisampling is turned on or off. ### API: al_draw_line Draws a line segment between two points. *Parameters:* * x1, y1, x2, y2 - Start and end points of the line * color - Color of the line * thickness - Thickness of the line, pass `<= 0` to draw hairline lines See also: [al_draw_soft_line] ### API: al_draw_triangle Draws an outlined triangle. *Parameters:* * x1, y1, x2, y2, x3, y3 - Three points of the triangle * color - Color of the triangle * thickness - Thickness of the lines, pass `<= 0` to draw hairline lines See also: [al_draw_filled_triangle], [al_draw_soft_triangle] ### API: al_draw_filled_triangle Draws a filled triangle. *Parameters:* * x1, y1, x2, y2, x3, y3 - Three points of the triangle * color - Color of the triangle See also: [al_draw_triangle] ### API: al_draw_rectangle Draws an outlined rectangle. *Parameters:* * x1, y1, x2, y2 - Upper left and lower right points of the rectangle * color - Color of the rectangle * thickness - Thickness of the lines, pass `<= 0` to draw hairline lines See also: [al_draw_filled_rectangle], [al_draw_rounded_rectangle] ### API: al_draw_filled_rectangle Draws a filled rectangle. *Parameters:* * x1, y1, x2, y2 - Upper left and lower right points of the rectangle * color - Color of the rectangle See also: [al_draw_rectangle], [al_draw_filled_rounded_rectangle] ### API: al_draw_rounded_rectangle Draws an outlined rounded rectangle. *Parameters:* * x1, y1, x2, y2 - Upper left and lower right points of the rectangle * color - Color of the rectangle * rx, ry - The radii of the round * thickness - Thickness of the lines, pass `<= 0` to draw hairline lines See also: [al_draw_filled_rounded_rectangle], [al_draw_rectangle] ### API: al_draw_filled_rounded_rectangle Draws an filled rounded rectangle. *Parameters:* * x1, y1, x2, y2 - Upper left and lower right points of the rectangle * color - Color of the rectangle * rx, ry - The radii of the round See also: [al_draw_rounded_rectangle], [al_draw_filled_rectangle] ### API: al_calculate_arc Calculates an elliptical arc, and sets the vertices in the destination buffer to the calculated positions. If `thickness <= 0`, then `num_points` of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of `stride` bytes) doublets of floats, corresponding to x and y coordinates of the vertices. *Parameters:* * dest - The destination buffer * stride - Distance (in bytes) between starts of successive pairs of coordinates * cx, cy - Center of the arc * rx, ry - Radii of the arc * start_theta - The initial angle from which the arc is calculated * delta_theta - Angular span of the arc (pass a negative number to switch direction) * thickness - Thickness of the arc * num_points - The number of points to calculate See also: [al_draw_arc], [al_calculate_spline], [al_calculate_ribbon] ### API: al_draw_pieslice Draws a pieslice (outlined circular sector). *Parameters:* * cx, cy - Center of the pieslice * r - Radius of the pieslice * color - Color of the pieslice * start_theta - The initial angle from which the pieslice is drawn * delta_theta - Angular span of the pieslice (pass a negative number to switch direction) * thickness - Thickness of the circle, pass `<= 0` to draw hairline pieslice Since: 5.0.6, 5.1.0 See also: [al_draw_filled_pieslice] ### API: al_draw_filled_pieslice Draws a filled pieslice (filled circular sector). *Parameters:* * cx, cy - Center of the pieslice * r - Radius of the pieslice * color - Color of the pieslice * start_theta - The initial angle from which the pieslice is drawn * delta_theta - Angular span of the pieslice (pass a negative number to switch direction) Since: 5.0.6, 5.1.0 See also: [al_draw_pieslice] ### API: al_draw_ellipse Draws an outlined ellipse. *Parameters:* * cx, cy - Center of the ellipse * rx, ry - Radii of the ellipse * color - Color of the ellipse * thickness - Thickness of the ellipse, pass `<= 0` to draw a hairline ellipse See also: [al_draw_filled_ellipse], [al_draw_circle] ### API: al_draw_filled_ellipse Draws a filled ellipse. *Parameters:* * cx, cy - Center of the ellipse * rx, ry - Radii of the ellipse * color - Color of the ellipse See also: [al_draw_ellipse], [al_draw_filled_circle] ### API: al_draw_circle Draws an outlined circle. *Parameters:* * cx, cy - Center of the circle * r - Radius of the circle * color - Color of the circle * thickness - Thickness of the circle, pass `<= 0` to draw a hairline circle See also: [al_draw_filled_circle], [al_draw_ellipse] ### API: al_draw_filled_circle Draws a filled circle. *Parameters:* * cx, cy - Center of the circle * r - Radius of the circle * color - Color of the circle See also: [al_draw_circle], [al_draw_filled_ellipse] ### API: al_draw_arc Draws an arc. *Parameters:* * cx, cy - Center of the arc * r - Radius of the arc * color - Color of the arc * start_theta - The initial angle from which the arc is calculated * delta_theta - Angular span of the arc (pass a negative number to switch direction) * thickness - Thickness of the arc, pass `<= 0` to draw hairline arc See also: [al_calculate_arc], [al_draw_elliptical_arc] ### API: al_draw_elliptical_arc Draws an elliptical arc. *Parameters:* * cx, cy - Center of the arc * rx, ry - Radii of the arc * color - Color of the arc * start_theta - The initial angle from which the arc is calculated * delta_theta - Angular span of the arc (pass a negative number to switch direction) * thickness - Thickness of the arc, pass `<= 0` to draw hairline arc Since: 5.0.6, 5.1.0 See also: [al_calculate_arc], [al_draw_arc] ### API: al_calculate_spline Calculates a Bézier spline given 4 control points. If `thickness <= 0`, then `num_segments` of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of stride bytes) doublets of floats, corresponding to x and y coordinates of the vertices. *Parameters:* * dest - The destination buffer * stride - Distance (in bytes) between starts of successive pairs of coordinates * points - An array of 4 pairs of coordinates of the 4 control points * thickness - Thickness of the spline ribbon * num_segments - The number of points to calculate See also: [al_draw_spline], [al_calculate_arc], [al_calculate_ribbon] ### API: al_draw_spline Draws a Bézier spline given 4 control points. *Parameters:* * points - An array of 4 pairs of coordinates of the 4 control points * color - Color of the spline * thickness - Thickness of the spline, pass `<= 0` to draw a hairline spline See also: [al_calculate_spline] ### API: al_calculate_ribbon Calculates a ribbon given an array of points. The ribbon will go through all of the passed points. If `thickness <= 0`, then `num_segments` of points are required in the destination buffer, otherwise twice as many are needed. The destination and the points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices. *Parameters:* * dest - Pointer to the destination buffer * dest_stride - Distance (in bytes) between starts of successive pairs of coordinates in the destination buffer * points - An array of pairs of coordinates for each point * points_stride - Distance (in bytes) between starts successive pairs of coordinates in the points buffer * thickness - Thickness of the spline ribbon * num_segments - The number of points to calculate See also: [al_draw_ribbon], [al_calculate_arc], [al_calculate_spline] ### API: al_draw_ribbon Draws a series of straight lines given an array of points. The ribbon will go through all of the passed points. *Parameters:* * points - An array of coordinate pairs (x and y) for each point * color - Color of the spline * thickness - Thickness of the spline, pass `<= 0` to draw hairline spline See also: [al_calculate_ribbon] ## Low level drawing routines Low level drawing routines allow for more advanced usage of the addon, allowing you to pass arbitrary sequences of vertices to draw to the screen. These routines also support using textures on the primitives with the following restrictions: For maximum portability, you should only use textures that have dimensions that are a power of two, as not every videocard supports them completely. This warning is relaxed, however, if the texture coordinates never exit the boundaries of a single bitmap (i.e. you are not having the texture repeat/tile). As long as that is the case, any texture can be used safely. Sub-bitmaps work as textures, but cannot be tiled. Some platforms also dictate a minimum texture size, which means that textures smaller than that size will not tile properly. The minimum size that will work on all platforms is 32 by 32. A note about pixel coordinates. In OpenGL the texture coordinate (0, 0) refers to the top left corner of the pixel. This confuses some drivers, because due to rounding errors the actual pixel sampled might be the pixel to the top and/or left of the (0, 0) pixel. To make this error less likely it is advisable to offset the texture coordinates you pass to the al_draw_prim by (0.5, 0.5) if you need precise pixel control. E.g. to refer to pixel (5, 10) you'd set the u and v to 5.5 and 10.5 respectively. See also: [Pixel-precise output] ### API: al_draw_prim Draws a subset of the passed vertex buffer. *Parameters:* * texture - Texture to use, pass 0 to use only color shaded primitves * vtxs - Pointer to an array of vertices * decl - Pointer to a vertex declaration. If set to NULL, the vertices are assumed to be of the ALLEGRO_VERTEX type * start - Start index of the subset of the vertex buffer to draw * end - One past the last index of subset of the vertex buffer to draw * type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying what kind of primitive to draw *Returns:* Number of primitives drawn For example to draw a textured triangle you could use: ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); ALLEGRO_VERTEX v[] = { {.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0}, {.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256}, {.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}}; al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); See also: [ALLEGRO_VERTEX], [ALLEGRO_PRIM_TYPE], [ALLEGRO_VERTEX_DECL], [al_draw_indexed_prim] ### API: al_draw_indexed_prim Draws a subset of the passed vertex buffer. This function uses an index array to specify which vertices to use. *Parameters:* * texture - Texture to use, pass 0 to use only shaded primitves * vtxs - Pointer to an array of vertices * decl - Pointer to a vertex declaration. If set to 0, the vtxs are assumed to be of the ALLEGRO_VERTEX type * indices - An array of indices into the vertex buffer * num_vtx - Number of indices from the indices array you want to draw * type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying what kind of primitive to draw *Returns:* Number of primitives drawn See also: [ALLEGRO_VERTEX], [ALLEGRO_PRIM_TYPE], [ALLEGRO_VERTEX_DECL], [al_draw_prim] ### API: al_create_vertex_decl Creates a vertex declaration, which describes a custom vertex format. *Parameters:* * elements - An array of ALLEGRO_VERTEX_ELEMENT structures. * stride - Size of the custom vertex structure *Returns:* Newly created vertex declaration. See also: [ALLEGRO_VERTEX_ELEMENT], [ALLEGRO_VERTEX_DECL], [al_destroy_vertex_decl] ### API: al_destroy_vertex_decl Destroys a vertex declaration. *Parameters:* * decl - Vertex declaration to destroy See also: [ALLEGRO_VERTEX_ELEMENT], [ALLEGRO_VERTEX_DECL], [al_create_vertex_decl] ### API: al_draw_soft_triangle Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/tri_soft.c. The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of each segment may be absent if two vertices are horizontally collinear. *Parameters:* * v1, v2, v3 - The three vertices of the triangle * state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions * init - Called once per call before any drawing is done. The three points passed to it may be altered by clipping. * first - Called twice per call, once per triangle segment. It is passed 4 parameters, the first two are the coordinates of the initial pixel drawn in the segment. The second two are the left minor and the left major steps, respectively. They represent the sizes of two steps taken by the rasterizer as it walks on the left side of the triangle. From then on, the each step will either be classified as a minor or a major step, corresponding to the above values. * step - Called once per scanline. The last parameter is set to 1 if the step is a minor step, and 0 if it is a major step. * draw - Called once per scanline. The function is expected to draw the scanline starting with a point specified by the first two parameters (corresponding to x and y values) going to the right until it reaches the value of the third parameter (the x value of the end point). All coordinates are inclusive. See also: [al_draw_triangle] ### API: al_draw_soft_line Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/line_soft.c. The line is drawn top to bottom. *Parameters:* * v1, v2 - The two vertices of the line * state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions * first - Called before drawing the first pixel of the line. It is passed the coordinates of this pixel, as well as the two vertices above. The passed vertices may have been altered by clipping. * step - Called once per pixel. The second parameter is set to 1 if the step is a minor step, and 0 if this step is a major step. Minor steps are taken only either in x or y directions. Major steps are taken in both directions diagonally. In all cases, the the absolute value of the change in coordinate is at most 1 in either direction. * draw - Called once per pixel. The function is expected to draw the pixel at the coordinates passed to it. ## Structures and types ### API: ALLEGRO_VERTEX Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set z to 0. Note that when you must initialize all members of this struct when you're using it. One exception to this rule are the u and v variables which can be left uninitialized when you are not using textures. *Fields:* * x, y, z - Position of the vertex (float) * color - [ALLEGRO_COLOR] structure, storing the color of the vertex * u, v - Texture coordinates measured in pixels (float) See also: [ALLEGRO_PRIM_ATTR] ### API: ALLEGRO_VERTEX_DECL A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions. See also: [al_create_vertex_decl], [al_destroy_vertex_decl], [ALLEGRO_VERTEX_ELEMENT] ### API: ALLEGRO_VERTEX_ELEMENT A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the al_create_vertex_decl function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the attribute field equal to 0, to signify that it is the end of the array. Here is an example code that would create a declaration describing the ALLEGRO_VERTEX structure (passing this as vertex declaration to al_draw_prim would be identical to passing NULL): /* On compilers without the offsetof keyword you need to obtain the * offset with sizeof and make sure to account for packing. */ ALLEGRO_VERTEX_ELEMENT elems[] = { {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)}, {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)}, {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)}, {0, 0, 0} }; ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX)); *Fields:* * attribute - A member of the [ALLEGRO_PRIM_ATTR] enumeration, specifying what this attribute signifies * storage - A member of the [ALLEGRO_PRIM_STORAGE] enumeration, specifying how this attribute is stored * offset - Offset in bytes from the beginning of the custom vertex structure. C function offsetof is very useful here. See also: [al_create_vertex_decl], [ALLEGRO_VERTEX_DECL], [ALLEGRO_PRIM_ATTR], [ALLEGRO_PRIM_STORAGE] ### API: ALLEGRO_PRIM_TYPE Enumerates the types of primitives this addon can draw. * ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point * ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices define disjointed lines * ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a strip of lines * ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first and the last vertices are also connected by a line * ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of vertices define disjointed triangles * ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices define a strip of triangles * ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the first vertex ### API: ALLEGRO_PRIM_ATTR Enumerates the types of vertex attributes that a custom vertex may have. * ALLEGRO_PRIM_POSITION - Position information, can be stored only in ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3. * ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an [ALLEGRO_COLOR]. The storage field of ALLEGRO_VERTEX_ELEMENT is ignored * ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are normalized by the width and height of the texture, meaning that the bottom-right corner has texture coordinates of (1, 1). * ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are measured in pixels. See also: [ALLEGRO_VERTEX_DECL], [ALLEGRO_PRIM_STORAGE] ### API: ALLEGRO_PRIM_STORAGE Enumerates the types of storage an attribute of a custom vertex may be stored in. * ALLEGRO_PRIM_FLOAT_2 - A doublet of floats * ALLEGRO_PRIM_FLOAT_3 - A triplet of floats * ALLEGRO_PRIM_SHORT_2 - A doublet of shorts See also: [ALLEGRO_PRIM_ATTR] ### API: ALLEGRO_VERTEX_CACHE_SIZE Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high-level primitives. This corresponds to the maximum number of line segments that will be used to form them. ### API: ALLEGRO_PRIM_QUALITY Defines the quality of the quadratic primitives. At 10, this roughly corresponds to error of less than half of a pixel. allegro-5.0.10/docs/src/refman/system.txt0000644000175000001440000001412412127655707017500 0ustar tjadenusers# System routines These functions are declared in the main Allegro header file: #include ## API: al_install_system Initialize the Allegro system. No other Allegro functions can be called before this (with one or two exceptions). The version field should always be set to ALLEGRO_VERSION_INT. If atexit_ptr is non-NULL, and if hasn't been done already, [al_uninstall_system] will be registered as an atexit function. Returns true if Allegro was successfully initialized by this function call (or already was initialized previously), false if Allegro cannot be used. See also: [al_init] ## API: al_init Like [al_install_system], but automatically passes in the version and uses the atexit function visible in the current compilation unit. See also: [al_install_system] ## API: al_uninstall_system Closes down the Allegro system. > Note: al_uninstall_system() can be called without a corresponding [al_install_system] call, e.g. from atexit(). ## API: al_is_system_installed Returns true if Allegro is initialized, otherwise returns false. ## API: al_get_allegro_version Returns the (compiled) version of the Allegro library, packed into a single integer as groups of 8 bits in the form `(major << 24) | (minor << 16) | (revision << 8) | release`. You can use code like this to extract them: uint32_t version = al_get_allegro_version(); int major = version >> 24; int minor = (version >> 16) & 255; int revision = (version >> 8) & 255; int release = version & 255; The `release` number is 0 for an unofficial version and 1 or greater for an official release. For example "5.0.2[1]" would be the (first) official 5.0.2 release while "5.0.2[0]" would be a compile of a version from the "5.0.2" branch before the official release. ## API: al_get_standard_path Gets a system path, depending on the `id` parameter. Some of these paths may be affected by the organization and application name, so be sure to set those before calling this function. The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may be the same on some platforms), so you should be sure your filenames are unique if you need to avoid naming collisions. Also, a returned path may not actually exist on the file system. ALLEGRO_RESOURCES_PATH : If you bundle data in a location relative to your executable, then you should use this path to locate that data. On most platforms, this is the directory that contains the executable file. If ran from an OS X app bundle, then this will point to the internal resource directory (/Contents/Resources). To maintain consistency, if you put your resources into a directory called "data" beneath the executable on some other platform (like Windows), then you should also create a directory called "data" under the OS X app bundle's resource folder. You should not try to write to this path, as it is very likely read-only. If you install your resources in some other system directory (e.g., in /usr/share or C:\\ProgramData), then you are responsible for keeping track of that yourself. ALLEGRO_TEMP_PATH : Path to the directory for temporary files. ALLEGRO_USER_HOME_PATH : This is the user's home directory. You should not normally write files into this directory directly, or create any sub folders in it, without explicit permission from the user. One practical application of this path would be to use it as the starting place of a file selector in a GUI. ALLEGRO_USER_DOCUMENTS_PATH : This location is easily accessible by the user, and is the place to store documents and files that the user might want to later open with an external program or transfer to another place. You should not save files here unless the user expects it, usually by explicit permission. ALLEGRO_USER_DATA_PATH : If your program saves any data that the user doesn't need to access externally, then you should place it here. This is generally the least intrusive place to store data. ALLEGRO_USER_SETTINGS_PATH : If you are saving configuration files (especially if the user may want to edit them outside of your program), then you should place them here. ALLEGRO_EXENAME_PATH : The full path to the executable. Returns NULL on failure. The returned path should be freed with [al_destroy_path]. See also: [al_set_app_name], [al_set_org_name], [al_destroy_path], [al_set_exe_name] ## API: al_set_exe_name This override the executable name used by [al_get_standard_path] for ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH. One possibility where changing this can be useful is if you use the Python wrapper. Allegro would then by default think that the system's Python executable is the current executable - but you can set it to the .py file being executed instead. Since: 5.0.6, 5.1.0 See also: [al_get_standard_path] ## API: al_set_app_name Sets the global application name. The application name is used by [al_get_standard_path] to build the full path to an application's files. This function may be called before [al_init] or [al_install_system]. See also: [al_get_app_name], [al_set_org_name] ## API: al_set_org_name Sets the global organization name. The organization name is used by [al_get_standard_path] to build the full path to an application's files. This function may be called before [al_init] or [al_install_system]. See also: [al_get_org_name], [al_set_app_name] ## API: al_get_app_name Returns the global application name string. See also: [al_set_app_name] ## API: al_get_org_name Returns the global organization name string. See also: [al_set_org_name] ## API: al_get_system_config Returns the current system configuration structure, or NULL if there is no active system driver. The returned configuration should not be destroyed with [al_destroy_config]. This is mainly used for configuring Allegro and its addons. ## API: al_register_assert_handler Register a function to be called when an internal Allegro assertion fails. Pass NULL to reset to the default behaviour, which is to do whatever the standard `assert()` macro does. Since: 5.0.6, 5.1.0 allegro-5.0.10/docs/src/refman/platform.txt0000644000175000001440000000456712051562272020000 0ustar tjadenusers# Platform-specific functions ## Windows These functions are declared in the following header file: #include ### API: al_get_win_window_handle Returns the handle to the window that the passed display is using. ## Mac OS X These functions are declared in the following header file: #include ### API: al_osx_get_window Retrieves the NSWindow handle associated with the Allegro display. Since: 5.0.8, 5.1.3 ## iPhone These functions are declared in the following header file: #include ### API: al_iphone_program_has_halted Multitasking on iOS is different than on other platforms. When an application receives an ALLEGRO_DISPLAY_SWITCH_OUT or ALLEGRO_DISPLAY_CLOSE event on a multitasking-capable device, it should cease all activity and do nothing but check for an ALLEGRO_DISPLAY_SWITCH_IN event. To let the iPhone driver know that you've ceased all activity, call this function. You should call this function very soon after receiving the event telling you it's time to switch out (within a couple milliseconds). Certain operations, if done, will crash the program after this call, most notably any function which uses OpenGL. This function is needed because the "switch out" handler on iPhone can't return until these operations have stopped, or a crash as described before can happen. ### API: al_iphone_override_screen_scale Original iPhones and iPod Touches had a screen resolution of 320x480 (in Portrait mode). When the iPhone 4 and iPod Touch 4th generation devices came out, they were backwards compatible with all old iPhone apps. This means that they assume a 320x480 screen resolution by default, while they actually have a 640x960 pixel screen (exactly 2x on each dimension). An API was added to allow access to the full (or in fact any fraction of the) resolution of the new devices. This function is normally not needed, as in the case when you want a scale of 2.0 for "retina display" resolution (640x960). In that case you would just call al_create_display with the larger width and height parameters. It is not limited to 2.0 scaling factors however. You can use 1.5 or 0.5 or other values in between, however if it's not an exact multiple of the original iPhone resolution, linear filtering will be applied to the final image. This function should be called BEFORE calling al_create_display. allegro-5.0.10/docs/src/refman/inc.a.txt0000644000175000001440000000374612057104470017140 0ustar tjadenusers
    allegro-5.0.10/docs/src/refman/threads.txt0000644000175000001440000001466312076346773017621 0ustar tjadenusers# Threads Allegro includes a simple cross-platform threading interface. It is a thin layer on top of two threading APIs: Windows threads and POSIX Threads (pthreads). Enforcing a consistent semantics on all platforms would be difficult at best, hence the behaviour of the following functions will differ subtly on different platforms (more so than usual). Your best bet is to be aware of this and code to the intersection of the semantics and avoid edge cases. These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_THREAD An opaque structure representing a thread. ## API: ALLEGRO_MUTEX An opaque structure representing a mutex. ## API: ALLEGRO_COND An opaque structure representing a condition variable. ## API: al_create_thread Spawn a new thread which begins executing `proc`. The new thread is passed its own thread handle and the value `arg`. Returns a pointer to the thread on success. Otherwise, returns NULL if there was an error. See also: [al_start_thread], [al_join_thread]. ## API: al_start_thread When a thread is created, it is initially in a suspended state. Calling [al_start_thread] will start its actual execution. Starting a thread which has already been started does nothing. See also: [al_create_thread]. ## API: al_join_thread Wait for the thread to finish executing. This implicitly calls [al_set_thread_should_stop] first. If `ret_value` is non-`NULL`, the value returned by the thread function will be stored at the location pointed to by `ret_value`. See also: [al_set_thread_should_stop], [al_get_thread_should_stop], [al_destroy_thread]. ## API: al_set_thread_should_stop Set the flag to indicate `thread` should stop. Returns immediately. See also: [al_join_thread], [al_get_thread_should_stop]. ## API: al_get_thread_should_stop Check if another thread is waiting for `thread` to stop. Threads which run in a loop should check this periodically and act on it when convenient. Returns true if another thread has called [al_join_thread] or [al_set_thread_should_stop] on this thread. See also: [al_join_thread], [al_set_thread_should_stop]. > *Note:* We don't support forceful killing of threads. ## API: al_destroy_thread Free the resources used by a thread. Implicitly performs [al_join_thread] on the thread if it hasn't been done already. Does nothing if `thread` is NULL. See also: [al_join_thread]. ## API: al_run_detached_thread Runs the passed function in its own thread, with `arg` passed to it as only parameter. This is similar to calling [al_create_thread], [al_start_thread] and (after the thread has finished) [al_destroy_thread] - but you don't have the possibility of ever calling [al_join_thread] on the thread any longer. ## API: al_create_mutex Create the mutex object (a mutual exclusion device). The mutex may or may not support "recursive" locking. Returns the mutex on success or `NULL` on error. See also: [al_create_mutex_recursive]. ## API: al_create_mutex_recursive Create the mutex object (a mutual exclusion device), with support for "recursive" locking. That is, the mutex will count the number of times it has been locked by the same thread. If the caller tries to acquire a lock on the mutex when it already holds the lock then the count is incremented. The mutex is only unlocked when the thread releases the lock on the mutex an equal number of times, i.e. the count drops down to zero. See also: [al_create_mutex]. ## API: al_lock_mutex Acquire the lock on `mutex`. If the mutex is already locked by another thread, the call will block until the mutex becomes available and locked. If the mutex is already locked by the calling thread, then the behaviour depends on whether the mutex was created with [al_create_mutex] or [al_create_mutex_recursive]. In the former case, the behaviour is undefined; the most likely behaviour is deadlock. In the latter case, the count in the mutex will be incremented and the call will return immediately. See also: [al_unlock_mutex]. **We don't yet have al_mutex_trylock.** ## API: al_unlock_mutex Release the lock on `mutex` if the calling thread holds the lock on it. If the calling thread doesn't hold the lock, or if the mutex is not locked, undefined behaviour results. See also: [al_lock_mutex]. ## API: al_destroy_mutex Free the resources used by the mutex. The mutex should be unlocked. Destroying a locked mutex results in undefined behaviour. Does nothing if `mutex` is `NULL`. ## API: al_create_cond Create a condition variable. Returns the condition value on success or `NULL` on error. ## API: al_destroy_cond Destroy a condition variable. Destroying a condition variable which has threads block on it results in undefined behaviour. Does nothing if `cond` is `NULL`. ## API: al_wait_cond On entering this function, `mutex` must be locked by the calling thread. The function will atomically release `mutex` and block on `cond`. The function will return when `cond` is "signalled", acquiring the lock on the mutex in the process. Example of proper use: al_lock_mutex(mutex); while (something_not_true) { al_wait_cond(cond, mutex); } do_something(); al_unlock_mutex(mutex); The mutex should be locked before checking the condition, and should be rechecked [al_wait_cond] returns. [al_wait_cond] can return for other reasons than the condition becoming true (e.g. the process was signalled). If multiple threads are blocked on the condition variable, the condition may no longer be true by the time the second and later threads are unblocked. Remember not to unlock the mutex prematurely. See also: [al_wait_cond_until], [al_broadcast_cond], [al_signal_cond]. ## API: al_wait_cond_until Like [al_wait_cond] but the call can return if the absolute time passes `timeout` before the condition is signalled. Returns zero on success, non-zero if the call timed out. See also: [al_wait_cond] ## API: al_broadcast_cond Unblock all threads currently waiting on a condition variable. That is, broadcast that some condition which those threads were waiting for has become true. See also: [al_signal_cond]. > *Note:* The pthreads spec says to lock the mutex associated with `cond` before signalling for predictable scheduling behaviour. ## API: al_signal_cond Unblock at least one thread waiting on a condition variable. Generally you should use [al_broadcast_cond] but [al_signal_cond] may be more efficient when it's applicable. See also: [al_broadcast_cond]. allegro-5.0.10/docs/src/refman/mouse.txt0000644000175000001440000001511211520366174017273 0ustar tjadenusers# Mouse routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_MOUSE_STATE Public fields (read only): * x - mouse x position * y - mouse y position * w, z - mouse wheel position (2D 'ball') * buttons - mouse buttons bitfield The zeroth bit is set if the primary mouse button is held down, the first bit is set if the secondary mouse button is held down, and so on. See also: [al_get_mouse_state], [al_get_mouse_state_axis], [al_mouse_button_down] ## API: al_install_mouse Install a mouse driver. Returns true if successful. If a driver was already installed, nothing happens and true is returned. ## API: al_is_mouse_installed Returns true if [al_install_mouse] was called successfully. ## API: al_uninstall_mouse Uninstalls the active mouse driver, if any. This will automatically unregister the mouse event source with any event queues. This function is automatically called when Allegro is shut down. ## API: al_get_mouse_num_axes Return the number of buttons on the mouse. The first axis is 0. See also: [al_get_mouse_num_buttons] ## API: al_get_mouse_num_buttons Return the number of buttons on the mouse. The first button is 1. See also: [al_get_mouse_num_axes] ## API: al_get_mouse_state Save the state of the mouse specified at the time the function is called into the given structure. Example: ALLEGRO_MOUSE_STATE state; al_get_mouse_state(&state); if (state.buttons & 1) { /* Primary (e.g. left) mouse button is held. */ printf("Mouse position: (%d, %d)\n", state.x, state.y); } if (state.buttons & 2) { /* Secondary (e.g. right) mouse button is held. */ } if (state.buttons & 4) { /* Tertiary (e.g. middle) mouse button is held. */ } See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state_axis], [al_mouse_button_down] ## API: al_get_mouse_state_axis Extract the mouse axis value from the saved state. The axes are numbered from 0, in this order: x-axis, y-axis, z-axis, w-axis. See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state], [al_mouse_button_down] ## API: al_mouse_button_down Return true if the mouse button specified was held down in the state specified. Unlike most things, the first mouse button is numbered 1. See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state], [al_get_mouse_state_axis] ## API: al_set_mouse_xy Try to position the mouse at the given coordinates on the given display. The mouse movement resulting from a successful move will generate an ALLEGRO_EVENT_MOUSE_WARPED event. Returns true on success, false on failure. See also: [al_set_mouse_z], [al_set_mouse_w] ## API: al_set_mouse_z Set the mouse wheel position to the given value. Returns true on success, false on failure. See also: [al_set_mouse_w] ## API: al_set_mouse_w Set the second mouse wheel position to the given value. Returns true on success, false on failure. See also: [al_set_mouse_z] ## API: al_set_mouse_axis Set the given mouse axis to the given value. The axis number must not be 0 or 1, which are the X and Y axes. Use [al_set_mouse_xy] for that. Returns true on success, false on failure. See also: [al_set_mouse_xy], [al_set_mouse_z], [al_set_mouse_w] ## API: al_get_mouse_event_source Retrieve the mouse event source. Returns NULL if the mouse subsystem was not installed. ## Mouse cursors ### API: al_create_mouse_cursor Create a mouse cursor from the bitmap provided. Returns a pointer to the cursor on success, or NULL on failure. See also: [al_set_mouse_cursor], [al_destroy_mouse_cursor] ### API: al_destroy_mouse_cursor Free the memory used by the given cursor. Has no effect if `cursor` is NULL. See also: [al_create_mouse_cursor] ### API: al_set_mouse_cursor Set the given mouse cursor to be the current mouse cursor for the given display. If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible. Returns true on success, false on failure. See also: [al_set_system_mouse_cursor], [al_show_mouse_cursor], [al_hide_mouse_cursor] ### API: al_set_system_mouse_cursor Set the given system mouse cursor to be the current mouse cursor for the given display. If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible. If the cursor doesn't exist on the current platform another cursor will be silently be substituted. The cursors are: * ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT * ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW * ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY * ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION * ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT * ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE * ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE * ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS * ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION * ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK * ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT * ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE Returns true on success, false on failure. See also: [al_set_mouse_cursor], [al_show_mouse_cursor], [al_hide_mouse_cursor] ### API: al_get_mouse_cursor_position On platforms where this information is available, this function returns the global location of the mouse cursor, relative to the desktop. You should not normally use this function, as the information is not useful except for special scenarios as moving a window. Returns true on success, false on failure. ### API: al_hide_mouse_cursor Hide the mouse cursor in the given display. This has no effect on what the current mouse cursor looks like; it just makes it disappear. Returns true on success (or if the cursor already was hidden), false otherwise. See also: [al_show_mouse_cursor] ### API: al_show_mouse_cursor Make a mouse cursor visible in the given display. Returns true if a mouse cursor is shown as a result of the call (or one already was visible), false otherwise. See also: [al_hide_mouse_cursor] ### API: al_grab_mouse Confine the mouse cursor to the given display. The mouse cursor can only be confined to one display at a time. Returns true if successful, otherwise returns false. Do not assume that the cursor will remain confined until you call [al_ungrab_mouse]. It may lose the confined status at any time for other reasons. > *Note:* not yet implemented on Mac OS X. See also: [al_ungrab_mouse] ### API: al_ungrab_mouse Stop confining the mouse cursor to any display belonging to the program. > *Note:* not yet implemented on Mac OS X. See also: [al_grab_mouse] allegro-5.0.10/docs/src/refman/memory.txt0000644000175000001440000000531311775710015017454 0ustar tjadenusers# Memory management routines These functions are declared in the main Allegro header file: #include ## API: al_malloc Like malloc() in the C standard library, but the implementation may be overridden. This is a macro. See also: [al_free], [al_realloc], [al_calloc], [al_malloc_with_context], [al_set_memory_interface] ## API: al_free Like free() in the C standard library, but the implementation may be overridden. Additionally, on Windows, a memory block allocated by one DLL must be freed from the same DLL. In the few places where an Allegro function returns a pointer that must be freed, you must use [al_free] for portability to Windows. This is a macro. See also: [al_malloc], [al_free_with_context] ## API: al_realloc Like realloc() in the C standard library, but the implementation may be overridden. This is a macro. See also: [al_malloc], [al_realloc_with_context] ## API: al_calloc Like calloc() in the C standard library, but the implementation may be overridden. This is a macro. See also: [al_malloc], [al_calloc_with_context] ## API: al_malloc_with_context This calls malloc() from the Allegro library (this matters on Windows), unless overridden with [al_set_memory_interface], Generally you should use the [al_malloc] macro. ## API: al_free_with_context This calls free() from the Allegro library (this matters on Windows), unless overridden with [al_set_memory_interface]. Generally you should use the [al_free] macro. ## API: al_realloc_with_context This calls realloc() from the Allegro library (this matters on Windows), unless overridden with [al_set_memory_interface], Generally you should use the [al_realloc] macro. ## API: al_calloc_with_context This calls calloc() from the Allegro library (this matters on Windows), unless overridden with [al_set_memory_interface], Generally you should use the [al_calloc] macro. ## API: ALLEGRO_MEMORY_INTERFACE This structure has the following fields. void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); void (*mi_free)(void *ptr, int line, const char *file, const char *func); void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, const char *func); void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, const char *func); See also: [al_set_memory_interface] ## API: al_set_memory_interface Override the memory management functions with implementations of [al_malloc_with_context], [al_free_with_context], [al_realloc_with_context] and [al_calloc_with_context]. The context arguments may be used for debugging. If the pointer is NULL, the default behaviour will be restored. See also: [ALLEGRO_MEMORY_INTERFACE] allegro-5.0.10/docs/src/refman/acodec.txt0000644000175000001440000000214212004635121017345 0ustar tjadenusers# Audio codecs addon These functions are declared in the following header file. Link with allegro_acodec. #include ## API: al_init_acodec_addon This function registers all the known audio file type handlers for [al_load_sample], [al_save_sample], [al_load_audio_stream], etc. Depending on what libraries are available, the full set of recognised extensions is: .wav, .flac, .ogg, .it, .mod, .s3m, .xm. *Limitations:* - Saving is only supported for wav files. - Wav file loader currently only supports 8/16 bit little endian PCM files. 16 bits are used when saving wav files. Use flac files if more precision is required. - Module files (.it, .mod, .s3m, .xm) are often composed with streaming in mind, and sometimes cannot be easily rendered into a finite length sample. Therefore they cannot be loaded with [al_load_sample]/[al_load_sample_f] and must be streamed with [al_load_audio_stream] or [al_load_audio_stream_f]. Return true on success. ## API: al_get_allegro_acodec_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/state.txt0000644000175000001440000000501611412636563017267 0ustar tjadenusers# State These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_STATE Opaque type which is passed to [al_store_state]/[al_restore_state]. The various state kept internally by Allegro can be displayed like this: global active system driver current config per thread new bitmap params new display params active file interface errno current blending mode current display deferred drawing current target bitmap current transformation current clipping rectangle bitmap locking In general, the only real global state is the active system driver. All other global state is per-thread, so if your application has multiple separate threads they never will interfere with each other. (Except if there are objects accessed by multiple threads of course. Usually you want to minimize that though and for the remaining cases use synchronization primitives described in the threads section or events described in the events section to control inter-thread communication.) ## API: ALLEGRO_STATE_FLAGS Flags which can be passed to [al_store_state]/[al_restore_state] as bit combinations. See [al_store_state] for the list of flags. ## API: al_restore_state Restores part of the state of the current thread from the given [ALLEGRO_STATE] object. See also: [al_store_state], [ALLEGRO_STATE_FLAGS] ## API: al_store_state Stores part of the state of the current thread in the given [ALLEGRO_STATE] objects. The flags parameter can take any bit-combination of these flags: * ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format, new_display_refresh_rate, new_display_flags * ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format, new_bitmap_flags * ALLEGRO_STATE_DISPLAY - current_display * ALLEGRO_STATE_TARGET_BITMAP - target_bitmap * ALLEGRO_STATE_BLENDER - blender * ALLEGRO_STATE_TRANSFORM - current_transformation * ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface * ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and ALLEGRO_STATE_TARGET_BITMAP * ALLEGRO_STATE_ALL - all of the above See also: [al_restore_state], [ALLEGRO_STATE] ## API: al_get_errno Some Allegro functions will set an error number as well as returning an error code. Call this function to retrieve the last error number set for the calling thread. ## API: al_set_errno Set the error number for for the calling thread. allegro-5.0.10/docs/src/refman/keyboard.txt0000644000175000001440000001061312124661464017745 0ustar tjadenusers# Keyboard routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_KEYBOARD_STATE This is a structure that is used to hold a "snapshot" of a keyboard's state at a particular instant. It contains the following publically readable fields: * display - points to the display that had keyboard focus at the time the state was saved. If no display was focused, this points to NULL. You cannot read the state of keys directly. Use the function [al_key_down]. ## Key codes The constant ALLEGRO_KEY_MAX is always one higher than the highest key code. So if you want to use the key code as array index you can do something like this: bool pressed_keys[ALLEGRO_KEY_MAX]; ... pressed_keys[key_code] = true; These are the list of key codes used by Allegro, which are returned in the event.keyboard.keycode field of the ALLEGRO_KEY_DOWN and ALLEGRO_KEY_UP events and which you can pass to [al_key_down]: ALLEGRO_KEY_A ... ALLEGRO_KEY_Z ALLEGRO_KEY_0 ... ALLEGRO_KEY_9 ALLEGRO_KEY_PAD_0 ... ALLEGRO_KEY_PAD_9 ALLEGRO_KEY_F1 ... ALLEGRO_KEY_F12 ALLEGRO_KEY_ESCAPE ALLEGRO_KEY_TILDE ALLEGRO_KEY_MINUS ALLEGRO_KEY_EQUALS ALLEGRO_KEY_BACKSPACE ALLEGRO_KEY_TAB ALLEGRO_KEY_OPENBRACE ALLEGRO_KEY_CLOSEBRACE ALLEGRO_KEY_ENTER ALLEGRO_KEY_SEMICOLON ALLEGRO_KEY_QUOTE ALLEGRO_KEY_BACKSLASH ALLEGRO_KEY_BACKSLASH2 ALLEGRO_KEY_COMMA ALLEGRO_KEY_FULLSTOP ALLEGRO_KEY_SLASH ALLEGRO_KEY_SPACE ALLEGRO_KEY_INSERT ALLEGRO_KEY_DELETE ALLEGRO_KEY_HOME ALLEGRO_KEY_END ALLEGRO_KEY_PGUP ALLEGRO_KEY_PGDN ALLEGRO_KEY_LEFT ALLEGRO_KEY_RIGHT ALLEGRO_KEY_UP ALLEGRO_KEY_DOWN ALLEGRO_KEY_PAD_SLASH ALLEGRO_KEY_PAD_ASTERISK ALLEGRO_KEY_PAD_MINUS ALLEGRO_KEY_PAD_PLUS ALLEGRO_KEY_PAD_DELETE ALLEGRO_KEY_PAD_ENTER ALLEGRO_KEY_PRINTSCREEN ALLEGRO_KEY_PAUSE ALLEGRO_KEY_ABNT_C1 ALLEGRO_KEY_YEN ALLEGRO_KEY_KANA ALLEGRO_KEY_CONVERT ALLEGRO_KEY_NOCONVERT ALLEGRO_KEY_AT ALLEGRO_KEY_CIRCUMFLEX ALLEGRO_KEY_COLON2 ALLEGRO_KEY_KANJI ALLEGRO_KEY_LSHIFT ALLEGRO_KEY_RSHIFT ALLEGRO_KEY_LCTRL ALLEGRO_KEY_RCTRL ALLEGRO_KEY_ALT ALLEGRO_KEY_ALTGR ALLEGRO_KEY_LWIN ALLEGRO_KEY_RWIN ALLEGRO_KEY_MENU ALLEGRO_KEY_SCROLLLOCK ALLEGRO_KEY_NUMLOCK ALLEGRO_KEY_CAPSLOCK ALLEGRO_KEY_PAD_EQUALS ALLEGRO_KEY_BACKQUOTE ALLEGRO_KEY_SEMICOLON2 ALLEGRO_KEY_COMMAND ## Keyboard modifier flags ALLEGRO_KEYMOD_SHIFT ALLEGRO_KEYMOD_CTRL ALLEGRO_KEYMOD_ALT ALLEGRO_KEYMOD_LWIN ALLEGRO_KEYMOD_RWIN ALLEGRO_KEYMOD_MENU ALLEGRO_KEYMOD_ALTGR ALLEGRO_KEYMOD_COMMAND ALLEGRO_KEYMOD_SCROLLLOCK ALLEGRO_KEYMOD_NUMLOCK ALLEGRO_KEYMOD_CAPSLOCK ALLEGRO_KEYMOD_INALTSEQ ALLEGRO_KEYMOD_ACCENT1 ALLEGRO_KEYMOD_ACCENT2 ALLEGRO_KEYMOD_ACCENT3 ALLEGRO_KEYMOD_ACCENT4 The event field 'keyboard.modifiers' is a bitfield composed of these constants. These indicate the modifier keys which were pressed at the time a character was typed. ## API: al_install_keyboard Install a keyboard driver. Returns true if successful. If a driver was already installed, nothing happens and true is returned. See also: [al_uninstall_keyboard], [al_is_keyboard_installed] ## API: al_is_keyboard_installed Returns true if [al_install_keyboard] was called successfully. ## API: al_uninstall_keyboard Uninstalls the active keyboard driver, if any. This will automatically unregister the keyboard event source with any event queues. This function is automatically called when Allegro is shut down. See also: [al_install_keyboard] ## API: al_get_keyboard_state Save the state of the keyboard specified at the time the function is called into the structure pointed to by *ret_state*. See also: [al_key_down], [ALLEGRO_KEYBOARD_STATE] ## API: al_key_down Return true if the key specified was held down in the state specified. See also: [ALLEGRO_KEYBOARD_STATE] ## API: al_keycode_to_name Converts the given keycode to a description of the key. ## API: al_set_keyboard_leds Overrides the state of the keyboard LED indicators. Set to -1 to return to default behavior. False is returned if the current keyboard driver cannot set LED indicators. ## API: al_get_keyboard_event_source Retrieve the keyboard event source. Returns NULL if the keyboard subsystem was not installed. allegro-5.0.10/docs/src/refman/native_dialog.txt0000644000175000001440000001600212110014175020732 0ustar tjadenusers# Native dialogs support These functions are declared in the following header file. Link with allegro_dialog. #include ## API: ALLEGRO_FILECHOOSER Opaque handle to a native file dialog. ## API: ALLEGRO_TEXTLOG Opaque handle to a text log window. ## API: al_init_native_dialog_addon Initialise the native dialog addon. Returns true on success, false on error. Since: 5.0.9, 5.1.0 > *Note:* Prior to Allegro 5.1.0 native dialog functions could be called without explicit initialisation, but that is now deprecated. Future functionality may require explicit initialisation. An exception is [al_show_native_message_box], which may be useful to show an error message if Allegro fails to initialise. See also: [al_shutdown_native_dialog_addon] ## API: al_shutdown_native_dialog_addon Shut down the native dialog addon. Since: 5.0.9, 5.1.5 See also: [al_init_native_dialog_addon] ## API: al_create_native_file_dialog Creates a new native file dialog. You should only have one such dialog opened at a time. Parameters: - initial_path: The initial search path and filename. Can be NULL. To start with a blank file name the string should end with a directory separator (this should be the common case). - title: Title of the dialog. - patterns: A list of semi-colon separated patterns to match. You should always include the pattern "\*.*" as usually the MIME type and not the file pattern is relevant. If no file patterns are supported by the native dialog, this parameter is ignored. - mode: 0, or a combination of the flags below. Possible flags for the 'flags' parameter are: ALLEGRO_FILECHOOSER_FILE_MUST_EXIST : If supported by the native dialog, it will not allow entering new names, but just allow existing files to be selected. Else it is ignored. ALLEGRO_FILECHOOSER_SAVE : If the native dialog system has a different dialog for saving (for example one which allows creating new directories), it is used. Else ignored. ALLEGRO_FILECHOOSER_FOLDER : If there is support for a separate dialog to select a folder instead of a file, it will be used. ALLEGRO_FILECHOOSER_PICTURES : If a different dialog is available for selecting pictures, it is used. Else ignored. ALLEGRO_FILECHOOSER_SHOW_HIDDEN : If the platform supports it, also hidden files will be shown. ALLEGRO_FILECHOOSER_MULTIPLE : If supported, allow selecting multiple files. Returns: A handle to the dialog which you can pass to [al_show_native_file_dialog] to display it, and from which you then can query the results. When you are done, call [al_destroy_native_file_dialog] on it. If a dialog window could not be created then this function returns NULL. ## API: al_show_native_file_dialog Show the dialog window. The display may be NULL, otherwise the given display is treated as the parent if possible. This function blocks the calling thread until it returns, so you may want to spawn a thread with [al_create_thread] and call it from inside that thread. Returns true on success, false on failure. ## API: al_get_native_file_dialog_count Returns the number of files selected, or 0 if the dialog was cancelled. ## API: al_get_native_file_dialog_path Returns one of the selected paths. ## API: al_destroy_native_file_dialog Frees up all resources used by the file dialog. ## API: al_show_native_message_box Show a native GUI message box. This can be used for example to display an error message if creation of an initial display fails. The display may be NULL, otherwise the given display is treated as the parent if possible. The message box will have a single "OK" button and use the style informative dialog boxes usually have on the native system. If the `buttons` parameter is not NULL, you can instead specify the button text in a string, with buttons separated by a vertical bar (|). ALLEGRO_MESSAGEBOX_WARN : The message is a warning. This may cause a different icon (or other effects). ALLEGRO_MESSAGEBOX_ERROR : The message is an error. ALLEGRO_MESSAGEBOX_QUESTION : The message is a question. ALLEGRO_MESSAGEBOX_OK_CANCEL : Instead of the "OK" button also display a cancel button. Ignored if `buttons` is not NULL. ALLEGRO_MESSAGEBOX_YES_NO : Instead of the "OK" button display Yes/No buttons. Ignored if `buttons` is not NULL. [al_show_native_message_box] may be called without Allegro being installed. This is useful to report an error to initialise Allegro itself. Returns: - 0 if the dialog window was closed without activating a button. - 1 if the OK or Yes button was pressed. - 2 if the Cancel or No button was pressed. If `buttons` is not NULL, the number of the pressed button is returned, starting with 1. If a message box could not be created then this returns 0, as if the window was dismissed without activating a button. Example: button = al_show_native_message_box( display, "Warning", "Are you sure?", "If you click yes then you are confirming that \"Yes\"" "is your response to the query which you have" "generated by the action you took to open this" "message box.", NULL, ALLEGRO_MESSAGEBOX_YES_NO ); ## API: al_open_native_text_log Opens a window to which you can append log messages with [al_append_native_text_log]. This can be useful for debugging if you don't want to depend on a console being available. Use [al_close_native_text_log] to close the window again. The flags available are: ALLEGRO_TEXTLOG_NO_CLOSE : Prevent the window from having a close button. Otherwise if the close button is pressed an event is generated; see [al_get_native_text_log_event_source]. ALLEGRO_TEXTLOG_MONOSPACE : Use a monospace font to display the text. Returns NULL if there was an error opening the window, or if text log windows are not implemented on the platform. See also: [al_append_native_text_log], [al_close_native_text_log] ## API: al_close_native_text_log Closes a message log window opened with [al_open_native_text_log] earlier. Does nothing if passed NULL. See also: [al_open_native_text_log] ## API: al_append_native_text_log Appends a line of text to the message log window and scrolls to the bottom (if the line would not be visible otherwise). This works like printf. A line is continued until you add a newline character. If the window is NULL then this function will fall back to calling printf. This makes it convenient to support logging to a window or a terminal. ## API: al_get_native_text_log_event_source Get an event source for a text log window. The possible events are: ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE : The window was requested to be closed, either by pressing the close button or pressing Escape on the keyboard. The user.data1 field will hold a pointer to the [ALLEGRO_TEXTLOG] which generated the event. The user.data2 field will be 1 if the event was generated as a result of a key press; otherwise it will be zero. ## API: al_get_allegro_native_dialog_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/fullscreen_mode.txt0000644000175000001440000000267012057104470021311 0ustar tjadenusers# Fullscreen modes These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_DISPLAY_MODE Used for fullscreen mode queries. Contains information about a supported fullscreen modes. typedef struct ALLEGRO_DISPLAY_MODE { int width; // Screen width int height; // Screen height int format; // The pixel format of the mode int refresh_rate; // The refresh rate of the mode } ALLEGRO_DISPLAY_MODE; The `refresh_rate` may be zero if unknown. See also: [al_get_display_mode] ## API: al_get_display_mode Retrieves a fullscreen mode. Display parameters should not be changed between a call of [al_get_num_display_modes] and [al_get_display_mode]. index must be between 0 and the number returned from al_get_num_display_modes-1. mode must be an allocated ALLEGRO_DISPLAY_MODE structure. This function will return NULL on failure, and the mode parameter that was passed in on success. See also: [ALLEGRO_DISPLAY_MODE], [al_get_num_display_modes] ## API: al_get_num_display_modes Get the number of available fullscreen display modes for the current set of display parameters. This will use the values set with [al_set_new_display_refresh_rate], and [al_set_new_display_flags] to find the number of modes that match. Settings the new display parameters to zero will give a list of all modes for the default driver. See also: [al_get_display_mode] allegro-5.0.10/docs/src/refman/images/0000755000175000001440000000000012157230720016641 5ustar tjadenusersallegro-5.0.10/docs/src/refman/images/primitives1.png0000644000175000001440000003727211421455043021636 0ustar tjadenusersPNG  IHDR|sRGB pHYsss"tIME .0> IDATxg|Te_f&^' EPJ(RHtފU"PBҤI/HB 'e~0)fr>Nr9|sfLEO' ' @~ ?@~ ?O ?O' ' @~ ?@~ ?O ?O' ' @~ @~ ?Dc߬d{챱i׮]Ν0QQQG֭[ڵU3glڴ)&&ںnݺ pqqQN9􀀀:,۷o߱cGNN3<ӫW/FClٲe˖juEGGkڠ_~_9?wݻ_բE>}TP~~~xxUHHHpp3D VXWI&F rss*|||k׮]NCݻrto5mTRu-77W!ſpBv&N_rU``Oʩk45k6h@VH&M+^I4Ξ=;22;vؙ3g>y ΣG^bŜ9s Ν;|(V^~Ğ={YfժU Xoֹs>tM6͘1C!ŷ0`vZ)SRRR.^cF3tЌ bccRSSǍwӧ3TNլYqƦ%EEE:tPk֬Q:v("W\Qf<("C;{%-Z\rqq!::ZO;vlٲEOKKիOҥKqqqݺu3-h4;w޹sN[1a9rDDڵkGO۷oСiIncbbGGGe?**}hxJkDrʥ$%%(C96m3xxx(7nٷoߺuFg0f׮]3 (((XtӦMU+Wjڃ[k׮ sO "RR ORRR2`/RQzj~ m۶:u.o_fUPǟ>}zե/ R~zUٳ+_xpBV+ >L:n;vo4h׮];== :p]QaoKi&O`wywJ+{zzիW/^X~+VʃViiifu K.;wAV|JVz#G~YYY~-?ѣG ,WZecc3ogvqq4iRrr.Y$777))ID>lS G0###njcn…<| PF۷]Vӽ;f{g_~t K@@޽{s1CZ]bb߿ %رc\޴iS|royZjUC󹹹-_\QſHێ;P)Sq5g%?%%iӦGjԨWZ04lcccyPxSnxnnnpp0q(/_jUV߬RQ'rrrzGզR5??~YfnnnO=ѣGԩS/SN.]Rl'OrJ֭ʹgvZN\]]===׭[(lR56jԨ]v)K,>}bҥݻӧOm۶`Ŋ?SQQQvN}6lPKӧOEz[#G<_~}HHHCCC? ̙aÆ}{ƍZv֬Y욁G從Я_0?6s |齌%\tiҥҥիNJOdյk &t:9|pxxx``믿^SIIɲeڶmhXRr尰+VoGoժՌ3^{yyۑغuk#""|ġ /6 }ݷo_ll,<;vx}s>;}ŋvڼy+WSb5kVzaf6o|5SƍSRR&MTPP0o;qDNWVH[[r-dСC"2cƌ gΜ)"iIAAm)*WԩS 裏Dm۶w999"2t o-QFݗZ58883&33UVHPNO[l{^x4۩S'O6k֬z=k֬С2A77ڵk+/_k߾}*...**J988T^}ԨQ}`80c /N#Dd۶ms8ƏbŊF)vQvm%<Μ9SO)WsΞ={׫}zdd[l+6lذf͚=WB`4tܦMfonFDԩ};p˗/ǏNLLlҤa{^reſ[^^^;v4%<@~zN>dzjݺuMOJJU˗/裏ի7z?">>*880۰a[+]JLL\|yxxxڵ=jZ|7OEGGרQ4[TTdggg3=8ʕ+*JD֭[׫W޽{wnQTTVM޿'Ϛ5˰>G? ._KP{FFi6 Ӧٓ'Oz{{Z;*!|Ȱ$==t'~٦MSrrMFQzzիW M:uLoU{2)QEGG׫Wʊ R˗/:::СC?GDD?>$$}"rܹ={nݺrʑ!!!qqq_}Cxxc?W^yjutt_tRêqY[[Ϙ1CD&LЭ[7WW_/,}]TTs@~z{?5JDUuO?ܹs5j1cƅ 6mk.___fGG,=\k###}}}[lYQ_^zꕱŋGQQooo_v*vO'  d>\]]\[h2XY^{p ƟO' Ox.f\= 33u)ڄj@~꽲DfGNT`V8~@~x8~Nc>!!dԨQ 69rüZ9'X7;|ÿO'  @~ ?p/?t_UTT7xzz_~~W2DXŶ47PWпx[ TO'(?>m49q℈=LJ0sׯ_;v\pADNh"5 #V(">>>>>>YYYYYY*`]IIaeoo߶m[1z* ?=^-ZP}PX4___v_Jc@~ ?Ow~V[t >I]'RV=7Aڎ OBuId%)IMWVgyq0}@Ks̩^z=L>+@~ypKGu:ۮtU ?O'O' @~eIHHTBvgJ'FKbWM-Jc,8{r˿j|[.Ph/{9'IIIYdIBBU>00044wݽ{wqq1|p8Kշo_y饗?>uTgg{k׮]v~<>?rJZ-"٫W~WCBB@~;{WZhT*N3,:uj6m<<</Z3>}ZJRT})Heee/C 0 JٳA):|pNNN(KJ&N8i$+++^_z!KĉSNupph޼yn ROO'7uȔ"">] D,769VD2], 8qr)WܹsΝ&LhԨQݻtOk4%KN:u111w۠iӦ/?\9vU.>.~5ɸvNՉ'N81^xᣏ>b8 8-[j#MS$=^ڌ*!e޵A6JnUâ+յ"{߾qݺuڵ+OOg~į]@s^1om/mFumfDm:emcv]aʢGw Ħ\]] zm@~Pe'VVV-[''#P[.] CM>>>-<4ibxK-Lw^5jԂ D4E ?ȑ#?>iҤ.]4)1G@IDATk֌&'(KFFƔ)S<<< ''*U<) wƟp\1IzLWO' @~ @~ ?O ?O'O' @~ dhrss7mtѤUvܹUV4WTTm۶}j_,??iҤD}Dd˦-ʬs8h6'(*Kt#TrZ}VnBBB6?m޼/8p`6mJ/Vipng酊RൎɎ+"Z"+]!oh/""nnnܪHffRJdG.::_o޼[VEDjݗɻKj)wjJ꯾zݗJחBΝ֭}v''2lҤɱc-Z4devA77?ȋ~Iynf2dHHHȸqsȩ-""JEdŊ ,عs'ŌSxWߞ={VZƖC]h`0V)F{q6mŋ,X?3ڵkg{]v^ZvxVXXTx嚟?޹s瀀m۶yxxP,ŵkڷos:uP!0N7,m$?ѷx\*HDD)֊QmYe""Wӭm%ԩӿe(19?IlҖVDzj%ww *!Pf:xm-t|Z&KI6=?UwCN(j S҈'KC_u䟇‹PF~ I fE':]0N'}O>QC("?.(t*5ww7xʼ.W>@~ ]{t06aNF  ?IwRxXӔޮo[DD_, $g{?ovuq-.O8Mrv=Ь""r%{+27XDD&miU8w nwϧ-FQnK֖mzk/M%g?QDDlĥ6mD%ݸt'nrs Tǧ$HZqjE$""kavצsu`O"nO٭k8f͚2^w[{Yn)e_DF]J#@~0p#+;0Qy._W+qz-\'"RpN .ok[hѢE2^oOVaTv*vO9{8EDDĭ}*J4EegcWOlD#"V|<,? ?}q"︤-UzoӞ ?݉KGqh ݮW}A?tӍ-(Snyr@~ PqgNb|nſe#tr1My~Ϝ9su//GS$gJq$~&*E3VK7jSɁG !!!***!!ťAAAA @~*k޼;F>|ܹsTQ>{E$)0hHeVWAbbbkrrrZEfD_֮]lٲ__Zj߿CCCEdѢEqošzz̙I]vmB}1x3gjm۶ll߾~7n\͚5~2669aVW۶m׬YO:u-3g|||*v={믿޻w LX?.`xpwT$ҍV5cѾ}}Μ9\(;F:tزeV}嫾Ldm8WtME/"vEI;ŝ>}O*##?tww}vZD."//H榊r\{)v3&ק?AoٲED䧇6qĘ✜_5""";;_.O)5~6>ɤ$[b{H n-ݢԭ2ӏ?XRYYYTHǹ~'^}NߒXZ^%͔o8IOovԩ"bmmmSN/f㓒k׮ .hڪU6k֬FYTb(qo2X I5bk1/K#$uqZatctҞ={Ν;ШQƍS-<ɖ֩=$=%?JD$wD7kš4UQ#9nY҇ήcǎ;v*V`jOn<̪0^>#kf7Ó} >HxTnevk]._ο$6>[}m9J ?Ŷ:Sy)R} !EVȩry%wȋ;HLt7\#*'.'%v7/dMd=//oT +X6,xJ ӓ;) mt)I3E}_)#RN7KR=i'/c ?+x?Yƅ)r$L5%+~ZzKaNJ4/d4ODB[@~;NWc{_ĉ؛-$> dĿ)9DH 9Z K%wUnUV'ZQq`O""V2zf(h-^*rb%r/K毢/|;,ޗSdmdJ쑚rYu> XV_fLRRRB>>'Oefz~ԩSXիW8pӦMmoTΜ9ӳgϘ eϯ\rrrZ6G=i$r^^^M4XkkkOOϦMR@dO"q`2o#OcǎС- ?֭[+rPo̙#ܪUBCCϝ;Gs%111~a]\\h3f+ 0-zׯ_vm ?=FZ;jժo nĉsss @~zZlVM;իWoٲeٶ4sh}EEE͛7oĉ~~~TPw{˫[nHHڵki-7oNMM6mڤ8qښ*3uG)**Og͚ES[NKK;w܏?{sS VZ矿[իWX[ly7_xۯ&P˗/:88x{{>}ޞ`t:[IIDGGWR:*3ZjʕfΜIx`I{Ue˖yyy> tI֨QaÆ7oXg}6))ɓ666P!ikM81;;{޼y?۷'<r}m۶͘1cʕjբXNk׮#GL8qҤIaaa P+WKmjԨQ*U3sL+++ ?HEO' ' @~ ?@~ ?O ?O' ' @~ ?@~ ?O ?O' ' @~ @~ ?O ?Of%HIENDB`allegro-5.0.10/docs/src/refman/images/primitives1.svg0000644000175000001440000007756711407060266021667 0ustar tjadenusers image/svg+xml x y 0 1 2 3 0 1 2 3 (0.5, 0.5) x y 0 1 2 3 0 1 2 3 allegro-5.0.10/docs/src/refman/images/primitives2.svg0000644000175000001440000020750511407060266021653 0ustar tjadenusers image/svg+xml x y 0 2 4 6 0 2 4 6 x y 0 2 4 6 0 2 4 6 allegro-5.0.10/docs/src/refman/images/primitives2.png0000644000175000001440000006231511421455043021633 0ustar tjadenusersPNG  IHDR}isRGB pHYsss"tIMEY2 IDATxw|SO6^Жhe]YRhd\YEp\Q(׉R "*^ZFeZ{ifiC I_=眜s|ϐ L """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """""bQADDDDDĢXT """""bQADDDDDĢXT """""bQADDDDDĢXT """""l҇tضm<\}b}a~:<==ѽ{w : Zo:#G/k.:u 2 :ts=z19T#R^zg SCǏGll,^ gggoGB`r,dժU(((жm[&dggc8~8aÆ! ɩPGT*aȐ!D" +:NץK(nZݺuJ%d@ >^YTX`/H Lݷ[ Lv wآXp~zA JR裏BXX􀲲OOO駟fQGGG]v˗텅ŋ; ԁ4oNNN3kZx{{cǎe͛775Vt-[Ŀoc&b׮]3f \\\/B29Tcz)c#""pM\|INT OOOA*cjj֭زe ;ѷo_j HHH@YY8q~~~tܶ-[ //>,QC.\@TT>s1!ի___~ .]ARl\v|C̙38qy^1}t[ bBPNN ТE ?hӦ 1c 0IuHKK0y \rr2L֭[^cBj@㥗^ A0|p&>rssvZlڴ :tܹsg1ITmJ )NT矇3{m믿̝;ɰ6e8p-[;w"<<_|f͚$A.=9oW]UF644666زe r9Rh&$$0R,jڵx-FjMp )FRgkװ}vxyy1)5k.^x)}zp]`ҤIL}jOf;99jP54w\_}Zhڴqx ɩwԾH˗!y+c(11j-Zddׯ_Gqq1x5c&55YYYhժuu """"Gr'""""bܝVO55N 慈HER^B !TS.^q""eeeP*&7H$""Oqqqڵ+.]ԩS~1jԨM x^ӂn!㳠"99 Zhzd4HMMEhh(\]]Q~}_J]uEFFbL]}aA ;vMڿ{c˖-IP^^z쉳goaÆ~4Z-;d>}U҃KIIիW RT8ydm۶!88l}_cǎXlmU*~7 >CGvmŌᗞ?R? FqeZ`B4GTWhwHLLoml1e 8Cek"99֭͛7/fH۔pT*̙3zagĉ2d0sLQ}VќS?O>0X~=k>8Vx>+r\Űx}[eh; I:6_]~>(*.?k QհQS ^ޙ7::?1cϯܹs1|;v EEE;v,&Mj5kzÇ'|+WYfL=4{ヒ~a„ hѢEwmltR :k֬AHHѭ[7lذ66:5Z4HII?͛?dܻヒE!))ɤ݅t`#8s :tp19Nt2wppȏVJtI'MP(&Ɵ=P Dp! dU򽽱{ڴ?ıcǠP(֭[c޼yݻ=PThѢ<<>;w8;;#00sAXX޽{#99zؽ{7D/є8ǖ{xx+oKKK3)*j f@8V1ŗT0ZW˚;v 8,\B Jiii8x lmm1|w,.1yd,X}5kXPԂbuj~R\pEp GmPWYRr'N|p׫Θ1#GDƍUQQXXh Wr III=W͛Hq#(dU0r?11gϞ^7nH >ʝ$!ˑd<ĿM T5k*mnAG{qD3=D?|xDg 2'>*+ZEV"”)S0b7}0`=zƪUXT܍/TyTL  `dg8mi*^ < g&'DWD$%!^1uuEUĚ$@֬U섉2y矿%&&"44mڴM`oo?ĉyӵGqŶ)DD5Ѯ];ˌWG~~> ^]vA6m ̚5F?l9 mڴ1RΝ;ѲeG+GzpjYEy%vb¢ "qw%K-bbkA^p!(J;vLnRRR#++ w6pppm﷨2e \իW֭[ .`ʔ)$W{ǗLgRW:R&5 = C;x &L;vl@:w+V :mJYYIQwQ5jT6DDѣGX4n5k֠gϞy~c}:>#߿ވE{DDտT6tPHUTE=~W\GNç~ɓ'C.?X_Jd2p> htj4H$ +<ػw/rrr`KYqQ>}:O.x;=Gf""ޑXT """""RB5rг)ADDDDĢ>%.@Qe֒d ~U},5QǩD%Y+"""37 *+)*o.yyȘ7>Vel,2C?>֜eː1o/HMEƼyȊ E{s7<>ٜ """"/)[K@nqpJQ^TInWuh33Z+VlX 7oFUڣp=p۷bMDq'+ccx{ezzũ1]^37s&Iכ:349r!!\nݕ+QE"͡ζg ڝj_lÂN]vq2\^<1QTJ%"#qkWn\QTdeƈH '("""\*0+`ϛᇸsegW9^(+CƜ99r$WvE_e _eˆXTԮl%5ؕP?ki\ӫK 7o6;}Í7nDqR[m8 ';;Vz|-r}7ڵkΝ;s8= \wGpCud"Pss7"Ǚ@# VkNRDgFcTFпTTX櫕-o AU44 EEbb"bj5,+ o=J$%¦}Nž*ڟMHOaY{w+))p=IvhFGJ`;zRS8;׮]Ȫt<~>/#Tw^&F] *ޓsbbbpuNtL8VS}9.;>PE:- -~yXpGh+6}a~~hQE/L8Vݖ;؄xs/m^/ OS"3pb$6+xG}#1[2Rx\V Spo)_$'0wkm $\y@]ܽ,>$bG>?WLv]\://l|}=f̀;W?vS##Wx|i`#4p z4͘~0kخ z4Əaի&K͚㏙45~VAjooRT*QΜj SΡwo #FBޢbc!o⎯ZzE=~wvWb y&L*=,>^QQ&'K 'OwU!""'j9ED)"O>˗ID @mғ"(CDD􈰧\O|\ݎ=PR[AADDDDd=DDDDDĢXT """""zDj,xps`.XT԰zy """" oS^ZK.}7q)0Ek3DkSOR` ue !""SQ @rYh?Hdȧ.?d貲ğ֔h!TSPINՕ+"":=DDDDDĢjgW O5<Lh߽|UG=_8W*S&L0yms X,Aم Ҹ81XehZϜiҦMO,[Nu̘ZUk ~"\rRwށiS~iXTX.[SG*6[T"**ʬ}߾};wI[Ν1bĈZE&LբBcG':NJx{jQ!Tw̩26dXVEEYBB jYǴi """nTW aogɆ+%OVqaɒ%fsέ6w |!Z"ۄ p8\w/J탢M nl:9jR''~t99p;f͌!!CHIt} $ Vs%DDDĢnV_E͋ .]Ú$cQUEoKmeFEd>صm+XNNf_]N/8gRaSoNt󟈈j_ """""5<<n%Kf6jH1J wn}7o.X킃!usMqJa߽;\x< nZG_||QȧIp4*btY17on5󟈈XTXD}' @DDDDTSADDDDD,*E """"OԮ"p"l<|Uƞj8u5 """""bQADDDDD!s*A}i&:u hԨ3gёsذa>7oAٳ'fϞ ///&ȂDS~a˖-qU̟?O<JKK9ñb "<<Xlڵk4&.vvvXz5/`ŊHNNɓ+WrnQ-^7nm_Xl233h"&.7nlmmm3g:ub 8< xl6uT8886.}* $)S:7FNl\  E^JObv\YBnV߫6]e{*++JB`` ADdAA'={ٳh֬xZ޽{CprL.<-'6| 7 Scujb7n"##:_ǧ~]v!44lQdz*` [׆lL8-[4|H8w6mSbq1%FeeP rKJ'ITGbi):ulK.eQ(}ᇘ?>.]ٳgصkqDF}s AR_m◝l~!M1?ax8DȪh4A_ZlzM4A-X+yf >ǏǪU|T*ß| v 4(xwtw=w~^̞=CE=Ľ_~?sqFddd`ƌ_ԩSѾ}{Qy ̙3?hٻ{{{cǎun+/1y* J h8fcc:Nd֧nxZOx饗h"z?l'a~ Dmƍg}777Qya쎍O?EA܋&;v`ׯV^z\ !%m_%Kcǎ5))I ˭"Vgggt }u.\+Wbƌ3f]Whi~D\E~B޳F>v]pUĺs( k33gĂ*믿0tPt[nB`RzQzjL:#F5k .e?\p!"3<:`prrbR駟0qD 2֭L&E\W;os!"ѺukܹDDd9HNN /`׿e2m۶x9LjZáT*ၩSsww_$յ8A.''lO&""q)JYYMi4&.ػw/Y)DD) """""-Psg.ng[@҇QUSADDDDD,*E """""T`y ҥKVgzz:S rUĚb`XT<~iV޽{ȜZZ?uݸqEcb.XT"a U5޼LVxNSSSqQ6OOO4mڴbիWM._ FR֭[ťbMHH@aa=s*ѩSZSɓ&mj7o4kzz:Laoo|mɉ+""""(zZ,dgg٤Yfknn.S;;;FRiXVP(L[l/7 +?XyyŐ!Cڏ=Ze{m D``I[ii),X{e9U(f1󢋵iӦf=e APPW:DDD,*/PXQMDDDDD,*jX5ha1*޽;\]]S y6bԫW/xzzrCDDĢg-:wlq6nܘ90L&虜EDDDßEö *#悈EE @q,c.XT """""bQADDDDD,**dggcڵHKKc23OE5> x:1DDwR~}# mڴAxx8ѣGpsCDĢ1@Dt/Ç5 qqqXx11h cD1<,^Xlذ2 PTT͛7㥗^/[ojL """s=6nHRz㸳gbݻ7ի#GbժU<EaÆaƍJJ+67 B/8q"d/9tOE{^퀢tqj{ ;h+VkG}oCq'xi~0JN]j''N@Trq;,X(H$`"C9sXx1Э[7DDD_ "bQuzYdZ%)2uV[dв"\%w7t,tå~_Fa.c-8 cUnhz{{W{vҤI֥*%%%ػw/݋9s}Tt:iZZrrr"VJ+WMq&%%AZs̩kYT<0b,\^L8V6΋(g} 8Ia'swN-2Uiqh(i }4ݡى:N^ 7toέlO,3 hժ~4'DTl(\T<:WZ-JKK$T*HR( ZPPH$(UVHbbyWkۡCDDD}/tAӡDINX0Ͻضy藇';ŐӳCDg*0&[Dh,A< sW>ֱx]Wq&d]s*辴 87;bG>&LGpp0f͚%X켑t1 4mY+k?pEQWruu5bРA-#sGsADt"22+VN0dXT<&ѽ ӧ#..QQQ C׮]ADĢz^zL ""$='MDDDDD,*j si|OǮ/:6dQADDDDĢH$́KU  D"""",*: w)ox@ڤvcw?C戈Dj8u^`]Vt1 t dEAz-zi/!@2b-9-8ˮ6""=ՐQhx,Q[Gϟ]LY+Qxh1P^z H?bҋ4qǩ+0T Q] zJNiW +W 7^zW ߘ hR7""""uHF͙p'/ ܿb>ùr1oDDDDւ?UayZNDcRbII{)9^ܩ kc ~@٭\*  +xD 1'o告m~Lʀ-.t.0\zpN[<:i%G+bpxa,Y1 ( h2+Ʒ~oP';L!s̝;פs1bģRJT o5UTS1Wh^^YhAL:cTmWͧ@[q\h3Qʒ ~(*.d@@Cqtx(gp 4:k (W"_ouY$CR||Յۆ/4U]6&-j &I0 """u@F@i%/C@.8dsV^+$|o~Vox@p /9PjŰ@ўlNك {>Ӱ<+ CPz P0"N$ @\[ULlCH^yÊ_z-*=wRr4m筂 áb[Appݯz%s1~7 EP Kx=p0Un$jݧn24w;BDDdx6=twPI/bIV0oDDDD,*N~\Ԅ"'bϊś؊aW =TwI!""bQ-1<ZG);tϣ ńbʭ`g]aLq57}\xL jmxln%WYh _u<5ˣ޾3,>Z4+&>oJ5 V>iZ상:"""D9 T7Oe """"Dw%7ܻKXeeW{7^c.XTՐ~,Pr "":oܛh\XuHdH(\xL jc#˲m t{Mݛ2I"؃9 ""bQ߿NBƍrnyW1qDKgTOޏxbH7CO]Ks!66x"ǡHOOǐ!CZ-*vlk%}Odg5ŚbUnww( \ ص0\Z/see9r$ "0^)22ݺumǒW.ep?54flaRPWZ`shhq*/Bz@\У{AբeKv=6EƍsNXskaXnqxf;a/{ {; Xp3\^H?b҉COovvvLC ßrrr+`ѢE *qk#|K?pssCpp0 pZ뱨(݋/B wwQV]n8@e/I~{JEgPXW}N/k@%Qcݯ݊G"!%b܋,:`L6έoESm6lܸ'NL&wE$fUmT"XOGA' ( ZfNYNG` IDATbCC\Q?g7|rպ:s;G;@_h0Sf4"ts,=Q\.[ݝwF XhͭxC ;69|=̀CUB;BA U_Y I-/>T#N(n @v2MDSQPP֭[^%KLvSqn۪PEb; <4d;!X}OGw!9Y MAGǐ: 8s N})ۦ85W`mhN;uSipC!ck)&v':w :|^ADk [Ekuwgz={7njlWO&NUVsnKD^EӞ{mzϟ';ŐӳLEF۠/ypC7>\+:EfA:W O>Сbbb ==111hժU\KģW^@ҕt l:WG/i7+O4 j:Ö3LX? 1+lh\-5)*ƍq1|&۔ &&ҥ EDT<`̘1fN:C;ùFhU"F_֞Y=I{Ӕi}O1R8c&N$*CGw!A1cFQF᧟~b,@4]t)lmm<̞=sNOͧd4qobYxXPḲ/em@='NrҶm[4jyyy("=;I&[r)ȥ o(9TeStsœ87T2))2ErM(V*PҴI~B[BOȣ9'srwN'#9Rt:tV?"44ƃ@BEid9SG#mlRnx#M7#nndZyN:f/a=ܖToX_wz~=JSm%Pg!f/xRGZ${M])x_H}Y׵N-ٳD*&Hظӂxs|@ +e=7H_QHdj@<ӂЂ:sII1'JˤBE#c%Uu&Jz@мN5g!TudT>@ Tl1sH;z0`ǟ&TЂ:cObGv|z^uM/R2_f @h,I7eH #;.KEz%Oqf/u*wn+<4ԵziT5_c@0`LE _҈ɓM_cicSbvSVMQөM5ѦW.SөM?=E_ TT~4famPz%{i,̲: `bp?)e??,DZhr+//2f)4>k?O'׷g65)] ֞>t$i˔1_llx>.;yLWZ꜂IW=]Gh|Vk?CO}%AQMمn_@Ea=UO?ݻnZ󤓛{뷯{hwqE\TuyʪS~7`azh:r뤑~(}[rHsFcCSL2Gv~}({ҋ#{Ks'Wwzzym/=moSgS;4y,~@}>5kWɞ.^%~FEj Tm?BٳtdZ0FIRBTnJ3Oa*<#˓.Sk;rԼ=j T)ϣ = Hnfl0ӧ[^J؞cuI%Ό;uRbRL]gxW)zҜ F⑁ҝKQͿ4?@SO1yA _ľBE#4.+# :T-;Wڞ)^ 8Rzao-5g|Wxja@Zy !mAirE]=XOz0[^ԕRbK1rI΋&15уo*-hw㪓ZR` ^Uj{;-6`/_ݨi TU UR}U-  1#PHx uc|M/̤@_( Go2_5'ow&Rޫ?s&E;0zQ *za&㖎Ӂ$,s=6$]{SV,j^u+"-븩II8=}e׾xz=QJL.+IZ2,>x6hWNK_j:,]~7w,/_ _Pe=c="w$i: F0ۤZ1q²M[kyi?$W3oM[맥ӈW۬_2c|zϽOcbO:*Gyd.1#!r}){`{Rvn/7F~l֝uvǏ?Olѣ5k,Y6Y~"BCCM2wj1}V='fZ=r L0{.wȐ!eҮ7heox5ZOdܴ~[-Us_rh=-س@^k^G˗/WJw$)j`]? hSNVݬsu|q=S'|XwHV~#K|7wi3MϛEޣ^>sa}lW_|MGBјi~UoGn]t#(A*,L[pJכ7o:h%^WiDiƌ?G}T;LQҥ/_*#Icݭ[7-_\=R{o4 }k6NN 1 PhnmDaGCCRܵ%b:%)\QrXD6Kk-qY-VO{@eR3INŦh4U:  %I/}IMr̢v1֖4fɘӷC[.X4|R>J4e)3Z`F3T3g3IR\?)rr㬎(%Ia0ͺqVi[jzsTVZ^{kɵRL#o*:D8= / ~IZt)ϓ% ,RR?h\z޷U׶HרQ4 HbLj$6IYx׍zu>c(Sripɞ"%Nfx40e`PI*#G)6u@0VRRzQg|?F.u+K/ T4Cu.h<@-ʥKy G*P?id ,vzKBZHw@m6fRC/#_X ^@Aԕ)#T1)v~&^5G4D)Kw64zFO̓ҷUҡ)5U}nRR>ҡi.Ro TK+0]dktL7^L]ҷJo4Y!}3N6+^*Y>BE*-s9AkG*t"-cW.C pi["mQR:)Pf uXʯNeiJ*H_5Q~D*;6+$.)4QE,Rx3/GRh:,!R%]/2ڒ 1}r}kIeIerr- PkHK)m><.U:$_Tq$7{Wܹ ;8b GNnRۚ޷V6r Չe8:!A2Tˈ҉5yQWIşHo*fx"zo{bl ؄Im:BvoTa͜93`^ǎuW[߿#6yoҖ6U?zed "-s,3R#nmcu2[S^t.Z.X~:RRh+ RUor4ݸ>b*vL iFʟ+2RސʏIΰJy{sΟI%koIik@Wޮ-:Z6MRw_#)utrw)itQS[\e"w ߴiSZ5x8bp*HƑO8B!;:UF 3+ޙ$2wTT{bӿ YʮpfH֊ur_Mwq߯!I%y敶tсTɞh8;8RaYp;RH2)_Y#E:$ozhc8zaqJSURفVRHE ҷJnFVt#*QeIa+(SZ"`EPͺ3plir[1iZRe~tttS;)㨃$u=TeؚHWmJ8WWgNG?,sv^jmr[y3qU{>Ry2Oۖfo3Oj2fi\IjX9rWm1.Չ?|qdU2>>SA4 Ԯw[7ي~lz}R@!IQ G*Wa —wInuIi[g㛶Oi6P@CÑ w'㔒g?N9Yq";0Pؓ G*j`D)0;vk m%ohl+)&cٵ[`"6%7fuon6Bj=?*J>]||k+ (w<#ĵKiP|i7W;BE;YfV6,DjN?Z)fq150s)~@s%Ts Pqns  PQť[_H.ne\N1T8p@_~\.:vLY, ?-9K9柷;"!wW-//Ok׮ѣGնm[C45T?~\Çג%KO0ASN 5Y-IӖI>/pLLo4s֢̀Ehcpݻ߯_~Y\sN6o,}Aj͗Ƽtm')t@ZU:ThFulH`Fz/^'xBvZh;wj޽45Tkھ}.\n`T2;CEHWD-ݑ%%6ec3Yb-ZSj„ KzAgUNEm!n6ҥ-~jpIr?6 &tbysHt2c5J(HБއzƨ2oşCGH43gt;W\W^yEvR4f :x<曧Oг_]V5< eH)hP\Iº{ tݻ}j޼z)M6M7nTrrcj: wUAA_]VZ_/wd=kӯ?O(M5{J $O4}5JQAqN__|Nۺuk 0 9R#ϧ?Xsѐ!Cԯ_?k6l8~8o^,Xpzi _l\`P!B€}ùl(77Wn[_4f͞=[=nݪ_-_\8=+IJV{S9:z(NX1F%-rM]gD5Z{]nJ>XSݝW)SY|X uٳgP ؼyu&Iz5l0I+??_PӦgEt֩X;vT\\YIi_Jvg|I:^$E}޳gBBB[RHvV}.Txx7|߯K23M۱c"##hZ?e)n:9T[)5^X7fn[C>OOH2ތ+rJ_^?=zf͚'jʔ)3gʕ+5o<ӯkܸq馛L]gNN222tqtʔ)ɩr33տ?O_bZ9RѪU+IS[nE_yf"[6l#ȑ#Ϻ)Қ}PJjxIw}c*$iܸWL6Fa#fVYi>Tt>yV\m 7vu\wr:_h}3gdvѣZ6lV\5kdԌiayr8WDD:H2ޅ>Xiz DBƎ+Ţ'jǎ*))̙3b [CHV˙o-Q!) ѽ+өS>Syy[o)))IIPGL=={ٳ5zh-ZH***R5{lY, RGX4VLiriC.im|WI66 0-Zhɒ%ջwo5iDjӦΝH*$oW߾}gڵ'¿qAv6hHݻwO?޽{Lv@JNN6UM hZhaS@Cg@@8{^Fs +BŞ={YVZZg}6`SO=%Cs!rG:t($ĸK_ԧO09N͝;t#ݮ4Tc*zNw^=5 뮻N_}$i˖-NS1C\Լysу5 #Gj5&~_h bРA $ƞ~2l*""Bg`_0ݡ &hڶmbccYZ{wtkׯ *+ 2Dwfɓ'#Gf;IDAT8tGy5 8gNSӦM#PO#w  o T3FW^ye:uzB6'=sTAAAegg+33SvQl"66V}80z5h ӟ ` ڸq֬Y0Pcǎ_:(PѫW/Iի3F[?̚H޽}N4iN8~&@0,l'wyG˖-?04Fe͘1C&MR||9ӧzN׮]4w\}'F*\.3h„ jӦ kpN[lƏngǟrssplR۷od ΚULL<$iǎJJJ1pAsuJLLTII{9OVTRR{@?!hTm۶ҥ.]ʚg:|n*NCG4i4c *̞=[}>{(**_|˗駟վ}{*y^}Zn&Mɓ'k4jAi6lt]wZ۲ev$r-zdXh {P@@@@BBBB*****PPPP T T T T@@@@BBBB***˕߼;IENDB`allegro-5.0.10/docs/src/refman/utf8.txt0000644000175000001440000006077112131265733017042 0ustar tjadenusers# UTF-8 string routines These functions are declared in the main Allegro header file: #include ## About UTF-8 string routines Some parts of the Allegro API, such as the font rountines, expect Unicode strings encoded in UTF-8. The following basic routines are provided to help you work with UTF-8 strings, however it does *not* mean you need to use them. You should consider another library (e.g. ICU) if you require more functionality. Briefly, Unicode is a standard consisting of a large character set of over 100,000 characters, and rules, such as how to sort strings. A *code point* is the integer value of a character, but not all code points are characters, as some code points have other uses. Unlike legacy character sets, the set of code points is open ended and more are assigned with time. Clearly it is impossible represent each code point with a 8-bit byte (limited to 256 code points) or even a 16-bit integer (limited to 65536 code points). It is possible to store code points in a 32-bit integers but it is space inefficient, and not actually that useful (at least, when handling the full complexity of Unicode; Allegro only does the very basics). There exist different Unicode Transformation Formats for encoding code points into smaller *code units*. The most important transformation formats are UTF-8 and UTF-16. UTF-8 is a *variable-length encoding* which encodes each code point to between one and four 8-bit bytes each. UTF-8 has many nice properties, but the main advantages are that it is backwards compatible with C strings, and ASCII characters (code points in the range 0-127) are encoded in UTF-8 exactly as they would be in ASCII. UTF-16 is another variable-length encoding, but encodes each code point to one or two 16-bit words each. It is, of course, not compatible with traditional C strings. Allegro does not generally use UTF-16 strings. Here is a diagram of the representation of the word "ål", with a NUL terminator, in both UTF-8 and UTF-16. ---------------- ---------------- -------------- String å l NUL ---------------- ---------------- -------------- Code points U+00E5 (229) U+006C (108) U+0000 (0) ---------------- ---------------- -------------- UTF-8 bytes 0xC3, 0xA5 0x6C 0x00 ---------------- ---------------- -------------- UTF-16LE bytes 0xE5, 0x00 0x6C, 0x00 0x00, 0x00 ---------------- ---------------- -------------- You can see the aforementioned properties of UTF-8. The first code point U+00E5 ("å") is outside of the ASCII range (0-127) so is encoded to multiple code units -- it requires two bytes. U+006C ("l") and U+0000 (NUL) both exist in the ASCII range so take exactly one byte each, as in a pure ASCII string. A zero byte never appears except to represent the NUL character, so many functions which expect C-style strings will work with UTF-8 strings without modification. On the other hand, UTF-16 represents each code point by either one or two 16-bit code units (two or four bytes). The representation of each 16-bit code unit depends on the byte order; here we have demonstrated little endian. Both UTF-8 and UTF-16 are self-synchronising. Starting from any offset within a string, it is efficient to find the beginning of the previous or next code point. Not all sequences of bytes or 16-bit words are valid UTF-8 and UTF-16 strings respectively. UTF-8 also has an additional problem of overlong forms, where a code point value is encoded using more bytes than is strictly necessary. This is invalid and needs to be guarded against. In the following "ustr" functions, be careful whether a function takes code unit (byte) or code point indices. In general, all position parameters are in code unit offsets. This may be surprising, but if you think about, is required for good performance. (It also means some functions will work even if they do not contain UTF-8, since they only care about storing bytes, so you may actually store arbitrary data in the ALLEGRO_USTRs.) For actual text processing, where you want to specify positions with code point indices, you should use [al_ustr_offset] to find the code unit offset position. However, most of the time you would probably just work with byte offsets. ## UTF-8 string types ### API: ALLEGRO_USTR An opaque type representing a string. ALLEGRO_USTRs normally contain UTF-8 encoded strings, but they may be used to hold any byte sequences, including NULs. ### API: ALLEGRO_USTR_INFO A type that holds additional information for an [ALLEGRO_USTR] that references an external memory buffer. See also: [al_ref_cstr], [al_ref_buffer] and [al_ref_ustr]. ## Creating and destroying strings ### API: al_ustr_new Create a new string containing a copy of the C-style string `s`. The string must eventually be freed with [al_ustr_free]. See also: [al_ustr_new_from_buffer], [al_ustr_newf], [al_ustr_dup], [al_ustr_new_from_utf16] ### API: al_ustr_new_from_buffer Create a new string containing a copy of the buffer pointed to by `s` of the given size in bytes. The string must eventually be freed with [al_ustr_free]. See also: [al_ustr_new] ### API: al_ustr_newf Create a new string using a printf-style format string. *Notes:* The "%s" specifier takes C string arguments, not ALLEGRO_USTRs. Therefore to pass an ALLEGRO_USTR as a parameter you must use [al_cstr], and it must be NUL terminated. If the string contains an embedded NUL byte everything from that byte onwards will be ignored. The "%c" specifier outputs a single byte, not the UTF-8 encoding of a code point. Therefore it is only usable for ASCII characters (value <= 127) or if you really mean to output byte values from 128--255. To insert the UTF-8 encoding of a code point, encode it into a memory buffer using [al_utf8_encode] then use the "%s" specifier. Remember to NUL terminate the buffer. See also: [al_ustr_new], [al_ustr_appendf] ### API: al_ustr_free Free a previously allocated string. Does nothing if the argument is NULL. See also: [al_ustr_new], [al_ustr_new_from_buffer], [al_ustr_newf] ### API: al_cstr Get a `char *` pointer to the data in a string. This pointer will only be valid while the [ALLEGRO_USTR] object is not modified and not destroyed. The pointer may be passed to functions expecting C-style strings, with the following caveats: * ALLEGRO_USTRs are allowed to contain embedded NUL ('\0') bytes. That means `al_ustr_size(u)` and `strlen(al_cstr(u))` may not agree. * An ALLEGRO_USTR may be created in such a way that it is not NUL terminated. A string which is dynamically allocated will always be NUL terminated, but a string which references the middle of another string or region of memory will *not* be NUL terminated. * If the ALLEGRO_USTR references another string, the returned C string will point into the referenced string. Again, no NUL terminator will be added to the referenced string. See also: [al_ustr_to_buffer], [al_cstr_dup] ### API: al_ustr_to_buffer Write the contents of the string into a pre-allocated buffer of the given size in bytes. The result will always be NUL terminated, so a maximum of `size - 1` bytes will be copied. See also: [al_cstr], [al_cstr_dup] ### API: al_cstr_dup Create a NUL ('\0') terminated copy of the string. Any embedded NUL bytes will still be presented in the returned string. The new string must eventually be freed with [al_free]. If an error occurs NULL is returned. See also: [al_cstr], [al_ustr_to_buffer], [al_free] ### API: al_ustr_dup Return a duplicate copy of a string. The new string will need to be freed with [al_ustr_free]. See also: [al_ustr_dup_substr], [al_ustr_free] ### API: al_ustr_dup_substr Return a new copy of a string, containing its contents in the byte interval \[start_pos, end_pos). The new string will be NUL terminated and will need to be freed with [al_ustr_free]. If necessary, use [al_ustr_offset] to find the byte offsets for a given code point that you are interested in. See also: [al_ustr_dup], [al_ustr_free] ## Predefined strings ### API: al_ustr_empty_string Return a pointer to a static empty string. The string is read only and must not be freed. ## Creating strings by referencing other data ### API: al_ref_cstr Create a string that references the storage of a C-style string. The information about the string (e.g. its size) is stored in the structure pointed to by the `info` parameter. The string will not have any other storage allocated of its own, so if you allocate the `info` structure on the stack then no explicit "free" operation is required. The string is valid until the underlying C string disappears. Example: ALLEGRO_USTR_INFO info; ALLEGRO_USTR *us = al_ref_cstr(&info, "my string"); See also: [al_ref_buffer], [al_ref_ustr] ### API: al_ref_buffer Create a string that references the storage of an underlying buffer. The size of the buffer is given in bytes. You can use it to reference only part of a string or an arbitrary region of memory. The string is valid while the underlying memory buffer is valid. See also: [al_ref_cstr], [al_ref_ustr] ### API: al_ref_ustr Create a read-only string that references the storage of another [ALLEGRO_USTR] string. The information about the string (e.g. its size) is stored in the structure pointed to by the `info` parameter. The new string will not have any other storage allocated of its own, so if you allocate the `info` structure on the stack then no explicit "free" operation is required. The referenced interval is \[start_pos, end_pos). Both are byte offsets. The string is valid until the underlying string is modified or destroyed. If you need a range of code-points instead of bytes, use [al_ustr_offset] to find the byte offsets. See also: [al_ref_cstr], [al_ref_buffer] ## Sizes and offsets ### API: al_ustr_size Return the size of the string in bytes. This is equal to the number of code points in the string if the string is empty or contains only 7-bit ASCII characters. See also: [al_ustr_length] ### API: al_ustr_length Return the number of code points in the string. See also: [al_ustr_size], [al_ustr_offset] ### API: al_ustr_offset Return the byte offset (from the start of the string) of the code point at the specified index in the string. A zero index parameter will return the first character of the string. If index is negative, it counts backward from the end of the string, so an index of -1 will return an offset to the last code point. If the index is past the end of the string, returns the offset of the end of the string. See also: [al_ustr_length] ### API: al_ustr_next Find the byte offset of the next code point in string, beginning at `*pos`. `*pos` does not have to be at the beginning of a code point. Returns true on success, and the value pointed to by `pos` will be updated to the found offset. Otherwise returns false if `*pos` was already at the end of the string, and `*pos` is unmodified. This function just looks for an appropriate byte; it doesn't check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes. See also: [al_ustr_prev] ### API: al_ustr_prev Find the byte offset of the previous code point in string, before `*pos`. `*pos` does not have to be at the beginning of a code point. Returns true on success, then value pointed to by `pos` will be updated to the found offset. Otherwise returns false if `*pos` was already at the end of the string, then `*pos` is unmodified. This function just looks for an appropriate byte; it doesn't check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes. See also: [al_ustr_next] ## Getting code points ### API: al_ustr_get Return the code point in `us` beginning at byte offset `pos`. On success returns the code point value. If `pos` was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. See also: [al_ustr_get_next], [al_ustr_prev_get] ### API: al_ustr_get_next Find the code point in `us` beginning at byte offset `*pos`, then advance to the next code point. On success return the code point value. If `pos` was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with [al_ustr_next], invalid byte sequences may be skipped while advancing. See also: [al_ustr_get], [al_ustr_prev_get] ### API: al_ustr_prev_get Find the beginning of a code point before byte offset `*pos`, then return it. Note this performs a *pre-increment*. On success returns the code point value. If `pos` was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with [al_ustr_prev], invalid byte sequences may be skipped while advancing. See also: [al_ustr_get_next] ## Inserting into strings ### API: al_ustr_insert Insert `us2` into `us1` beginning at byte offset `pos`. `pos` cannot be less than 0. If `pos` is past the end of `us1` then the space between the end of the string and `pos` will be padded with NUL ('\0') bytes. If required, use [al_ustr_offset] to find the byte offset for a given code point index. Returns true on success, false on error. See also: [al_ustr_insert_cstr], [al_ustr_insert_chr], [al_ustr_append], [al_ustr_offset] ### API: al_ustr_insert_cstr Like [al_ustr_insert] but inserts a C-style string at byte offset `pos`. See also: [al_ustr_insert], [al_ustr_insert_chr] ### API: al_ustr_insert_chr Insert a code point into `us` beginning at byte offset `pos`. `pos` cannot be less than 0. If `pos` is past the end of `us` then the space between the end of the string and `pos` will be padded with NUL ('\0') bytes. Returns the number of bytes inserted, or 0 on error. See also: [al_ustr_insert], [al_ustr_insert_cstr] ## Appending to strings ### API: al_ustr_append Append `us2` to the end of `us1`. Returns true on success, false on error. This function can be used to append an arbitrary buffer: ALLEGRO_USTR_INFO info; al_ustr_append(us, al_ref_buffer(&info, buf, size)); See also: [al_ustr_append_cstr], [al_ustr_append_chr], [al_ustr_appendf], [al_ustr_vappendf] ### API: al_ustr_append_cstr Append C-style string `s` to the end of `us`. Returns true on success, false on error. See also: [al_ustr_append] ### API: al_ustr_append_chr Append a code point to the end of `us`. Returns the number of bytes added, or 0 on error. See also: [al_ustr_append] ### API: al_ustr_appendf This function appends formatted output to the string `us`. `fmt` is a printf-style format string. See [al_ustr_newf] about the "%s" and "%c" specifiers. Returns true on success, false on error. See also: [al_ustr_vappendf], [al_ustr_append] ### API: al_ustr_vappendf Like [al_ustr_appendf] but you pass the variable argument list directly, instead of the arguments themselves. See [al_ustr_newf] about the "%s" and "%c" specifiers. Returns true on success, false on error. See also: [al_ustr_appendf], [al_ustr_append] ## Removing parts of strings ### API: al_ustr_remove_chr Remove the code point beginning at byte offset `pos`. Returns true on success. If `pos` is out of range or `pos` is not the beginning of a valid code point, returns false leaving the string unmodified. Use [al_ustr_offset] to find the byte offset for a code-points offset. See also: [al_ustr_remove_range] ### API: al_ustr_remove_range Remove the interval \[start_pos, end_pos) from a string. `start_pos` and `end_pos` are byte offsets. Both may be past the end of the string but cannot be less than 0 (the start of the string). Returns true on success, false on error. See also: [al_ustr_remove_chr], [al_ustr_truncate] ### API: al_ustr_truncate Truncate a portion of a string at byte offset `start_pos` onwards. `start_pos` can be past the end of the string (has no effect) but cannot be less than 0. Returns true on success, false on error. See also: [al_ustr_remove_range], [al_ustr_ltrim_ws], [al_ustr_rtrim_ws], [al_ustr_trim_ws] ### API: al_ustr_ltrim_ws Remove leading whitespace characters from a string, as defined by the C function `isspace()`. Returns true on success, or false on error. See also: [al_ustr_rtrim_ws], [al_ustr_trim_ws] ### API: al_ustr_rtrim_ws Remove trailing ("right") whitespace characters from a string, as defined by the C function `isspace()`. Returns true on success, or false on error. See also: [al_ustr_ltrim_ws], [al_ustr_trim_ws] ### API: al_ustr_trim_ws Remove both leading and trailing whitespace characters from a string. Returns true on success, or false on error. See also: [al_ustr_ltrim_ws], [al_ustr_rtrim_ws] ## Assigning one string to another ### API: al_ustr_assign Overwrite the string `us1` with another string `us2`. Returns true on success, false on error. See also: [al_ustr_assign_substr], [al_ustr_assign_cstr] ### API: al_ustr_assign_substr Overwrite the string `us1` with the contents of `us2` in the byte interval \[start_pos, end_pos). The end points will be clamed to the bounds of `us2`. Usually you will first have to use [al_ustr_offset] to find the byte offsets. Returns true on success, false on error. See also: [al_ustr_assign], [al_ustr_assign_cstr] ### API: al_ustr_assign_cstr Overwrite the string `us` with the contents of the C-style string `s`. Returns true on success, false on error. See also: [al_ustr_assign_substr], [al_ustr_assign_cstr] ## Replacing parts of string ### API: al_ustr_set_chr Replace the code point beginning at byte offset `pos` with `c`. `pos` cannot be less than 0. If `pos` is past the end of `us1` then the space between the end of the string and `pos` will be padded with NUL ('\0') bytes. If `pos` is not the start of a valid code point, that is an error and the string will be unmodified. On success, returns the number of bytes written, i.e. the offset to the following code point. On error, returns 0. See also: [al_ustr_replace_range] ### API: al_ustr_replace_range Replace the part of `us1` in the byte interval \[start_pos, end_pos) with the contents of `us2`. `start_pos` cannot be less than 0. If `start_pos` is past the end of `us1` then the space between the end of the string and `start_pos` will be padded with NUL ('\0') bytes. Use [al_ustr_offset] to find the byte offsets. Returns true on success, false on error. See also: [al_ustr_set_chr] ## Searching ### API: al_ustr_find_chr Search for the encoding of code point `c` in `us` from byte offset `start_pos` (inclusive). Returns the position where it is found or -1 if it is not found. See also: [al_ustr_rfind_chr] ### API: al_ustr_rfind_chr Search for the encoding of code point `c` in `us` backwards from byte offset `end_pos` (exclusive). Returns the position where it is found or -1 if it is not found. See also: [al_ustr_find_chr] ### API: al_ustr_find_set This function finds the first code point in `us`, beginning from byte offset `start_pos`, that matches any code point in `accept`. Returns the position if a code point was found. Otherwise returns -1. See also: [al_ustr_find_set_cstr], [al_ustr_find_cset] ### API: al_ustr_find_set_cstr Like [al_ustr_find_set] but takes a C-style string for `accept`. See also: [al_ustr_find_set], [al_ustr_find_cset_cstr] ### API: al_ustr_find_cset This function finds the first code point in `us`, beginning from byte offset `start_pos`, that does *not* match any code point in `reject`. In other words it finds a code point in the complementary set of `reject`. Returns the byte position of that code point, if any. Otherwise returns -1. See also: [al_ustr_find_cset_cstr], [al_ustr_find_set] ### API: al_ustr_find_cset_cstr Like [al_ustr_find_cset] but takes a C-style string for `reject`. See also: [al_ustr_find_cset], [al_ustr_find_set_cstr] ### API: al_ustr_find_str Find the first occurrence of string `needle` in `haystack`, beginning from byte offset `pos` (inclusive). Return the byte offset of the occurrence if it is found, otherwise return -1. See also: [al_ustr_find_cstr], [al_ustr_rfind_str], [al_ustr_find_replace] ### API: al_ustr_find_cstr Like [al_ustr_find_str] but takes a C-style string for `needle`. See also: [al_ustr_find_str], [al_ustr_rfind_cstr] ### API: al_ustr_rfind_str Find the last occurrence of string `needle` in `haystack` before byte offset `end_pos` (exclusive). Return the byte offset of the occurrence if it is found, otherwise return -1. See also: [al_ustr_rfind_cstr], [al_ustr_find_str] ### API: al_ustr_rfind_cstr Like [al_ustr_rfind_str] but takes a C-style string for `needle`. See also: [al_ustr_rfind_str], [al_ustr_find_cstr] ### API: al_ustr_find_replace Replace all occurrences of `find` in `us` with `replace`, beginning at byte offset `start_pos`. The `find` string must be non-empty. Returns true on success, false on error. See also: [al_ustr_find_replace_cstr] ### API: al_ustr_find_replace_cstr Like [al_ustr_find_replace] but takes C-style strings for `find` and `replace`. ## Comparing ### API: al_ustr_equal Return true iff the two strings are equal. This function is more efficient than [al_ustr_compare] so is preferable if ordering is not important. See also: [al_ustr_compare] ### API: al_ustr_compare This function compares `us1` and `us2` by code point values. Returns zero if the strings are equal, a positive number if `us1` comes after `us2`, else a negative number. This does *not* take into account locale-specific sorting rules. For that you will need to use another library. See also: [al_ustr_ncompare], [al_ustr_equal] ### API: al_ustr_ncompare Like [al_ustr_compare] but only compares up to the first `n` code points of both strings. Returns zero if the strings are equal, a positive number if `us1` comes after `us2`, else a negative number. See also: [al_ustr_compare], [al_ustr_equal] ### API: al_ustr_has_prefix Returns true iff `us1` begins with `us2`. See also: [al_ustr_has_prefix_cstr], [al_ustr_has_suffix] ### API: al_ustr_has_prefix_cstr Returns true iff `us1` begins with `s2`. See also: [al_ustr_has_prefix], [al_ustr_has_suffix_cstr] ### API: al_ustr_has_suffix Returns true iff `us1` ends with `us2`. See also: [al_ustr_has_suffix_cstr], [al_ustr_has_prefix] ### API: al_ustr_has_suffix_cstr Returns true iff `us1` ends with `s2`. See also: [al_ustr_has_suffix], [al_ustr_has_prefix_cstr] ## UTF-16 conversion ### API: al_ustr_new_from_utf16 Create a new string containing a copy of the 0-terminated string `s` which must be encoded as UTF-16. The string must eventually be freed with [al_ustr_free]. See also: [al_ustr_new] ### API: al_ustr_size_utf16 Returns the number of bytes required to encode the string in UTF-16 (including the terminating 0). Usually called before [al_ustr_encode_utf16] to determine the size of the buffer to allocate. See also: [al_ustr_size] ### API: al_ustr_encode_utf16 Encode the string into the given buffer, in UTF-16. Returns the number of bytes written. There are never more than `n` bytes written. The minimum size to encode the complete string can be queried with [al_ustr_size_utf16]. If the `n` parameter is smaller than that, the string will be truncated but still always 0 terminated. See also: [al_ustr_size_utf16], [al_utf16_encode] ## Low-level UTF-8 routines ### API: al_utf8_width Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-8. This is between 1 and 4 bytes for legal code point values. Otherwise returns 0. See also: [al_utf8_encode], [al_utf16_width] ### API: al_utf8_encode Encode the specified code point to UTF-8 into the buffer `s`. The buffer must have enough space to hold the encoding, which takes between 1 and 4 bytes. This routine will refuse to encode code points above 0x10FFFF. Returns the number of bytes written, which is the same as that returned by [al_utf8_width]. See also: [al_utf16_encode] ## Low-level UTF-16 routines ### API: al_utf16_width Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-16. This is either 2 or 4 bytes for legal code point values. Otherwise returns 0. See also: [al_utf16_encode], [al_utf8_width] ### API: al_utf16_encode Encode the specified code point to UTF-16 into the buffer `s`. The buffer must have enough space to hold the encoding, which takes either 2 or 4 bytes. This routine will refuse to encode code points above 0x10FFFF. Returns the number of bytes written, which is the same as that returned by [al_utf16_width]. See also: [al_utf8_encode], [al_ustr_encode_utf16] allegro-5.0.10/docs/src/refman/transformations.txt0000644000175000001440000001556312043112547021400 0ustar tjadenusers# Transformations These functions are declared in the main Allegro header file: #include The transformations are combined in the order of the function invocations. Thus to create a transformation that first rotates a point and then translates it, you would (starting with an identity transformation) call [al_rotate_transform] and then [al_translate_transform]. This approach is opposite of what OpenGL uses but similar to what Direct3D uses. For those who known the matrix algebra going behind the scenes, what the transformation functions in Allegro do is "pre-multiply" the successive transformations. So, for example, if you have code that does: al_identity_transform(&T); al_compose_transform(&T, &T1); al_compose_transform(&T, &T2); al_compose_transform(&T, &T3); al_compose_transform(&T, &T4); The resultant matrix multiplication expression will look like this: T4 * T3 * T2 * T1 Since the point coordinate vector term will go on the right of that sequence of factors, the transformation that is called first, will also be applied first. This means if you have code like this: al_identity_transform(&T1); al_scale_transform(&T1, 2, 2); al_identity_transform(&T2); al_translate_transform(&T2, 100, 0); al_identity_transform(&T); al_compose_transform(&T, &T1); al_compose_transform(&T, &T2); al_use_transform(T); it does exactly the same as: al_identity_transform(&T); al_scale_transform(&T, 2, 2); al_translate_transform(&T, 100, 0); al_use_transform(T); ## API: ALLEGRO_TRANSFORM Defines the generic transformation type, a 4x4 matrix. 2D transforms use only a small subsection of this matrix, namely the top left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values. *Fields:* * m - A 4x4 float matrix ## API: al_copy_transform Makes a copy of a transformation. *Parameters:* * dest - Source transformation * src - Destination transformation ## API: al_use_transform Sets the transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own transformation). Every drawing operation after this call will be transformed using this transformation. Call this function with an identity transformation to return to the default behaviour. This function does nothing if there is no target bitmap. The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables. void setup_my_transformation(void) { ALLEGRO_TRANSFORM transform; al_translate_transform(&transform, 5, 10); al_use_transform(&transform); } *Parameters:* * trans - Transformation to use See also: [al_get_current_transform], [al_transform_coordinates] ## API: al_get_current_transform Returns the transformation of the current target bitmap, as set by [al_use_transform]. If there is no target bitmap, this function returns NULL. *Returns:* A pointer to the current transformation. ## API: al_invert_transform Inverts the passed transformation. If the transformation is nearly singular (close to not having an inverse) then the returned transformation may be invalid. Use [al_check_inverse] to ascertain if the transformation has an inverse before inverting it if you are in doubt. *Parameters:* * trans - Transformation to invert See also: [al_check_inverse] ## API: al_check_inverse Checks if the transformation has an inverse using the supplied tolerance. Tolerance should be a small value between 0 and 1, with 1e-7 being sufficient for most applications. In this function tolerance specifies how close the determinant can be to 0 (if the determinant is 0, the transformation has no inverse). Thus the smaller the tolerance you specify, the "worse" transformations will pass this test. Using a tolerance of 1e-7 will catch errors greater than 1/1000's of a pixel, but let smaller errors pass. That means that if you transformed a point by a transformation and then transformed it again by the inverse transformation that passed this check, the resultant point should less than 1/1000's of a pixel away from the original point. Note that this check is superfluous most of the time if you never touched the transformation matrix values yourself. The only thing that would cause the transformation to not have an inverse is if you applied a 0 (or very small) scale to the transformation or you have a really large translation. As long as the scale is comfortably above 0, the transformation will be invertible. *Parameters:* * trans - Transformation to check * tol - Tolerance *Returns:* 1 if the transformation is invertible, 0 otherwise See also: [al_invert_transform] ## API: al_identity_transform Sets the transformation to be the identity transformation. This is the default transformation. Use [al_use_transform] on an identity transformation to return to the default. ALLEGRO_TRANSFORM t; al_identity_transform(&t); al_use_transform(&t); *Parameters:* * trans - Transformation to alter See also: [al_translate_transform], [al_rotate_transform], [al_scale_transform] ## API: al_build_transform Builds a transformation given some parameters. This call is equivalent to calling the transformations in this order: make identity, scale, rotate, translate. This method is faster, however, than actually calling those functions. *Parameters:* * trans - Transformation to alter * x, y - Translation * sx, sy - Scale * theta - Rotation angle in radians See also: [al_translate_transform], [al_rotate_transform], [al_scale_transform], [al_compose_transform] ## API: al_translate_transform Apply a translation to a transformation. *Parameters:* * trans - Transformation to alter * x, y - Translation See also: [al_rotate_transform], [al_scale_transform], [al_build_transform] ## API: al_rotate_transform Apply a rotation to a transformation. *Parameters:* * trans - Transformation to alter * theta - Rotation angle in radians See also: [al_translate_transform], [al_scale_transform], [al_build_transform] ## API: al_scale_transform Apply a scale to a transformation. *Parameters:* * trans - Transformation to alter * sx, sy - Scale See also: [al_translate_transform], [al_rotate_transform], [al_build_transform] ## API: al_transform_coordinates Transform a pair of coordinates. *Parameters:* * trans - Transformation to use * x, y - Pointers to the coordinates See also: [al_use_transform] ## API: al_compose_transform Compose (combine) two transformations by a matrix multiplication. trans := trans other Note that the order of matrix multiplications is important. The effect of applying the combined transform will be as if first applying `trans` and then applying `other` and not the other way around. *Parameters:* * trans - Transformation to alter * other - Transformation used to transform `trans` allegro-5.0.10/docs/src/refman/misc.txt0000644000175000001440000000136011454330452017072 0ustar tjadenusers# Miscellaneous routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_PI C99 compilers have no predefined value like M_PI for the constant π, but you can use this one instead. ## API: al_run_main This function is useful in cases where you don't have a main() function but want to run Allegro (mostly useful in a wrapper library). Under Windows and Linux this is no problem because you simply can call [al_install_system]. But some other system (like OSX) don't allow calling [al_install_system] in the main thread. al_run_main will know what to do in that case. The passed argc and argv will simply be passed on to user_main and the return value of user_main will be returned. allegro-5.0.10/docs/src/refman/direct3d.txt0000644000175000001440000000330611454330452017642 0ustar tjadenusers# Direct3D integration These functions are declared in the following header file: #include ## API: al_get_d3d_device Returns the Direct3D device of the display. The return value is undefined if the display was not created with the Direct3D flag. *Returns:* A pointer to the Direct3D device. ## API: al_get_d3d_system_texture Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). This texture is used for the render-to-texture feature set. *Returns:* A pointer to the Direct3D system texture. ## API: al_get_d3d_video_texture Returns the video texture (stored with the D3DPOOL_DEFAULT or D3DPOOL_MANAGED flags depending on whether render-to-texture is enabled or disabled respectively). *Returns:* A pointer to the Direct3D video texture. ## API: al_have_d3d_non_pow2_texture_support Returns whether the Direct3D device supports textures whose dimensions are not powers of two. *Returns:* True if device suports NPOT textures, false otherwise. ## API: al_have_d3d_non_square_texture_support Returns whether the Direct3D device supports textures that are not square. *Returns:* True if the Direct3D device suports non-square textures, false otherwise. ## API: al_get_d3d_texture_position Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels. *Parameters:* * bitmap - ALLEGRO_BITMAP to examine * u - Will hold the returned u coordinate * v - Will hold the returned v coordinate ## API: al_is_d3d_device_lost Returns a boolean indicating whether or not the Direct3D device belonging to the given display is in a lost state. *Parameters:* * display - The display that the device you wish to check is attached to allegro-5.0.10/docs/src/refman/main.txt0000644000175000001440000000160111771531666017075 0ustar tjadenusers# Main addon The `main` addon has no public API, but contains functionality to enable programs using Allegro to build and run without platform-specific changes. On platforms that require this functionality (e.g. OSX) this addon contains a C `main` function that invokes [al_run_main] with the user's own `main` function, where the user's `main` function has had its name mangled to something else. The file that defines the user `main` function must include the header file `allegro5/allegro.h`; that header performs the name mangling using some macros. If the user `main` function is defined in C++, then it must have the following signature for this addon to work: int main(int argc, char **argv) This addon does nothing on platforms that don't require its functionality, but you should keep it in mind in case you need to port to platforms that do require it. Link with allegro_main. allegro-5.0.10/docs/src/refman/inc.z.txt0000644000175000001440000000000711415353074017157 0ustar tjadenusers
    allegro-5.0.10/docs/src/refman/fshook.txt0000644000175000001440000002035612062066402017433 0ustar tjadenusers# File system routines These functions are declared in the main Allegro header file: #include These functions allow access to the filesystem. This can either be the real filesystem like your harddrive, or a virtual filesystem like a .zip archive (or whatever else you or an addon makes it do). ## API: ALLEGRO_FS_ENTRY Opaque filesystem entry object. Represents a file or a directory (check with [al_get_fs_entry_mode]). There are no user accessible member variables. ## API: ALLEGRO_FILE_MODE Filesystem modes/types * ALLEGRO_FILEMODE_READ - Readable * ALLEGRO_FILEMODE_WRITE - Writable * ALLEGRO_FILEMODE_EXECUTE - Executable * ALLEGRO_FILEMODE_HIDDEN - Hidden * ALLEGRO_FILEMODE_ISFILE - Regular file * ALLEGRO_FILEMODE_ISDIR - Directory ## API: al_create_fs_entry Creates an [ALLEGRO_FS_ENTRY] object pointing to path on the filesystem. 'path' can be a file or a directory and must not be NULL. ## API: al_destroy_fs_entry Destroys a fs entry handle. The file or directory represented by it is not destroyed. If the entry was opened, it is closed before being destroyed. Does nothing if passed NULL. ## API: al_get_fs_entry_name Returns the entry's filename path. Note that the filesystem encoding may not be known and the conversion to UTF-8 could in very rare cases cause this to return an invalid path. Therefore it's always safest to access the file over its [ALLEGRO_FS_ENTRY] and not the path. On success returns a read only string which you must not modify or destroy. Returns NULL on failure. > Note: prior to 5.1.5 it was written: "... the path will not be an absolute path if the entry wasn't created from an absolute path". This is no longer true. ## API: al_update_fs_entry Updates file status information for a filesystem entry. File status information is automatically updated when the entry is created, however you may update it again with this function, e.g. in case it changed. Returns true on success, false on failure. Fills in errno to indicate the error. See also: [al_get_errno], [al_get_fs_entry_atime], [al_get_fs_entry_ctime], [al_get_fs_entry_mode] ## API: al_get_fs_entry_mode Returns the entry's mode flags, i.e. permissions and whether the entry refers to a file or directory. See also: [al_get_errno], [ALLEGRO_FILE_MODE] ## API: al_get_fs_entry_atime Returns the time in seconds since the epoch since the entry was last accessed. Warning: some filesystem either don't support this flag, or people turn it off to increase performance. It may not be valid in all circumstances. See also: [al_get_fs_entry_ctime], [al_get_fs_entry_mtime], [al_update_fs_entry] ## API: al_get_fs_entry_ctime Returns the time in seconds since the epoch this entry was created on the filesystem. See also: [al_get_fs_entry_atime], [al_get_fs_entry_mtime], [al_update_fs_entry] ## API: al_get_fs_entry_mtime Returns the time in seconds since the epoch since the entry was last modified. See also: [al_get_fs_entry_atime], [al_get_fs_entry_ctime], [al_update_fs_entry] ## API: al_get_fs_entry_size Returns the size, in bytes, of the given entry. May not return anything sensible for a directory entry. See also: [al_update_fs_entry] ## API: al_fs_entry_exists Check if the given entry exists on in the filesystem. Returns true if it does exist or false if it doesn't exist, or an error occurred. Error is indicated in Allegro's errno. See also: [al_filename_exists] ## API: al_remove_fs_entry Delete this filesystem entry from the filesystem. Only files and empty directories may be deleted. Returns true on success, and false on failure, error is indicated in Allegro's errno. See also: [al_filename_exists] ## API: al_filename_exists Check if the path exists on the filesystem, without creating an [ALLEGRO_FS_ENTRY] object explicitly. See also: [al_fs_entry_exists] ## API: al_remove_filename Delete the given path from the filesystem, which may be a file or an empty directory. This is the same as [al_remove_fs_entry], except it expects the path as a string. Returns true on success, and false on failure. Allegro's errno is filled in to indicate the error. See also: [al_remove_fs_entry] ## Directory functions ### API: al_open_directory Opens a directory entry object. You must call this before using [al_read_directory] on an entry and you must call [al_close_directory] when you no longer need it. Returns true on success. See also: [al_read_directory], [al_close_directory] ### API: al_read_directory Reads the next directory item and returns a filesystem entry for it. Returns NULL if there are no more entries or if an error occurs. Call [al_destroy_fs_entry] on the returned entry when you are done with it. See also: [al_open_directory], [al_close_directory] ### API: al_close_directory Closes a previously opened directory entry object. Returns true on success, false on failure and fills in Allegro's errno to indicate the error. See also: [al_open_directory], [al_read_directory] ### API: al_get_current_directory Returns the path to the current working directory, or NULL on failure. The returned path is dynamically allocated and must be destroyed with [al_free]. Allegro's errno is filled in to indicate the error if there is a failure. This function may not be implemented on some (virtual) filesystems. See also: [al_get_errno], [al_free] ### API: al_change_directory Changes the current working directory to 'path'. Returns true on success, false on error. ### API: al_make_directory Creates a new directory on the filesystem. This function also creates any parent directories as needed. Returns true on success (including if the directory already exists), otherwise returns false on error. Fills in Allegro's errno to indicate the error. See also: [al_get_errno] ### API: al_open_fs_entry Open an [ALLEGRO_FILE] handle to a filesystem entry, for the given access mode. This is like calling [al_fopen] with the name of the filesystem entry, but uses the appropriate file interface, not whatever was set with the latest call to [al_set_new_file_interface]. Returns the handle on success, NULL on error. See also: [al_fopen] ## Alternative filesystem functions By default, Allegro uses platform specific filesystem functions for things like directory access. However if for example the files of your game are not in the local filesystem but inside some file archive, you can provide your own set of functions (or use an addon which does this for you, for example our physfs addon allows access to the most common archive formats). ### API: ALLEGRO_FS_INTERFACE The available functions you can provide for a filesystem. They are: ~~~ ALLEGRO_FS_ENTRY * fs_create_entry (const char *path); void fs_destroy_entry (ALLEGRO_FS_ENTRY *e); const char * fs_entry_name (ALLEGRO_FS_ENTRY *e); bool fs_update_entry (ALLEGRO_FS_ENTRY *e); uint32_t fs_entry_mode (ALLEGRO_FS_ENTRY *e); time_t fs_entry_atime (ALLEGRO_FS_ENTRY *e); time_t fs_entry_mtime (ALLEGRO_FS_ENTRY *e); time_t fs_entry_ctime (ALLEGRO_FS_ENTRY *e); off_t fs_entry_size (ALLEGRO_FS_ENTRY *e); bool fs_entry_exists (ALLEGRO_FS_ENTRY *e); bool fs_remove_entry (ALLEGRO_FS_ENTRY *e); bool fs_open_directory (ALLEGRO_FS_ENTRY *e); ALLEGRO_FS_ENTRY * fs_read_directory (ALLEGRO_FS_ENTRY *e); bool fs_close_directory(ALLEGRO_FS_ENTRY *e); bool fs_filename_exists(const char *path); bool fs_remove_filename(const char *path); char * fs_get_current_directory(void); bool fs_change_directory(const char *path); bool fs_make_directory(const char *path); ALLEGRO_FILE * fs_open_file(ALLEGRO_FS_ENTRY *e); ~~~ ### API: al_set_fs_interface Set the [ALLEGRO_FS_INTERFACE] table for the calling thread. See also: [al_set_standard_fs_interface], [al_store_state], [al_restore_state]. ### API: al_set_standard_fs_interface Return the [ALLEGRO_FS_INTERFACE] table to the default, for the calling thread. See also: [al_set_fs_interface]. ### API: al_get_fs_interface Return a pointer to the [ALLEGRO_FS_INTERFACE] table in effect for the calling thread. See also: [al_store_state], [al_restore_state]. allegro-5.0.10/docs/src/refman/joystick.txt0000644000175000001440000001330511454330452020000 0ustar tjadenusers# Joystick routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_JOYSTICK This is an abstract data type representing a physical joystick. See also: [al_get_joystick] ## API: ALLEGRO_JOYSTICK_STATE This is a structure that is used to hold a "snapshot" of a joystick's axes and buttons at a particular instant. All fields public and read-only. struct { float axis[num_axes]; // -1.0 to 1.0 } stick[num_sticks]; int button[num_buttons]; // 0 to 32767 See also: [al_get_joystick_state] ## API: ALLEGRO_JOYFLAGS * ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input * ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input (this enum is a holdover from the old API and may be removed) See also: [al_get_joystick_stick_flags] ## API: al_install_joystick Install a joystick driver, returning true if successful. If a joystick driver was already installed, returns true immediately. See also: [al_uninstall_joystick] ## API: al_uninstall_joystick Uninstalls the active joystick driver. All outstanding [ALLEGRO_JOYSTICK] structures are invalidated. If no joystick driver was active, this function does nothing. This function is automatically called when Allegro is shut down. See also: [al_install_joystick] ## API: al_is_joystick_installed Returns true if [al_install_joystick] was called successfully. ## API: al_reconfigure_joysticks Allegro is able to cope with users connecting and disconnected joystick devices on-the-fly. On existing platforms, the joystick event source will generate an event of type `ALLEGRO_EVENT_JOYSTICK_CONFIGURATION` when a device is plugged in or unplugged. In response, you should call [al_reconfigure_joysticks]. Afterwards, the number returned by [al_get_num_joysticks] may be different, and the handles returned by [al_get_joystick] may be different or be ordered differently. All [ALLEGRO_JOYSTICK] handles remain valid, but handles for disconnected devices become inactive: their states will no longer update, and [al_get_joystick] will not return the handle. Handles for devices which remain connected will continue to represent the same devices. Previously inactive handles may become active again, being reused to represent newly connected devices. Returns true if the joystick configuration changed, otherwise returns false. It is possible that on some systems, Allegro won't be able to generate `ALLEGRO_EVENT_JOYSTICK_CONFIGURATION` events. If your game has an input configuration screen or similar, you may wish to call [al_reconfigure_joysticks] when entering that screen. See also: [al_get_joystick_event_source], [ALLEGRO_EVENT] ## API: al_get_num_joysticks Return the number of joysticks currently on the system (or potentially on the system). This number can change after [al_reconfigure_joysticks] is called, in order to support hotplugging. Returns 0 if there is no joystick driver installed. See also: [al_get_joystick], [al_get_joystick_active] ## API: al_get_joystick Get a handle for a joystick on the system. The number may be from 0 to [al_get_num_joysticks]-1. If successful a pointer to a joystick object is returned, which represents a physical device. Otherwise NULL is returned. The handle and the index are only incidentally linked. After [al_reconfigure_joysticks] is called, [al_get_joystick] may return handles in a different order, and handles which represent disconnected devices will not be returned. See also: [al_get_num_joysticks], [al_reconfigure_joysticks], [al_get_joystick_active] ## API: al_release_joystick This function currently does nothing. See also: [al_get_joystick] ## API: al_get_joystick_active Return if the joystick handle is "active", i.e. in the current configuration, the handle represents some physical device plugged into the system. [al_get_joystick] returns active handles. After reconfiguration, active handles may become inactive, and vice versa. See also: [al_reconfigure_joysticks] ## API: al_get_joystick_name Return the name of the given joystick. See also: [al_get_joystick_stick_name], [al_get_joystick_axis_name], [al_get_joystick_button_name] ## API: al_get_joystick_stick_name Return the name of the given "stick". If the stick doesn't exist, NULL is returned. See also: [al_get_joystick_axis_name], [al_get_joystick_num_sticks] ## API: al_get_joystick_axis_name Return the name of the given axis. If the axis doesn't exist, NULL is returned. Indices begin from 0. See also: [al_get_joystick_stick_name], [al_get_joystick_num_axes] ## API: al_get_joystick_button_name Return the name of the given button. If the button doesn't exist, NULL is returned. Indices begin from 0. See also: [al_get_joystick_stick_name], [al_get_joystick_axis_name], [al_get_joystick_num_buttons] ## API: al_get_joystick_stick_flags Return the flags of the given "stick". If the stick doesn't exist, NULL is returned. Indices begin from 0. See also: [ALLEGRO_JOYFLAGS] ## API: al_get_joystick_num_sticks Return the number of "sticks" on the given joystick. A stick has one or more axes. See also: [al_get_joystick_num_axes], [al_get_joystick_num_buttons] ## API: al_get_joystick_num_axes Return the number of axes on the given "stick". If the stick doesn't exist, 0 is returned. See also: [al_get_joystick_num_sticks] ## API: al_get_joystick_num_buttons Return the number of buttons on the joystick. See also: [al_get_joystick_num_sticks] ## API: al_get_joystick_state Get the current joystick state. See also: [ALLEGRO_JOYSTICK_STATE], [al_get_joystick_num_buttons], [al_get_joystick_num_axes] ## API: al_get_joystick_event_source Returns the global joystick event source. All joystick events are generated by this event source. allegro-5.0.10/docs/src/refman/display.txt0000644000175000001440000004141412110014175017577 0ustar tjadenusers# Displays These functions are declared in the main Allegro header file: #include ## Display creation ### API: ALLEGRO_DISPLAY An opaque type representing an open display or window. ### API: al_create_display Create a display, or window, with the specified dimensions. The parameters of the display are determined by the last calls to al_set_new_display\_\*. Default parameters are used if none are set explicitly. Creating a new display will automatically make it the active one, with the backbuffer selected for drawing. Returns NULL on error. Each display has a distinct OpenGL rendering context associated with it. See [al_set_target_bitmap] for the discussion about rendering contexts. See also: [al_set_new_display_flags], [al_set_new_display_option], [al_set_new_display_refresh_rate], [al_set_new_display_adapter], [al_set_window_position] ### API: al_destroy_display Destroy a display. If the target bitmap of the calling thread is tied to the display, then it implies a call to "al_set_target_bitmap(NULL);" before the display is destroyed. That special case notwithstanding, you should make sure no threads are currently targeting a bitmap which is tied to the display before you destroy it. See also: [al_set_target_bitmap] ### API: al_get_new_display_flags Get the display flags to be used when creating new displays on the calling thread. See also: [al_set_new_display_flags], [al_set_display_flag] ### API: al_set_new_display_flags Sets various flags to be used when creating new displays on the calling thread. flags is a bitfield containing any reasonable combination of the following: ALLEGRO_WINDOWED : Prefer a windowed mode. Under multi-head X (not XRandR/TwinView), the use of more than one adapter is impossible due to bugs in X and GLX. [al_create_display] will fail if more than one adapter is attempted to be used. ALLEGRO_FULLSCREEN : Prefer a fullscreen mode. Under X the use of more than one FULLSCREEN display when using multi-head X, or true Xinerama is not possible due to bugs in X and GLX, display creation will fail if more than one adapter is attempted to be used. ALLEGRO_FULLSCREEN_WINDOW : Make the window span the entire screen. Unlike ALLEGRO_FULLSCREEN this will never attempt to modify the screen resolution. Instead the pixel dimensions of the created display will be the same as the desktop. The passed width and height are only used if the window is switched out of fullscreen mode later but will be ignored initially. Under Windows and X11 a fullscreen display created with this flag will behave differently from one created with the ALLEGRO_FULLSCREEN flag - even if the ALLEGRO_FULLSCREEN display is passed the desktop dimensions. The exact difference is platform dependent, but some things which may be different is how alt-tab works, how fast you can toggle between fullscreen/windowed mode or how additional monitors behave while your display is in fullscreen mode. Additionally under X, the use of more than one adapter in multi-head mode or with true Xinerama enabled is impossible due to bugs in X/GLX, creation will fail if more than one adapter is attempted to be used. ALLEGRO_RESIZABLE : The display is resizable (only applicable if combined with ALLEGRO_WINDOWED). ALLEGRO_OPENGL : Require the driver to provide an initialized OpenGL context after returning successfully. ALLEGRO_OPENGL_3_0 : Require the driver to provide an initialized OpenGL context compatible with OpenGL version 3.0. ALLEGRO_OPENGL_FORWARD_COMPATIBLE : If this flag is set, the OpenGL context created with ALLEGRO_OPENGL_3_0 will be forward compatible *only*, meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not be supported. Currently, a display created with this flag will *not* be compatible with Allegro drawing routines; the display option ALLEGRO_COMPATIBLE_DISPLAY will be set to false. ALLEGRO_DIRECT3D : Require the driver to do rendering with Direct3D and provide a Direct3D device. ALLEGRO_FRAMELESS : Try to create a window without a frame (i.e. no border or titlebar). This usually does nothing for fullscreen modes, and even in windowed modes it depends on the underlying platform whether it is supported or not. Since: 5.0.7, 5.1.2 ALLEGRO_NOFRAME : Original name for ALLEGRO_FRAMELESS. This works with older versions of Allegro. ALLEGRO_GENERATE_EXPOSE_EVENTS : Let the display generate expose events. 0 can be used for default values. See also: [al_set_new_display_option], [al_get_display_option], [al_change_display_option] ### API: al_get_new_display_option Retrieve an extra display setting which was previously set with [al_set_new_display_option]. ### API: al_set_new_display_option Set an extra display option, to be used when creating new displays on the calling thread. Display options differ from display flags, and specify some details of the context to be created within the window itself. These mainly have no effect on Allegro itself, but you may want to specify them, for example if you want to use multisampling. The 'importance' parameter can be either: * ALLEGRO_REQUIRE - The display will not be created if the setting can not be met. * ALLEGRO_SUGGEST - If the setting is not available, the display will be created anyway. FIXME: We need a way to query the settings back from a created display. * ALLEGRO_DONTCARE - If you added a display option with one of the above two settings before, it will be removed again. Else this does nothing. The supported options are: ALLEGRO_COLOR_SIZE : This can be used to ask for a specific bit depth. For example to force a 16-bit framebuffer set this to 16. ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE : Individual color component size in bits. ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT : Together with the previous settings these can be used to specify the exact pixel layout the display should use. Normally there is no reason to use these. ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE : This can be used to define the required accumulation buffer size. ALLEGRO_STEREO : Whether the display is a stereo display. ALLEGRO_AUX_BUFFERS : Number of auxiliary buffers the display should have. ALLEGRO_DEPTH_SIZE : How many depth buffer (z-buffer) bits to use. ALLEGRO_STENCIL_SIZE : How many bits to use for the stencil buffer. ALLEGRO_SAMPLE_BUFFERS : Whether to use multisampling (1) or not (0). ALLEGRO_SAMPLES : If the above is 1, the number of samples to use per pixel. Else 0. ALLEGRO_RENDER_METHOD: : 0 if hardware acceleration is not used with this display. ALLEGRO_FLOAT_COLOR : Whether to use floating point color components. ALLEGRO_FLOAT_DEPTH : Whether to use a floating point depth buffer. ALLEGRO_SINGLE_BUFFER : Whether the display uses a single buffer (1) or another update method (0). ALLEGRO_SWAP_METHOD : If the above is 0, this is set to 1 to indicate the display is using a copying method to make the next buffer in the flip chain available, or to 2 to indicate a flipping or other method. ALLEGRO_COMPATIBLE_DISPLAY : Indicates if Allegro's graphics functions can use this display. If you request a display not useable by Allegro, you can still use for example OpenGL to draw graphics. ALLEGRO_UPDATE_DISPLAY_REGION : Set to 1 if the display is capable of updating just a region, and 0 if calling [al_update_display_region] is equivalent to [al_flip_display]. ALLEGRO_VSYNC : Set to 1 to tell the driver to wait for vsync in [al_flip_display], or to 2 to force vsync off. The default of 0 means that Allegro does not try to modify the vsync behavior so it may be on or off. Note that even in the case of 1 or 2 it is possible to override the vsync behavior in the graphics driver so you should not rely on it. ALLEGRO_MAX_BITMAP_SIZE : When queried this returns the maximum size (width as well as height) a bitmap can have for this display. Calls to [al_create_bitmap] or [al_load_bitmap] for bitmaps larger than this size will fail. It does not apply to memory bitmaps which always can have arbitrary size (but are slow for drawing). ALLEGRO_SUPPORT_NPOT_BITMAP : Set to 1 if textures used for bitmaps on this display can have a size which is not a power of two. This is mostly useful if you use Allegro to load textures as otherwise only power-of-two textures will be used internally as bitmap storage. ALLEGRO_CAN_DRAW_INTO_BITMAP : Set to 1 if you can use [al_set_target_bitmap] on bitmaps of this display to draw into them. If this is not the case software emulation will be used when drawing into display bitmaps (which can be very slow). ALLEGRO_SUPPORT_SEPARATE_ALPHA : This is set to 1 if the [al_set_separate_blender] function is supported. Otherwise the alpha parameters will be ignored. See also: [al_set_new_display_flags] ### API: al_reset_new_display_options This undoes any previous call to [al_set_new_display_option] on the calling thread. ### API: al_get_new_window_position Get the position where new non-fullscreen displays created by the calling thread will be placed. See also: [al_set_new_window_position] ### API: al_set_new_window_position Sets where the top left pixel of the client area of newly created windows (non-fullscreen) will be on screen, for displays created by the calling thread. Negative values allowed on some multihead systems. To reset to the default behaviour, pass (INT_MAX, INT_MAX). See also: [al_get_new_window_position] ### API: al_get_new_display_refresh_rate Get the requested refresh rate to be used when creating new displays on the calling thread. See also: [al_set_new_display_refresh_rate] ### API: al_set_new_display_refresh_rate Sets the refresh rate to use when creating new displays on the calling thread. If the refresh rate is not available, [al_create_display] will fail. A list of modes with refresh rates can be found with [al_get_num_display_modes] and [al_get_display_mode]. The default setting is zero (don't care). See also: [al_get_new_display_refresh_rate] ## Display operations ### API: al_get_display_event_source Retrieve the associated event source. ### API: al_get_backbuffer Return a special bitmap representing the back-buffer of the display. Care should be taken when using the backbuffer bitmap (and its sub-bitmaps) as the source bitmap (e.g as the bitmap argument to [al_draw_bitmap]). Only untransformed operations are hardware accelerated. This consists of [al_draw_bitmap] and [al_draw_bitmap_region] when the current transformation is the identity. If the tranformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the [al_draw_bitmap] and [al_draw_bitmap_region]), and then use that temporary bitmap as the source bitmap. ### API: al_flip_display Copies or updates the front and back buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back buffer bitmap remain valid and retain their semantics as the back buffer, although the contents may have changed. Several display options change how this function behaves: - With ALLEGRO_SINGLE_BUFFER, no flipping is done. You still have to call this function to display graphics, depending on how the used graphics system works. - The ALLEGRO_SWAP_METHOD option may have additional information about what kind of operation is used internally to flip the front and back buffers. - If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. If ALLEGRO_VSYNC is 2, this function will not wait for vsync. With many drivers the vsync behavior is controlled by the user and not the application, and ALLEGRO_VSYNC will not be set; in this case [al_flip_display] will wait for vsync depending on the settings set in the system's graphics preferences. See also: [al_set_new_display_flags], [al_set_new_display_option] ### API: al_update_display_region Does the same as [al_flip_display], but tries to update only the specified region. With many drivers this is not possible, but for some it can improve performance. The ALLEGRO_UPDATE_DISPLAY_REGION option (see [al_get_display_option]) will specify the behavior of this function in the display. See also: [al_flip_display], [al_get_display_option] ### API: al_wait_for_vsync Wait for the beginning of a vertical retrace. Some driver/card/monitor combinations may not be capable of this. Note how [al_flip_display] usually already waits for the vertical retrace, so unless you are doing something special, there is no reason to call this function. Returns false if not possible, true if successful. See also: [al_flip_display] ## Display size and position ### API: al_get_display_width Gets the width of the display. This is like SCREEN_W in Allegro 4.x. See also: [al_get_display_height] ### API: al_get_display_height Gets the height of the display. This is like SCREEN_H in Allegro 4.x. See also: [al_get_display_width] ### API: al_resize_display Resize the display. Returns true on success, or false on error. This works on both fullscreen and windowed displays, regardless of the ALLEGRO_RESIZABLE flag. Adjusts the clipping rectangle to the full size of the backbuffer. See also: [al_acknowledge_resize] ### API: al_acknowledge_resize When the user receives a resize event from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display. Returns true on success. Adjusts the clipping rectangle to the full size of the backbuffer. Note that a resize event may be outdated by the time you acknowledge it; there could be further resize events generated in the meantime. See also: [al_resize_display], [ALLEGRO_EVENT] ### API: al_get_window_position Gets the position of a non-fullscreen display. See also: [al_set_window_position] ### API: al_set_window_position Sets the position on screen of a non-fullscreen display. See also: [al_get_window_position] ## Display settings ### API: al_get_display_flags Gets the flags of the display. In addition to the flags set for the display at creation time with [al_set_new_display_flags] it can also have the ALLEGRO_MINIMIZED flag set, indicating that the window is currently minimized. This flag is very platform-dependent as even a minimized application may still render a preview version so normally you should not care whether it is minimized or not. See also: [al_set_new_display_flags], [al_set_display_flag] ### API: al_set_display_flag Enable or disable one of the display flags. The flags are the same as for [al_set_new_display_flags]. The only flags that can be changed after creation are: - ALLEGRO_FULLSCREEN_WINDOW - ALLEGRO_FRAMELESS Returns true if the driver supports toggling the specified flag else false. You can use [al_get_display_flags] to query whether the given display property actually changed. Since: 5.0.7, 5.1.2 See also: [al_set_new_display_flags], [al_get_display_flags] ### API: al_toggle_display_flag Deprecated synonym for [al_set_display_flag]. ### API: al_get_display_option Return an extra display setting of the display. See also: [al_set_new_display_option] ### API: al_get_display_format Gets the pixel format of the display. See also: [ALLEGRO_PIXEL_FORMAT] ### API: al_get_display_refresh_rate Gets the refresh rate of the display. See also: [al_set_new_display_refresh_rate] ### API: al_set_window_title Set the title on a display. See also: [al_set_display_icon], [al_set_display_icons] ### API: al_set_display_icon Changes the icon associated with the display (window). Same as [al_set_display_icons] with one icon. See also: [al_set_display_icons], [al_set_window_title] ### API: al_set_display_icons Changes the icons associated with the display (window). Multiple icons can be provided for use in different contexts, e.g. window frame, taskbar, alt-tab popup. The number of icons must be at least one. > *Note:* If the underlying OS requires an icon of a size not provided then one of the bitmaps will be scaled up or down to the required size. The choice of bitmap is implementation dependent. Since: 5.0.9, 5.1.5 See also: [al_set_display_icon], [al_set_window_title] ## Screensaver ### API: al_inhibit_screensaver This function allows the user to stop the system screensaver from starting up if true is passed, or resets the system back to the default state (the state at program start) if false is passed. It returns true if the state was set successfully, otherwise false. allegro-5.0.10/docs/src/refman/config.txt0000644000175000001440000001426111617370211017406 0ustar tjadenusers# Configuration files These functions are declared in the main Allegro header file: #include Allegro supports reading and writing of configuration files with a simple, INI file-like format. A configuration file consists of key-value pairs separated by newlines. Keys are separated from values by an equals sign (`=`). All whitespace before the key, after the value and immediately adjacent to the equals sign is ignored. Keys and values may have whitespace characters within them. Keys do not need to be unique, but all but the last one are ignored. The hash (`#`) character is used a comment when it is the first non-whitespace character on the line. All characters following that character are ignored to the end of the line. The hash character anywhere else on the line has no special significance. Key-value pairs can be optionally grouped into sections, which are declared by surrounding a section name with square brackets (`[` and `]`) on a single line. Whitespace before the opening bracket is ignored. All characters after the trailing bracket are also ignored. All key-value pairs that follow a section declaration belong to the last declared section. Key-value pairs that don't follow any section declarations belong to the global section. Sections do not nest. Here is an example configuration file: # Monster description monster name = Allegro Developer [weapon 0] damage = 443 [weapon 1] damage = 503 It can then be accessed like this (make sure to check for errors in an actual program): ALLEGRO_CONFIG* cfg = al_load_config_file("test.cfg"); printf("%s\n", al_get_config_value(cfg, "", "monster name")); /* Prints: Allegro Developer */ printf("%s\n", al_get_config_value(cfg, "weapon 0", "damage")); /* Prints: 443 */ printf("%s\n", al_get_config_value(cfg, "weapon 1", "damage")); /* Prints: 503 */ al_destroy_config(cfg); ## API: ALLEGRO_CONFIG An abstract configuration structure. ## API: al_create_config Create an empty configuration structure. See also: [al_load_config_file], [al_destroy_config] ## API: al_destroy_config Free the resources used by a configuration structure. Does nothing if passed NULL. See also: [al_create_config], [al_load_config_file] ## API: al_load_config_file Read a configuration file from disk. Returns NULL on error. The configuration structure should be destroyed with [al_destroy_config]. See also: [al_load_config_file_f], [al_save_config_file] ## API: al_load_config_file_f Read a configuration file from an already open file. Returns NULL on error. The configuration structure should be destroyed with [al_destroy_config]. The file remains open afterwards. See also: [al_load_config_file] ## API: al_save_config_file Write out a configuration file to disk. Returns true on success, false on error. See also: [al_save_config_file_f], [al_load_config_file] ## API: al_save_config_file_f Write out a configuration file to an already open file. Returns true on success, false on error. The file remains open afterwards. See also: [al_save_config_file] ## API: al_add_config_section Add a section to a configuration structure with the given name. If the section already exists then nothing happens. ## API: al_add_config_comment Add a comment in a section of a configuration. If the section doesn't yet exist, it will be created. The section can be NULL or "" for the global section. The comment may or may not begin with a hash character. Any newlines in the comment string will be replaced by space characters. See also: [al_add_config_section] ## API: al_get_config_value Gets a pointer to an internal character buffer that will only remain valid as long as the ALLEGRO_CONFIG structure is not destroyed. Copy the value if you need a copy. The section can be NULL or "" for the global section. Returns NULL if the section or key do not exist. See also: [al_set_config_value] ## API: al_set_config_value Set a value in a section of a configuration. If the section doesn't yet exist, it will be created. If a value already existed for the given key, it will be overwritten. The section can be NULL or "" for the global section. For consistency with the on-disk format of config files, any leading and trailing whitespace will be stripped from the value. If you have significant whitespace you wish to preserve, you should add your own quote characters and remove them when reading the values back in. See also: [al_get_config_value] ## API: al_get_first_config_section Returns the name of the first section in the given config file. Usually this will return an empty string for the global section. The `iterator` parameter will receive an opaque iterator which is used by [al_get_next_config_section] to iterate over the remaining sections. The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG. See also: [al_get_next_config_section] ## API: al_get_next_config_section Returns the name of the next section in the given config file or NULL if there are no more sections. The `iterator` must have been obtained with [al_get_first_config_section] first. See also: [al_get_first_config_section] ## API: al_get_first_config_entry Returns the name of the first key in the given section in the given config or NULL if the section is empty. The `iterator` works like the one for [al_get_first_config_section]. The returned string and the iterator are only valid as long as no change is made to the passed [ALLEGRO_CONFIG]. See also: [al_get_next_config_entry] ## API: al_get_next_config_entry Returns the next key for the iterator obtained by [al_get_first_config_entry]. The `iterator` works like the one for [al_get_next_config_section]. ## API: al_merge_config Merge two configuration structures, and return the result as a new configuration. Values in configuration 'cfg2' override those in 'cfg1'. Neither of the input configuration structures are modified. Comments from 'cfg2' are not retained. See also: [al_merge_config_into] ## API: al_merge_config_into Merge one configuration structure into another. Values in configuration 'add' override those in 'master'. 'master' is modified. Comments from 'add' are not retained. See also: [al_merge_config] allegro-5.0.10/docs/src/refman/monitor.txt0000644000175000001440000000326612057104470017634 0ustar tjadenusers# Monitors These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_MONITOR_INFO Describes a monitors size and position relative to other monitors. x1, y1 will be 0, 0 on the primary display. Other monitors can have negative values if they are to the left or above the primary display. typedef struct ALLEGRO_MONITOR_INFO { int x1; int y1; int x2; int y2; } ALLEGRO_MONITOR_INFO; See also: [al_get_monitor_info] ## API: al_get_new_display_adapter Gets the video adapter index where new displays will be created by the calling thread, if previously set with [al_set_new_display_adapter]. Otherwise returns `ALLEGRO_DEFAULT_DISPLAY_ADAPTER`. See also: [al_set_new_display_adapter] ## API: al_set_new_display_adapter Sets the adapter to use for new displays created by the calling thread. The adapter has a monitor attached to it. Information about the monitor can be gotten using [al_get_num_video_adapters] and [al_get_monitor_info]. To return to the default behaviour, pass `ALLEGRO_DEFAULT_DISPLAY_ADAPTER`. See also: [al_get_num_video_adapters], [al_get_monitor_info] ## API: al_get_monitor_info Get information about a monitor's position on the desktop. adapter is a number from 0 to al_get_num_video_adapters()-1. Returns true on success, false on failure. See also: [ALLEGRO_MONITOR_INFO], [al_get_num_video_adapters] ## API: al_get_num_video_adapters Get the number of video "adapters" attached to the computer. Each video card attached to the computer counts as one or more adapters. An adapter is thus really a video port that can have a monitor connected to it. See also: [al_get_monitor_info] allegro-5.0.10/docs/src/refman/file.txt0000644000175000001440000003520312125202174017054 0ustar tjadenusers# File I/O These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_FILE An opaque object representing an open file. This could be a real file on disk or a virtual file. ## API: ALLEGRO_FILE_INTERFACE A structure containing function pointers to handle a type of "file", real or virtual. See the full discussion in [al_set_new_file_interface]. The fields are: void* (*fi_fopen)(const char *path, const char *mode); void (*fi_fclose)(ALLEGRO_FILE *f); size_t (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size); size_t (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size); bool (*fi_fflush)(ALLEGRO_FILE *f); int64_t (*fi_ftell)(ALLEGRO_FILE *f); bool (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence); bool (*fi_feof)(ALLEGRO_FILE *f); bool (*fi_ferror)(ALLEGRO_FILE *f); void (*fi_fclearerr)(ALLEGRO_FILE *f); int (*fi_fungetc)(ALLEGRO_FILE *f, int c); off_t (*fi_fsize)(ALLEGRO_FILE *f); The fi_open function must allocate memory for whatever userdata structure it needs. The pointer to that memory must be returned; it will then be associated with the file. The other functions can access that data by calling [al_get_file_userdata] on the file handle. If fi_open returns NULL then [al_fopen] will also return NULL. The fi_fclose function must clean up and free the userdata, but Allegro will free the [ALLEGRO_FILE] handle. If fi_fungetc is NULL, then Allegro's default implementation of a 16 char long buffer will be used. ## API: ALLEGRO_SEEK * ALLEGRO_SEEK_SET - seek relative to beginning of file * ALLEGRO_SEEK_CUR - seek relative to current file position * ALLEGRO_SEEK_END - seek relative to end of file See also: [al_fseek] ## API: al_fopen Creates and opens a file (real or virtual) given the path and mode. The current file interface is used to open the file. Parameters: * path - path to the file to open * mode - access mode to open the file in ("r", "w", etc.) Depending on the stream type and the mode string, files may be opened in "text" mode. The handling of newlines is particularly important. For example, using the default stdio-based streams on DOS and Windows platforms, where the native end-of-line terminators are CR+LF sequences, a call to [al_fgetc] may return just one character ('\\n') where there were two bytes (CR+LF) in the file. When writing out '\\n', two bytes would be written instead. (As an aside, '\\n' is not defined to be equal to LF either.) Newline translations can be useful for text files but is disastrous for binary files. To avoid this behaviour you need to open file streams in binary mode by using a mode argument containing a "b", e.g. "rb", "wb". Returns a file handle on success, or NULL on error. See also: [al_set_new_file_interface], [al_fclose]. ## API: al_fopen_interface Opens a file using the specified interface, instead of the interface set with [al_set_new_file_interface]. See also: [al_fopen] ## API: al_fopen_slice Opens a slice (subset) of an already open random access file as if it were a stand alone file. While the slice is open, the parent file handle must not be used in any way. The slice is opened at the current location of the parent file, up through `initial_size` bytes. The `initial_size` may be any non-negative integer that will not exceed the bounds of the parent file. Seeking with `ALLEGRO_SEEK_SET` will be relative to this starting location. `ALLEGRO_SEEK_END` will be relative to the starting location plus the size of the slice. The mode can be any combination of: * r: read access * w: write access * e: expandable For example, a mode of "rw" indicates the file can be read and written. (Note that this is slightly different from the stdio modes.) Keep in mind that the parent file must support random access and be open in normal write mode (not append) for the slice to work in a well defined way. If the slice is marked as expandable, then reads and writes can happen after the initial end point, and the slice will grow accordingly. Otherwise, all activity is restricted to the initial size of the slice. A slice must be closed with [al_fclose]. The parent file will then be positioned immediately after the end of the slice. Since: 5.0.6, 5.1.0 See also: [al_fopen] ## API: al_fclose Close the given file, writing any buffered output data (if any). ## API: al_fread Read 'size' bytes into the buffer pointed to by 'ptr', from the given file. Returns the number of bytes actually read. If an error occurs, or the end-of-file is reached, the return value is a short byte count (or zero). al_fread() does not distinguish between EOF and other errors. Use [al_feof] and [al_ferror] to determine which occurred. See also: [al_fgetc], [al_fread16be], [al_fread16le], [al_fread32be], [al_fread32le] ## API: al_fwrite Write 'size' bytes from the buffer pointed to by 'ptr' into the given file. Returns the number of bytes actually written. If an error occurs, the return value is a short byte count (or zero). See also: [al_fputc], [al_fputs], [al_fwrite16be], [al_fwrite16le], [al_fwrite32be], [al_fwrite32le] ## API: al_fflush Flush any pending writes to the given file. Returns true on success, false otherwise. errno is set to indicate the error. See also: [al_get_errno] ## API: al_ftell Returns the current position in the given file, or -1 on error. errno is set to indicate the error. On some platforms this function may not support large files. See also: [al_fseek], [al_get_errno] ## API: al_fseek Set the current position of the given file to a position relative to that specified by 'whence', plus 'offset' number of bytes. 'whence' can be: * ALLEGRO_SEEK_SET - seek relative to beginning of file * ALLEGRO_SEEK_CUR - seek relative to current file position * ALLEGRO_SEEK_END - seek relative to end of file Returns true on success, false on failure. errno is set to indicate the error. After a successful seek, the end-of-file indicator is cleared and all pushback bytes are forgotten. On some platforms this function may not support large files. See also: [al_ftell], [al_get_errno] ## API: al_feof Returns true if the end-of-file indicator has been set on the file, i.e. we have attempted to read *past* the end of the file. This does *not* return true if we simply are at the end of the file. The following code correctly reads two bytes, even when the file contains exactly two bytes: int b1 = al_fgetc(f); int b2 = al_fgetc(f); if (al_feof(f)) { /* At least one byte was unsuccessfully read. */ report_error(); } See also: [al_ferror], [al_fclearerr] ## API: al_ferror Returns true if the error indicator is set on the given file, i.e. there was some sort of previous error. See also: [al_feof], [al_fclearerr] ## API: al_fclearerr Clear the error indicator for the given file. The standard I/O backend also clears the end-of-file indicator, and other backends *should* try to do this. However, they may not if it would require too much effort (e.g. PhysicsFS backend), so your code should not rely on it if you need your code to be portable to other backends. See also: [al_ferror], [al_feof] ## API: al_fungetc Ungets a single byte from a file. Pushed-back bytes are not written to the file, only made available for subsequent reads, in reverse order. The number of pushbacks depends on the backend. The standard I/O backend only guarantees a single pushback; this depends on the libc implementation. For backends that follow the standard behavior, the pushback buffer will be cleared after any seeking or writing; also calls to [al_fseek] and [al_ftell] are relative to the number of pushbacks. If a pushback causes the position to become negative, the behavior of [al_fseek] and [al_ftell] are undefined. See also: [al_fgetc], [al_get_errno] ## API: al_fsize Return the size of the file, if it can be determined, or -1 otherwise. ## API: al_fgetc Read and return next byte in the given file. Returns EOF on end of file or if an error occurred. See also: [al_fungetc] ## API: al_fputc Write a single byte to the given file. The byte written is the value of c cast to an unsigned char. Parameters: * c - byte value to write * f - file to write to Returns the written byte (cast back to an int) on success, or EOF on error. ## API: al_fread16le Reads a 16-bit word in little-endian format (LSB first). On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use [al_feof] to check if the end of the file was reached prematurely, or [al_ferror] to check if an error occurred. See also: [al_fread16be] ## API: al_fread16be Reads a 16-bit word in big-endian format (MSB first). On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use [al_feof] to check if the end of the file was reached prematurely, or [al_ferror] to check if an error occurred. See also: [al_fread16le] ## API: al_fwrite16le Writes a 16-bit word in little-endian format (LSB first). Returns the number of bytes written: 2 on success, less than 2 on an error. See also: [al_fwrite16be] ## API: al_fwrite16be Writes a 16-bit word in big-endian format (MSB first). Returns the number of bytes written: 2 on success, less than 2 on an error. See also: [al_fwrite16le] ## API: al_fread32le Reads a 32-bit word in little-endian format (LSB first). On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use [al_feof] to check if the end of the file was reached prematurely, or [al_ferror] to check if an error occurred. See also: [al_fread32be] ## API: al_fread32be Read a 32-bit word in big-endian format (MSB first). On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use [al_feof] to check if the end of the file was reached prematurely, or [al_ferror] to check if an error occurred. See also: [al_fread32le] ## API: al_fwrite32le Writes a 32-bit word in little-endian format (LSB first). Returns the number of bytes written: 4 on success, less than 4 on an error. See also: [al_fwrite32be] ## API: al_fwrite32be Writes a 32-bit word in big-endian format (MSB first). Returns the number of bytes written: 4 on success, less than 4 on an error. See also: [al_fwrite32le] ## API: al_fgets Read a string of bytes terminated with a newline or end-of-file into the buffer given. The line terminator(s), if any, are included in the returned string. A maximum of max-1 bytes are read, with one byte being reserved for a NUL terminator. Parameters: * f - file to read from * buf - buffer to fill * max - maximum size of buffer Returns the pointer to buf on success. Returns NULL if an error occurred or if the end of file was reached without reading any bytes. See [al_fopen] about translations of end-of-line characters. See also: [al_fget_ustr] ## API: al_fget_ustr Read a string of bytes terminated with a newline or end-of-file. The line terminator(s), if any, are included in the returned string. On success returns a pointer to a new ALLEGRO_USTR structure. This must be freed eventually with [al_ustr_free]. Returns NULL if an error occurred or if the end of file was reached without reading any bytes. See [al_fopen] about translations of end-of-line characters. See also: [al_fgetc], [al_fgets] ## API: al_fputs Writes a string to file. Apart from the return value, this is equivalent to: al_fwrite(f, p, strlen(p)); Parameters: * f - file handle to write to * p - string to write Returns a non-negative integer on success, EOF on error. Note: depending on the stream type and the mode passed to [al_fopen], newline characters in the string may or may not be automatically translated to native end-of-line sequences, e.g. CR/LF instead of LF. See also: [al_fwrite] ## Standard I/O specific routines ### API: al_fopen_fd Create an [ALLEGRO_FILE] object that operates on an open file descriptor using stdio routines. See the documentation of fdopen() for a description of the 'mode' argument. Returns an ALLEGRO_FILE object on success or NULL on an error. On an error, the Allegro errno will be set and the file descriptor will not be closed. The file descriptor will be closed by [al_fclose] so you should not call close() on it. See also: [al_fopen] ### API: al_make_temp_file Make a temporary randomly named file given a filename 'template'. 'template' is a string giving the format of the generated filename and should include one or more capital Xs. The Xs are replaced with random alphanumeric characters, produced using a simple pseudo-random number generator only. There should be no path separators. If 'ret_path' is not NULL, the address it points to will be set to point to a new path structure with the name of the temporary file. Returns the opened [ALLEGRO_FILE] on success, NULL on failure. ## Alternative file streams By default, the Allegro file I/O routines use the C library I/O routines, hence work with files on the local filesystem, but can be overridden so that you can read and write to other streams. For example, you can work with block of memory or sub-files inside .zip files. There are two ways to get an [ALLEGRO_FILE] that doesn't use stdio. An addon library may provide a function that returns a new ALLEGRO_FILE directly, after which, all al_f* calls on that object will use overridden functions for that type of stream. Alternatively, [al_set_new_file_interface] changes which function will handle the following [al_fopen] calls for the current thread. ### API: al_set_new_file_interface Set the [ALLEGRO_FILE_INTERFACE] table for the calling thread. This will change the handler for later calls to [al_fopen]. See also: [al_set_standard_file_interface], [al_store_state], [al_restore_state]. ### API: al_set_standard_file_interface Set the [ALLEGRO_FILE_INTERFACE] table to the default, for the calling thread. This will change the handler for later calls to [al_fopen]. See also: [al_set_new_file_interface] ### API: al_get_new_file_interface Return a pointer to the [ALLEGRO_FILE_INTERFACE] table in effect for the calling thread. See also: [al_store_state], [al_restore_state]. ### API: al_create_file_handle Creates an empty, opened file handle with some abstract user data. This allows custom interfaces to extend the [ALLEGRO_FILE] struct with their own data. You should close the handle with the standard [al_fclose] function when you are finished with it. See also: [al_fopen], [al_fclose], [al_set_new_file_interface] ### API: al_get_file_userdata Returns a pointer to the custom userdata that is attached to the file handle. This is intended to be used by functions that extend [ALLEGRO_FILE_INTERFACE]. allegro-5.0.10/docs/src/refman/image.txt0000644000175000001440000000170211412246207017217 0ustar tjadenusers# Image I/O addon These functions are declared in the following header file. Link with allegro_image. #include ## API: al_init_image_addon Initializes the image addon. This registers bitmap format handlers for [al_load_bitmap], [al_load_bitmap_f], [al_save_bitmap], [al_save_bitmap_f]. The following types are built into the Allegro image addon and guaranteed to be available: BMP, PCX, TGA. Every platform also supports JPEG and PNG via external dependencies. Other formats may be available depending on the operating system and installed libraries, but are not guaranteed and should not be assumed to be universally available. ## API: al_shutdown_image_addon Shut down the image addon. This is done automatically at program exit, but can be called any time the user wishes as well. ## API: al_get_allegro_image_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/fixed.txt0000644000175000001440000003352611357547112017254 0ustar tjadenusers# Fixed point math routines These functions are declared in the main Allegro header file: #include ## API: al_fixed A fixed point number. Allegro provides some routines for working with fixed point numbers, and defines the type `al_fixed` to be a signed 32-bit integer. The high word is used for the integer part and the low word for the fraction, giving a range of -32768 to 32767 and an accuracy of about four or five decimal places. Fixed point numbers can be assigned, compared, added, subtracted, negated and shifted (for multiplying or dividing by powers of two) using the normal integer operators, but you should take care to use the appropriate conversion routines when mixing fixed point with integer or floating point values. Writing `fixed_point_1 + fixed_point_2` is OK, but `fixed_point + integer` is not. The only advantage of fixed point math routines is that you don't require a floating point coprocessor to use them. This was great in the time period of i386 and i486 machines, but stopped being so useful with the coming of the Pentium class of processors. From Pentium onwards, CPUs have increased their strength in floating point operations, equaling or even surpassing integer math performance. Depending on the type of operations your program may need, using floating point types may be faster than fixed types if you are targeting a specific machine class. Many embedded processors have no FPUs so fixed point maths can be useful there. ## API: al_itofix Converts an integer to fixed point. This is the same thing as x<<16. Remember that overflows (trying to convert an integer greater than 32767) and underflows (trying to convert an integer lesser than -32768) are not detected even in debug builds! The values simply "wrap around". Example: ~~~~ al_fixed number; /* This conversion is OK. */ number = al_itofix(100); assert(al_fixtoi(number) == 100); number = al_itofix(64000); /* This check will fail in debug builds. */ assert(al_fixtoi(number) == 64000); ~~~~ Return value: Returns the value of the integer converted to fixed point ignoring overflows. See also: [al_fixtoi], [al_ftofix], [al_fixtof]. ## API: al_fixtoi Converts fixed point to integer, rounding as required to the nearest integer. Example: ~~~~ int result; /* This will put 33 into `result'. */ result = al_fixtoi(al_itofix(100) / 3); /* But this will round up to 17. */ result = al_fixtoi(al_itofix(100) / 6); ~~~~ See also: [al_itofix], [al_ftofix], [al_fixtof], [al_fixfloor], [al_fixceil]. ## API: al_fixfloor Returns the greatest integer not greater than x. That is, it rounds towards negative infinity. Example: ~~~~ int result; /* This will put 33 into `result'. */ result = al_fixfloor(al_itofix(100) / 3); /* And this will round down to 16. */ result = al_fixfloor(al_itofix(100) / 6); ~~~~ See also: [al_fixtoi], [al_fixceil]. ## API: al_fixceil Returns the smallest integer not less than x. That is, it rounds towards positive infinity. Example: ~~~~ int result; /* This will put 34 into `result'. */ result = al_fixceil(al_itofix(100) / 3); /* This will round up to 17. */ result = al_fixceil(al_itofix(100) / 6); ~~~~ See also: [al_fixtoi], [al_fixfloor]. ## API: al_ftofix Converts a floating point value to fixed point. Unlike [al_itofix], this function clamps values which could overflow the type conversion, setting Allegro's errno to ERANGE in the process if this happens. Example: ~~~~ al_fixed number; number = al_itofix(-40000); assert(al_fixfloor(number) == -32768); number = al_itofix(64000); assert(al_fixfloor(number) == 32767); assert(!al_get_errno()); /* This will fail. */ ~~~~ Return value: Returns the value of the floating point value converted to fixed point clamping overflows (and setting Allegro's errno). See also: [al_fixtof], [al_itofix], [al_fixtoi], [al_get_errno] ## API: al_fixtof Converts fixed point to floating point. Example: ~~~~ float result; /* This will put 33.33333 into `result'. */ result = al_fixtof(al_itofix(100) / 3); /* This will put 16.66666 into `result'. */ result = al_fixtof(al_itofix(100) / 6); ~~~~ See also: [al_ftofix], [al_itofix], [al_fixtoi]. ## API: al_fixmul A fixed point value can be multiplied or divided by an integer with the normal `*` and `/` operators. To multiply two fixed point values, though, you must use this function. If an overflow occurs, Allegro's errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for overflow you should call `al_set_errno(0)` before calling [al_fixmul]. Example: ~~~~ al_fixed result; /* This will put 30000 into `result'. */ result = al_fixmul(al_itofix(10), al_itofix(3000)); /* But this overflows, and sets errno. */ result = al_fixmul(al_itofix(100), al_itofix(3000)); assert(!al_get_errno()); ~~~~ Return value: Returns the clamped result of multiplying `x` by `y`, setting Allegro's errno to ERANGE if there was an overflow. See also: [al_fixadd], [al_fixsub], [al_fixdiv], [al_get_errno]. ## API: al_fixdiv A fixed point value can be divided by an integer with the normal `/` operator. To divide two fixed point values, though, you must use this function. If a division by zero occurs, Allegro's errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for division by zero you should call `al_set_errno(0)` before calling [al_fixdiv]. Example: ~~~~ al_fixed result; /* This will put 0.06060 `result'. */ result = al_fixdiv(al_itofix(2), al_itofix(33)); /* This will put 0 into `result'. */ result = al_fixdiv(0, al_itofix(-30)); /* Sets errno and puts -32768 into `result'. */ result = al_fixdiv(al_itofix(-100), al_itofix(0)); assert(!al_get_errno()); /* This will fail. */ ~~~~ Return value: Returns the result of dividing `x` by `y`. If `y` is zero, returns the maximum possible fixed point value and sets Allegro's errno to ERANGE. See also: [al_fixadd], [al_fixsub], [al_fixmul], [al_get_errno]. ## API: al_fixadd Although fixed point numbers can be added with the normal `+` integer operator, that doesn't provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro's errno and clamp the result, rather than just letting it wrap. Example: ~~~~ al_fixed result; /* This will put 5035 into `result'. */ result = al_fixadd(al_itofix(5000), al_itofix(35)); /* Sets errno and puts -32768 into `result'. */ result = al_fixadd(al_itofix(-31000), al_itofix(-3000)); assert(!al_get_errno()); /* This will fail. */ ~~~~ Return value: Returns the clamped result of adding `x` to `y`, setting Allegro's errno to ERANGE if there was an overflow. See also: [al_fixsub], [al_fixmul], [al_fixdiv]. ## API: al_fixsub Although fixed point numbers can be subtracted with the normal `-` integer operator, that doesn't provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro's errno and clamp the result, rather than just letting it wrap. Example: ~~~~ al_fixed result; /* This will put 4965 into `result'. */ result = al_fixsub(al_itofix(5000), al_itofix(35)); /* Sets errno and puts -32768 into `result'. */ result = al_fixsub(al_itofix(-31000), al_itofix(3000)); assert(!al_get_errno()); /* This will fail. */ ~~~~ Return value: Returns the clamped result of subtracting `y` from `x`, setting Allegro's errno to ERANGE if there was an overflow. See also: [al_fixadd], [al_fixmul], [al_fixdiv], [al_get_errno]. ## Fixed point trig The fixed point square root, sin, cos, tan, inverse sin, and inverse cos functions are implemented using lookup tables, which are very fast but not particularly accurate. At the moment the inverse tan uses an iterative search on the tan table, so it is a lot slower than the others. On machines with good floating point processors using these functions could be slower Always profile your code. Angles are represented in a binary format with 256 equal to a full circle, 64 being a right angle and so on. This has the advantage that a simple bitwise 'and' can be used to keep the angle within the range zero to a full circle. ### API: al_fixtorad_r This constant gives a ratio which can be used to convert a fixed point number in binary angle format to a fixed point number in radians. Example: ~~~~ al_fixed rad_angle, binary_angle; /* Set the binary angle to 90 degrees. */ binary_angle = 64; /* Now convert to radians (about 1.57). */ rad_angle = al_fixmul(binary_angle, al_fixtorad_r); ~~~~ See also: [al_fixmul], [al_radtofix_r]. ### API: al_radtofix_r This constant gives a ratio which can be used to convert a fixed point number in radians to a fixed point number in binary angle format. Example: ~~~~ al_fixed rad_angle, binary_angle; ... binary_angle = al_fixmul(rad_angle, radtofix_r); ~~~~ See also: [al_fixmul], [al_fixtorad_r]. ### API: al_fixsin This function finds the sine of a value using a lookup table. The input value must be a fixed point binary angle. Example: ~~~~ al_fixed angle; int result; /* Set the binary angle to 90 degrees. */ angle = al_itofix(64); /* The sine of 90 degrees is one. */ result = al_fixtoi(al_fixsin(angle)); assert(result == 1); ~~~~ Return value: Returns the sine of a fixed point binary format angle. The return value will be in radians. ### API: al_fixcos This function finds the cosine of a value using a lookup table. The input value must be a fixed point binary angle. Example: ~~~~ al_fixed angle; float result; /* Set the binary angle to 45 degrees. */ angle = al_itofix(32); /* The cosine of 45 degrees is about 0.7071. */ result = al_fixtof(al_fixcos(angle)); assert(result > 0.7 && result < 0.71); ~~~~ Return value: Returns the cosine of a fixed point binary format angle. The return value will be in radians. ### API: al_fixtan This function finds the tangent of a value using a lookup table. The input value must be a fixed point binary angle. Example: ~~~~ al_fixed angle, res_a, res_b; float dif; angle = al_itofix(37); /* Prove that tan(angle) == sin(angle) / cos(angle). */ res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle)); res_b = al_fixtan(angle); dif = al_fixtof(al_fixsub(res_a, res_b)); printf("Precision error: %f\n", dif); ~~~~ Return value: Returns the tangent of a fixed point binary format angle. The return value will be in radians. ### API: al_fixasin This function finds the inverse sine of a value using a lookup table. The input value must be a fixed point value. The inverse sine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro's errno to EDOM and return zero. Example: ~~~~ float angle; al_fixed val; /* Sets `val' to a right binary angle (64). */ val = al_fixasin(al_itofix(1)); /* Sets `angle' to 0.2405. */ angle = al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)), al_fixtorad_r)); /* This will trigger the assert. */ val = al_fixasin(al_ftofix(-1.09)); assert(!al_get_errno()); ~~~~ Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of the range. All return values of this function will be in the range -64 to 64. ### API: al_fixacos This function finds the inverse cosine of a value using a lookup table. The input value must be a fixed point radian. The inverse cosine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro's errno to EDOM and return zero. Example: ~~~~ al_fixed result; /* Sets result to binary angle 128. */ result = al_fixacos(al_itofix(-1)); ~~~~ Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range. All return values of this function will be in the range 0 to 128. ### API: al_fixatan This function finds the inverse tangent of a value using a lookup table. The input value must be a fixed point radian. The inverse tangent is the value whose tangent is `x`. Example: ~~~~ al_fixed result; /* Sets result to binary angle 13. */ result = al_fixatan(al_ftofix(0.326)); ~~~~ Return value: Returns the inverse tangent of a fixed point value, measured as a fixed point binary format angle. ### API: al_fixatan2 This is a fixed point version of the libc atan2() routine. It computes the arc tangent of `y / x`, but the signs of both arguments are used to determine the quadrant of the result, and `x` is permitted to be zero. This function is useful to convert Cartesian coordinates to polar coordinates. Example: ~~~~ al_fixed result; /* Sets `result' to binary angle 64. */ result = al_fixatan2(al_itofix(1), 0); /* Sets `result' to binary angle -109. */ result = al_fixatan2(al_itofix(-1), al_itofix(-2)); /* Fails the assert. */ result = al_fixatan2(0, 0); assert(!al_get_errno()); ~~~~ Return value: Returns the arc tangent of `y / x` in fixed point binary format angle, from -128 to 128. If both `x` and `y` are zero, returns zero and sets Allegro's errno to EDOM. ### API: al_fixsqrt This finds out the non negative square root of `x`. If `x` is negative, Allegro's errno is set to EDOM and the function returns zero. ### API: al_fixhypot Fixed point hypotenuse (returns the square root of `x*x + y*y`). This should be better than calculating the formula yourself manually, since the error is much smaller. allegro-5.0.10/docs/src/refman/physfs.txt0000644000175000001440000000252511341166564017465 0ustar tjadenusers# PhysicsFS integration PhysicsFS is a library to provide abstract access to various archives. See for more information. This addon makes it possible to read and write files (on disk or inside archives) using PhysicsFS, through Allegro's file I/O API. For example, that means you can use the Image I/O addon to load images from .zip files. You must set up PhysicsFS through its own API. When you want to open an ALLEGRO_FILE using PhysicsFS, first call [al_set_physfs_file_interface], then [al_fopen] or another function that calls [al_fopen]. These functions are declared in the following header file. Link with allegro_physfs. #include ## API: al_set_physfs_file_interface After calling this, subsequent calls to [al_fopen] will be handled by PHYSFS_open(). Operations on the files returned by [al_fopen] will then be performed through PhysicsFS. At the same time, all filesystem functions like [al_read_directory] or [al_create_fs_entry] will use PhysicsFS. This functions only affects the thread it was called from. To remember and restore another file I/O backend, you can use [al_store_state]/[al_restore_state]. See also: [al_set_new_file_interface]. ## API: al_get_allegro_physfs_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/timer.txt0000644000175000001440000000574112025010163017253 0ustar tjadenusers# Timer routines These functions are declared in the main Allegro header file: #include ## API: ALLEGRO_TIMER This is an abstract data type representing a timer object. ## API: ALLEGRO_USECS_TO_SECS Convert microseconds to seconds. ## API: ALLEGRO_MSECS_TO_SECS Convert milliseconds to seconds. ## API: ALLEGRO_BPS_TO_SECS Convert beats per second to seconds. ## API: ALLEGRO_BPM_TO_SECS Convert beats per minute to seconds. ## API: al_create_timer Allocates and initializes a timer. If successful, a pointer to a new timer object is returned, otherwise NULL is returned. *speed_secs* is in seconds per "tick", and must be positive. The new timer is initially stopped. Usage note: typical granularity is on the order of microseconds, but with some drivers might only be milliseconds. See also: [al_start_timer], [al_destroy_timer] ## API: al_start_timer Start the timer specified. From then, the timer's counter will increment at a constant rate, and it will begin generating events. Starting a timer that is already started does nothing. See also: [al_stop_timer], [al_get_timer_started] ## API: al_stop_timer Stop the timer specified. The timer's counter will stop incrementing and it will stop generating events. Stopping a timer that is already stopped does nothing. See also: [al_start_timer], [al_get_timer_started] ## API: al_get_timer_started Return true if the timer specified is currently started. ## API: al_destroy_timer Uninstall the timer specified. If the timer is started, it will automatically be stopped before uninstallation. It will also automatically unregister the timer with any event queues. Does nothing if passed the NULL pointer. See also: [al_create_timer] ## API: al_get_timer_count Return the timer's counter value. The timer can be started or stopped. See also: [al_set_timer_count] ## API: al_set_timer_count Set the timer's counter value. The timer can be started or stopped. The count value may be positive or negative, but will always be incremented by +1 at each tick. See also: [al_get_timer_count], [al_add_timer_count] ## API: al_add_timer_count Add *diff* to the timer's counter value. This is similar to writing: al_set_timer_count(timer, al_get_timer_count(timer) + diff); except that the addition is performed atomically, so no ticks will be lost. See also: [al_set_timer_count] ## API: al_get_timer_speed Return the timer's speed, in seconds. (The same value passed to [al_create_timer] or [al_set_timer_speed].) See also: [al_set_timer_speed] ## API: al_set_timer_speed Set the timer's speed, i.e. the rate at which its counter will be incremented when it is started. This can be done when the timer is started or stopped. If the timer is currently running, it is made to look as though the speed change occurred precisely at the last tick. *speed_secs* has exactly the same meaning as with [al_create_timer]. See also: [al_get_timer_speed] ## API: al_get_timer_event_source Retrieve the associated event source. allegro-5.0.10/docs/src/refman/font.txt0000644000175000001440000003036012123474405017110 0ustar tjadenusers# Font addons These functions are declared in the following header file. Link with allegro_font. #include ## General font routines ### API: ALLEGRO_FONT A handle identifying any kind of font. Usually you will create it with [al_load_font] which supports loading all kinds of TrueType fonts supported by the FreeType library. If you instead pass the filename of a bitmap file, it will be loaded with [al_load_bitmap] and a font in Allegro's bitmap font format will be created from it with [al_grab_font_from_bitmap]. ### API: al_init_font_addon Initialise the font addon. Note that if you intend to load bitmap fonts, you will need to initialise allegro_image separately (unless you are using another library to load images). See also: [al_init_image_addon], [al_init_ttf_addon], [al_shutdown_font_addon] ### API: al_shutdown_font_addon Shut down the font addon. This is done automatically at program exit, but can be called any time the user wishes as well. See also: [al_init_font_addon] ### API: al_load_font Loads a font from disk. This will use [al_load_bitmap_font] if you pass the name of a known bitmap format, or else [al_load_ttf_font]. Bitmap and TTF fonts are affected by the current bitmap flags at the time the font is loaded. See also: [al_destroy_font], [al_init_font_addon], [al_register_font_loader] ### API: al_destroy_font Frees the memory being used by a font structure. Does nothing if passed NULL. See also: [al_load_font] ### API: al_register_font_loader Informs Allegro of a new font file type, telling it how to load files of this format. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `load_font` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_init_font_addon] ### API: al_get_font_line_height Returns the usual height of a line of text in the specified font. For bitmap fonts this is simply the height of all glyph bitmaps. For truetype fonts it is whatever the font file specifies. In particular, some special glyphs may be higher than the height returned here. If the X is the position you specify to draw text, the meaning of ascent and descent and the line height is like in the figure below. X------------------------ /\ | | / \ | | /____\ ascent | / \ | | / \ | height ---------------- | | | descent | | | ------------------------- See also: [al_get_text_width], [al_get_text_dimensions] ### API: al_get_font_ascent Returns the ascent of the specified font. See also: [al_get_font_descent], [al_get_font_line_height] ### API: al_get_font_descent Returns the descent of the specified font. See also: [al_get_font_ascent], [al_get_font_line_height] ### API: al_get_text_width Calculates the length of a string in a particular font, in pixels. See also: [al_get_ustr_width], [al_get_font_line_height], [al_get_text_dimensions] ### API: al_get_ustr_width Like [al_get_text_width] but expects an ALLEGRO_USTR. See also: [al_get_text_width], [al_get_ustr_dimensions] ### API: al_draw_text Writes the NUL-terminated string `text` onto the target bitmap at position `x`, `y`, using the specified `font`. The `flags` parameter can be 0 or one of the following flags: - ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0). - ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given position. - ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given position. It can also be combined with this flag: - ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer pixel position. This is formerly the default behaviour. Since: 5.0.8, 5.1.4 See also: [al_draw_ustr], [al_draw_textf], [al_draw_justified_text] ### API: al_draw_ustr Like [al_draw_text], except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array. See also: [al_draw_text], [al_draw_justified_ustr] ### API: al_draw_justified_text Like [al_draw_text], but justifies the string to the region x1-x2. The *diff* parameter is the maximum amount of horizontal space to allow between words. If justisfying the text would exceed *diff* pixels, or the string contains less than two words, then the string will be drawn left aligned. The `flags` parameter can be 0 or one of the following flags: - ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel positions. Since: 5.0.8, 5.1.5 See also: [al_draw_justified_textf], [al_draw_justified_ustr] ### API: al_draw_justified_ustr Like [al_draw_justified_text], except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array. See also: [al_draw_justified_text], [al_draw_justified_textf]. ### API: al_draw_textf Formatted text output, using a printf() style format string. All parameters have the same meaning as with [al_draw_text] otherwise. See also: [al_draw_text], [al_draw_ustr] ### API: al_draw_justified_textf Formatted text output, using a printf() style format string. All parameters have the same meaning as with [al_draw_justified_text] otherwise. See also: [al_draw_justified_text], [al_draw_justified_ustr]. ### API: al_get_text_dimensions Sometimes, the [al_get_text_width] and [al_get_font_line_height] functions are not enough for exact text placement, so this function returns some additional information. Returned variables (all in pixel): - x, y - Offset to upper left corner of bounding box. - w, h - Dimensions of bounding box. Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values. See also: [al_get_text_width], [al_get_font_line_height], [al_get_ustr_dimensions] ### API: al_get_ustr_dimensions Sometimes, the [al_get_ustr_width] and [al_get_font_line_height] functions are not enough for exact text placement, so this function returns some additional information. See also: [al_get_text_dimensions] ### API: al_get_allegro_font_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. ## Bitmap fonts ### API: al_grab_font_from_bitmap Creates a new font from an Allegro bitmap. You can delete the bitmap after the function returns as the font will contain a copy for itself. Parameters: - bmp: The bitmap with the glyphs drawn onto it - n: Number of unicode ranges in the bitmap. - ranges: 'n' pairs of first and last unicode point to map glyphs to for each range. The bitmap format is as in the following example, which contains three glyphs for 1, 2 and 3. ............. . 1 .222.333. . 1 . 2. 3. . 1 .222.333. . 1 .2 . 3. . 1 .222.333. ............. In the above illustration, the dot is for pixels having the background color. It is determined by the color of the top left pixel in the bitmap. There should be a border of at least 1 pixel with this color to the bitmap edge and between all glyphs. Each glyph is inside a rectangle of pixels not containing the background color. The height of all glyph rectangles should be the same, but the width can vary. The placement of the rectangles does not matter, except that glyphs are scanned from left to right and top to bottom to match them to the specified unicode codepoints. The glyphs will simply be drawn using [al_draw_bitmap], so usually you will want the rectangles filled with full transparency and the glyphs drawn in opaque white. Examples: int ranges[] = {32, 126}; al_grab_font_from_bitmap(bitmap, 1, ranges) int ranges[] = { 0x0020, 0x007F, /* ASCII */ 0x00A1, 0x00FF, /* Latin 1 */ 0x0100, 0x017F, /* Extended-A */ 0x20AC, 0x20AC}; /* Euro */ al_grab_font_from_bitmap(bitmap, 4, ranges) The first example will grab glyphs for the 95 standard printable ASCII characters, beginning with the space character (32) and ending with the tilde character (126). The second example will map the first 96 glyphs found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to Extended-A, and the last glyph to the Euro character. (This is just the characters found in the Allegro 4 font.) See also: [al_load_bitmap], [al_grab_font_from_bitmap] ### API: al_load_bitmap_font Load a bitmap font from. It does this by first calling [al_load_bitmap] and then [al_grab_font_from_bitmap]. If you want to for example load an old A4 font, you could load the bitmap yourself, then call [al_convert_mask_to_alpha] on it and only then pass it to [al_grab_font_from_bitmap]. ### API: al_create_builtin_font Creates a monochrome bitmap font (8x8 pixels per character). This font is primarily intended to be used for displaying information in environments or during early runtime states where no external font data is available or loaded (e.g. for debugging). The builtin font contains the following unicode character ranges: 0x0020 to 0x007F (ASCII) 0x00A1 to 0x00FF (Latin 1) 0x0100 to 0x017F (Extended A) 0x20AC to 0x20AC (euro currency symbol) Returns NULL on an error. The font memory must be freed the same way as for any other font, using [al_destroy_font]. Since: 5.0.8, 5.1.3 See also: [al_load_bitmap_font], [al_destroy_font] ## TTF fonts These functions are declared in the following header file. Link with allegro_ttf. #include ### API: al_init_ttf_addon Call this after [al_init_font_addon] to make [al_load_font] recognize ".ttf" and other formats supported by [al_load_ttf_font]. Returns true on success, false on failure. ### API: al_shutdown_ttf_addon Unloads the ttf addon again. You normally don't need to call this. ### API: al_load_ttf_font Loads a TrueType font from a file using the FreeType library. Quoting from the FreeType FAQ this means support for many different font formats: *TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and others* The *size* parameter determines the size the font will be rendered at, specified in pixels. The standard font size is measured in *units per EM*, if you instead want to specify the size as the total height of glyphs in pixels, pass it as a negative value. > *Note:* If you want to display text at multiple sizes, load the font multiple times with different size parameters. The following flags are supported: * ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font file supports it. * ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no anti-aliasing of the font is done). * ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled by default in newer versions of FreeType. Since: 5.0.6, 5.1.2 See also: [al_init_ttf_addon], [al_load_ttf_font_f] ### API: al_load_ttf_font_f Like [al_load_ttf_font], but the font is read from the file handle. The filename is only used to find possible additional files next to a font file. > *Note:* The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time. ### API: al_load_ttf_font_stretch Like [al_load_ttf_font], except it takes separate width and height parameters instead of a single size parameter. If the height is a positive value, and the width zero or positive, then font will be stretched according to those parameters. The width must not be negative if the height is positive. As with [al_load_ttf_font], the height may be a negative value to specify the total height in pixels. Then the width must also be a negative value, or zero. The behaviour is undefined the height is positive while width is negative, or if the height is negative while the width is positive. Since: 5.0.6, 5.1.0 See also: [al_load_ttf_font], [al_load_ttf_font_stretch_f] ### API: al_load_ttf_font_stretch_f Like [al_load_ttf_font_stretch], but the font is read from the file handle. The filename is only used to find possible additional files next to a font file. > *Note:* The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time. Since: 5.0.6, 5.1.0 See also: [al_load_ttf_font_stretch] ### API: al_get_allegro_ttf_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. allegro-5.0.10/docs/src/refman/audio.txt0000644000175000001440000011352212101344246017240 0ustar tjadenusers# Audio addon These functions are declared in the following header file. Link with allegro_audio. #include ## Audio types ### API: ALLEGRO_AUDIO_DEPTH Sample depth and type, and signedness. Mixers only use 32-bit signed float (-1..+1), or 16-bit signed integers. The unsigned value is a bit-flag applied to the depth value. * ALLEGRO_AUDIO_DEPTH_INT8 * ALLEGRO_AUDIO_DEPTH_INT16 * ALLEGRO_AUDIO_DEPTH_INT24 * ALLEGRO_AUDIO_DEPTH_FLOAT32 * ALLEGRO_AUDIO_DEPTH_UNSIGNED For convenience: * ALLEGRO_AUDIO_DEPTH_UINT8 * ALLEGRO_AUDIO_DEPTH_UINT16 * ALLEGRO_AUDIO_DEPTH_UINT24 ### API: ALLEGRO_AUDIO_PAN_NONE A special value for the pan property of samples and audio streams. Use this value to disable panning on samples and audio streams, and play them without attentuation implied by panning support. ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) because, when panning is enabled, we try to maintain a constant sound power level as a sample is panned from left to right. A sound coming out of one speaker should sound as loud as it does when split over two speakers. As a consequence, a sample with pan value 0.0 will be 3 dB softer than the original level. (Please correct us if this is wrong.) ### API: ALLEGRO_CHANNEL_CONF Speaker configuration (mono, stereo, 2.1, etc). * ALLEGRO_CHANNEL_CONF_1 * ALLEGRO_CHANNEL_CONF_2 * ALLEGRO_CHANNEL_CONF_3 * ALLEGRO_CHANNEL_CONF_4 * ALLEGRO_CHANNEL_CONF_5_1 * ALLEGRO_CHANNEL_CONF_6_1 * ALLEGRO_CHANNEL_CONF_7_1 ### API: ALLEGRO_MIXER A mixer is a type of stream which mixes together attached streams into a single buffer. ### API: ALLEGRO_MIXER_QUALITY * ALLEGRO_MIXER_QUALITY_POINT - point sampling * ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation * ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8, 5.1.4) ### API: ALLEGRO_PLAYMODE Sample and stream playback mode. * ALLEGRO_PLAYMODE_ONCE * ALLEGRO_PLAYMODE_LOOP * ALLEGRO_PLAYMODE_BIDIR ### API: ALLEGRO_SAMPLE_ID An ALLEGRO_SAMPLE_ID represents a sample being played via [al_play_sample]. It can be used to later stop the sample with [al_stop_sample]. ### API: ALLEGRO_SAMPLE An ALLEGRO_SAMPLE object stores the data necessary for playing pre-defined digital audio. It holds information pertaining to data length, frequency, channel configuration, etc. You can have an ALLEGRO_SAMPLE object playing multiple times simultaneously. The object holds a user-specified PCM data buffer, of the format the object is created with. See also: [ALLEGRO_SAMPLE_INSTANCE] ### API: ALLEGRO_SAMPLE_INSTANCE An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a predefined sound effect. It holds information pertaining to the looping mode, loop start/end points, playing position, etc. An instance uses the data from an [ALLEGRO_SAMPLE] object. Multiple instances may be created from the same ALLEGRO_SAMPLE. An ALLEGRO_SAMPLE must not be destroyed while there are instances which reference it. To be played, an ALLEGRO_SAMPLE_INSTANCE object must be attached to an [ALLEGRO_VOICE] object, or to an [ALLEGRO_MIXER] object which is itself attached to an ALLEGRO_VOICE object (or to another ALLEGRO_MIXER object which is attached to an ALLEGRO_VOICE object, etc). See also: [ALLEGRO_SAMPLE] ### API: ALLEGRO_AUDIO_STREAM An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the sound device, in real-time. This is done by reading from a buffer, which is split into a number of fragments. Whenever a fragment has finished playing, the user can refill it with new data. As with [ALLEGRO_SAMPLE_INSTANCE] objects, streams store information necessary for playback, so you may not play the same stream multiple times simultaneously. Streams also need to be attached to an [ALLEGRO_VOICE] object, or to an [ALLEGRO_MIXER] object which, eventually, reaches an ALLEGRO_VOICE object. While playing, you must periodically fill fragments with new audio data. To know when a new fragment is ready to be filled, you can either directly check with [al_get_available_audio_stream_fragments], or listen to events from the stream. You can register an audio stream event source to an event queue; see [al_get_audio_stream_event_source]. An ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event is generated whenever a new fragment is ready. When you receive an event, use [al_get_audio_stream_fragment] to obtain a pointer to the fragment to be filled. The size and format are determined by the parameters passed to [al_create_audio_stream]. If you're late with supplying new data, the stream will be silent until new data is provided. You must call [al_drain_audio_stream] when you're finished with supplying data to the stream. If the stream is created by [al_load_audio_stream] then it can also generate an ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event if it reaches the end of the file and is not set to loop. ### API: ALLEGRO_VOICE A voice represents an audio device on the system, which may be a real device, or an abstract device provided by the operating system. To play back audio, you would attach a mixer or sample or stream to a voice. See also: [ALLEGRO_MIXER], [ALLEGRO_SAMPLE], [ALLEGRO_AUDIO_STREAM] ## Setting up audio ### API: al_install_audio Install the audio subsystem. Returns true on success, false on failure. Note: most users will call [al_reserve_samples] and [al_init_acodec_addon] after this. See also: [al_reserve_samples], [al_uninstall_audio], [al_is_audio_installed], [al_init_acodec_addon] ### API: al_uninstall_audio Uninstalls the audio subsystem. See also: [al_install_audio] ### API: al_is_audio_installed Returns true if [al_install_audio] was called previously and returned successfully. ### API: al_reserve_samples Reserves a number of sample instances, attaching them to the default mixer. If no default mixer is set when this function is called, then it will automatically create a voice with an attached mixer, which becomes the default mixer. This diagram illustrates the structures that are set up: sample instance 1 / sample instance 2 voice <-- default mixer <--- . \ . sample instance N Returns true on success, false on error. [al_install_audio] must have been called first. See also: [al_set_default_mixer], [al_play_sample] ## Misc audio functions ### API: al_get_allegro_audio_version Returns the (compiled) version of the addon, in the same format as [al_get_allegro_version]. ### API: al_get_audio_depth_size Return the size of a sample, in bytes, for the given format. The format is one of the values listed under [ALLEGRO_AUDIO_DEPTH]. ### API: al_get_channel_count Return the number of channels for the given channel configuration, which is one of the values listed under [ALLEGRO_CHANNEL_CONF]. ## Voice functions ### API: al_create_voice Creates a voice structure and allocates a voice from the digital sound driver. The passed frequency, sample format and channel configuration are used as a hint to what kind of data will be sent to the voice. However, the underlying sound driver is free to use non-matching values. For example it may be the native format of the sound hardware. If a mixer is attached to the voice, the mixer will convert from the mixer's format to the voice format and care does not have to be taken for this. However if you access the voice directly, make sure to not rely on the parameters passed to this function, but instead query the returned voice for the actual settings. See also: [al_destroy_voice] ### API: al_destroy_voice Destroys the voice and deallocates it from the digital driver. Does nothing if the voice is NULL. See also: [al_create_voice] ### API: al_detach_voice Detaches the mixer or sample or stream from the voice. See also: [al_attach_mixer_to_voice], [al_attach_sample_instance_to_voice], [al_attach_audio_stream_to_voice] ### API: al_attach_audio_stream_to_voice Attaches an audio stream to a voice. The same rules as [al_attach_sample_instance_to_voice] apply. This may fail if the driver can't create a voice with the buffer count and buffer size the stream uses. An audio stream attached directly to a voice has a number of limitations. The audio stream plays immediately and cannot be stopped. The stream position, speed, gain, panning, cannot be changed. At this time, we don't recommend attaching audio streams directly to voices. Use a mixer in between. Returns true on success, false on failure. See also: [al_detach_voice] ### API: al_attach_mixer_to_voice Attaches a mixer to a voice. The same rules as [al_attach_sample_instance_to_voice] apply, with the exception of the depth requirement. Returns true on success, false on failure. See also: [al_detach_voice] ### API: al_attach_sample_instance_to_voice Attaches a sample to a voice, and allows it to play. The sample's volume and loop mode will be ignored, and it must have the same frequency and depth (including signed-ness) as the voice. This function may fail if the selected driver doesn't support preloading sample data. At this time, we don't recommend attaching samples directly to voices. Use a mixer in between. Returns true on success, false on failure. See also: [al_detach_voice] ### API: al_get_voice_frequency Return the frequency of the voice, e.g. 44100. ### API: al_get_voice_channels Return the channel configuration of the voice. See also: [ALLEGRO_CHANNEL_CONF]. ### API: al_get_voice_depth Return the audio depth of the voice. See also: [ALLEGRO_AUDIO_DEPTH]. ### API: al_get_voice_playing Return true if the voice is currently playing. See also: [al_set_voice_playing] ### API: al_set_voice_playing Change whether a voice is playing or not. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance. On success the voice's current sample position is reset. Returns true on success, false on failure. See also: [al_get_voice_playing] ### API: al_get_voice_position When the voice has a non-streaming object attached to it, e.g. a sample, returns the voice's current sample position. Otherwise, returns zero. See also: [al_set_voice_position]. ### API: al_set_voice_position Set the voice position. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance. Returns true on success, false on failure. See also: [al_get_voice_position]. ## Sample functions ### API: al_create_sample Create a sample data structure from the supplied buffer. If `free_buf` is true then the buffer will be freed with [al_free] when the sample data structure is destroyed. For portability (especially Windows), the buffer should have been allocated with [al_malloc]. Otherwise you should free the sample data yourself. To allocate a buffer of the correct size, you can use something like this: sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); bytes = samples * sample_size; buffer = al_malloc(bytes); See also: [al_destroy_sample], [ALLEGRO_AUDIO_DEPTH], [ALLEGRO_CHANNEL_CONF] ### API: al_destroy_sample Free the sample data structure. If it was created with the `free_buf` parameter set to true, then the buffer will be freed with [al_free]. This function will stop any sample instances which may be playing the buffer referenced by the [ALLEGRO_SAMPLE]. See also: [al_destroy_sample_instance], [al_stop_sample], [al_stop_samples] ### API: al_play_sample Plays a sample on one of the sample instances created by [al_reserve_samples]. Returns true on success, false on failure. Playback may fail because all the reserved sample instances are currently used. Parameters: * gain - relative volume at which the sample is played; 1.0 is normal. * pan - 0.0 is centred, -1.0 is left, 1.0 is right, or ALLEGRO_AUDIO_PAN_NONE. * speed - relative speed at which the sample is played; 1.0 is normal. * loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or ALLEGRO_PLAYMODE_BIDIR * ret_id - if non-NULL the variable which this points to will be assigned an id representing the sample being played. See also: [ALLEGRO_PLAYMODE], [ALLEGRO_AUDIO_PAN_NONE], [ALLEGRO_SAMPLE_ID], [al_stop_sample], [al_stop_samples]. ### API: al_stop_sample Stop the sample started by [al_play_sample]. See also: [al_stop_samples] ### API: al_stop_samples Stop all samples started by [al_play_sample]. See also: [al_stop_sample] ### API: al_get_sample_channels Return the channel configuration. See also: [ALLEGRO_CHANNEL_CONF], [al_get_sample_depth], [al_get_sample_frequency], [al_get_sample_length], [al_get_sample_data] ### API: al_get_sample_depth Return the audio depth. See also: [ALLEGRO_AUDIO_DEPTH], [al_get_sample_channels], [al_get_sample_frequency], [al_get_sample_length], [al_get_sample_data] ### API: al_get_sample_frequency Return the frequency of the sample. See also: [al_get_sample_channels], [al_get_sample_depth], [al_get_sample_length], [al_get_sample_data] ### API: al_get_sample_length Return the length of the sample in sample values. See also: [al_get_sample_channels], [al_get_sample_depth], [al_get_sample_frequency], [al_get_sample_data] ### API: al_get_sample_data Return a pointer to the raw sample data. See also: [al_get_sample_channels], [al_get_sample_depth], [al_get_sample_frequency], [al_get_sample_length] ## Sample instance functions ### API: al_create_sample_instance Creates a sample stream, using the supplied data. This must be attached to a voice or mixer before it can be played. The argument may be NULL. You can then set the data later with [al_set_sample]. See also: [al_destroy_sample_instance] ### API: al_destroy_sample_instance Detaches the sample stream from anything it may be attached to and frees it (the sample data is *not* freed!). See also: [al_create_sample_instance] ### API: al_play_sample_instance Play an instance of a sample data. Returns true on success, false on failure. See also: [al_stop_sample_instance] ### API: al_stop_sample_instance Stop an sample instance playing. See also: [al_play_sample_instance] ### API: al_get_sample_instance_channels Return the channel configuration. See also: [ALLEGRO_CHANNEL_CONF]. ### API: al_get_sample_instance_depth Return the audio depth. See also: [ALLEGRO_AUDIO_DEPTH]. ### API: al_get_sample_instance_frequency Return the frequency of the sample instance. ### API: al_get_sample_instance_length Return the length of the sample instance in sample values. See also: [al_set_sample_instance_length], [al_get_sample_instance_time] ### API: al_set_sample_instance_length Set the length of the sample instance in sample values. Return true on success, false on failure. Will fail if the sample instance is currently playing. See also: [al_get_sample_instance_length] ### API: al_get_sample_instance_position Get the playback position of a sample instance. See also: [al_set_sample_instance_position] ### API: al_set_sample_instance_position Set the playback position of a sample instance. Returns true on success, false on failure. See also: [al_get_sample_instance_position] ### API: al_get_sample_instance_speed Return the relative playback speed. See also: [al_set_sample_instance_speed] ### API: al_set_sample_instance_speed Set the relative playback speed. 1.0 is normal speed. Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_sample_instance_speed] ### API: al_get_sample_instance_gain Return the playback gain. See also: [al_set_sample_instance_gain] ### API: al_set_sample_instance_gain Set the playback gain. Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_sample_instance_gain] ### API: al_get_sample_instance_pan Get the pan value. See also: [al_set_sample_instance_pan]. ### API: al_set_sample_instance_pan Set the pan value on a sample instance. A value of -1.0 means to play the sample only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value [ALLEGRO_AUDIO_PAN_NONE] disables panning and plays the sample at its original level. This will be louder than a pan value of 0.0. > Note: panning samples with more than two channels doesn't work yet. Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_sample_instance_pan], [ALLEGRO_AUDIO_PAN_NONE] ### API: al_get_sample_instance_time Return the length of the sample instance in seconds, assuming a playback speed of 1.0. See also: [al_get_sample_instance_length] ### API: al_get_sample_instance_playmode Return the playback mode. See also: [ALLEGRO_PLAYMODE], [al_set_sample_instance_playmode] ### API: al_set_sample_instance_playmode Set the playback mode. Returns true on success, false on failure. See also: [ALLEGRO_PLAYMODE], [al_get_sample_instance_playmode] ### API: al_get_sample_instance_playing Return true if the sample instance is playing. See also: [al_set_sample_instance_playing] ### API: al_set_sample_instance_playing Change whether the sample instance is playing. Returns true on success, false on failure. See also: [al_get_sample_instance_playing] ### API: al_get_sample_instance_attached Return whether the sample instance is attached to something. See also: [al_attach_sample_instance_to_mixer], [al_attach_sample_instance_to_voice], [al_detach_sample_instance] ### API: al_detach_sample_instance Detach the sample instance from whatever it's attached to, if anything. Returns true on success. See also: [al_attach_sample_instance_to_mixer], [al_attach_sample_instance_to_voice], [al_get_sample_instance_attached] ### API: al_get_sample Return the sample data that the sample instance plays. Note this returns a pointer to an internal structure, *not* the [ALLEGRO_SAMPLE] that you may have passed to [al_set_sample]. You may, however, check which sample buffer is being played by the sample instance with [al_get_sample_data], and so on. See also: [al_set_sample] ### API: al_set_sample Change the sample data that a sample instance plays. This can be quite an involved process. First, the sample is stopped if it is not already. Next, if data is NULL, the sample is detached from its parent (if any). If data is not NULL, the sample may be detached and reattached to its parent (if any). This is not necessary if the old sample data and new sample data have the same frequency, depth and channel configuration. Reattaching may not always succeed. On success, the sample remains stopped. The playback position and loop end points are reset to their default values. The loop mode remains unchanged. Returns true on success, false on failure. On failure, the sample will be stopped and detached from its parent. See also: [al_get_sample] ## Mixer functions ### API: al_create_mixer Creates a mixer stream, to attach sample streams or other mixers to. It will mix into a buffer at the requested frequency and channel count. The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 and ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete). Returns true on success, false on error. See also: [al_destroy_mixer], [ALLEGRO_AUDIO_DEPTH], [ALLEGRO_CHANNEL_CONF] ### API: al_destroy_mixer Destroys the mixer stream. See also: [al_create_mixer] ### API: al_get_default_mixer Return the default mixer, or NULL if one has not been set. Although different configurations of mixers and voices can be used, in most cases a single mixer attached to a voice is what you want. The default mixer is used by [al_play_sample]. See also: [al_reserve_samples], [al_play_sample], [al_set_default_mixer], [al_restore_default_mixer] ### API: al_set_default_mixer Sets the default mixer. All samples started with [al_play_sample] will be stopped. If you are using your own mixer, this should be called before [al_reserve_samples]. Returns true on success, false on error. See also: [al_reserve_samples], [al_play_sample], [al_get_default_mixer], [al_restore_default_mixer] ### API: al_restore_default_mixer Restores Allegro's default mixer. All samples started with [al_play_sample] will be stopped. Returns true on success, false on error. See also: [al_get_default_mixer], [al_set_default_mixer], [al_reserve_samples]. ### API: al_attach_mixer_to_mixer Attaches a mixer onto another mixer. The same rules as with [al_attach_sample_instance_to_mixer] apply, with the added caveat that both mixers must be the same frequency. Returns true on success, false on error. Currently both mixers must have the same audio depth, otherwise the function fails. See also: [al_detach_mixer]. ### API: al_attach_sample_instance_to_mixer Attach a sample instance to a mixer. The instance must not already be attached to anything. Returns true on success, false on failure. See also: [al_detach_sample_instance]. ### API: al_attach_audio_stream_to_mixer Attach a stream to a mixer. Returns true on success, false on failure. See also: [al_detach_audio_stream]. ### API: al_get_mixer_frequency Return the mixer frequency. See also: [al_set_mixer_frequency] ### API: al_set_mixer_frequency Set the mixer frequency. This will only work if the mixer is not attached to anything. Returns true on success, false on failure. See also: [al_get_mixer_frequency] ### API: al_get_mixer_channels Return the mixer channel configuration. See also: [ALLEGRO_CHANNEL_CONF]. ### API: al_get_mixer_depth Return the mixer audio depth. See also: [ALLEGRO_AUDIO_DEPTH]. ### API: al_get_mixer_gain Return the mixer gain (amplification factor). The default is 1.0. Since: 5.0.6, 5.1.0 See also: [al_set_mixer_gain]. ### API: al_set_mixer_gain Set the mixer gain (amplification factor). Returns true on success, false on failure. Since: 5.0.6, 5.1.0 See also: [al_get_mixer_gain] ### API: al_get_mixer_quality Return the mixer quality. See also: [ALLEGRO_MIXER_QUALITY], [al_set_mixer_quality] ### API: al_set_mixer_quality Set the mixer quality. This can only succeed if the mixer does not have anything attached to it. Returns true on success, false on failure. See also: [ALLEGRO_MIXER_QUALITY], [al_get_mixer_quality] ### API: al_get_mixer_playing Return true if the mixer is playing. See also: [al_set_mixer_playing]. ### API: al_set_mixer_playing Change whether the mixer is playing. Returns true on success, false on failure. See also: [al_get_mixer_playing]. ### API: al_get_mixer_attached Return true if the mixer is attached to something. See also: [al_attach_sample_instance_to_mixer], [al_attach_audio_stream_to_mixer], [al_attach_mixer_to_mixer], [al_detach_mixer] ### API: al_detach_mixer Detach the mixer from whatever it is attached to, if anything. See also: [al_attach_mixer_to_mixer]. ### API: al_set_mixer_postprocess_callback Sets a post-processing filter function that's called after the attached streams have been mixed. The buffer's format will be whatever the mixer was created with. The sample count and user-data pointer is also passed. ## Stream functions ### API: al_create_audio_stream Creates an [ALLEGRO_AUDIO_STREAM]. The stream will be set to play by default. It will feed audio data from a buffer, which is split into a number of fragments. Parameters: * fragment_count - How many fragments to use for the audio stream. Usually only two fragments are required - splitting the audio buffer in two halves. But it means that the only time when new data can be supplied is whenever one half has finished playing. When using many fragments, you usually will use fewer samples for one, so there always will be (small) fragments available to be filled with new data. * frag_samples - The size of a fragment in samples. See note below. * freq - The frequency, in Hertz. * depth - Must be one of the values listed for [ALLEGRO_AUDIO_DEPTH]. * chan_conf - Must be one of the values listed for [ALLEGRO_CHANNEL_CONF]. The choice of *fragment_count*, *frag_samples* and *freq* directly influences the audio delay. The delay in seconds can be expressed as: delay = fragment_count * frag_samples / freq This is only the delay due to Allegro's streaming, there may be additional delay caused by sound drivers and/or hardware. > *Note:* If you know the fragment size in bytes, you can get the size in samples > like this: > > sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); > samples = bytes_per_fragment / sample_size; > > The size of the complete buffer is: > > buffer_size = bytes_per_fragment * fragment_count > *Note:* unlike many Allegro objects, audio streams are not implicitly destroyed when Allegro is shut down. You must destroy them manually with [al_destroy_audio_stream] before the audio system is shut down. ### API: al_destroy_audio_stream Destroy an audio stream which was created with [al_create_audio_stream] or [al_load_audio_stream]. > *Note:* If the stream is still attached to a mixer or voice, [al_detach_audio_stream] is automatically called on it first. See also: [al_drain_audio_stream]. ### API: al_get_audio_stream_event_source Retrieve the associated event source. See [al_get_audio_stream_fragment] for a description of the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event that audio streams emit. ### API: al_drain_audio_stream You should call this to finalise an audio stream that you will no longer be feeding, to wait for all pending buffers to finish playing. The stream's playing state will change to false. See also: [al_destroy_audio_stream] ### API: al_rewind_audio_stream Set the streaming file playing position to the beginning. Returns true on success. Currently this can only be called on streams created with [al_load_audio_stream], [al_load_audio_stream_f] and the format-specific functions underlying those functions. ### API: al_get_audio_stream_frequency Return the stream frequency. ### API: al_get_audio_stream_channels Return the stream channel configuration. See also: [ALLEGRO_CHANNEL_CONF]. ### API: al_get_audio_stream_depth Return the stream audio depth. See also: [ALLEGRO_AUDIO_DEPTH]. ### API: al_get_audio_stream_length Return the stream length in samples. ### API: al_get_audio_stream_speed Return the relative playback speed. See also: [al_set_audio_stream_speed]. ### API: al_set_audio_stream_speed Set the relative playback speed. 1.0 is normal speed. Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_audio_stream_speed]. ### API: al_get_audio_stream_gain Return the playback gain. See also: [al_set_audio_stream_gain]. ### API: al_set_audio_stream_gain Set the playback gain. Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_audio_stream_gain]. ### API: al_get_audio_stream_pan Get the pan value. See also: [al_set_audio_stream_pan]. ### API: al_set_audio_stream_pan Set the pan value on an audio stream. A value of -1.0 means to play the stream only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value [ALLEGRO_AUDIO_PAN_NONE] disables panning and plays the stream at its original level. This will be louder than a pan value of 0.0. Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. See also: [al_get_audio_stream_pan], [ALLEGRO_AUDIO_PAN_NONE] ### API: al_get_audio_stream_playing Return true if the stream is playing. See also: [al_set_audio_stream_playing]. ### API: al_set_audio_stream_playing Change whether the stream is playing. Returns true on success, false on failure. See also: [al_get_audio_stream_playing] ### API: al_get_audio_stream_playmode Return the playback mode. See also: [ALLEGRO_PLAYMODE], [al_set_audio_stream_playmode]. ### API: al_set_audio_stream_playmode Set the playback mode. Returns true on success, false on failure. See also: [ALLEGRO_PLAYMODE], [al_get_audio_stream_playmode]. ### API: al_get_audio_stream_attached Return whether the stream is attached to something. See also: [al_attach_audio_stream_to_mixer], [al_attach_audio_stream_to_voice], [al_detach_audio_stream]. ### API: al_detach_audio_stream Detach the stream from whatever it's attached to, if anything. See also: [al_attach_audio_stream_to_mixer], [al_attach_audio_stream_to_voice], [al_get_audio_stream_attached]. ### API: al_get_audio_stream_fragment When using Allegro's audio streaming, you will use this function to continuously provide new sample data to a stream. If the stream is ready for new data, the function will return the address of an internal buffer to be filled with audio data. The length and format of the buffer are specified with [al_create_audio_stream] or can be queried with the various functions described here. Once the buffer is filled, you must signal this to Allegro by passing the buffer to [al_set_audio_stream_fragment]. If the stream is not ready for new data, the function will return NULL. > *Note:* If you listen to events from the stream, an ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event will be generated whenever a new fragment is ready. However, getting an event is *not* a guarantee that [al_get_audio_stream_fragment] will not return NULL, so you still must check for it. See also: [al_set_audio_stream_fragment], [al_get_audio_stream_event_source], [al_get_audio_stream_frequency], [al_get_audio_stream_channels], [al_get_audio_stream_depth], [al_get_audio_stream_length] ### API: al_set_audio_stream_fragment This function needs to be called for every successful call of [al_get_audio_stream_fragment] to indicate that the buffer is filled with new data. See also: [al_get_audio_stream_fragment] ### API: al_get_audio_stream_fragments Returns the number of fragments this stream uses. This is the same value as passed to [al_create_audio_stream] when a new stream is created. See also: [al_get_available_audio_stream_fragments] ### API: al_get_available_audio_stream_fragments Returns the number of available fragments in the stream, that is, fragments which are not currently filled with data for playback. See also: [al_get_audio_stream_fragment], [al_get_audio_stream_fragments] ### API: al_seek_audio_stream_secs Set the streaming file playing position to time. Returns true on success. Currently this can only be called on streams created with [al_load_audio_stream], [al_load_audio_stream_f] and the format-specific functions underlying those functions. See also: [al_get_audio_stream_position_secs], [al_get_audio_stream_length_secs] ### API: al_get_audio_stream_position_secs Return the position of the stream in seconds. Currently this can only be called on streams created with [al_load_audio_stream]. See also: [al_get_audio_stream_length_secs] ### API: al_get_audio_stream_length_secs Return the length of the stream in seconds, if known. Otherwise returns zero. Currently this can only be called on streams created with [al_load_audio_stream], [al_load_audio_stream_f] and the format-specific functions underlying those functions. See also: [al_get_audio_stream_position_secs] ### API: al_set_audio_stream_loop_secs Sets the loop points for the stream in seconds. Currently this can only be called on streams created with [al_load_audio_stream], [al_load_audio_stream_f] and the format-specific functions underlying those functions. ## Audio file I/O ### API: al_register_sample_loader Register a handler for [al_load_sample]. The given function will be used to handle the loading of sample files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_sample_loader_f], [al_register_sample_saver] ### API: al_register_sample_loader_f Register a handler for [al_load_sample_f]. The given function will be used to handle the loading of sample files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_sample_loader] ### API: al_register_sample_saver Register a handler for [al_save_sample]. The given function will be used to handle the saving of sample files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `saver` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_sample_saver_f], [al_register_sample_loader] ### API: al_register_sample_saver_f Register a handler for [al_save_sample_f]. The given function will be used to handle the saving of sample files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `saver` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_sample_saver] ### API: al_register_audio_stream_loader Register a handler for [al_load_audio_stream]. The given function will be used to open streams from files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `stream_loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_audio_stream_loader_f] ### API: al_register_audio_stream_loader_f Register a handler for [al_load_audio_stream_f]. The given function will be used to open streams from files with the given extension. The extension should include the leading dot ('.') character. It will be matched case-insensitively. The `stream_loader` argument may be NULL to unregister an entry. Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist. See also: [al_register_audio_stream_loader] ### API: al_load_sample Loads a few different audio file formats based on their extension. Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use [al_load_audio_stream]. Returns the sample on success, NULL on failure. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_register_sample_loader], [al_init_acodec_addon] ### API: al_load_sample_f Loads an audio file from an [ALLEGRO_FILE] stream into an [ALLEGRO_SAMPLE]. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot. Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use [al_load_audio_stream_f]. Returns the sample on success, NULL on failure. The file remains open afterwards. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_register_sample_loader_f], [al_init_acodec_addon] ### API: al_load_audio_stream Loads an audio file from disk as it is needed. Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain *buffer_count* buffers with *samples* samples. The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See [ALLEGRO_AUDIO_STREAM] for more details. Returns the stream on success, NULL on failure. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_load_audio_stream_f], [al_register_audio_stream_loader], [al_init_acodec_addon] ### API: al_load_audio_stream_f Loads an audio file from [ALLEGRO_FILE] stream as it is needed. Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain *buffer_count* buffers with *samples* samples. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot. The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See [ALLEGRO_AUDIO_STREAM] for more details. Returns the stream on success, NULL on failure. On success the file should be considered owned by the audio stream, and will be closed when the audio stream is destroyed. On failure the file will be closed. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_load_audio_stream], [al_register_audio_stream_loader_f], [al_init_acodec_addon] ### API: al_save_sample Writes a sample into a file. Currently, wav is the only supported format, and the extension must be ".wav". Returns true on success, false on error. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_save_sample_f], [al_register_sample_saver], [al_init_acodec_addon] ### API: al_save_sample_f Writes a sample into a [ALLEGRO_FILE] filestream. Currently, wav is the only supported format, and the extension must be ".wav". Returns true on success, false on error. The file remains open afterwards. > *Note:* the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. See also: [al_save_sample], [al_register_sample_saver_f], [al_init_acodec_addon] allegro-5.0.10/docs/src/changes-5.0.txt0000644000175000001440000040105312157071564016611 0ustar tjadenusers% Allegro changelog for 5.0.x series See `changes._tx` for changes in earlier versions of Allegro. These lists serve as summaries; the full histories are in the Subversion repository. Changes from 5.0.9 to 5.0.10 (June 2013) ======================================== The main developers this time were: Trent Gamblin, Paul Suntsov, Peter Wang. Core: - Register system interface even if no display driver available on Windows. Displays: - Don't crash in al_create_display if there is no display driver. - Don't crash at shutdown if there is no display driver (Windows). - Don't fail init if both D3D, GL drivers unavailable (Windows). - Run fullscreen toggle on main thread (OS X). - Destroy the backbuffer bitmap when destroying the display (OS X). - Switch to new NSTrackingArea API (OS X). - Check availability of fullscreen button on window frame at run-time (OS X). Graphics: - Add ALLEGRO_SRC_COLOR, ALLEGRO_DEST_COLOR, ALLEGRO_INVERSE_SRC_COLOR, ALLEGRO_INVERSE_DEST_COLOR blending modes (initially by Jon Rafkind and Elias Pschernig). - Let al_destroy_bitmap implicitly untarget the bitmap on the calling thread. - Use memory bitmap drawing when either bitmap is locked (OpenGL). - Add const qualifiers to glUniform*v() functions (Aaron Bolyard). Input: - al_set_mouse_xy on Windows resulted in the mouse getting set to the wrong position in windowed modes. - Scale the user supplied mouse cursor if it's too big (Windows). - Fix mouse warping on OS X. - Fix mouse warping in Linux evdev mouse driver. Audio addon: - pulseaudio: Use smaller buffer size by default, and make it configurable. - pulseaudio: Clean up state transitions. - Fix looping in Ogg Vorbis stream (Todd Cope). - Enable the use of the unpatched DirectX SDK to build Allegro with MinGW. Color addon: - Fix al_color_rgb_to_html blue component (Jeff Bernard). Font addons: - Make al_init_ttf_addon return true for subsequent calls. Primitives addon: - Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. - Check that the vertex declaration is valid before creating it. - Respect filter settings of textures in the D3D backend. Build system: - Do not install most internal header files. - Do not search for and link with unneeded X libraries. Examples: - ex_audio_timer: New example. Other: - Minor fixes. - Various documentation updates. - A lot of code refactoring. Changes from 5.0.8 to 5.0.9 (February 2013) =========================================== The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Core: - Clean up logging subsystem at shutdown (muhkuh). - Fix a problem with creating a display after Allegro is shut down then re-initialised on X11. - Fix use of clobbered return value from setlocale() on X11. - Fix use of double math functions for float arguments (Nick Trout). Displays: - Fix al_set/get_window position on Windows so getting/setting to the same position continuosly doesn't move the window. (Michael Swiger) - Add al_set_display_icons (plural). Implemented on X11 and Windows. - Made al_get_display_mode return the closest thing to a pixel format possible with the WGL driver (tobing). - Move WGL context destruction out of the message pump thread and into the user/main thread. - Allow command-tab to work in fullscreen window mode on OS X. Graphics: - Avoid null pointer dereference when setting a target bitmap after its video_texture has already been released (D3D). - Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap failed, likely because the device was lost. - Set device_lost flag immediately when d3d_display_thread_proc finds the device is lost. - Sync bitmaps before resizing display to prevent changes being lost after the resize (D3D). - Revert a faulty FBO rebinding optimisation in al_set_target_bitmap. - Fix OpenGL extensions being completely ignored on OS X. - Support stencil buffer on iOS. Input: - Partially fix mouse buttons "sticking" on Mac, e.g. holding the mouse and toggling fullscreen window. Filesystem: - Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to the working directory do not affect the interpretation of the path. - Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. - Make sure stat mode bits are cleared in default implementation of al_update_fs_entry. - Support Unicode paths on Windows. - Change description of al_get_fs_entry_name about not returning absolute path if created from relative path; no longer true for either the default or Physfs implementations. Audio addons: - Shut down threads properly when when destroying FLAC and modaudio streams. - Fix PulseAudio driver trying to connect to a non-existent server forever. Image I/O addon: - Fixed loading interlaced .png files with libpng. - Use Allegro built-in loaders in preference to OS X loaders for BMP/TGA/PCX. The OS X TGA loader doesn't support alpha and this is also more consistent. - Restored ability of the native OSX image loader to load grayscale pictures. Native dialog addon: - Add al_init_native_dialog_addon and al_shutdown_native_dialog_addon. Build system: - Rename allegro\*-5.0.pc files to allegro\*-5.pc. The old names are deprecated but retained on the 5.0 branch for backwards compatibility. - Only generate and install pkg-config files for libraries that we build. - Install iPhone internals headers (Nick Trout). Examples: - ex_icon2: New example. - speed: Use builtin font. Other: - Documentation updates. - A lot of code refactoring. Changes from 5.0.7 to 5.0.8 (November 2012) =========================================== The main developers this time were: Dennis Busch, Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Core: - Added alternate spelling: ALLEGRO_ALIGN_CENTER. Displays: - Rewrite D3D display format listing code, which was broken. This should re-enable multi-sampling and fix ex_depth_mask being slow with D3D. - Fixed a case where changing fullscreen mode in D3D via al_resize_display caused a crash and loss of loaded bitmaps information. - Fixed a case where changing fullscreen mode in OpenGL (on Windows) via al_resize_display cause nothing to be rendered after the mode change. - Fix crashes when resizing a WGL fullscreen window. - Fixed missing/incorrect resize events under Windows. - Fix al_set_new_display_adapter on OS X. - Fix use of invalidated pointers in D3D driver when the first format fails. - Fix bug where setting the mouse cursor had no effect when the mouse was captured (mouse button held down). - Fix windows not having a minimise button when set to windowed state from fullscreen window state. - Respect ALLEGRO_FRAMELESS flag properly when toggling from fullscreen window state to windowed state (Windows). - Don't generate DISPLAY_LOST events when resizing a fullscreen display. - Scale window icon to sizes returned by GetSystemMetrics (Windows). - Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. - Added al_osx_get_window function (Dennis Gooden). Graphics: - al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. - Fix a potential crash when drawing the screen to a bitmap with D3D. - Avoid null pointer dereference when setting a target bitmap after its video_texture has already been released (D3D). - Lock bitmap to prevent slowness when creating a cursor from a non-memory bitmap on Windows. - Conditionally lock bitmap when creating cursor on X11 (previously it did so even if already locked). - Don't use NSOpenGLPFAAccelerated unnecessarily (OS X). Input: - Fix incorrect keyboard modifier flags after leaving and re-entering a window (Windows). - Fixed a bug with mouse enter/leave events for resized windows under OSX (Dennis Gooden). - Temporary fix for delay after mouse warp on OS X. File I/O: - Fix al_fputc on big-endian. Reported by Andreas Rönnquist and Tobias Hansen. - Make al_fputc return value like fputc when out of range. - Fix al_read_directory crash on 64-bit Windows (simast). Image addon: - Don't include native image loader source files in builds with the native image loaders disabled (OSX, iOS). - Added a missing autorelease-pool to the OSX bitmap saving function (sleepywind). - Fix OSX native image loader for loading not-premultiplied RGB data. Previously the data was "de-multiplied", with possibly all information lost. - Fix OSX native image loader for loading bitmaps without an alpha channel. They appeared completely black previously. Font addons: - Add builtin font creation function. - Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). - Made TTF addon include padding on the top and left edges of pages (Todd Cope). Audio addon: - Use programmatically generated interpolators. They cover an additional case which was missed and should be slightly more efficient. - Support linear interpolation for 16-bit mixers. - Add cubic interpolation for mixers (off by default). - Fix potential deadlock in stop_voice for OpenAL. - Fix potential deadlock in stop_voice for DirectSound. - Improve buffer filling behaviour for DirectSound, reducing pops and crackles significantly on slower machines. - Increase default buffer size for DirectSound to 8192 samples. - Fix setting the speed of an audio stream after it was attached to the mixer. Native dialogs addon: - Do not unload of rich edit module when closing one text log window while another exists. Reported by URB753. - Use default colours for Windows text log implementation, avoiding problems when the previous custom colours failed, leading to black text on a nearly black background. Build system: - Install pkg-config files when cross-compiling on Unix. Examples: - ex_synth: Add button to save waveform to a file. - ex_multisample: Demonstrate using moving bitmaps. - speed: Avoid poor performance due to needless redraws. - Renamed a5teroids to Cosmic Protector Other: - Many minor bug fixes. - Various documentation updates. Changes from 5.0.6 to 5.0.7 (June 2012) ======================================= The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Core: - Fix ALLEGRO_STATIC_ASSERT collisions from different files included in the same translation unit. Reported by tobing. - Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const ALLEGRO_USTR* instead of just an ALLEGRO_USTR* (Paul Suntsov). - Make al_ustr_empty_string const correct. - Fix many memory leak/warnings on MacOS X (Pär Arvidsson). - Fix typo preventing get_executable_name from using System V procfs correctly. Reported by Max Savenkov. Displays: - Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing ALLEGRO_NOFRAME flag. - Rename al_toggle_display_flag to al_set_display_flag, retaining the older name for compatibility. - Set WM_NAME for some window managers (X11). Graphics: - Force al_create_bitmap to not create oversized bitmaps, to mitigate integer overflow problems. - Removed initial black frame on all Allegro programs. OpenGL: - Texture should be 'complete' (min/mag and wrap set) before glTexImage2D. - Fixed a bug in al_unlock_bitmap where the pixel alignment mistakenly was used as row length. - Fixed typo in names of some OpenGL extension functions. - Display list of OpenGL extensions in allegro.log also for OpenGL 3.0. Direct3D: - Fixed a bug in the D3D driver where separate alpha blending was being tested for when it shouldn't have been (Max Savenkov). Input: - Monitor /dev/input instead of /dev on Linux for hotplugging joysticks (Jon Rafkind). - Do not permanently change the locale for the X11 keyboard driver. Set LC_CTYPE only, not LC_ALL. Audio addon: - Fix desychronization due to inaccurate sample positions when resampling. Thanks to _Bnu for discovering the issue and Paul Suntsov for devising the correct solution. - Fix linear interpolation across audio stream buffer fragments. - Fix two minor memory leaks in the PulseAudio driver. Image I/O addon: - Improve compatibility of BMP loader. In particular, support bitmaps with V2-V5 headers and certain alpha bit masks. - Fix TGA loader using more memory than necessary. Reported by Max Savenkov. Font addon: - Use user set pixel format for fonts. Native dialogs addon: - Clear mouse state after dialogs or else it gets messed up (OSX). - Fix some warnings in gtk_dialog.c. - Wrap use of NSAlert so it can be run on the main thread with return value. Examples: - Add ex_resample_test. - ex_audio_props: Add bidir button. - ex_joystick_events: Support hotplugging and fix display of 3-axis sticks. - Add test_driver --no-display flag. (Tobias Hansen) Other: - Various documentation updates. - Other minor bug fixes. - Fix whatis entries of man pages. (Tobias Hansen) Changes from 5.0.5 to 5.0.6 (March 2012) ======================================== The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Paul Suntsov, Peter Wang. Core: - Added al_register_assert_handler. Graphics: - Added al_draw_tinted_scaled_rotated_bitmap_region. - Added al_reset_clipping_rectangle convenience function. - Added al_get_parent_bitmap. - Fixed a bug in the OpenGL driver when drawing the backbuffer outside the clipping rectangle of the target bitmap. - Make blitting from backbuffer work when using multisampling on Windows/D3D. Displays: - Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). - Don't generate bogus resize events after restoring minimised window on Windows. - Fixed bug on Windows where two SWITCH_IN events were fired when window was minimized/restored (Michael Swiger). - Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under Windows as well as a bug where repeatedly setting the flag to on would make the window grow bigger and bigger (Michael Swiger). - Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in X11. - Prevent a deadlock during display creation on X. - Fallback to the 'old' visual selection method on X instead of crashing if the 'new' visual selection doesn't work. Input: - Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was used for FULLSCREEN. (Max OS X) Filesystem: - Added al_fopen_slice. - Added al_set_exe_name which allows overriding Allegro's idea of the path to the current executable. - Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat the value of TMPDIR et al. as a directory name even without a trailing slash. (Unix) - Make stdio al_fopen implementation set proper errno on failure. Audio addons: - Add mixer gain property and functions. - Improve code to check that DLL symbols are loaded in the acodec addon. The old method was hacky and broke under -O2 using GCC 4.6.1. Image I/O addon: - Improved accuracy of un-alpha-premultiplying in the native OSX bitmap loader. Primitives addon: - Added al_draw_filled_pieslice and al_draw_pieslice. - Added al_draw_elliptical_arc. TTF addon: - Added al_load_ttf_font_stretch functions (tobing). - Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto Hinter which is enabled by default in newer version of FreeType (Michał Cichoń). - Clear locked region so pixel borders aren't random garbage that can be seen sometimes with linear filtering on. - Unlock glyph cache page at end of text_length and get_text_dimensions (jmasterx). Examples: - Added new examples: ex_audio_chain, ex_display_events, ex_file_slice. - ex_ogre3d: Make it work under Windows (AMCerasoli). - a5teroids: Support gamepads that report small non-zero values for sticks that are at rest. Other: - Added index to HTML version of the reference manual (Jon Rafkind). - Various documentation updates. - Other minor bug fixes. Changes from 5.0.4 to 5.0.5 (November 2011) =========================================== The main developers this time were: Elias Pschernig and Trent Gamblin. Graphics: - Fixed several instances of windows being positioned wrong on Windows: regular windows, WGL FULLSCREEN_WINDOW, and ALLEGRO_NOFRAME windows. - Don't re-bind the FBO in al_set_target_bitmap if the new target bitmap shares the parent bitmap with the new target bitmap (Paul Suntsov). - Zero out fake refresh rate information from the nvidia proprietary driver on X11 (Peter Wang). - Implemented the ALLEGRO_FULLSCREEN_WINDOW flag for iOS. Input: - Make al_set_mouse_xy work in fullscreen on Windows. - Fixed a race condition in al_init_joystick. - Fixed problem on OS X where having two identical gamepads attached would cause joystick initialization to hang (Thanks to Todd Cope for pointing it out.) - Fixed iphone joystick events (it assumed a call to al_get_joystick but that's not required when using events). TTF fonts: - Save new bitmap flags and bitmap format at time of loading font and use them when creating pages. Primitives addon: - Very thin arcs/pieslices were not drawn due to an overzealous check (Paul Suntsov). Native dialogs addon: - Implemented al_show_native_message_box for iOS. Other: - Use .../Library/Application Support for ALLEGRO_USER_SETTINGS_PATH and ALLEGRO_USER_DATA_PATH on iOS. - Listen for applicationDidBecomeActive and applicationWillResignActive instead of applicationWillEnterForeground and applicationDidEnterBackground on iOS. This makes all of the common situations where you want to pause your game work, such as the lock button. - Fix some memory leaks on iOS. Documentation: - Various documentation updates. - Generate multiple copies of a man page for all the API entries that it documents. Changes from 5.0.3 to 5.0.4 (August 2011) ========================================= The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang and torhu. Core: - Restore searching of directories on PATH for DLLs to load on Windows. - Fix crash on shutdown in headless Unix environment (no X11 display). - Change all instances of al_malloc + memset(0) to al_calloc. Graphics: - Save memory in OpenGL case by freeing bitmap memory after uploading a texture. Use a temporary buffer when converting lock buffer back to native texture format. - Don't release or refresh memory or sub-bitmaps when D3D device gets lost/found. - Do not set D3D sub bitmaps to modified when first creating them. This can cause major slowdowns when creating a lot of sub-bitmaps and is likely responsible for slow font performance/startup when using D3D. - Fix incorrect number of display formats in D3D (tobing). - Honor ALLEGRO_VSYNC in the WGL driver. - Make titlebar icons the right size on Windows. - Fix typo causing weird results of al_get_monitor_info on X. - Don't setup FBO for a sub-bitmap whose parent is locked. - Specialise ADD/ONE/INVERSE_ALPHA blend mode software scanline drawers. - Toggle ALLEGRO_VIDEO_BITMAP flag off when creating a memory bitmap (both bits were previously on). - Add null bitmap assertion to al_clone_bitmap. Input: - New system for mapping extended keys in Windows keyboard driver. Mainly for getting the same keycode for numpad keys independently of the state of Num Lock. - More reliable updating of the toggle modifiers in Windows keyboard driver (Num Lock, Caps Lock, and Scroll Lock). Timers: - Fix race conditions when starting timers from different threads. Audio addons: - Don't mix into a global temporary sample buffer, causing noise when two separate mixers are trying to run in parallel. - Make it possible to start/stop an audio stream which is attached to a voice. - ALSA voices could not be resumed after being stopped, because the update threads quit as soon as a voice is stopped. - OpenAL backend did not handle the case where _al_voice_update returns less than a full buffer. - Attempt to load FLAC and Vorbis DLLs only once to avoid Windows popping up too many error windows. Native dialogs addon: - al_show_native_messagebox() on Windows: add UTF-8 support; show heading; show information icon by default. TTF addon: - Reduce memory usage. - Don't make multiple passes over strings when computing text dimensions. Build system: - Make sure static builds on Windows never use DLL_TLS (Zac Evans). - Made compilation possible with different combinations of Xinerama, XF86VidMode, or Randr being present. - cmake: Use find_path HINTS instead of PATHS in our DirectX SDK scripts. - cmake: Search for D3DX9 once instead of multiple times (John-Kim Murphy). - cmake: Find FLAC/Ogg/Vorbis libraries under the names generated by the official MSVC project files. - Include zlib.h explicitly for libpng 1.5. Examples: - Add multisampling to SPEED example. Change examples to use ALLEGRO_SUGGEST for multisampling. - Include the font for speed.app under OSX within the bundle so it can be run by double clicking. - Use default blending/pre-multiplied alpha in ex_blend2. Other: - Various documentation updates. - Fix minor memory leaks. Bindings: - Better way to make the Python wrapper work with both Python 2 and 3. - Include Windows-specific functions in the Python wrapper. Changes from 5.0.2.1 to 5.0.3 (May 2011) ======================================== Input: - Fixed keyboard repeat for extended keys on Windows. Added ALLEGRO_KEY_MENU. (torhu) - Make Delete key in Windows send KEY_CHAR event with unichar code 127 (Peter Wang). Filesystem: - al_remove_filename returned false even if successful (reported by xpolife). Graphics: - On OpenGL ES 1.1, glReadPixels can only read 4 byte pixels (Trent Gamblin). Font addon: - Fix a small memory leak when unregistering a handler with al_register_font_loader (Trent Gamblin). Primitives addon: - Fix assertion failures when drawing al_draw_ellipse, al_draw_arc, al_draw_rounded_rectangle, al_draw_filled_rounded_rectangle at very small scales (reported by Carl Olsson). Native dialogs addon: - gtk: Fix truncated string if the final button contained a non-ASCII character (Peter Wang). Other: - Minor build fixes and documentation updates. Changes from 5.0.2 to 5.0.2.1 (April 2011) ========================================== - Fix regression on Windows where the keyboard state was not updated unless the keyboard event source is registered to an event queue. Changes from 5.0.1 to 5.0.2 (April 2011) ======================================== Input: - Fix inverted mouse wheel on X11. - Make unicode field in KEY_CHAR events zero for Fn, arrow keys, etc. for OS X (jmasterx, Peter Hull). - Support ALLEGRO_KEY_PAD_ENTER and detect left/right Alt and Ctrl keys independently on Windows (torhu, Matthew Leverton). Changes from 5.0.0 to 5.0.1 (March 2011) ======================================== The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. Other contributions noted in-line. Graphics: - Automatically destroy framebuffer objects (FBOs) created for non-memory bitmaps after a while. This solves the problem of running out of resources if you set many different target bitmaps. - Make al_get_opengl_fbo attempt to create an FBO if one doesn't exist. - Avoid very small textures in Direct3D. - Do not sync from memory when first creating/uploading a bitmap (D3D). - Try to fix the problem of the taskbar appearing above fullscreen windows on Windows. - Center the window after toggling fullscreen on Windows. Input: - Support 4-way mouse-wheel and up to 32 mouse buttons in X11. Audio addons: - Avoid buffer overrun while reading from vorbis files. - Added optional support for Tremor in place of libvorbis on any platform. - Do not prefer DirectSound with OpenAL. This can cause problems and also will override user config. - Play silence where needed in DirectSound driver. TTF addon: - Do not hold bitmap drawing when changing target bitmap, which is invalid and caused transformations to be misapplied. - Remove FBO for a cache bitmap once we are no longer adding glyphs to it. Build system: - Force "default" visibility of _al_mangled_main on OS X, otherwise the dynamic linker cannot find the symbol if building with XCode4 (Owen Anderson and Peter Hull). - Generated pkg-config files should take into account LIB_SUFFIX variable (Cristian Morales Vega). - Update allegro_font pkg-config file to not require allegro_primitives. Documentation: - Various documentation updates. - Add copy of DejaVu font licence. Bindings: - Add allegro_main addon to the Python wrapper. Make the wrapper work with Python 3, which has a different string representation. Add parameter type checking for custom types. Changes from 5.0.0 RC5 to 5.0.0 (February 2011) =============================================== Color addon: - Use colour names from CSS. This is the same as the previous list but with all grey/gray alternatives. Documentation: - Minor documentation updates. Changes from 5.0.0 RC4 to 5.0.0 RC5 (February 2011) =================================================== The main developers this time were: Thomas Fjellstrom, Trent Gamblin, Peter Hull, Matthew Leverton and Peter Wang. Other contributions noted in-line. System: - Load allegro5.cfg from the directory containing the executable, not the initial working directory. Graphics: - Make al_get_monitor_info return success code. - Replace al_set_new_display_adaptor(-1) with a named constant ALLEGRO_DEFAULT_DISPLAY_ADAPTER. - Fix numerous bugs in X mode setting and multi monitor related code, and introduce new xrandr code. - Generate ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY when mouse leaves OS X window (Evert Glebbeek). - Hide OS X window during exiting fullscreen window mode, to prevent the hideous misaligned animation from showing. - Fix erroneous assertions in OpenGL backend. - Added a hack which makes OpenGL mode work under Wine for me (Elias Pschernig). - Add support for some al_get_display_options in D3D port. Keyboard: - Don't send KEY_CHAR events for modifier and dead keys (with contributions from torhu). - Don't send KEY_DOWN events for non-physical key events. - osx: Allow unicode entry (single keypresses only). - x11: Set the keycode field in KEY_CHAR events to the code of the last key pressed, as stated in the documentation, even if the char is due to a compose sequence. - x11: Get rid of historic behaviour where the unicode field is always zero when Alt is held down. - Rename ALLEGRO_KEY_EQUALS_PAD to ALLEGRO_KEY_PAD_EQUALS for consistency. Mouse: - Add al_grab_mouse and al_ungrab_mouse. Implemented on X11 and Windows. - Allow the user configure a key binding to toggle mouse grabbing on a window. - Support horizontal mouse wheel on Windows (jmasterx). - Calculate Y position for al_set_mouse_xy correctly in OS X windowed mode (X-G). - Use more appropriate CURSOR_LINK cursor on OS X (X-G). - Assign different button IDs for separate touches on iPhone (Michał Cichoń). - iphone: Remove fake mouse move events as they're unncessary and can cause problems with user input tracking. Filesystem: - Clean up al_get_standard_path(): remove SYSTEM_DATA, SYSTEM_SETTINGS, PROGRAM paths; add RESOURCES and USER_DOCUMENTS paths. Use system API calls if possible. - Implement ALLEGRO_USER_DATA_PATH under Linux. Honor XDG_DATA/CONFIG_HOME environment variables. - Fix al_make_directory on Windows due to problems with calls to stat() with trailing slashes. Native dialogs addon: - Use string arguments to al_create_native_file_dialog() and al_get_native_file_dialog_path() instead of ALLEGRO_PATH. - Enhance the Windows file selector (initial patch by Todd Cope): - Use Windows' folder selector for ALLEGRO_FILECHOOSER_FOLDER. - Implement patterns. - Display the title of the dialog that the user specified. Primitives addon: - Fix changing the D3D blender state without updating the cached state. TTF addon: - Align glyphs in ttf font sheets so as to work around problems with forced S3TC compression with some OpenGL drivers (Elias Pschernig). Examples: - SPEED: add full screen flag, use standard paths for highscores and data. Build system: - Check PulseAudio backend will compile before enabling support. - Give a louder warning if FLAC/Vorbis/DUMB compile tests fail. Other: - Many leaks fixed on OS X. - Minor bug fixes and documentation updates. Changes from 5.0.0 RC3 to 5.0.0 RC4 (December 2010) =================================================== The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Peter Wang. Graphics: - d3d: Don't generate intermediate resize events during modal resize loop. - Optimize D3D9 driver by caching blender state and scissor rectangle so redundant calls to D3D9 functions are avoided (Michał Cichoń). - gl: Use glGenerateMipmapEXT to generate mipmaps when FBOs are used. - x11: Don't restore display mode if another fullscreen display is active. Input: - iphone: Reverse button/axis events that were swapped at some point. File I/O: - Change the way user code implements new ALLEGRO_FILE structures. This adds al_create_file_handle and al_get_file_userdata. - Implement default ungetc behavior - used if the interface does not supply its own. - Add al_fopen_interface. Memfile addon: - Implement ungetc. - Add rw file modes. - Rename header to allegro_memfile.h. - Add documentation. Image I/O addon: - Fix endian issues in TGA and Mac OS X image loaders. Other: - Use _NSGetExecutablePath for al_get_standard_path(ALLEGRO_EXENAME_PATH) on OS X (Jeff Connelly). - Minor bug fixes and documentation updates. Changes from 5.0.0 RC2 to 5.0.0 RC3 (December 2010) =================================================== The main developers this time were: Michał Cichoń, Trent Gamblin, Peter Wang. Graphics: - Honour subbitmap clipping rectangle under OpenGL (Elias Pschernig). - Fix an error in the Direct3D primitives blending. - al_set_new_window_position() did not have an effect for resizable windows on X11. - Fix windows only showing up on first monitor on X11 (Thomas Fjellstrom). - Implement al_get_monitor_info() for iDevices. Input: - Separate character inputs from physical key down events. This removes unichar and modifiers fields from ALLEGRO_EVENT_KEY_DOWN, and replaces ALLEGRO_EVENT_KEY_REPEAT by ALLEGRO_EVENT_KEY_CHAR. We decided this design flaw was better fixed now than later. - Make Mac OS X keyboard driver properly distinguish key down and key repeat events. TTF addon: - Respect ALLEGRO_NO_PREMULTIPLIED_ALPHA flag when loading TTF fonts. Other: - Fix returning a garbage pointer in maybe_load_library_at_cwd (Vadik Mironov). - Remove dependency on dxguid. - Minor compilation fixes and documentation updates. Changes from 5.0.0 RC1 to 5.0.0 RC2 (December 2010) =================================================== The developers this time were: Trent Gamblin, Elias Pschernig and Peter Wang. System: - Add al_is_system_installed and hide al_get_system_driver. - Prevent 'DLL hijacking' security issue on Windows. Graphics: - Change to using premultiplied alpha by default. The new bitmap flag ALLEGRO_NO_PREMULTIPLIED_ALPHA was added. - Change the value of ALLEGRO_VIDEO_BITMAP to non-zero. - Change al_get_opengl_version to return a packed integer. - Made al_get_opengl_version return an OpenGL ES version (if using OpenGL ES) rather than an attempted estimate at a desktop GL version. - Added function al_get_opengl_variant that returns either ALLEGRO_DESKTOP_OPENGL or ALLEGRO_OPENGL_ES. - Make al_have_opengl_extension return bool. - Fix OpenGL graphics mode height value on Windows. - Only try to create one Direct3D display at a time. - Make screensaver activate on Windows Vista and above unless inhibited. - Avoid potential divide-by-zeroes when computing the refresh rate in X11 video modes. Events: - Delete an incorrect mutex destroy in al_unregister_event_source. Input: - Revert the joystick driver used on OS X 10.4 to the pre-hotplugging version, rather than one which contained an earlier attempt at implementing hotplugging. Select the 10.4 or greater joystick driver at runtime. iPhone: - Added two iPhone-specific functions: al_iphone_override_screen_scale and al_iphone_program_has_halted. Image I/O addon: - Made the iPhone and OSX image loaders not try and correct colors to some arbitrary color space, but instead use the values directly from the image. Native dialogs addon: - Tolerate null display in al_show_native_file_dialog on Windows. - Make GTK native dialog implementation only call GTK from a single thread. - Define al_show_native_message_box to be usable without installing Allegro. Primitives addon: - Make primitives addon compilable again without OpenGL. Examples: - ex_ttf: Test the monochrome flag. - Work around problems with MSVC and UTF-8 string literals. ex_utf8 is now not built under MSVC. - Don't use WIN32 executable type on examples that require the console (David Capello). Other: - Minor bug fixes and documentation updates. Changes from 4.9.22 to 5.0.0 RC1 (November 2010) ================================================ The developers this time were: Trent Gamblin, Evert Glebbeek, Elias Pschernig, Paul Suntsov, Peter Wang. Graphics: - Make al_resize_display keep the original resolution (or change back) if it can't set the users request, on Windows. - Do not emit ALLEGRO_DISPLAY_RESIZE events from the Windows and X11 display drivers when using al_resize_display. - [X11] Make al_get_num_display_modes and al_get_display_mode work if the adapter is set to default. Right now there was no way to query the modes of the default monitor. - [X11] Use _NET_WM_STATE_FULLSCREEN hint for "true" fullscreen displays. Enable mouse grabbing in fullscreen modes. - Added ALLEGRO_EVENT_DISPLAY_ORIENTATION and implement it on iOS. - Dennis Busch fixed a problem with displays not showing up on the primary display by default in some dual head setups, on Windows. - Increase the precision of texture coordinate deltas in the software triangle renderer, from floats to doubles. - Remove al_get_frontbuffer(). It wasn't implemented anywhere. - Implement min/mag filter and mipmap flags for Direct3D. Input: - Report correct initial mouse position if a display is created with the mouse pointer inside, or if the mouse routines are installed after a display is created (X11, Windows). - John Murphy fixed improperly mapped axes on the Windows joystick driver. Events: - Do not register user event sources with the destructor system as it cannot work reliably. User event sources must be destroyed manually. Filesystem: - Make al_get_fs_entry_name and al_get_current_directory return strings instead of ALLEGRO_PATH. - Make al_make_directory create parent directories as needed. - Fix al_create_fs_entry to not trim the root path "/" down to the empty string with the stdio backend. Path routines: - Remove al_make_path_absolute and replace it by al_rebase_path. - Remove undocumented behavior of setting a default organization name of "allegro" for all apps. - Correctly return standard paths as directories on OS X. Threads: - Rename al_wait_cond_timed to al_wait_cond_until to match al_wait_cond_until. Config routines: - Add a blank line between sections when writing out a config file. Other core: - Move the Windows event loops back into the same thread as the D3D event loop. It's a requirement of D3D, else you can get crashes as I was when resetting the device (like tabbing away from a fullscreen app). - Add some missing standard entries to the OS X menu bar (the "hide", "hide others" and the window list, mainly). Audio addon: - Automatically stop sample instances which point to a buffer of a sample which is about to be destroyed with al_destroy_sample. - alsa: Resume properly after suspending. Image I/O addon: - Make GDI+ support compile cleanly with the headers that come with MinGW package w32api-3.15. - Speed up PNG and BMP saving, and NSImageFromAllegroBitmap loading. TTF addon: - Add a flag for loading TTFs without anti-aliasing (ALLEGRO_TTF_MONOCHROME). Primitives addon: - Fix several failed sub-bitmap related unit tests on Windows. - Made thick outlined triangles look nicer when the triangles are very thin. - Add a debug-only check for primitives addon initialization to aid in code portability. Examples: - Added example demonstrating the effect of premultiplied alpha. - Make 'F' toggle fullscreen window in SPEED (in-game). - Minor improvements to the a5teroids demo. Documentation: - Many documentation updates. - Add list of contributors and a readme for packagers. - Make make_doc tool build cleanly on MSVC, and work around a problem with recent version of Pandoc on Windows. - Improve styling of PDF output. - Add generated man pages to archives. Bindings: - Implemented array types in the Python wrapper. Changes from 4.9.21 to 4.9.22 (September 2010) ============================================== The developers this time included: Michał Cichoń, Trent Gamblin, Evert Glebbeek, Angelo Mottola, Elias Pschernig, Paul Suntsov and Peter Wang. System: - Allow the X11 port to initialise without an X server connection. Graphics: - Fix many bugs with bitmap locking. - Fix many bugs to do with transformations, flipping and clipping. - Fix many bugs to do with sub-bitmaps as source and destination. - Renamed al\_draw\_[tinted\_]rotated_scaled_bitmap to al\_draw\_[tinted\_]scaled_rotated_bitmap to match the parameter order. - Reimplemented bitmap software rendering routines using newly optimised software triangle renderer, formerly in the primitives addon. - Add pixel_size field to ALLEGRO_LOCKED_REGION. - Fix bugs to do with pixel alignment on OpenGL. - Fix OpenGL pixel transfer of 15 bpp formats, where Allegro does not Allegro does not care whether the unused bit is set or not, but when transferring to OpenGL it will be interpreted as an alpha bit. - Disabled support for drawing a bitmap into itself. - Changed specification of al\_draw_*bitmap to not allow transformation and ignore blending/tinting when the screen itself is being drawn (except when drawn into a memory bitmap). - Allow bitmap regions to be outside the bitmap area in drawing routines. - Added al_add_new_bitmap_flag convenience function. - Added three new bitmaps flags ALLEGRO_MAG_LINEAR, ALLEGRO_MIN_LINEAR, ALLEGRO_MIPMAP. Removed the config settings for linear/anisotropic min/mag filtering. DirectX side not yet updated. - Register destructors for bitmaps, so they will be implicitly destroyed when Allegro is shut down. This was only true for some bitmaps previously. - Don't allocate memory buffers for video bitmaps when using OpenGL. - Make al_get_opengl_extension_list() return NULL if called on a non-GL display. - Fix al_create_display for OpenGL forward compatible contexts. - Add al_set_current_opengl_context as an explicit way to set the OpenGL context. - Rename al_is_opengl_extension_supported to al_have_opengl_extension. - Produce more accurate/correct color when going from less to more bits per component. - Fix al_set_new_window_position() everywhere. - Avoid potential deadlock if resizing window to the same size on X11. - Fixed turning off vsync in X11. - Added al_is_d3d_device_lost function. - Dynamically load dinput and d3d DLLs on Windows. - Replaced PeekMessage with GetMessage in window event loops for the D3D and WGL drivers (David Capello). Input: - Added hotplugging support for joysticks on Linux, Windows and OS X. - Added al_reconfigure_joysticks function. - Merged all joystick devices under a single joystick event source. - Removed al_get_joystick_number. - Add al_is_joystick_installed. - The OS X joystick driver was rewritten; it requires OS X 10.5. The older driver still exists for OS X 10.4 and earlier but is in a semi-updated state with regards to hotplugging. - Allow user to override joystick device paths in the config file (Linux). - Fix iphone touch input and clipping for modes other than w=768,h=1024. - Fixed missing mouse movement messages on IPhone on touch-up/down. Also changed how mouse buttons are reported - always as button 1 now. Config: - Give config iterators proper types instead of void *. - Make al_get_system_config() always return non-NULL if a system driver is installed. Events: - Rename al_event_queue_is_empty to al_is_event_queue_empty (with compatibility define). Timers: - Add al_add_timer_count function. - Rename al_timer_is_started to al_get_timer_started. - Rename al_current_time to al_get_time (with compatibility define). File I/O: - Add al_open_fs_entry to open a file handle from an FS_ENTRY. - Add al_fclearerr. - Set ALLEGRO_FILEMODE_HIDDEN flag on entries for file names beginning with dot (OS X). - Remove al_is_path_present, al_fs_entry_is_directory, al_fs_entry_is_file (all trivial). Primitives addon: - Optimised most of the software rendering routines by a lot. - Triangle drawer was skipping pixels in very thin triangles. - Handle lost d3d devices better. - Fix some bugs found during testing. Image I/O addon: - Fix native image loader on Mac OS X: images that were not 72 dpi would be rescaled to a smaller size. - Added native bitmap saving support for OSX. - Fix jpeg saving when locked region has negative pitch. Native dialogs addon: - Add Windows and OS X text log implementations. - Add ALLEGRO_FILECHOOSER and ALLEGRO_TEXTLOG types instead of conflating them into ALLEGRO_NATIVE_DIALOG. - Fix race condition in al_open_native_text_log. - Rename al_destroy_native_dialog to al_destroy_native_file_dialog. - Rename al_get_native_dialog_event_source to al_get_native_text_log_event_source. - Speed up text log appending by making the reader/writers asynchronous. - Register destructors for file chooser and text log dialogs. - Fix file chooser on Windows returning multiple selections with slashes appended to filenames. If an initial path was specified then the dialog wouldn't open at all; fixed. - Let native dialog functions fail gracefully. Audio addons: - Init destructors even if audio driver fails to install. - Dynamically load dsound DLL on Windows. Font addons: - Added al_shutdown_ttf_addon. - Prevent SIGSEGV for double-closing a file in the TTF addon if it is not a valid font file. - Make al_grab_font_from_bitmap not cause a segmentation fault if the bitmap is garbage. - Some TTF fonts would not render right at small sizes; fixed. - Make al_destroy_font ignore NULL. Tests: - Added a test suite (finally). - Add a shell script to produce test coverage results using lcov. Examples: - Add ex_haiku, an example based on Mark Oates's Haiku game. Mark generously agreed to let us include it as an Allegro example. - Added a new example ex_joystick_hotplugging. - Added a new example ex_filter. - Make ex_fs_window work on MSVC. - Allow a5teroids to run without audio, or if audio data doesn't load. Build system: - Re-added CMake option that allows forced static linking of libFLAC. - Replaced the old iphone xcode project with a cmake iphone toolchain. Documentation: - Many updates to the reference manual. Bindings: - Added a workaround to the Python wrapper for a Mingw bug. Changes from 4.9.20 to 4.9.21 (July 2010) ========================================= The main developers this time were: Trent Gamblin, Matthew Leverton, Elias Pschernig, Paul Suntsov, Peter Wang. Graphics: - Fixed the mis-termed "blend color". There is no more color state. - al_set*_blender functions lose the color parameter. - Added 5 new bitmap drawing functions al_draw_tinted*_bitmap with a color parameter. The parameter is used just like the "blend color" before. - All text drawing functions gain a color parameter and use it like they used the "blend color" before. - Primitive drawing functions previously sometimes (and sometimes not) used the "blend color". Not any longer. - Make the current blending mode thread-local state instead of per-display state. - Add explicit display arguments to functions which require a display, but don't require the rendering context to be current. - Make al_set_target_bitmap change the current display as necessary. al_set_target_bitmap(NULL) releases the rendering context. - Add al_set_target_backbuffer as a convenience. - Remove al_set_current_display. - Give each bitmap its own transformation, i.e. every bitmap has a transformation, which is in effect when that bitmap is the target. - Remove sub-bitmap clip-to-parent restriction on create. Add out-of-bounds blitting support to memory bitmaps. - Merge sub-bitmap and parent bitmap clipping; clip source bitmap to (0,0)-(w,h); fix flipping to/from clipped bitmaps. - Made mouse cursors independent of displays. You may create cursors without a display, and you may use a cursor with any display. - Rename al_{set,get}_current_video_adapter to *new_display_adapter for consistency. - Move the new display video adapter and new window position to thread-local state, like other new display parameters. Make al_store_state also save those parameters with ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS. - Rename al_transform_transform to al_compose_transform. Switched the order of parameters in al_compose_transform and al_copy_transform to match the rest of the transform functions. - Made memory bitmap manipulation without a display possible (again?). - Fixed window resizing in D3D driver. Simplify resize-postponing on Windows. - Make al_create_display abort early when the new_display_adapter is greater than the screen count (X11). - Added ALLEGRO_MINIMIZED flag to the X11 port. - Fixed OpenGL version string parsing (bug #3016654). Other core: - Renamed al_install_timer to al_create_timer, and al_uninstall_timer to al_destroy_timer. - Rename al\_{get,set}\_{appname,orgname} to \*app_name and \*org_name. - Fix assertion failure in al_create_mutex_recursive on Windows (spoofle). Primitives addon: - Made the D3D driver of the primitives addon work with multiple displays. Also made it handle the display being destroyed properly. - Simplified shader recreating on thread destruction when using the primitives addon with D3D. - Avoid double free when shutting down the primitives addon multiple times. - Older Intel cards don't implement DrawIndexedPrimitiveUP correctly. Altered the D3D code to work around that. Audio addon: - Allow setting the DirectSound buffer size via allegro5.cfg. Image addon: - Make GDI+ image loader work with MinGW. Font addon: - Nicolas Martyanoff added al_get_font_descent/ascent functions which query per-font properties. Previously it was necessary to call al_get_text_dimensions (which now just reports the text dimensions as it should). Native dialogs addon: - Add text log window functions (GTK only for now). Documentation: - Many updates to the reference manual. - Improve styling and add Allegro version to HTML pages. - Separated readme_a5.txt into multiple files, and hopefully improve them. Build system: - Remove INSTALL_PREFIX. Windows users can now use CMAKE_INSTALL_PREFIX to set the install path. - Allow the user to place dependencies in a subdirectory "deps", which will be automatically searched. Examples: - Use text log windows in many examples. - Add ex_noframe: test bitmap manipulation without a display. Bindings: - Update Python bindings. Changes from 4.9.19 to 4.9.20 (May 2010) ======================================== The developers this time were: Thomas Fjellstrom, Evert Glebbeek, Matthew Leverton, Milan Mimica, Paul Suntsov, Trent Gamblin, Elias Pschernig, Peter Wang. With significant contributions from Michał Cichoń. Core: - Add al_malloc, al_free, et al. These are now used consistently throughout Allegro and its addons. - Replace al_set_memory_management_functions by a simpler function, al_set_memory_interface. - Renamed some D3D/Windows specific functions to follow the al_{verb}_{stuff} convention. Graphics: - Move image I/O framework to core, i.e. al_load_bitmap, al_save_bitmap and bitmap file type registration. Image codecs remain in allegro_image. - Added a simple display capabilities querying capability to al_get_display_option: ALLEGRO_MAX_BITMAP_SIZE, ALLEGRO_SUPPORT_NPOT_BITMAP, ALLEGRO_CAN_DRAW_INTO_BITMAP, ALLEGRO_SUPPORT_SEPARATE_ALPHA. (OpenGL only for now) - Fix in OpenGL 3.0 context creation. - Make the extensions mechanism compatible with OpenGL version >= 3. Declared symbols needed by OpenGL 3.2 and 3.3 and brought OpenGL extensions up to date. - Fix an assertion in _al_draw_bitmap_region_memory so it does not trigger when source and destination are the same bitmap. - Fix some locking issues by setting GL_PACK_ALIGNMENT and GL_UNPACK_ALIGNMENT before reading/writing pixels. - Partial implementation of ALLEGRO_FULLSCREEN_WINDOW on OS X (Snow Leopard, probably Leopard). - Started X11 fullscreen support (resolution switching). - Fix handling of X11 size hints. - Fixed a deadlock related to fullscreen windows under X11 caused by using a nested lock for a condition variable. - Use _NET_WM_ICON to set icon on X11 instead of XSetWMHints. - Get the iPhone OpenGL version more properly. Only use separate blending on iPhone with OpenGL ES 2.0+. - Release the splash view and windows on iPhone, which makes backgrounding Allegro apps on OS 4.0 work. - Updated iphone port for IPad (only tested in the simulator). Input: - Disabled Raw Input code in Windows. Mouse events now reflect system cursor movements even in fullscreen mode. - Prevent late WM_MOUSELEAVE notifications from overriding mouse state display field (Windows). - Update pollable mouse state with axes events as well as button events on iPhone. Filesystem: - Made the filesystem entry functions work under Windows even if the name passed to al_create_fs_entry has a trailing slash or backslash. Config routines: - Add al_{load,save}_config_file_f. - Reorder al_save_config_file* arguments to match al_save_bitmap and al_save_sample. - Optimise config routines to work well for thousands of keys/sections. Image addon: - Added a GDI+ implementation of the image codecs, which will be used in favour of libjpeg/libpng if Allegro is compiled with MSVC. Then allegro_image will not require JPEG/PNG DLLs at runtime. - Removed format specific image functions. - Fixed bug in native png loader on iphone: was using the source color space instead of the target color space which made it fail whenever they differed (alpha-less paletted pictures). - Add an autorelease pool around iphone native image loading to stop memory leaks. Font addons: - Sever the tie between allegro_font and allegro_image. The user needs to initialise the image addon separately now. - Rename al_load_ttf_font_entry to al_load_ttf_font_f. - Fixed problem with glyph precision after applying transformations in the ttf addon. Primitives addon: - Added al_init_primitives addon function. This is now required. - Removed ALLEGRO_PRIM_COLOR; ALLEGRO_COLOR can now be used where it was required. - v textures coordinates were off for OpenGL non-power-of-two textures. - Free the vertex cache in al_destroy_display on X11. - Added the dummy vertex shader support to D3D driver of the primitives addon. Without this, custom vertices either resulted in warnings or outright crashes on some systems. - Bring D3D driver up to speed a little bit: transformations now work properly with sub-bitmap targets; the half-pixel offset now properly interacts with transformations; al_set_target_bitmap does not clear the transformation; the proper transformation is set at display creation. - Cull the primitives that are completely outside the clipping region. - Scale the numbers of vertices for the curvy primitives with the scale of the current transformation. Audio addon: - Remove driver parameter from al_install_audio. - Rename al_get_depth_size to al_get_audio_depth_size. - Rename al_get_audio_stream_buffer to al_get_audio_stream_fragment. - Many improvements to AQueue driver. Audio codecs: - Add MOD/S3M/XM/IT file support, using the DUMB library. - Revert to a monolithic allegro_acodec addon, i.e. remove separate allegro_flac, allegro_vorbis addons. WAV file support is in allegro_acodec. - Implement DLL loading for FLAC/Vorbis/DUMB on Windows. allegro_acodec will load the DLL at runtime to enable support for that format. If your program does not require said format, you don't need to distribute the DLL. - Remove format-specific loader/saver audio codec functions. - Make acodec loaders have consistent file closing behaviour. - Optimised wave file loading. Examples: - Make SPEED port run acceptably on graphics drivers without FBOs. Documentation: - Added documentation for the public Direct3D specific functions. - Documented ALLEGRO_OPENGL_3_0 and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. Other: - Many bug and documentation fixes. Changes from 4.9.18 to 4.9.19 (April 2010) ========================================== The main developers this time were: Milan Mimica, Trent Gamblin, Paul Suntsov, Peter Wang. Other contributions from: Evert Glebbeek and Shawn Hargreaves. Graphics: - Implemented support for transformations for memory bitmaps. - Transformations now work properly when the target bitmap is a sub-bitmap in OpenGL (still broken in D3D). Also fixed OpenGL bitmap drawing in the same scenario (it used to always revert to software drawing). - Use the memory drawers when the source bitmap is the backbuffer with the rotated/scaled bitmaps. - Make al_put_pixel clip even if the bitmap is locked, which was the reason why software primitives were not clipping. - Added al_put_blended_pixel, the blended version of al_put_pixel. - Sub bitmaps of sub bitmaps must be clipped to the first parent. - Don't clear the transformation when setting the target bitmap in OpenGL. - Implemented ALLEGRO_NOFRAME and ALLEGRO_FULLSCREEN_WINDOW in WGL. - Set the ALLEGRO_DISPLAY->refresh_rate variable for fullscreen modes under D3D. - Make d3d_clear return immediately if the display is in a lost state. - Rewrote the function that reads the OpenGL version so it works for previously unrecognised versions, and future versions. - Check for framebuffer extension on iPhone properly. - Fixed locking bugs on iPhone. allegro_ttf works now. Input: - Removed al_set_mouse_range. - Don't call al_get_mouse_state if the mouse driver isn't installed (Windows). - Send events even when the mouse cursor leaves the window, while any buttons are held down (Windows and Mac OS X; X11 already did this). - Allow mouse presses and accelerometer data simultaneously. (iPhone) File I/O: - Optimise al_fread{16,32}* by using only one call to al_fread each. - Optimise al_fgetc() for stdio backend. Path: - Fix an infinite loop in _find_executable_file when searching for the executable on the PATH (Alan Coopersmith). Primitives addon: - Made the software driver for the primitives addon check for blending properly. Also, fixed two line shaders. - Made the D3D driver thread-safe. The whole addon should be thread-safe now. - The addon now officially supports 3D vertices, even though the software component can't draw them yet. - Changed the way the primitives addon handles the OpenGL state (fixes a few bugs and makes life easier for raw-OpenGL people) Image addon: - Optimised BMP, PCX, TGA loaders. - Fix loading 16-bit BMP files. - Fix loading grayscale TGA images. - Nial Giacomelli fixed a bug where images could be corrupt using the native Apple image loader (iPhone). Audio addon: - Add al_is_audio_installed. - Fix al_attach_sample_instance_to_mixer for int16 mixers. - Implement attaching an INT16 mixer to another INT16 mixer. - Handle conversion when an INT16 mixer is attached to a UINT16 voice. Build system: - Add an option to disable Apple native image loader (iPhone and OS X). - Add ttf addon target to iPhone xcode project. Examples: - Special contribution from Shawn "the Progenitor" Hargreaves. Changes from 4.9.17 to 4.9.18 (March 2010) ========================================== The main developers this time were: Trent Gamblin, Elias Pschernig, Evert Glebbeek, Peter Wang. Other contributions from: Milan Mimica, Paul Suntsov, Peter Hull. Graphics: - Fixed broken drawing into memory bitmaps as access to the global transformation required an active display. Now both transformation and current blending mode are stored in the display but provisions are made for them to also work if the current thread has no display. - Fixed a bunch of clipping problems with OpenGL, especially with sub-bitmaps. - Fix bug in OpenGL FBO setup when the target bitmap is the sub-bitmap of a bitmap with an FBO. - Fixed crash in al_get_num_display_modes under OSX 10.5. - Fixed some problems in _al_convert_to_display_bitmap that caused problems in WGL FS display resize. - Fixed al_set_current_display(NULL) on WGL. - Added subtractive blending. al_set_blender() takes another parameter. - Added ALLEGRO_FULLSCREEN_WINDOW display flag (X11 and D3D for now). - Allow changing ALLEGRO_FULLSCREEN_WINDOW with al_toggle_display_flag. - Figured out how to switch display modes using Carbon on OS X 10.6. - Stop the OpenGL driver on iPhone from changing the currently bound FBO behind our back when locking a bitmap. - Prevent screen flicker at app startup by simulating the splash screen (iPhone). Input: - Added "pressure" field to the mouse event struct and mouse state, which can be used with pressure sensitive pointing devices, i.e. tablets/stylus (currently OS X only). - Report scroll ball "w" position in mouse event struct, on OS X. - Removed OS X 10.1 specific code from mouse driver. We don't support OS X 10.1 any more. - Fix building of Linux joystick driver on some systems. Threads: - Fix a problem when al_join_thread() is called immediately after al_start_thread(). The thread could be joined before the user's thread function starts at all. - Fix a possible deadlock with al_join_thread() on Windows (thanks to Michał Cichoń for the report). - Fix some error messages running threading examples on OS X. Other core: - Added version check to al_install_system. - Rename al_free_path to al_destroy_path for consistency. - Make it possible to have an empty organization name with al_set_org_name(). - Changed implementation of AL_ASSERT to use POSIX-standard assert instead. - Removed al_register_assert_handler. - Fix timer macros which did not parenthesize their arguments. - Make stricmp, strlwr, strupr macros conditionally defined. Audio addon: - Rename al_attach_sample_to_mixer to al_attach_sample_instance_to_mixer. - Fix a premature free() when detaching samples and other audio objects. - Fix mixers attaching to mixers. - Pass correct number of samples to mixer postprocess callback. - AudioQueue code was not compiled even though version requirements may have been met (OS X). Primitives addon: - Make high-level primitives functions thread safe. (note: the DirectX driver is not yet thread safe) - Fix a bug causing crashes on Windows 7 when using the primitives addon and Direct3D (Invalid vertex declarations were being used). - Fixed another issue with primitives drawing to memory bitmaps. - Hopefully fix the bitmap clipping bugs, and make the D3D and OGL/Software outputs to be near-identical again. Image addon: - Added a "native loader" for MacOS X that uses the NSImage bitmap loading functions. In addition to .png and .jpg, this allows us to read a whole zoo of image formats (listed in allegro.log). - Add native support for tif, jpg, gif, png, BMPf, ico, cur, xbm formats to under IPhone. - Fixed an over-zealous ASSERT() that disallowed passing NULL to al_register_bitmap_loader() despite this being an allowed value. - Avoid using a field which is deprecated in libpng 1.4. Color addon: - Make al_color_name_to_rgb return a bool. Native dialogs addon: - Fixed some erratic behaviour and crashes on OS X. Build system: - Set VERSION and SOVERSION properties on targets to give Unix shared libraries proper sonames. e.g. liballegro[_addon].so.4.9, liballegro[_addon].4.9.dylib - Static libraries are now named without version number suffixes to minimise the differences with the shared libraries, which no longer have the versions in their base names. e.g. liballegro[_addon]-static.a, allegro[_addon]-static.lib - Windows import libraries are also named without version suffixes, e.g. liballegro[_addon].a, allegro[_addon].lib - DLLs are named with a short version suffix, not the full version. e.g. allegro-4.9.dll instead of allegro-4.9.18.dll - Add support for Mac OS X frameworks (untested), which are enabled with WANT_FRAMEWORKS and WANT_EMBED. There is one framework per addon. - Search for static OGG/Vorbis libraries built with MSVC named libogg_static.lib, etc. - Updated iPhone XCode project. Examples: - ex_mixer_pp: New example to test mixer postprocessing callbacks. - ex_threads: Make it more visually interesting and test out per-display transformations. - ex_ogre3d: New example demonstrating use of Ogre graphics rendering alongside Allegro (currently GLX only). Commented out in the build system for now. - ex_fs_window: New example to test ALLEGRO_FULLSCREEN_WINDOW flag and al_toggle_display_flag. - ex_blend2: Updated to test subtractive blending, including scaled/rotated blits and the primitives addon. - ex_mouse_events: Show "w" field. - ex_prim: Added possibility to click the mouse to advance screens (for iPhone). - ex_vsync: Display config parameters and warning. - ex_gldepth: Make the textures appear again though we're not sure why they disappeared. Documentation: - Many documentation updates. - Add which header file and which library to link with for each page of the reference manual. - Minor improvements to HTML styling and man page output. Changes from 4.9.16 to 4.9.17 (February 2010) ============================================= The main developers this time were: Trent Gamblin, Elias Pschernig, Evert Glebbeek, Paul Suntsov, Peter Wang. Core: - Removed END_OF_MAIN() everywhere. For MSVC, we pass a linker option through a #pragma. On Mac OS X, we rename main() and call it from a real main() function in the allegro-main addon. The prototype for main() for C++ applications should be "int main(int, char **)", or the code will not compile on OS X. For C, either of the normal ANSI forms is fine. \#define ALLEGRO_NO_MAGIC_MAIN disables the \#pragma or name mangling, so you can write a WinMain() or use al_run_main() yourself. Graphics: - Fixed a bug in the OpenGL driver where al_draw_bitmap() wouldn't handle blitting from the back buffer. - Changing the blending color now works with deferred drawing (Todd Cope). - Avoid some problems with window resizing in Windows/D3D. - Added al_get_d3d_texture_position. - Fixed bug under X11 where al_create_display() would always use the display options from the first al_create_display() call. - Properly implemented osx_get_opengl_pixelformat_attributes(). - Fixed automatic detection of colour depth on OS X. - Fixed al_get_num_display_modes() on Mac OS X 10.6. - Removed al_get_num_display_formats, al_get_display_format_option, al_set_new_display_format functions as they can't be implemented on OSX/iPhone/GPX ports (and were awkward to use). - Replaced al_toggle_window_frame function with a new function al_toggle_display_flags. - al_load_bitmap() and al_convert_mask_to_alpha() no longer reset the current transformation. - Add a minimize button to all non-resizable windows on Windows. - The wgl display switch-in/out vtable entries were swapped (Milan Mimica). Input: - Some keycodes were out of order in src/win/wkeyboard.c - Fixed mouse range after resizing window on Windows. - Fixed (or worked around) a joystick axis detection problem on Mac OS X. - Change timer counts from 'long' to 'int64_t'. File I/O: - Remove `ret_success' arguments from al_fread32be/le. allegro-main addon: - Added an "allegro-main" addon to hold the main() function that is required on Mac OS X. This way the user can opt out of it. Primitives addon: - Added support for sub-bitmap textures in OpenGL driver. - Added support for sub-bitmap textures in D3D driver. Made D3D sub-bitmaps work better with user D3D code. Audio addons: - Changed the _stream suffix to _f in the audio loading functions. - Added the stream versions of loading functions for wav, ogg and flac. - Rename audio I/O functions to al_load_{format}, al_save_{format}, al_load_{format}_f and al_save_{format}_f. - Added al_load_sample_f, al_save_sample_f, al_load_audio_stream_f and the related functions. - Fixed a bug where al_save_sample was improperly handling the extension. - al_drain_audio_stream would hang on an audio stream in the 'playing' state (the default) which wasn't attached to anything. - Fixed a potential deadlock on destroying audio streams by shutting down the audio driver. - Comment out PA_SINK_SUSPENDED check, which breaks the PulseAudio driver, at least on Ubuntu 9.10. - Replace unnecessary uses of `long' in audio interfaces. Image addons: - Fixed return values of al_save_bmp_f and al_save_pcx_f being ignored. - Changed the _stream suffix to _f in the image loading functions. TTF addon: - Drawing TTF fonts no longer resets the current transformation. Build system: - Add the CMake option FLAC_STATIC, required when using MSVC with a static FLAC library. - Link with zlib if linking with PhysicsFS is not enough. - Updated iPhone project files. Documentation: - Many documentation updates. Examples: - ex_display_options: Added mouse support, query current display settings, display error if a mode can't be set. Bindings: - Made the Python wrapper work under OSX. - Added a CMake option to build the Python wrapper. - Added al_run_main() mainly to support the Python wrapper on OSX. Changes from 4.9.15.1 to 4.9.16 (November 2009) =============================================== The main developers this time were: Trent Gamblin and Paul Suntsov. Graphics: - Fixed clipping of the right/bottom edges for the software primitives. - Enable sub-pixel accuracy for rotated blitting in software. - Made the D3D output look closer to the OGL/Software output. - OpenGL driver now respects the 'linear' texture filtering configuration option. Anisotropic is interpreted as linear at this time. - Added deferred bitmap drawing (al_hold_bitmap_drawing). - Made the font addons use deferred bitmap drawing instead of the primitives addon, removing the link between the two addons. - Changed al_transform_vertex to al_transform_coordinates to make the function more versatile. - Transfered transformations from the primitives addon into the core. Added documentation for that, as well as a new example, ex_transform. Transformations work for hardware accelerated bitmap drawing (including fonts) but the software component is not implemented as of yet. Also fixed some bugs inside the code of the transformations. - Increase performance of screen->bitmap blitting in the D3D driver. - Fixed a strange bug with textured primitives (u/v repeat flags were being ignored on occasion). - Added ALLEGRO_VIDEO_BITMAP for consistency. Input: - Work around a memory leak in iPhone OS that occurs when the accelerometer is on during touch input. Other core: - Don't #define true/false/bool macros in C++. Audio addon: - Some minor cleanups to the Audio Queue driver. Changes from 4.9.15 to 4.9.15.1 (October 2009) ============================================== - Fixed a problem building on MinGW (dodgy dinput.h). Changes from 4.9.14 to 4.9.15 (October 2009) ============================================ The main developers this time were: Trent Gamblin, Elias Pschernig, Matthew Leverton, Paul Suntsov, Peter Wang. Core: - Set the initial title of new windows to the app name. - Add al_set/get_event_source_data. - Make locking work on bitmaps that didn't have an FBO prior to the call on iPhone. - Make al_get_opengl_fbo work on iPhone. - Made iPhone port properly choose a visual (so depth buffer creation works). Font addon: - Improved drawing speed for longish strings. The font addon now depends on the primitives addon. Primitives addon: - Made the ribbon drawer handle the case of extremely sharp corners more gracefully. - Make al_draw_pixel use blend color in the D3D driver. - Added POINT_LIST to the primitive types. - Various fixes for the D3D driver: fixed line loop drawing; made the indexed primitives a little faster; added workabouts for people with old/Intel graphics cards. - Fall back to software if given a memory bitmap as a texture. - Removed OpenGL state saving code, it was causing massive slowdown when drawing. Also removed glFlush for the same reason. Audio addon: - Added PulseAudio driver. - Support AudioQueue driver on Mac OS X. - Add al_uninstall_audio exit function. - Added ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event to signify when non-looping streams made with al_load_audio_stream reach the end of the file. - Fixed a deadlock when destroying voices. - Handle underruns in the r/w ALSA updater. - Minor change to the ALSA driver to improve compatibility with PulseAudio. Documentation: - Replaced awk/sh documentation scripts with C programs. Changes from 4.9.13 to 4.9.14 (September 2009) ============================================== The main developers this time were: Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Evert Glebbeek, Matthew Leverton. Ports: - Elias Pschernig and Trent Gamblin started a iPhone port. Graphics: - Added al_get_opengl_texture_size and al_get_opengl_texture_position functions. - Try to take into account GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT when locking OpenGL bitmaps. - Fixed all (hopefully) conversion mistakes in the color conversion macros. - Sped up memory blitting, which was using conversion even with identical formats (in some cases). - Make al_set_current_display(NULL); unset the current display. - Added ALLEGRO_LOCK_READWRITE flag for al_lock_bitmap (in place of 0). - Fixed window titles which contain non-ASCII characters in X11. - Added OES_framebuffer_object extension. Input: - Added a lot more system mouse cursors. - Renamed al_get_cursor_position to al_get_mouse_cursor_position. - Prevent Windows from intercepting ALT for system menus. Filesystem: - Make the path returned by al_get_entry_name() owned by the filesystem entry so the user doesn't need to free it manually. - Renamed the filesystem entry functions, mainly to include "fs_entry" in their names instead of just "entry". - Reordered and renamed ALLEGRO_FS_INTERFACE members. - Make al_read_directory() not return . and .. directory entries. - Renamed al_create_path_for_dir to al_create_path_for_directory. - Added al_set_standard_file_interface, al_set_standard_fs_interface. Events: - Exported ALLEGRO_EVENT_TYPE_IS_USER. Threads: - Added a new function al_run_detached_thread. Other core: - Put prefixes on register_assert_handler, register_trace_handler. - Added functions to return the compiled Allegro version and addon versions. - Added al_ prefix to fixed point routines and document them. - Added al_get_system_config(). - Renamed al_system_driver() to al_get_system_driver(). - Added 64-bit intptr_t detection for Windows. - Added work-around to make OS X port compile in 64 bit mode. Addons: - Renamed addons from a5\_\* to allegro_*. Image addon: - Renamed the IIO addon to "allegro_image". - Renamed \*\_entry functions that take ALLEGRO_FILE * arguments to *_stream. - Fixed off-by-one error in greyscale JPEG loader. Audio addons: - Renamed the kcm_audio addon to "allegro_audio". - Renamed ALLEGRO_STREAM and stream functions to ALLEGRO\_AUDIO\_STREAM and al\_\*audio_stream\*. - Renamed al_stream_from_file to al_load_audio_stream - Added int16 mixing and configurable frequency and depth for default mixer/voice (see configuration file). - Fixed FLAC decoding and added FLAC streaming support. - Changed the function signature of al_get_stream_fragment() to be more straightforward. - Fixed bug in kcm audio that caused data to be deleted that was still used. - Made ALSA audio driver work when the driver does not support mmap (commonly because the ALSA really is PulseAudio). - Removed al_is_channel_conf function. Font addons: - Optimized font loading by converting the mask color on a memory copy instead of have to lock a texture. - Made the ttf addon read from file streams. Primitives addon: - Fixed the direction of the last segment in software line loop, and fixed the offsets in the line drawer. - Fixed the thick ribbon code in the primitives addon, was broken for straight segments. - Various fixes/hacks for the D3D driver of the primitives addon: hack to make the indexed primitives work and a fix for the textured primitives. - Various enhancements to the transformations API: const correctness, transformation inverses and getting the current transformation. - Added support for custom vertex formats. - Flipped the v axis of texture coordinates for primitives. Now (u=0, v=0) correspond to (x=0, y=0) on the texture bitmap. - Added a way to use texture coordinates measured in pixels. Changed ALLEGRO_VERTEX to use them by default. PhysicsFS: - PhysFS readdir didn't prepend the parent directory name to the returned entry's path. - Set execute bit on PhysFS directory entries. Examples: - Made examples report errors using the native dialogs addon if WANT_POPUP_EXAMPLES is enabled in CMake (default). - Added new example ex_draw_bitmap, which simply measures FPS when drawing a bunch of bitmaps (similar to exaccel in A4). Documentation: - Many documentation updates and clarifications. - Fixed up Info and PDF documentation. Bindings: - Added a script to generate a 1:1 Python wrapper (see `python` directory). Changes from 4.9.12 to 4.9.13 (August 2009) =========================================== The main developers this time were: Trent Gamblin, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Todd Cope, Evert Glebbeek, Michael Harrington, Matthew Leverton. Ports: - Trent Gamblin started a port to the GP2X Wiz handheld console. Graphics: - Some OpenGL bitmap routines were not checking whether the target bitmap was locked. - Scaled bitmap drawer was not setting the blend mode. - Fixed a bug where al_map_rgb followed by al_unmap_rgb would return different values. - Fixed problems with sub-sub-bitmaps. - Fixed window placement on OS X, which did not properly translate the coordinates specified by the user with al_set_new_window_position(). - Made is_wgl_extension_supported() fail gracefuly. - Added ALLEGRO_ALPHA_TEST bitmap flag. - Minor optimizations in some memory blitting routines. Input: - Replaced (ALLEGRO_EVENT_SOURCE *) casting with type-safe functions, namely al_get_keyboard_event_source, al_get_mouse_event_source, al_get_joystick_event_source, al_get_display_event_source, al_get_timer_event_source, etc. - Made it so that users can derive their own structures from ALLEGRO_EVENT_SOURCE. al_create_user_event_source() is replaced by al_init_user_event_source(). - Fixed a problem on Windows where the joystick never regains focus when tabbing away from a window. - Fixed a problem with missing key repeat with broken X.Org drivers. - Implemented ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY for X11. Image I/O addon: - Changed return type of al_save_bitmap() to bool. - Separated al_add_image_handler into al_register_bitmap_loader, al_register_bitmap_saver, etc. - Made JPEG and PNG loaders handle al_create_bitmap() failing. - Speed up JPEG loading and saving. - Fixed a reinitialisation issue in iio. Audio addons: - Moved basic sample loading/saving routines to kcm_audio from acodec and added file type registration functions. - Moved WAV support into kcm_audio. - Made WAV loader not choke on extra chunks in the wave. - Separated acodec into a5_flac, a5_vorbis addons. You need to initialise them explicitly. Removed sndfile support. - Renamed al\_\*\_oggvorbis to al\_\*\_ogg\_vorbis. - Changed argument order in al_save_sample and al_stream_from_file. - Reordered parameters in al\_attach\_* functions to follow the word order. - Renamed a few streaming functions to refer to fragments/buffers as fragments consistently. - Added missing getters for ALLEGRO_SAMPLE fields. - Fixed mutex locking problems with kcm_audio objects. - Avoid underfilling a stream when it is fed with a short looping stream. Other addons: - Added glyph advance caching for the TTF addon. - Renamed al_register_font_extension to al_register_font_loader. Match the file name extension case insensitively. Documentation: - Lots of documentation updates. - Added a short "Getting started guide" to the reference manual. Examples: - Added another example for kcm_audio streaming: ex_synth. Build system: - Fix pkg-config .pc files generated for static linking. - DLL symbols are now exported by name, not ordinals. Changes from 4.9.11 to 4.9.12 (July 2009) ========================================= - Fixed bugs in Windows keyboard driver (Todd Cope). - Fixed problems with ALLEGRO_MOUSE_STATE buttons on Windows (Milan Mimica). - Fixed problems with PhysicsFS addon DLL on MSVC (Peter Wang). - Set the D3D texture address mode to CLAMP (Todd Cope). - Fixed hang if Allegro was initialized more than once on Windows (Michael Harrington). - Added a CMake option to force the use of DllMain style TLS on Windows, for use with C# bindings (Michael Harrington). - Fixed a bug where drawing circles with a small radius would crash (Elias Pschernig). - Fixed several memory leaks throughout the libraries (Trent Gamblin). - Fixed some compilation warnings on Mac OS X (Evert Glebbeek). - Small documentation updates. Changes from 4.9.10.1 to 4.9.11 (June 2009) =========================================== The main developers this time were: Trent Gamblin, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Christopher Bludau, David Capello, Todd Cope, Evert Glebbeek, Peter Hull. Graphics: - Changed rotation direction in memory blitting routines to match D3D/OpenGL routines. - Made al_set_target_bitmap not create an FBO if the bitmap is locked. - Added explicit FBO handling functions al_get_opengl_fbo and al_remove_opengl_fbo in case we weren't quite clever enough above and the user has to intervene manually. - Added OpenGL 3.1 support and a bunch of new OpenGL extensions. - Fixed al_inhibit_screensaver on Windows - Fixed selection of X pixel formats with WGL if a new bitmap has alpha. - Made X11 icon work regardless of the backbuffer format. Input: - Ditched DirectInput keyboard driver and replaced it with WinAPI. Fixes several issues the old driver had. - Rewrote Windows mouse driver to use WinAPI instad of DirectInput. - Added al_get_joystick_number. Filesystem: - Merged ALLEGRO_FS_HOOK_ENTRY_INTERFACE into ALLEGRO_FS_INTERFACE and made ALLEGRO_FS_INTERFACE public. - Added al_set_fs_interface and al_get_fs_interface. - Made al_opendir take an ALLEGRO_FS_ENTRY. - Removed functions which are obsolete or probably have no use. - Made al_get_standard_path(ALLEGRO_PROGRAM_PATH) return a path with an empty filename. Path routines: - Renamed functions to follow conventions. File I/O: - Fix al_fgets() returning wrong pointer value on success. Primitives addon: - Added support for textured primitives in software. - Introduced ALLEGRO_PRIM_COLOR, removed ALLEGRO_VBUFFER. - Exposed the software line and triangle drawers to the user. - Added rounded rectangles. - Fix an extraneous pixel bug in the triangle drawer. Audio addon: - Change from using generic get/set audio property functions to specific getter/setter functions. - Change return types on many functions to return true on success instead of zero. (Watch out when porting your code, the C compiler won't help.) Native dialogs: - Added a Windows implementation. - Added a title to al_show_native_message_box(). Other addons: - Implemented the filesystem interface for PhysicsFS and demonstrate its use in ex_physfs. - Fixed al_color_html_to_rgb. Examples: - Added an OpenGL pixel shader example. Build system: - Output separate pkg-config .pc files for static linking. Changes from 4.9.10 to 4.9.10.1 (May 2009) ========================================== - Fixed uses of snprintf on MSVC. - Disabled ex_curl on Windows as it requires Winsock. Changes from 4.9.9.1 to 4.9.10 (May 2009) ========================================= The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan Mimica, Elias Pschernig, Peter Wang. Other contributions from: Peter Hull, Paul Suntsov. Graphics: - Renamed al_clear() to al_clear_to_color(). - Renamed al_opengl_version() to al_get_opengl_version(). - Changed the direction of rotation for al_draw_rotated* from counter-clockwise to clockwise. - Added new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which guanrantees component ordering. - Added ALLEGRO_NO_PRESERVE_TEXTURE flag. - Fixed horizontal flipping in plain software blitting routines. - Fixed some blending bugs in the OpenGL driver. - Made OpenGL driver fall back to software rendering if separate alpha blending is requested but not supported. - Added a config option which allows pretending a lower OpenGL version. - Implemented al_get_num_display_formats(), al_get_display_format_option() and al_set_new_display_format() for WGL. - Fixed bug in al_get_display_format_option() with the GLX driver. - Fixed a bug in the D3D driver that made display creation crash if the first scored mode failed. - Made the OpenGL driver prefer the backbuffer format for new bitmaps. - Defer FBO creation to when first setting a bitmap as target bitmap. Input: - Renamed some joystick functions. - Account for caps lock state in OS X keyboard driver. - Made UTF-8 input work on X11. File I/O: - Separated part of fshook API into a distinct file I/O API (actually generic streams). - Make the file I/O API match stdio more closely and account for corner cases. (incomplete) - Made it possible to set a stream vtable on a per-thread basis, which affects al_fopen() for that thread. - Added al_fget_ustr() to read a line conveniently. - Change al_fputs() not to do its own CR insertion. - Add al_fopen_fd() to create an ALLEGRO_FILE from an existing file descriptor. Filesystem: - Changed al_getcwd, al_get_entry_name to return ALLEGRO_PATHs. - Renamed al_get_path to al_get_standard_path, and to return an ALLEGRO_PATH. - Changed al_readdir to return an ALLEGRO_FS_ENTRY. - Added al_path_create_dir. - Removed some filesystem querying functions which take string paths (ALLEGRO_FS_ENTRY versions will do). Config routines: - Added functions to traverse configurations structures. - Change al_save_config_file() return type to bool. - Removed an arbitrary limit on the length of config values. - Renamed configuration files to allegro5.cfg and allegro5rc. String routines: - Allegro 4-era string routines removed. - Added al_ustr_to_buffer(). Other core: - Renamed al_thread_should_stop to al_get_thread_should_stop. - Added a new internal logging mechanism with configurable debug "channels", verbosity levels and output formatting. - Cleaned up ASSERT namespace pollution. Font addons: - Renamed font and TTF addon functions to conform to conventions. - Added al_init_ttf_addon. - Implemented slightly nicer text drawing API: - functions are called "draw_text" instead of "textout" - centre/right alignment handled by a flag instead of functions - functions accepting ALLEGRO_USTR arguments provided - substring support is removed so 'count' arguments not needed in usual case, however ALLEGRO_USTR functions provide similar thing. - Removed al_font_is_compatible_font. - Sped up al_grab_font_from_bitmap() by five times. - ttf: Fixed a possible bug with kerning of unicode code points > 127. Image I/O addon: - Renamed everything in the IIO addon. - Exposed al_load_bmp/al_save_bmp etc. Audio addon: - Renamed al_mixer_set_postprocess_callback. - Added two config options to OSS driver. - Made ALSA read config settings from [alsa] section. Native dialogs: - Added al_show_native_message_box() which works like allegro_message() in A4. Implemented for GTK and OS X. PhysicsFS addon: - Added PhysicsFS addon. Primitives addon: - Removed global state flags. - Removed normals from ALLEGRO_VERTEX. - Removed read/write flags from vertex buffers. Examples: - Added an example that tests al_get_display_format_option(). - Added an example which shows playing a sample directly to a voice. - Added an example for PhysicsFS addon. - Added a (silly) example that loads an image off the network using libcurl. - Added ex_dir which demonstrates the use of al_readdir and al_get_entry_name. Other: - Many bug and documentation fixes. Changes from 4.9.9 to 4.9.9.1 (March 2009) ========================================== - Made it compile and work with MSVC and MinGW 3.4.5. - Enabled SSE instruction set in MSVC. - Fixed X11 XIM keyboard input (partially?). - Fall back on the reference (software) rasterizer in D3D. Changes from 4.9.8 to 4.9.9 (March 2009) ======================================== The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Todd Cope, Angelo Mottola, Trezker. Graphics: - Added display options API and scoring, based on AllegroGL, for finer control over display creation. - Added API to query possible display formats (implemented on X, Mac OS X). - Changed the bitmap locking mechanism. The caller can choose a pixel format. - Added support for multisampling. - Simplified the semantics of al_update_display_region(). - Optimised software blitting routines. - Optimised al_map_rgb/al_map_rgba. - Replaced al_draw_rectangle() and al_draw_line() from core library with al_draw_rectangle_ex() and al_draw_line_ex() from the primitives addon. - Implemented al_wait_for_vsync() everywhere except WGL. - Fixed problems with sub-bitmaps with the OpenGL driver. - Fixed bugs in software scaled/rotated blit routines. - Added a new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_F32. Removed ALLEGRO_PIXEL_FORMAT_ANY_15_WITH_ALPHA, ALLEGRO_PIXEL_FORMAT_ANY_24_WITH_ALPHA. - Added support for creating OpenGL 3.0 contexts (untested; only WGL/GLX for now). Relevant display flags are ALLEGRO_OPENGL_3_0 and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. - Allow disabling any OpenGL extensions from allegro.cfg to test alternative rendering paths. - Fixed problem with windows only activating on title bar clicks (Windows). - Fixed a minimize/restore bug in D3D (with the help of Christopher Bludau). Input: - Implemented al_set_mouse_xy under X11. - Added ALLEGRO_EVENT_MOUSE_WARPED event for al_set_mouse_xy(). Path routines: - Made al_path_get_drive/filename return the empty string instead of NULL if the drive or filename is missing. - Changed al_path_set_extension/al_path_get_extension to include the leading dot. - Made al_path_get_extension(), al_path_get_basename(), al_path_to_string() return pointers to internal strings. Unicode: - Changed type of ALLEGRO_USTR; now you should use pointers to ALLEGRO_USTRs. - Added UTF-16 conversion routines. Other core: - Added ALLEGRO_GET_EVENT_TYPE for constructing integers for event type IDs. - Renamed configuration function names to conform to conventions. - Removed public MIN/MAX/ABS/MID/SGN/CLAMP/TRUE/FALSE macros. - Replaced AL_PI by ALLEGRO_PI and documented it as part of public API. Audio addons: - Added stream seeking and stream start/end loop points. - Add panning support for kcm_audio (stereo only). Font addons: - Made al_font_grab_font_from_bitmap() accept code point ranges. - Made font routines use new UTF-8 routines; lifted some arbitrary limits. - Fixed artefacts in bitmap font and TTF rendering. Image I/O addon: - Made the capability to load/save images from/to ALLEGRO_FS_ENTRYs public. - Added missing locking to .png save function. Other addons: - Added native_dialog addon, with file selector dialogs. - Fixed many bugs in the primitives addon. - Made hsv/hsl color functions accept angles outside the 0..360° range. - Fixed a bug in al_color_name_to_rgb. Examples: - New programs: ex_audio_props, ex_blend_bench, ex_blend_test, ex_blit, ex_clip, ex_draw, ex_font_justify, ex_gl_depth, ex_logo, ex_multisample, ex_native_filechooser, ex_path_test, ex_rotate, ex_stream_seek, ex_vsync, ex_warp_mouse. (ex_draw demonstrated known bugs currently.) - Updated programs: ex_joystick_events, ex_monitorinfo ex_pixelformat, ex_scale, ex_subbitmap. Build system: - Added pkg-config support. .pc files are generated and installed on Unix. - Allowed gcc to generate SSE instructions on x86 by default. For Pentium 2 (or lower) compatibility you must uncheck a CMake option before building Allegro. Other: - Many other bug fixes. Changes from 4.9.7.1 to 4.9.8 (February 2009) ============================================= The main developers this time were: Thomas Fjellstrom, Trent Gamblin, Evert Glebbeek, Matthew Leverton, Milan Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. General: - Lots of bug fixes. File system hooks: - Rationalised file system hook functions. Failure reasons can be retrieved with al_get_errno(). - Enable large file support on 32-bit systems. - Converted the library and addons to use file system hook functions. Path functions: - Added al_path_clone(), al_path_make_canonical(), al_path_make_absolute(), al_path_set\_extension(), al\_{get,set}\_org_name, al\_{get,set}_app_name} functions. - Made al_path_get_extension() not include the leading "." of the extension, - Add AL_EXENAME_PATH, AL_USER_SETTINGS_PATH, AL_SYSTEM_SETTINGS_PATH enums for al_get_path(). String routines: - Added a new, dynamically allocating UTF-8 string API. This uses bstrlib internally, which is distributed under a BSD licence. Allegro 5 will expect all strings to be either ASCII compatible, or in UTF-8 encoding. - Removed many old Unicode string functions. (Eventually they will all be removed.) Config routines: - Clarified behaviour of al_config_add_comment, al_config_set_value with regards to whitespace and leading comment marks. Graphics: - Bug fixes on Windows and Mac OS X for resizing, switching away, setting full screens, multi-monitor, etc. - Added an al_get_opengl_texture() convenience function. - Added separate alpha blending. - Added ALLEGRO_PIXEL_FORMAT_ANY. - Honour al_set_new_window_position() in X11 port. - Made the X11 port fail to set a full screen mode if the requested resolution cannot be set rather than falling back to a windowed mode. Input: - Added a field to the mouse state struct to indicate the display the mouse is currently on. - Made DirectX enumerate all joysticks/gamepads properly by using a device type new to DirectInput 8. - Fixed a bug in wmouse.c where y was not changed in al_set_mouse_xy. - Support ALLEGRO_EVENT_MOUSE_ENTER/LEAVE_DISPLAY events in Windows. Addons: - Added a primitives addon. - Revamp interface for kcm_audio addon to make simple cases easier. - Added native .wav support and save sample routines to acodec addon. - Added a colors addon. - Added memory file addon and example. TTF addon: - Added al_ttf_get_text_dimensions() function. - Allow specifying the font size more precisely by passing a negative font size. - Guess the filenames of kerning info for Type1 fonts. Documentation: - Added a new documentation system using Pandoc. Now we can generate HTML, man, Info and PDF formats. - Added and fixed lots of documentation. Examples: - Added ex_prim, ex_mouse_focus examples. - Made ex_blend2 more comprehensive. - Updated ex_get_path example. - Made ex_ttf accept the TTF file name on the command line. Build system: - Use official CMAKE_BUILD_TYPE method of selecting which build configuration. This should work better for non-make builds, however, it's no longer possible to build multiple configurations with a single configuration step as we could previously. Removals: - Remove outdated A4 tools. - Remove icodec addon. - SCons build was unmaintained and not working. Changes from 4.9.7 to 4.9.7.1 (December 2008) ============================================= - Scan aintern_dtor.h for export symbols, needed for MSVC. Changes from 4.9.6 to 4.9.7 (December 2008) =========================================== The main developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Peter Wang. Graphics: - Fixed a bug where the "display" field of a bitmap was not correctly reset when it was transfered to another display on OS X. - Made al_create_display() respect al_set_new_window_position() on OS X. - Fixed the bug that caused input focus to be lost in OS X when a window was resized. - Made resizable Allegro windows respond properly to the green "+" button at the top of the screen on OS X. - Properly implemented fullscreen resize in WGL. - Made the memory blenders work the same as the hardware ones. - Made al_get_pixel()/al_draw_pixel() handle sub bitmaps in case the bitmap was locked. - In the OpenGL driver, if the bitmap is locked by the user, use memory drawing on the locked region. - Added implementations of al_inhibit_screensaver() for the X and Mac OS X ports. - Added multi-monitor support to Mac OS X port (untested!). - Other fixes. Input: - Made al_get_keyboard_state() return structures with the `display' field correctly set. - Made keyboard event member 'unichar' uppercase when Shift/CapsLock is on, in Windows. - Made mouse cursor show/hide work with Mac OS X full screen. Config routines: - Preserve comment and empty lines in config files when writing. Addons: - Add a simple interface layer for kcm_audio. - Made kcm_audio objects automatically be destroyed when it is shut down. - Renamed functions in kcm_audio to conform better with the rest of the library. - Made the TTF addon aggregate glyph cache bitmaps into larger bitmaps for faster glyph rendering (less source bitmap switching). Examples: - Add an example to test the ALLEGRO_KEYBOARD_STATE `display' field. - Add an example for testing config routines. - Add an example for checking software blending routines against hardware blending. - Add an example for the simple interface for kcm_audio. Changes from 4.9.5 to 4.9.6 (November 2008) =========================================== The core developers this time were: Thomas Fjellstrom, Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Jon Rafkind, Peter Wang. Allegro 4.9.6 and onwards are licensed under the zlib licence (see LICENSE.txt). This is a simple permissive free software licence, close in spirit to the 'giftware' licence, but is clearer and more well-known. General: - Added filesystem hook (fshook) and path API functions. - Many minor bug fixes. Graphics: - Added allegro5/a5_opengl.h, which has to be included by programs to use OpenGL specifics. ALLEGRO_EXCLUDE_GLX and ALLEGRO_EXCLUDE_WGL can be #defined to exclude GLX and WGL OpenGL extensions respectively. - Added allegro/a5_direct3d.h, which has to be included by programs to use D3D specifics. - Fixed some drawing from and onto sub-bitmaps. - Fixed blending with the wrong color in case of sub-bitmaps. - Fixed a bug in the D3D driver where the transformation matrix was not reset after drawing a bitmap. - Added draw pixel to OpenGL driver. - Added more OpenGL extensions. - Added function to inhibit screen saver (currently Windows only). Config routines: - Added al_config_create(). - Deleted al_config_set_global(). Made empty section name equivalent to the global section. - Read system wide and home directory config files on Unix (Ryan Patterson). Events: - Added support for injecting user-defined events into event queues. Audio addon: - Made the ALSA driver read the device name from the config file (Ryan Patterson). Examples: - Added ex_subbitmap example. - Added ex_disable_screensaver example. Build system: - Rationalised library names and made CMake and SCons build systems agree on the names. Changes from 4.9.4 to 4.9.5 (October 2008) ========================================== The core developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, Milan Mimica, Elias Pschernig, Jon Rafkind, Peter Wang. Graphics: - Added fullscreen support on Mac OS X. - Added support for resizable windows on Mac OS X. - Made frameless windows respond to events on Mac OS X. - Fixed a problem with D3D blending. - Made D3D driver work on systems without hardware vertex processing. - Made WGL driver fail more gracefully. - Implemented sprite flipping for OpenGL drivers (Steven Wallace). - Added al_is_sub_bitmap() function. Input: - Fixed input with multiple windows on Windows. - Fixed keyboard autorepeat events in X11. - Added al_is_keyboard_installed(). - Fixed key shifts on Windows (ported from 4.2). - Fixed mouse button reporting on Mac OS X. - Implemented system mouse cursors on MacOS X. - Fixed mouse cursors with alpha channels on X11. - Some work on Mac OS X joystick support (incomplete). Events: - Simplified internals of events system further. At the same time, this change happens to also allow event queues to grow unboundedly. (You should still avoid letting them get too big, of course.) Audio addons: - Made ALLEGRO_STREAM objects emit events for empty fragments that need to be refilled. - Added a possiblity to drain a stream created by al_stream_from_file(). - Added a function to rewind a stream. - Added gain support to ALLEGRO_STREAM and ALLEGRO_SAMPLE objects. - Made it possible to attach a sample to a mixer that isn't already attached to something. - Fixed Ogg Vorbis loader on big-endian systems. - Made the OpenAL driver the least preferred driver, as it doesn't play stereo samples properly. Image addons: - Added JPEG support to iio addon, using libjpeg. - Fixed TGA loader on big-endian systems. - Fixed image loading in icodec addon. Font addon: - Fixed count-restricted text output functions calculations on non-ASCII strings. - Made al_textout* functions always a 'count' parameter. - Renamed al_font_text_length* to al_font_text_width*. - Harmonised the order of al_font_textout* and al_font_textprintf* arguments. Examples: - Added ex_bitmap_flip example (Steven Wallace). - Added ex_mixer_chain example. - Split ex_events into smaller examples. - Made the demo use ALLEGRO_STREAM to play music. - Build an app bundle from the demo, on Mac OS X. Build system: - Improved detection of external dependencies in CMake build. - Guess compiler locations for MinGW and MSVC (CMake). - Many improvements to scons build, including install support. General: - Many other bug fixes. Changes from 4.9.3 to 4.9.4 (September 2008) ============================================ The core developers this time were: Trent Gamblin, Peter Hull, Milan Mimica, Elias Pschernig and Peter Wang. Ryan Dickie and Jon Rafkind also contributed. General: - Many bug fixes all around. - Added a public threads API. - Added a basic configuration API. - Added al_store_state/al_restore_state functions. - Added al_get_errno/al_set_errno (not used much yet). - Renamed some functions/structures to be more consistent. - Code formatting improvements. - Added more debugging messages. - Removed a lot of A4 code that is no longer used. Graphics: - Added support for some new OpenGL extensions. - Multihead support on Windows (preliminary support on OSX and Linux). - Many enhancements to all drivers. - Merged common parts of WGL and D3D drivers. - Borderless windows, setting window positions and titles. - Fullscreen support on OSX and Linux. - Do not clear bitmaps when they are created. - Improved compile times and DLL sizes by simplifying "memblit" functions. - Added EXPOSE, SWITCH_IN and SWITCH_OUT display events. Build system: - Many bug fixes and enhancements to SCons and CMake build systems. - Support for Turbo C++ 2006. - Support for cross-compiling on Linux to MinGW (CMake). Events: - Filled in a display field for all relevant events. - Added al_wait_for_event_until. Addons: - Added an ImageMagick addon - Added iio (Image IO) addon - Supports BMP, PCX, TGA. - Supports PNG support with libpng. - Added new audio addon, kcm_audio. (The 'audio' addon was taken in a new direction between the 4.9.3 and 4.9.4 releases, but we decided against that, so actually it's actually a continuation of the old audio addon.) - Added audio streaming functionality. - Added OSS, ALSA, DirectSound drivers. - A lot of reorganisation, internally and externally. - Added TTF font addon, using FreeType. - Made all addons use "al_" prefix. Examples: - Lots of new examples. - Wait for keypress in some examples instead of arbitrary delay. - Clean up files when done in some examples. Changes from 4.9.2 to 4.9.3 (April 2008) ======================================== Graphics: - Milan Mimica did lots of work on the OpenGL drivers, such as adding an OpenGL driver for Windows and making the OpenGL code shared between platforms. - Peter Hull added an OpenGL graphics driver for Mac OS X. - Milan Mimica made the OpenGL driver share contexts between displays. - Peter Wang and Milan Mimica made the OpenGL driver work with cards that don't support non-power-of-two (NPOT) textures. - Trent Gamblin added support for NPOT textures in the Direct3D driver. - Trent Gamblin fixed blending in memory drawing functions. - Trent Gamblin added al_draw_pixel() which obeys blending. - Trent Gamblin made al_clear() not affected by blending in D3D. - Milan Mimica added the following functions to the public API: al_opengl_version(), al_is_opengl_extension_supported(), al_get_opengl_proc_address(), al_get_opengl_extension_list(). - Milan Mimica added sub-bitmaps support for memory bitmaps and in the OpenGL display driver. - Milan Mimica made displays keep a list of bitmaps. When destroying a display its bitmaps will be managed properly, e.g. converted to memory bitmaps if necessary. All display bitmaps will be automatically destroyed on exit. - Peter Wang made X window resizing work without GLX 1.3. - Trent Gamblin fixed a bug in the Direct3D driver when windows were minimized (thanks to David McCallum). - Trent Gamblin fixed the coordinates of Direct3D primitives to match OpenGL style. - Peter Hull fixed some logic in bitmap drawing and al_load_bitmap(). Fonts: - Milan Mimica made font drawing faster, by making glyphs sub-bitmaps of a larger glyph sheet. - Milan Mimica and Peter Wang made font loading faster. - Trent Gamblin added versions of text output functions which take as an explicit argument the length of the strings. Audio: - A new audio API implementation, originally by Chris Robinson, was added (currently as an addon only). It has received additional work in the past from Milan Mimica and recently much work from Ryan Dickie. - Ryan Dickie also added an acodec addon, which has loaders for FLAC, Wave and Ogg Vorbis files, using other libraries. Timers: - Ryan Dickie changed the type of timestamps throughout the API from int expressed in milliseconds to double expressed in seconds and improved timer resolution on Windows. - Ryan Dickie added an 'error' field to the timer event, and added error and overhead statistics to exnew_timer. - Trent Gamblin made the Windows timer use QueryPerformanceCounter. - Peter Wang split al_wait_for_event() into two functions, a version that takes a timeout and a version that doesn't. - Trent Gamblin merged the Windows and Unix timer source files. Input: - Peter Wang renamed some joystick and timer functions to adhere to the `al__` convention. - Peter Wang made al_num_joysticks() more lenient if there is no joystick driver installed. Other: - David Capello added support for various different BMPs. - Elias Pschernig fixed compilation of the X port in case the XVidMode extension is unavailable (thanks to Thomas Fjellstrom). - Elias Pschernig added a exnew_timer example. - Trent Gamblin added exnew_multiwin and exnew_drawpixels. - Peter Wang added exnew_timedwait and exnew_scale. - Jon Rafkind and Elias Pschernig updated the SCons build. - Jon Rafkind added a `_s` suffix to static libraries in the SCons build. - Elias Pschernig did some work on cross-compilation with SCons and MinGW. - Milan Mimica made the CMake build work with MSVC project solutions and made the library build with MSVC 8. - Jacod Dawid added a nicer spaceship graphic for a5teroids demo. - Many more bug fixes and documentation updates. Changes from 4.9.1 to 4.9.2 (November 2007) =========================================== *This list is still to be summarised.* - Trent Gamblin made the mouse cursor always hide when the user calls al_hide_mouse_cursor in fullscreen (D3D). - Trent Gamblin fixed some signedness warnings and implemented show/hide_mouse in the display vtable for D3D. - Elias Pschernig made show/hide cursor use the display driver instead of the 4.2 gfx_driver. - Elias Pschernig fixed missing keyboard events in exnew_mouse_events example. - Elias Pschernig wired the X11 mouse driver to the XGLX system driver. - Jon Rafkind made various fixes to get the OSX build to compile - Trent Gamblin added exnew_mouse_events. - Trent Gamblin added exnew_mouse. - Jon Rafkind made the scons build get the library name dynamically. - Jon Rafkind made the scons build link Allegro using -l instead of using the full path. - Trent Gamblin added a note about MINGDIR in readme_a5.txt. - Trent Gamblin removed -lalleg_unsharable from allegro-config.in, since assembly is not used anymore. - Jon Rafkind fixed up allegro-config. - Trent Gamblin added some documentation on ALLEGRO_MSESTATE. - Trent Gamblin listed the examples in readme_a5.txt. - Trent Gamblin improved some inline documentation. - Jon Rafkind removed /lib from install path in unix.scons. - Jon Rafkind added the new demo to the scons build and allowed addons to be built statically or shared. - Trent Gamblin made the glx line drawing function use blending. - Trent Gamblin added cmake instructions to readme_a5.txt. - Elias Pschernig added readme_a5.txt. - Trent Gamblin fixed warnings in the demo. - Trent Gamblin fixed a crash-on-exit bug in tls.c. - Trent Gamblin replaced the old demo with a temporary one. - Peter Wang fixed gcc string warnings. - Peter Wang added some assertions to display_new.c. - Peter Wang merged changes from the 4.2 branch. - Elias Pschernig removed an unnecessary import from the naturaldocs upload script. - Elias Pschernig added a script to automatically upload the naturaldocs generated documentation to the website. - Peter Wang fixed missed renamings from AL_ to ALLEGRO_ in the Linux and X code. - Elias Pschernig merged 4.9-newgfx back to 4.9. - Peter Wang fixed a "ALLEGRO__JOYSTICK" typo. - Trent Gamblin renamed AL_ to ALLEGRO_ in input, events, and timer code. - Elias Pschernig implemented outline flag and blending for draw_rectangle in the GLX driver. - Elias Pschernig added another mysha.pcx for the font example. - Elias Pschernig re-added GLX checked to scons build which went missing in the merge. - Elias Pschernig added icon.xpm which went missing in the merge. - Peter Wang replaced _al_draw_bitmap_region_memory_fast with _al_draw_bitmap_region_memory. - Trent Gamblin made memblit.c compile a little faster in debug mode. - Peter Wang mergedd changes in r7948:10859 on 4.9 branch to 4.9-newgfx branch. - Peter Wang enabled WANT_D3D by default. Only set ALLEGRO_D3D on Windows. - Trent Gamblin made al_acknowledge_resize take the display as a parameter. - Trent Gamblin fixed some warnings and made the MinGW build compilable statically with gcc 4.2.1. - Peter Wang fixed a bug in ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444. - Peter Wang renamed al_memory_management_functions() to al_set_memory_management_functions() and added some extra documenation for it. - Peter Wang removed NaturalDocs markup for Allegro 4.x display functions. - Peter Wang made OpenGL libraries link if building with X11 support. - Peter Wang fixed a signedness warning. - Peter Wang made al_destroy_bitmap return immediately when passed a null pointer instead of segfaulting. - Elias Pschernig made some cosmetic improvements to the code. - Elias Pschernig removed a bad optimization. - Elias Pschernig removed > GLX 1.1 specific code. - Trent Gamblin fixed several of the floating point unmapping functions that were doing integer division. - Elias Pschernig implemented blending in the GLX driver. - Elias Pschernig fixed GLX rotation to use radians and allow negative angles. - Elias Pschernig implemented rotated blitting in the GLX driver. - Jon Rafkind made scons install addons/font. - Jon Rafkind added a scons file for addons. - Jon Rafkind used target_scanner to find makedoc instead of using Depends. - Jon Rafkind forced makedoc to be a dependancy of the docs. - Trent Gamblin made 60hz the default refresh rate of the D3D driver. - Trent Gamblin changed al_create_mouse_cursor to accept ALLEGRO_BITMAP structures. - Trent Gamblin renamed __al_unmap_rgba to al_unmap_rgba_ex in the glx driver. - Trent Gamblin made al_(map|unmap)_rgb(a)_*_ex public. - Trent Gamblin made D3D windows show the resize cursor when resizing windows. - Jon Rafkind added allegro includes for asmdef. - Jon Rafkind erased older build demo target. - Jon Rafkind added the demo to the scons build. - Jon Rafkind made it so assembly files can be built statically. - Jon Rafkind made scons always build asmdef. - Trent Gamblin made al_acknowledge_resize and al_resize_display adjust clipping in the D3D driver. Mad eal_set_current_display - Trent Gamblin used higher compatibility flags to Direct3DCreate9, made D3D driver die more gracefully on unsupported configurations, removed flags from draw_line, and did more error checking. - Trent Gamblin turned al_init macros into an inline function. - Trent Gamblin commented out a TRACE line that was causing the entire log to be overwritten. - Peter Wang fixed an incorrect call to _al_vector_find_and_delete. - Peter Wang made various formatting fixes. - Peter Wang converted CR/LF line endings to LF. - Trent Gamblin added NaturalDocs for the graphics api. - Trent Gamblin fixed an instance where a variable could have been used uninitialized. - Trent Gamblin fixed texture coordinates in the D3D driver. - Trent Gamblin fixed formatting and an improper assertion. - Trent Gamblin removed a redundant call to al_set_target_bitmap. - Trent Gamblin fixed a bug in the DX joystick code that caused it to assert when it shouldn't. - Trent Gamblin made al_create_display call al_flip_display so the window is cleared. - Trent Gamblin made the D3D driver work where render-to-texture is not supported. - Trent Gamblin removed masking support completely. - Elias Pschernig got the font example working with the GLX driver. - Elias Pschernig renamed the font addon in the scons build. - Jon Rafkind made scons build modules in a separate directory. - Jon Rafkind bumped the version to match cmake. - Jon Rafkind fixed esd to be like the other unix modules. - Trent Gamblin changed color map and unmap functions to use the target bitmap. - Trent Gamblin added the font example to the cmake build process. - Elias Pschernig added the font example to the scons build process. - Elias Pschernig removed special handling of "src" dir, and made various cosmetic changes. - Trent Gamblin made cmake install to MINGDIR. - Trent Gamblin added a better font and example for the bitmap font addon. - Trent Gamblin removed unix header from install on other platforms. - Trent Gamblin added a bitmap font addon. - Trent Gamblin fixed a locking bug in the D3D driver. - Elias Pschernig removed masking from the GLX driver. - Trent Gamblin implemented blending for memory bitmaps (very slow unless the blend mode is ALLEGRO_ONE,ALLEGRO_ZERO with a pure white blend color). - Trent Gamblin implemented blending for the D3D driver. - Trent Gamblin added ALLEGRO_PIXEL_FORMAT_ANY_(15|16|24|32)_(WITH_ALPHA|NO_ALPHA) formats, used ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA in locking examples, and ixed some formatting. - Trent Gamblin added al_clone_bitmap which makes an exact copy of the color-data of a bitmap. - Trent Gamblin added a ALLEGRO_KEEP_BITMAP_FORMAT flag that forces Allegro to use the same format as the disk file when loading bitmaps. - Elias Pschernig implemented video bitmap masking for the GLX driver (by converting to alpha textures and drawing with alpha blending). - Elias Pschernig fixed clipping in the GLX driver. - Trent Gamblin removed ALLEGRO_MASK_SOURCE flag in favor of ALLEGRO_USE_MASKING. Mask color is now a bitmap property. Removed ALLEGRO_NO_ALPHA flag and changed the meaning of ALLEGRO_USE_ALPHA to mean do alpha blending or not. Added al_set/get_bitmap_mask_color and removed al_set/get_mask_color. New masking example added (exnew_masking). - Trent Gamblin added proper clipping to al_put_pixel. - Trent Gamblin renamed graphics stuff from AL_ to ALLEGRO_ and removed patterned drawing. - Elias Pschernig implemented clipping for the X11 GLX driver (only for screen so far). - Trent Gamblin removed unused set_bitmap_clip entry from the bitmap vtable. - Trent Gamblin made clipping always enabled and made the clipping functions operate on the current target bitamp. - Trent Gamblin removed src/compat/coblit.c. - Trent Gamblin renamed scroll_display to scroll_screen in display.c - Trent Gamblin Removed commented code from src/display.c. Removed include/allegro/display.h and src/compat/cogfx.c - Elias Pschernig renamed XDUMMY driver to XGLX. - Elias Pschernig made some cosmetic changes. - Elias Pschernig made exblend work over the compatibility screen. - Elias Pschernig implemented upload_compat_screen method in the GLX driver. - Elias Pschernig optimized al_lock_bitmap/al_unlock_bitmap slightly. - Elias Pschernig added a flags parameter to the drawing primitives methods. - Trent Gamblin added flags to primitives in display vtable and renamed draw_filled_rectangle vtable entry to draw_rectangle. - Elias Pschernig implemented AL_SINGLEBUFFER flag and fixed bug with AL_FULLSCREEN in the GLX driver. - Trent Gamblin added a mode parameter to al_set_drawing_pattern. - Trent Gamblin added AL_OUTLINED flag that is the default for primitives. - Trent Gamblin added al_set_drawing_pattern and al_get_drawing_pattern, added a flags parameters to all the primitive drawing functions that can be: AL_FILLED, AL_PATTERNED, and added hline and vline functions for memory bitmaps. - Trent Gamblin ifdefed d3d stuff in win/wnewsys.c. - Trent Gamblin removed d3dx9 library from CMakeLists.txt. - Trent Gamblin ifdefed Direct3D stuff in display.c. - Jon Rafkind made scons read win32 files from cmake file list. - Trent Gamblin added al_wait_for_vsync and made it work with the D3D driver. - Elias Pschernig implemented immediate-resize for al_resize_display, and implemented fullscreen resizing. - Trent Gamblin added al_enable_bitmap_clip and al_is_bitmap_clip_enabled, added al_create_sub_bitmap, and made it work with D3D and memory bitmaps. - Elias Pschernig improved fullscreen handling. - Elias Pschernig added shutdown_system vtable entry to the system driver, and automatically call it on program exit. This allows unsetting fullscreen modes in the X11 driver. - Trent Gamblin added al_set_bitmap_clip and al_get_bitmap_clip, and made them work with D3D and memory bitmaps. - Elias Pschernig added XF86Vidmode fullscreen modes. - Elias Pschernig added xdummy files to cmake files list. - Elias Pschernig made al_resize_display work on non-resizable windows. - Elias Pschernig fixed opengl setup being issued in wrong thread. - Elias Pschernig moved src/misc/colconv.c from windows sources to general sources. - Elias Pschernig uncommented accidentally commented out line. - Elias Pschernig made scons read the list of source files from cmake/FileList.cmake, so there's only one place to add new files. - Trent Gamblin made _al_get_pixel_value faster. - Trent Gamblin made al_unmap_rgba_i use a table instead of relying on al_unmap_rgba_f. - Peter Wang changed #includes to use file names from the root of the include hierarchy, i.e. #include "allegro/internal/foo.h" instead of #include "internal/foo.h" and likewise for allegro/platform/foo.h. - Peter Wang removed some stray CR characters. - Trent Gamblin added al_get_bitmap_width, al_get_bitmap_height, al_get_bitmap_format, and al_get_bitmap_flags. - Trent Gamblin made al_draw_rotated_(scaled_)bitmap only lock the region of the destination is needs to for memory bitmaps. - Trent Gamblin made al_draw_scaled_bitmap use the AL_FLIP_* flags. - Trent Gamblin added an example of resizing a fullscreen display. - Elias Pschernig updated xdummy driver and implemented al_resize_display for it. - Elias Pschernig added another testcase. - Trent Gamblin added al_get_display_width and al_get_display_height, made al_get_display_* work on the current display, and renamed al_notify_resize to al_acknowledge_resize. - Trent Gamblin uncommented everything in cogfx.c (removing the display parameter). - Trent Gamblin made exnew_lockscreen use pitch. - Trent Gamblin fixed scaled conversion macros (4444, 555, 565), added XRGB_8888 pixel format, made windowed mode default, moved get_num_display_modes and get_display_mode into the system vtable. - Trent Gamblin made exnew_lockbitmap use pitch. - Trent Gamblin fixed D3D unlocking bug, and used desktop format in windowed mode if not specified. - Elias Pschernig fixed a bug where events reported the wrong source display under X11. - Elias Pschernig added three simple test cases. - Elias Pschernig fixed al_lock_bitmap and al_unlock_bitmap implementation in the xdummy driver (for now it works in a slow way). - Trent Gamblin made al_notify_resize return success/failure and added al_resize_display to resize the display from code. - Elias Pschernig started implementing lock_region and unlock_region for the xdummy driver. - Elias Pschernig split xdraw.c out of xdisplay.c, used _AL_THREAD instead of pthreads in the xdummy driver, added a lock to the xdummy driver, in order to implement al_destroy_display, used the correct format. - Elias Pschernig fixed a comment typo. - Elias Pschernig fixed a typo in AL_CONVERT_PALETTE_8_TO_ABGR_8888. - Trent Gamblin improved D3D line drawing, added al_get_num_display_modes and al_get_display_mode, and cleaned up & organized some code. - Trent Gamblin removed _al_win_delete_from_vector. - Trent Gamblin added draw_memory_bitmap_region vtable hook to AL_DISPLAY. - Elias Pschernig implemented enough of the xdummy driver to run exnewap (doesn't display correctly yet though). - Elias Pschernig updated scons build files. - Elias Pschernig Removed windows specific includes from exnewapi.c. - Elias Pschernig added missing al_convert_mask_to_alpha prototype. - Peter Wang fixed src/tls.c to compile under Linux (not tested). - Trent Gamblin put TLS support back in for MSVC and UNIX. - Trent Gamblin cleaned up some code, added headers to new source files, grouped thread local variables into one structure (UNIX support is broken for now), and made mask color thread local. - Trent Gamblin added clear, filled rectangle, and line for memory bitmaps. - Trent Gamblin made it so the system driver is no longer hard coded, added switch_out method to display vtable, made the D3D window and system driver code generic. - Trent Gamblin merged 4.9-elias and 4.9-trentg into 4.9-newgfx. - Elias Pschernig adjusted prototype of _al_init to implementation. - Elias Pschernig fixed a bogus cast. - Elias Pschernig fixed typo in al_get_new_diplay_format for non-mingw. - Trent Gamblin made display and bitmap parameters local to the calling thread. - Trent Gamblin added al_draw_rotated_bitmap and al_draw_rotated_scaled_bitmap for memory bitmaps using Allegro's software rotation code as a base. - Trent Gamblin ported a stretch blit fix from 4.2, made al_init call allegro_init, made al_draw_bitmap(_region) much faster on memory bitmaps, and added al_draw_scaled_bitmap for memory bitmaps. - Trent Gamblin renamed AL_LOCKED_RECTANGLE to AL_LOCKED_REGION, and started on memory bitmaps (al_draw_bitmap and al_draw_bitmap region work). - Trent Gamblin made seperate functions for getting/setting display/bitmap parameters, made backbuffer-as-source bitmap work in D3D, and changed parameter ordering of some functions. - Trent Gamblin added al_is_compatible_bitmap removed dependancy on Allegro's 3D math functions from the D3D driver. - Trent Gamblin added al_convert_mask_to_alpha, made put/get_pixel faster if the bitmap is locked ahead of time, and brought back AL_MASK_SOURCE. - Trent Gamblin committed various bugfixes, implemented the RGB mapping/unmapping functions from Bob's API. - Trent Gamblin removed the D3DX library dependancy. - Trent Gamblin committed various bugfixes and got all of the examples working with the D3D driver. - Trent Gamblin fixed some of the compatibility conversions. - Trent Gamblin changed the examples back to autodetecting the graphics driver. - Trent Gamblin made fullscreen mode work with the D3D driver, and non-resizable windows. - Trent Gamblin finished bitmap conversion functions, improved locking, implemented get/put pixel, and made some speed improvements. - Trent Gamblin added a bitmap conversion function. - Trent Gamblin got the demo game running in D3D. - Trent Gamblin removed an unnecessary bitmap copy. - Trent Gamblin added a skeleton D3D driver. - Peter Wang fixed the generation of allegro-config under Mac OS. - Michael Jensen fixed a mistake in the documenation for is_compatible_font. - Peter Wang fixed wrong variable in example code for load_font(); - Trent Gamblin fixed some problems with the cmake build on Windows. - Peter Wang removed the second parameter in a call to _al_event_source_needs_to_generate_event() which was missed earlier. - Peter Wang exposed some internal documentation on destructors, events and event sources to NaturalDocs. - Peter Wang changed al_wait_for_event() so that a timeout value of "0" means to not wait at all. To wait an indefinite amount of time the caller should pass the AL_WAIT_FOREVER constant. - Peter Wang removed the declarations of al_event_source_set_mask and al_event_source_mask which were missed in the previous change. - Peter Wang removed event masking abilities, that is, for the user to prevent an event source from generating particular event types. This was implemented using bitfields which limited the number of event types to 32. Although the limit could be raised event masking was probably not very useful anyway. In all, the functions removed are: al_event_source_mask, al_event_source_set_mask, al_wait_for_specific_event. The al_wait_for_specific_event() API also required event types to be bitfields. - Peter Wang fixed some spelling mistakes in the examples. - Peter Wang bumped the version to 4.9.2. - Peter Wang moved allegro/branches/4.3 to allegro/branches/4.9. - Ryan Patterson clarified the documentation of stop_sample(). - Peter Wang and Trent Gamblin fixed some issues with the CMake build. The allegro-config script was not generated properly and liballeg_unsharable wasn't being installed. - Matthew Leverton changed an instance of long long to LONG_LONG and an LL suffix into a (LONG_LONG) cast, both for MSVC 6. - Matthew Leverton submitted a fix for MSVC 6 regarding MSVC's lack of a \_\_FUNCTION\_\_ macro. - orz, Matthew Leverton, and Peter Wang made the ALLEGRO_USE_C=1 option to work under MinGW and MSVC. - Anthony Cassidy fixed a typo. - Peter Wang removed the 'msvc' target from the fix.sh help message as it should not be used by users any more. Added a comment that it is used by zipup.sh. - Anthony 'Timorg' Cassidy made d_menu_proc fill up its assigned area with the gui_bg_color. Changes from 4.9.0 to 4.9.1 (March 2007) ======================================== *Note that 4.9.1 was called 4.3.1 when it was originally released.* - Added a new mouse and cursor API. The new functions are: al_install_mouse, al_uninstall_mouse, al_get_mouse, al_get_mouse_num_buttons, al_get_mouse_num_axes, al_set_mouse_xy, al_set_mouse_z, al_set_mouse_w, al_set_mouse_axis, al_set_mouse_range, al_get_mouse_state, al_mouse_button_down, al_mouse_state_axis al_create_mouse_cursor, al_destroy_mouse_cursor, al_set_mouse_cursor, al_set_system_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor - Added documentation for some parts of the 4.9 API using the NaturalDocs generation system. The documentation is nowhere near as good as a proper manual, but it's still better than nothing. - Added a commented example demonstating the new API (exnew_events.c). - Added CMake and SCons build systems. These are mainly for use by Allegro developers at present. - Various bug fixes and minor changes. Changes from 4.2 series to 4.9.0 (July 2006) ============================================ *Note that 4.9.0 was called 4.3.0 when it was originally released.* Basically we're just wrapping up what we have in version control up to now. See the commit logs if you want details. This release introduces a few new subsystems. We have an event system, a new keyboard API, a new joystick API, a new timer API, and the start of a new graphics API. All of these are subject to change, as is usual for a WIP. We are maintaining a certain level of source compatibility with the 4.2 API. If it's easy to maintain compatibility then we do it, otherwise compatibility is dropped. Obscure features are more likely to be dropped. This release has had minimal testing on Linux/x86, Windows/x86 (MinGW) and Windows/x86 (MSVC). It seems to work on some Linux/x86-64 machines also. Other ports are broken or untested. The new functions are as follows (in no particular order). No real documentation exists at the moment but interesting header files are: altime.h, display.h, draw.h, events.h, joystick.h, keyboard.h, timer.h. - al_current_time al_rest - al_create_video_bitmap al_create_system_bitmap al_scroll_display al_request_scroll al_poll_scroll al_show_video_bitmap al_request_video_bitmap al_enable_triple_buffer al_create_display al_set_update_method al_destroy_display al_flip_display al_get_buffer al_get_update_method al_enable_vsync al_disable_vsync al_toggle_vsync al_vsync_is_enabled al_blit al_blit_region al_blit_scaled - al_event_source_set_mask al_event_source_mask - al_create_event_queue al_destroy_event_queue al_register_event_source al_unregister_event_source al_event_queue_is_empty al_get_next_event al_peek_next_event al_drop_next_event al_flush_event_queue al_wait_for_event al_wait_for_specific_event - al_install_joystick al_uninstall_joystick al_num_joysticks al_get_joystick al_release_joystick al_joystick_name al_joystick_num_sticks al_joystick_stick_flags al_joystick_stick_name al_joystick_num_axes al_joystick_axis_name al_joystick_button_name al_get_joystick_state - al_install_keyboard al_uninstall_keyboard al_get_keyboard al_set_keyboard_leds al_keycode_to_name al_get_keyboard_state al_key_down - al_install_timer al_uninstall_timer al_start_timer al_stop_timer al_timer_is_started al_timer_get_speed al_timer_set_speed al_timer_get_count al_timer_set_count allegro-5.0.10/docs/src/autosuggest.js0000644000175000001440000007715211331332743017051 0ustar tjadenusers/* Auto-suggest control, version 2.4, October 10th 2009. * * (c) 2007-2009 Dmitriy Khudorozhkov (dmitrykhudorozhkov@yahoo.com) * * Latest version download and documentation: * http://www.codeproject.com/KB/scripting/AutoSuggestControl.aspx * * Based on "Auto-complete Control" by zichun: * http://www.codeproject.com/KB/scripting/jsactb.aspx * * This software is provided "as-is", without any express or implied warranty. * In no event will the author be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ var autosuggest_url = ""; // Global link to the server-side script, that gives you the suggestion list. // Used for controls that do not define their own server script urls. function autosuggest(id, array, url, onSelect) { var field = document.getElementById(id); var exists = field.autosuggest; if(exists) return exists; // "Public" variables: this.time_out = 0; // autocomplete timeout, in milliseconds (0: autocomplete never times out) this.response_time = 250; // time, in milliseconds, between the last char typed and the actual query this.entry_limit = 10; // number of entries autocomplete will show at a time this.limit_start = false; // should the auto complete be limited to the beginning of keyword? this.match_first = true; // if previous is false, should the exact matches be displayed first? this.restrict_typing = true; // restrict to existing members of array this.full_refresh = false; // should the script re-send the AJAX request after each typed character? this.use_iframe = true; // should the control use an IFrame element to fix suggestion list positioning (MS IE only)? this.use_scroll = true; // should the control use a scroll bar (true) or a up/down arrow-buttons (false)? this.use_mouse = true; // enable mouse support this.no_default = false; // should the control omit selecting the 1st item in a suggestion list? this.start_check = 0; // show widget only after this number of characters is typed in (effective if >1) this.text_delimiter = [";", ","]; // delimiter for multiple autocomplete entries. Set it to empty array ( [] ) for single autocomplete. this.ajax_delimiter = "|"; // character that delimits entries in the string returned by AJAX call this.item_delimiter = ","; // character that delimits key and value for the suggestion item in the string returned by AJAX call this.selectedIndex = -1; // index (zero-based) of the entry last selected // "Private" variables: this.suggest_url = url || (array ? "" : autosuggest_url); // URL the server-side script that gives you the suggestion list this.msie = (document.all && !window.opera); this.displayed = false; this.delim_words = []; this.current_word = 0; this.delim_char = []; this.current = 0; this.total = 0; this.range_up = 0; this.range_down = 0; this.previous = 0; this.timer = 0; this.rebuild = false; this.evsetup = false; this.bool = []; this.rows = []; this.onSelect = onSelect || null; this.cur_x = 0; this.cur_y = 0; this.cur_w = 0; this.cur_h = 0; this.mouse_x = 0; this.mouse_y = 0; this.mouse_on_list = 0; this.caret_moved = false; this.field_id = id; this.field = field; this.lastterm = field.value; this.keywords = [], this.keywords_init = []; this.values = [], this.values_init = []; return this.construct(array || []); }; autosuggest.prototype = { construct: function(array) { function callLater(func, obj, param1, param2) { return function() { func.call(obj, param1 || null, param2 || null) }; } this.field.autosuggest = this; // Initialize the control from JS array, if any: this.bindArray(array); // Create event handlers: this.funcClick = this.mouseClick; this.funcCheck = this.checkKey; this.funcPress = this.keyPress; this.funcHighlight = this.highlightTable; this.funcClear = callLater(this.clearEvents, this); this.funcUp = callLater(this.scroll, this, true, 1); this.funcDown = callLater(this.scroll, this, false, 1); this.funcFocus = callLater(this.focusTable, this); this.funcUnfocus = callLater(this.unfocusTable, this); this.addEvent(this.field, "focus", callLater(this.setupEvents, this)); this.addEvent(window, "resize", callLater(this.reposition, this)); return this; }, bindArray: function(array) { if(!array || !array.length) return; this.suggest_url = ""; this.keywords = [], this.keywords_init = []; this.values = [], this.values_init = []; for(var i = 0, cl = array.length; i < cl; i++) { var item = array[i]; if(item.constructor == Array) { this.keywords[i] = this.keywords_init[i] = item[0]; this.values[i] = this.values_init[i] = item[1]; } else { this.keywords[i] = this.keywords_init[i] = item; this.values[i] = this.values_init[i] = ""; } } }, bindURL: function(url) { if(!url) url = autosuggest_url; this.suggest_url = url; }, setupEvents: function() { if(!this.evsetup) { this.evsetup = true; this.addEvent(document, "keydown", this.funcCheck); this.addEvent(this.field, "blur", this.funcClear); this.addEvent(document, "keypress", this.funcPress); } }, clearEvents: function() { // Removes an event handler: function removeEvent(obj, event_name, func_ref) { if(obj.removeEventListener && !window.opera) { obj.removeEventListener(event_name, func_ref, true); } else if(obj.detachEvent) { obj.detachEvent("on" + event_name, func_ref); } else { obj["on" + event_name] = null; } } var event = window.event; if(event && this.cur_h) { var elem = event.srcElement || event.target; var x = this.mouse_x + (document.documentElement.scrollLeft || document.body.scrollLeft || 0); var y = this.mouse_y + (document.documentElement.scrollTop || document.body.scrollTop || 0); if((elem.id == this.field_id) && (x > this.cur_x && x < (this.cur_x + this.cur_w)) && (y > this.cur_y && y < (this.cur_y + this.cur_h))) { this.field.focus(); return; } } removeEvent(document, "keydown", this.funcCheck); removeEvent(this.field, "blur", this.funcClear); removeEvent(document, "keypress", this.funcPress); this.hide(); this.evsetup = false; }, parse: function(n, plen, re) { if(!n || !n.length) return ""; if(!plen) return n; var tobuild = [], c = 0, p = n.search(re); tobuild[c++] = n.substr(0, p); tobuild[c++] = ""; tobuild[c++] = n.substring(p, plen + p); tobuild[c++] = ""; tobuild[c++] = n.substring(plen + p, n.length); return tobuild.join(""); }, build: function() { if(this.total == 0) { this.displayed = false; return; } this.rows = []; this.current = this.no_default ? -1 : 0; var that = this; this.addEvent(document, "mousemove", function(event) { event = event || window.event; that.mouse_x = event.x; that.mouse_y = event.y; }); var body = document.getElementById("suggest_table_" + this.field_id); if(body) { this.displayed = false; document.body.removeChild(body); var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) document.body.removeChild(helper); } var bb = document.createElement("div"); bb.id = "suggest_table_" + this.field_id; bb.className = "autosuggest-body"; this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; bb.style.top = this.cur_y + "px"; this.cur_x = this.curPos(this.field, "Left"); bb.style.left = this.cur_x + "px"; this.cur_w = this.field.offsetWidth - (this.msie ? 2 : 6); bb.style.width = this.cur_w + "px"; this.cur_h = 1; bb.style.height = "1px"; var cc = null; if(this.msie && this.use_iframe) { var cc = document.createElement("iframe"); cc.id = "suggest_helper_" + this.field_id; cc.src = "javascript:\"\";"; cc.scrolling = "no"; cc.frameBorder = "no"; } var that = this; var showFull = (this.total > this.entry_limit); if(cc) { document.body.appendChild(cc); cc.style.top = this.cur_y + "px"; cc.style.left = this.cur_x + "px"; cc.style.width = bb.offsetWidth + 2; } document.body.appendChild(bb); var first = true, dispCount = showFull ? this.entry_limit : this.total; var str = [], cn = 0; // cellspacing and cellpadding were not moved to css - IE doesn't understand border-spacing. str[cn++] = ""; bb.innerHTML = str.join(""); var table = bb.firstChild; if(this.use_mouse) { table.onmouseout = this.funcUnfocus; table.onmouseover = this.funcFocus; } var real_height = 0, real_width = 0; function createArrowRow(dir) { var row = table.insertRow(-1); row.className = dir ? "up" : "down"; var cell = row.insertCell(0); real_height += cell.offsetHeight + 1; return cell; } if(!this.use_scroll && showFull) createArrowRow(true).parentNode.className = "up-disabled"; var kl = this.keywords.length, counter = 0, j = 0; // For "parse" call: var t, plen; if(this.text_delimiter.length > 0) { var word = this.delim_words[this.current_word]; t = this.trim(this.addSlashes(word)); plen = this.trim(word).length; } else { var word = this.field.value; t = this.addSlashes(word); plen = word.length; } var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); function addSuggestion(index, _first) { var row = that.rows[j] = table.insertRow(-1); row.className = (_first || (that.previous == index)) ? "selected" : ""; var cell = row.insertCell(0); cell.innerHTML = that.parse(that.keywords[index], plen, re); cell.setAttribute("pos", j++); cell.autosuggest = that; if(that.use_mouse) { that.addEvent(cell, "click", that.funcClick); cell.onmouseover = that.funcHighlight; } return [row.offsetWidth, row.offsetHeight]; } for(var i = 0; i < kl; i++) { if(this.bool[i]) { var dim = addSuggestion(i, (first && !this.no_default && !this.rebuild)); first = false; if(counter <= this.entry_limit) real_height += dim[1] + 1; if(real_width < dim[0]) real_width = dim[0]; if(++counter == this.entry_limit) { ++i; break; } } } var last = i; if(showFull) { if(!this.use_scroll) { var cell = createArrowRow(false); if(this.use_mouse) this.addEvent(cell, "click", this.funcDown); } else { bb.style.height = real_height + "px"; bb.style.overflow = "auto"; bb.style.overflowX = "hidden"; } } this.cur_h = real_height + 1; bb.style.height = this.cur_h + "px"; this.cur_w = ((real_width > bb.offsetWidth) ? real_width : bb.offsetWidth) + (this.msie ? -2 : 2) + 100; bb.style.width = this.cur_w + "px"; if(cc) { cc.style.height = this.cur_h + "px"; cc.style.width = this.cur_w + "px"; } this.range_up = 0; this.range_down = j - 1; this.displayed = true; if(this.use_scroll) { setTimeout(function() { counter = 0; for(var i = last; i < kl; i++) { if(!that.displayed) return; if(that.bool[i]) { addSuggestion(i); if(++counter == that.entry_limit) { ++i; break; } } } last = i; if(j < that.total) setTimeout(arguments.callee, 25); }, 25); } }, remake: function() { this.rows = []; var a = document.getElementById("suggest_table2_" + this.field_id); var k = 0, first = true; function adjustArrow(obj, which, cond, handler) { var r = a.rows[k++]; r.className = which ? (cond ? "up" : "up-disabled") : (cond ? "down" : "down-disabled"); var c = r.firstChild; if(cond && handler && obj.use_mouse) obj.addEvent(c, "click", handler); } if(this.total > this.entry_limit) { var b = (this.range_up > 0); adjustArrow(this, true, b, this.funcUp); } // For "parse" call: var t, plen; if(this.text_delimiter.length > 0) { var word = this.delim_words[this.current_word]; t = this.trim(this.addSlashes(word)); plen = this.trim(word).length; } else { var word = this.field.value; t = this.addSlashes(word); plen = word.length; } var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); var kl = this.keywords.length, j = 0; for(var i = 0; i < kl; i++) { if(this.bool[i]) { if((j >= this.range_up) && (j <= this.range_down)) { var r = this.rows[j] = a.rows[k++]; r.className = ""; var c = r.firstChild; c.innerHTML = this.parse(this.keywords[i], plen, re); c.setAttribute("pos", j); } if(++j > this.range_down) break; } } if(kl > this.entry_limit) { var b = (j < this.total); adjustArrow(this, false, b, this.funcDown); } if(this.msie) { var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) helper.style.width = a.parentNode.offsetWidth + 2; } }, reposition: function() { if(this.displayed) { this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; this.cur_x = this.curPos(this.field, "Left"); var control = document.getElementById("suggest_table_" + this.field_id); control.style.top = this.cur_y + "px"; control.style.left = this.cur_x + "px"; } }, startTimer: function(on_list) { if(this.time_out > 0) this.timer = setTimeout(function() { this.mouse_on_list = on_list; this.hide(); }, this.time_out); }, stopTimer: function() { if(this.timer) { clearTimeout(this.timer); this.timer = 0; } }, getRow: function(index) { if(typeof(index) == "undefined") index = this.current; return (this.rows[index] || null); }, fixArrows: function(base) { if(this.total <= this.entry_limit) return; var table = base.firstChild, at_start = (this.current == 0), at_end = (this.current == (this.total - 1)); var row = table.rows[0]; row.className = at_start ? "up-disabled" : "up"; row = table.rows[this.entry_limit + 1]; row.className = at_end ? "down-disabled" : "down"; }, scroll: function(direction, times) { if(!this.displayed) return; this.field.focus(); if(this.current == (direction ? 0 : (this.total - 1))) return; if(!direction && (this.current < 0)) { this.current = -1; } else { var t = this.getRow(); if(t && t.style) t.className = ""; } this.current += times * (direction ? -1 : 1); if(direction) { if(this.current < 0) this.current = 0; } else { if(this.current >= this.total) this.current = this.total - 1; if(this.use_scroll && (this.current >= this.rows.length)) this.current = this.rows.length - 1; } var t = this.getRow(), base = document.getElementById("suggest_table_" + this.field_id); if(this.use_scroll) { if(direction) { if(t.offsetTop < base.scrollTop) base.scrollTop = t.offsetTop; } else { if((t.offsetTop + t.offsetHeight) > (base.scrollTop + base.offsetHeight)) { var ndx = this.current - this.entry_limit + 1; if(ndx > 0) base.scrollTop = this.getRow(ndx).offsetTop; } } } else { if(direction) { if(this.current < this.range_up) { this.range_up -= times; if(this.range_up < 0) this.range_up = 0; this.range_down = this.range_up + this.entry_limit - 1; this.remake(); } else this.fixArrows(base); } else { if(this.current > this.range_down) { this.range_down += times; if(this.range_down > (this.total - 1)) this.range_down = this.total - 1; this.range_up = this.range_down - this.entry_limit + 1; this.remake(); } else this.fixArrows(base); } t = this.getRow(); } if(t && t.style) t.className = "selected"; this.stopTimer(); this.startTimer(1); this.field.focus(); }, mouseClick: function(event) { event = event || window.event; var elem = event.srcElement || event.target; if(!elem.id) elem = elem.parentNode; var obj = elem.autosuggest; if(!obj) { var tag = elem.tagName.toLowerCase(); elem = (tag == "tr") ? elem.firstChild : elem.parentNode; obj = elem.autosuggest; } if(!obj || !obj.displayed) return; obj.mouse_on_list = 0; obj.current = parseInt(elem.getAttribute("pos"), 10); obj.choose(); }, focusTable: function() { this.mouse_on_list = 1; }, unfocusTable: function() { this.mouse_on_list = 0; this.stopTimer(); this.startTimer(0) }, highlightTable: function(event) { event = event || window.event; var elem = event.srcElement || event.target; var obj = elem.autosuggest; if(!obj) return; obj.mouse_on_list = 1; var row = obj.getRow(); if(row && row.style) row.className = ""; obj.current = parseInt(elem.getAttribute("pos"), 10); row = obj.getRow(); if(row && row.style) row.className = "selected"; obj.stopTimer(); obj.startTimer(0); }, choose: function() { if(!this.displayed) return; if(this.current < 0) return; this.displayed = false; var kl = this.keywords.length; for(var i = 0, c = 0; i < kl; i++) if(this.bool[i] && (c++ == this.current)) break; this.selectedIndex = i; this.insertWord(this.keywords[i]); if(this.onSelect) this.onSelect(i, this); }, insertWord: function(a) { // Sets the caret position to l in the object function setCaretPos(obj, l) { obj.focus(); if(obj.setSelectionRange) { obj.setSelectionRange(l, l); } else if(obj.createTextRange) { var m = obj.createTextRange(); m.moveStart("character", l); m.collapse(); m.select(); } } if(this.text_delimiter.length > 0) { var str = "", word = this.delim_words[this.current_word], wl = word.length, l = 0; for(var i = 0; i < this.delim_words.length; i++) { if(this.current_word == i) { var prespace = "", postspace = "", gotbreak = false; for(var j = 0; j < wl; ++j) { if(word.charAt(j) != " ") { gotbreak = true; break; } prespace += " "; } for(j = wl - 1; j >= 0; --j) { if(word.charAt(j) != " ") break; postspace += " "; } str += prespace; str += a; l = str.length; if(gotbreak) str += postspace; } else { str += this.delim_words[i]; } if(i != this.delim_words.length - 1) str += this.delim_char[i]; } this.field.value = str; setCaretPos(this.field, l); } else { this.field.value = a; } this.mouse_on_list = 0; this.hide(); }, hide: function() { if(this.mouse_on_list == 0) { this.displayed = false; var base = document.getElementById("suggest_table_" + this.field_id); if(base) { var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) document.body.removeChild(helper); document.body.removeChild(base); } this.stopTimer(); this.cur_x = 0; this.cur_y = 0; this.cur_w = 0; this.cur_h = 0; this.rows = []; } }, keyPress: function(event) { // On firefox there is no way to distingish pressing shift-8 (asterix) // from pressing 8 during the keyDown event, so we do restrict_typing // whilest handling the keyPress event event = event || window.event; var code = window.event ? event.keyCode : event.charCode; var obj = event.srcElement || event.target; obj = obj.autosuggest; if(obj.restrict_typing && !obj.suggest_url.length && (code >= 32)) { var caret_pos = obj.getCaretEnd(obj.field); var new_term = obj.field.value.substr(0, caret_pos).toLowerCase(); var isDelimiter = false; if(obj.text_delimiter.length > 0) { // check whether the pressed key is a delimiter key var delim_split = ""; for(var j = 0; j < obj.text_delimiter.length; j++) { delim_split += obj.text_delimiter[j]; if(obj.text_delimiter[j] == String.fromCharCode(code)) isDelimiter = true; } // only consider part of term after last delimiter delim_split = obj.addSlashes(delim_split); var lastterm_rx = new RegExp(".*([" + delim_split + "])"); new_term = new_term.replace(lastterm_rx, ''); } var keyw_len = obj.keywords.length; var i = 0; if(isDelimiter) { // pressed key is a delimiter: allow if current term is complete for(i = 0; i < keyw_len; i++) if(obj.keywords[i].toLowerCase() == new_term) break; } else { new_term += String.fromCharCode(code).toLowerCase(); for(i = 0; i < keyw_len; i++) if(obj.keywords[i].toLowerCase().indexOf(new_term) != -1) break; } if(i == keyw_len) { obj.stopEvent(event); return false; } } if(obj.caret_moved) obj.stopEvent(event); return !obj.caret_moved; }, checkKey: function(event) { event = event || window.event; var code = event.keyCode; var obj = event.srcElement || event.target; obj = obj.autosuggest; obj.caret_moved = 0; var term = ""; obj.stopTimer(); switch(code) { // Up arrow: case 38: if(obj.current <= 0) { obj.stopEvent(event); obj.hide(); } else { obj.scroll(true, 1); obj.caret_moved = 1; obj.stopEvent(event); } return false; // Down arrow: case 40: if(!obj.displayed) { obj.timer = setTimeout(function() { obj.preSuggest(-1); }, 25); } else { obj.scroll(false, 1); obj.caret_moved = 1; } return false; // Page up: case 33: if(obj.current == 0) { obj.caret_moved = 0; return false; } obj.scroll(true, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_up])) ? obj.entry_limit : (obj.current - obj.range_up)); obj.caret_moved = 1; break; // Page down: case 34: if(obj.current == (obj.total - 1)) { obj.caret_moved = 0; return false; } obj.scroll(false, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_down])) ? obj.entry_limit : (obj.range_down - obj.current)); obj.caret_moved = 1; break; // Home case 36: if(obj.current == 0) { obj.caret_moved = 0; return false; } obj.scroll(true, obj.total); obj.caret_moved = 1; break; // End case 35: if(obj.current == (obj.total - 1)) { obj.caret_moved = 0; return false; } obj.scroll(false, obj.total); obj.caret_moved = 1; break; // Esc: case 27: term = obj.field.value; obj.mouse_on_list = 0; obj.hide(); break; // Enter: case 13: if(obj.displayed) { obj.caret_moved = 1; obj.choose(); return false; } break; // Tab: case 9: if((obj.displayed && (obj.current >= 0)) || obj.timer) { obj.caret_moved = 1; obj.choose(); setTimeout(function() { obj.field.focus(); }, 25); return false; } break; case 16: //shift break; default: obj.caret_moved = 0; obj.timer = setTimeout(function() { obj.preSuggest(code); }, (obj.response_time < 10 ? 10 : obj.response_time)); } if(term.length) setTimeout(function() { obj.field.value = term; }, 25); return true; }, preSuggest: function(kc) { if(!this.timer) return; this.stopTimer(); if(this.displayed && (this.lastterm == this.field.value)) return; this.lastterm = this.field.value; if(kc == 38 || kc == 40 || kc == 13) return; var c = 0; if(this.displayed && (this.current >= 0)) { for(var i = 0; i < this.keywords.length; i++) { if(this.bool[i]) ++c; if(c == this.current) { this.previous = i; break; } } } else { this.previous = -1; } if(!this.field.value.length && (kc != -1)) { this.mouse_on_list = 0; this.hide(); } var ot, t; if(this.text_delimiter.length > 0) { var caret_pos = this.getCaretEnd(this.field); var delim_split = ""; for(var i = 0; i < this.text_delimiter.length; i++) delim_split += this.text_delimiter[i]; delim_split = this.addSlashes(delim_split); var delim_split_rx = new RegExp("([" + delim_split + "])"); c = 0; this.delim_words = []; this.delim_words[0] = ""; for(var i = 0, j = this.field.value.length; i < this.field.value.length; i++, j--) { if(this.field.value.substr(i, j).search(delim_split_rx) == 0) { var ma = this.field.value.substr(i, j).match(delim_split_rx); this.delim_char[c++] = ma[1]; this.delim_words[c] = ""; } else { this.delim_words[c] += this.field.value.charAt(i); } } var l = 0; this.current_word = -1; for(i = 0; i < this.delim_words.length; i++) { if((caret_pos >= l) && (caret_pos <= (l + this.delim_words[i].length))) this.current_word = i; l += this.delim_words[i].length + 1; } ot = this.trim(this.delim_words[this.current_word]); t = this.trim(this.addSlashes(this.delim_words[this.current_word])); } else { ot = this.field.value; t = this.addSlashes(ot); } if(ot.length == 0 && (kc != -1)) { this.mouse_on_list = 0; this.hide(); } else if((ot.length == 1) || this.full_refresh || ((ot.length > 1) && !this.keywords.length) || ((ot.length > 1) && (this.keywords[0].charAt(0).toLowerCase() != ot.charAt(0).toLowerCase()))) { var ot_ = ((ot.length > 1) && !this.full_refresh) ? ot.charAt(0) : ot; if(this.suggest_url.length) { // create xmlhttprequest object: var http = null; if(typeof(XMLHttpRequest) != "undefined") { try { http = new XMLHttpRequest(); } catch (e) { http = null; } } else { try { http = new ActiveXObject("Msxml2.XMLHTTP") ; } catch (e) { try { http = new ActiveXObject("Microsoft.XMLHTTP") ; } catch (e) { http = null; } } } if(http) { // Uncomment for local debugging in Mozilla/Firefox: // try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { } if(http.overrideMimeType) http.overrideMimeType("text/xml"); http.open("GET", this.suggest_url + ot_, true); var that = this; http.onreadystatechange = function(n) { if(http.readyState == 4) { if((http.status == 200) || (http.status == 0)) { var text = http.responseText; var index1 = text.indexOf(""); var index2 = (index1 == -1) ? text.length : text.indexOf(" obj.value.length) return -1; return rb; } return -1; }, // Get offset position from the top/left of the screen: curPos: function(obj, what) { var coord = 0; while(obj) { coord += obj["offset" + what]; obj = obj.offsetParent; } return coord; }, // String functions: addSlashes: function(str) { return str.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, "\\$1"); }, trim: function(str) { return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"); } }; allegro-5.0.10/docs/CMakeLists.txt0000644000175000001440000001262511467730662016120 0ustar tjadenusersfind_program(MAKEINFO NAMES makeinfo) mark_as_advanced(MAKEINFO) find_program(PANDOC NAMES pandoc) mark_as_advanced(PANDOC) # sh is only used for a developer-only target. find_program(SH NAMES ash dash sh) mark_as_advanced(SH) find_package(LATEX) find_program(CTAGS NAMES ctags) mark_as_advanced(CTAGS) #-----------------------------------------------------------------------------# # Pandoc < 1.0 is usable but doesn't have Texinfo support. if(PANDOC AND NOT DEFINED PANDOC_WITH_TEXINFO) message(STATUS "Checking Pandoc version") execute_process( COMMAND ${PANDOC} --version OUTPUT_VARIABLE PANDOC_VERSION_TEXT ERROR_VARIABLE PANDOC_VERSION_TEXT ) if(PANDOC_VERSION_TEXT MATCHES "pandoc [1-9]") set(PANDOC_WITH_TEXINFO 1 CACHE BOOL "Pandoc supports Texinfo") else() set(PANDOC_WITH_TEXINFO 0 CACHE BOOL "Pandoc supports Texinfo") endif() mark_as_advanced(PANDOC_WITH_TEXINFO) endif() # Pandoc 1.2 and 1.2.1 accidentally changed the way it generates HTML # identifiers. if(PANDOC AND NOT DEFINED PANDOC_STRIP_UNDERSCORES) if(NOT PANDOC_VERSION_TEXT) execute_process( COMMAND ${PANDOC} --version OUTPUT_VARIABLE PANDOC_VERSION_TEXT ERROR_VARIABLE PANDOC_VERSION_TEXT ) endif() if(PANDOC_VERSION_TEXT MATCHES "pandoc 1[.]2(\n|[.]1)") set(PANDOC_STRIP_UNDERSCORES 1 CACHE BOOL "Pandoc strips underscores for HTML identifiers") else() set(PANDOC_STRIP_UNDERSCORES 0 CACHE BOOL "Pandoc strips underscores for HTML identifiers") endif() mark_as_advanced(PANDOC_STRIP_UNDERSCORES) endif() # Pandoc 1.5 or later is required for LaTeX as it will begin # sectioning with \chapter. if(PANDOC AND NOT DEFINED PANDOC_FOR_LATEX) if(NOT PANDOC_VERSION_TEXT) execute_process( COMMAND ${PANDOC} --version OUTPUT_VARIABLE PANDOC_VERSION_TEXT ERROR_VARIABLE PANDOC_VERSION_TEXT ) endif() if(PANDOC_VERSION_TEXT MATCHES "pandoc (0|1[.][01234])") set(PANDOC_FOR_LATEX 0 CACHE BOOL "Pandoc recent enough for LaTeX output") else() set(PANDOC_FOR_LATEX 1 CACHE BOOL "Pandoc recent enough for LaTeX output") endif() mark_as_advanced(PANDOC_FOR_LATEX) endif() #-----------------------------------------------------------------------------# set(all_docs) macro(add_info n) if(MAKEINFO) makedoc(src/${n}._tx -texi texi/${n}.texi) set(abs_info ${CMAKE_CURRENT_BINARY_DIR}/info/${n}.info) set(abs_texi ${CMAKE_CURRENT_BINARY_DIR}/texi/${n}.texi) list(APPEND all_docs ${abs_info}) add_custom_command( OUTPUT ${abs_info} DEPENDS ${abs_texi} COMMAND ${MAKEINFO} --no-split -o ${abs_info} ${abs_texi} ) endif(MAKEINFO) endmacro(add_info) #-----------------------------------------------------------------------------# function(pandoc source output) # extraargs... set(abs_source ${CMAKE_CURRENT_SOURCE_DIR}/${source}) set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output}) # Use native Windows syntax to avoid "c:/foo.txt" being treated as a # remote URI by Pandoc 1.5 and 1.6. file(TO_NATIVE_PATH ${abs_source} abs_source_native) list(APPEND all_docs ${abs_output}) set(all_docs ${all_docs} PARENT_SCOPE) add_custom_command( OUTPUT ${abs_output} DEPENDS ${abs_source} COMMAND ${PANDOC} ${abs_source_native} --toc --standalone ${ARGN} -o ${abs_output} ) endfunction(pandoc source output) function(texi2text source output) # The source file is a generated Texinfo file. set(abs_source ${CMAKE_CURRENT_BINARY_DIR}/${source}) set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output}) list(APPEND all_docs ${abs_output}) set(all_docs ${all_docs} PARENT_SCOPE) # Writing to stdout suppresses the table of contents. # To get the table of contents, use `makeinfo -o ${output}`. add_custom_command( OUTPUT ${abs_output} DEPENDS ${abs_source} COMMAND ${MAKEINFO} --plaintext --paragraph-indent 0 --no-number-sections ${abs_source} > ${abs_output} ) endfunction(texi2text) if(PANDOC) pandoc( src/changes-5.0.txt html/changes-5.0.html -c pandoc.css ) endif(PANDOC) if(PANDOC_WITH_TEXINFO) pandoc( src/changes-5.0.txt texi/changes-5.0.texi ) if(MAKEINFO) texi2text( texi/changes-5.0.texi txt/changes-5.0.txt ) endif(MAKEINFO) endif(PANDOC_WITH_TEXINFO) add_custom_target(docs ALL DEPENDS ${all_docs} ) #-----------------------------------------------------------------------------# make_directory(${CMAKE_CURRENT_BINARY_DIR}/html/refman) make_directory(${CMAKE_CURRENT_BINARY_DIR}/txt) make_directory(${CMAKE_CURRENT_BINARY_DIR}/texi) # Copy CSS files. configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/pandoc.css ${CMAKE_CURRENT_BINARY_DIR}/html/pandoc.css COPYONLY ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/pandoc.css ${CMAKE_CURRENT_BINARY_DIR}/html/refman/pandoc.css COPYONLY ) if(PANDOC AND NOT CMAKE_CROSSCOMPILING) include(Refman.cmake) endif() #-----------------------------------------------------------------------------# # vim: set sts=4 sw=4 et: allegro-5.0.10/docs/scripts/0000755000175000001440000000000012157230746015034 5ustar tjadenusersallegro-5.0.10/docs/scripts/make_html_refs.c0000644000175000001440000000220111306654671020155 0ustar tjadenusers/* * make_html_refs DOC-FILE... * * Generate a file containing (HTML-specific) link definitions for each API * entry found. e.g. if foo.txt contains "# API: bar" then we generate: * * [bar]: foo.html#bar * * OPTIONS * * --strip-underscores * Pandoc 1.2 and 1.2.1 strip underscores when generating HTML identifiers * so we must do the same. */ #include #include "dawk.h" int main(int argc, char *argv[]) { int strip_underscores = false; dstr line; dstr file; const char *name; dstr sec_id; if (argc >= 2 && 0 == strcmp(argv[1], "--strip-underscores")) { strip_underscores = true; argc--; argv++; } d_init(argc, argv); while (d_getline(line)) { if (d_match(line, "^#+ API: *")) { d_basename(d_filename, ".html", file); name = d_after_match; d_tolower(name, sec_id); if (strip_underscores) { d_delchr(sec_id, '_'); } /* The extra blank lines are to work around Pandoc issue #182. */ d_printf("[%s]: %s#%s\n\n", name, file, sec_id); } } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/make_single.c0000644000175000001440000000731411655353507017466 0ustar tjadenusers#include #include "dawk.h" #include "make_doc.h" static void preprocess(void); static void postprocess_latex(void); static void postprocess_texinfo(void); static void cat(void); static void print_sans_backslashes(const char *p); void make_single_doc(int argc, char *argv[]) { d_init(argc, argv); /* Hidden format for debugging. */ if (streq(to_format, "preprocess")) { preprocess(); return; } d_open_output(tmp_preprocess_output); preprocess(); d_close_output(); call_pandoc(tmp_preprocess_output, tmp_pandoc_output, ""); d_open_input(tmp_pandoc_output); if (streq(to_format, "latex")) postprocess_latex(); else if (streq(to_format, "texinfo")) postprocess_texinfo(); else cat(); d_close_input(); } static void preprocess(void) { dstr line; while (d_getline(line)) { /* Raise sections by one level. Top-most becomes the document title. */ if (line[0] == '#' && raise_sections) { if (line[1] == ' ') { line[0] = '%'; } else { char *p = strchr(line, ' '); if (p) { p[-1] = ' '; } } } /* Make sure there is a blank line between input files so paragraphs * across files don't get merged. But don't break document titles which * must be on the first line. */ if (d_line_num == 1 && line[0] != '%') { d_print(""); } if (d_match(line, "^(#+) +API: *")) { const char *hashes = d_submatch(1); const char *name = d_after_match; const char *text = lookup_prototype(name); d_printf("%s %s\n", hashes, name); d_print(text); } else { d_print(line); } } } static void postprocess_latex(void) { dstr line; while (d_getline(line)) { /* Insert \label{id} for all sections which are probably API entries. * T-Rex doesn't seem to backtrack properly if we write "(sub)*". */ if (d_match(line, "\\\\(sub)?(sub)?(sub)?(sub)?section\\{((al|ALLEGRO)[^}]+)")) { d_print(line); d_printf("\\label{"); print_sans_backslashes(d_submatch(5)); d_printf("}\n"); continue; } /* Replace `verbatim' environment by `Verbatim' from fancyvrb, * which gives us some flexibility over the formatting. */ if (d_match(line, "\\\\begin\\{verbatim\\}$")) { d_printf("%s", d_before_match); d_print("\\begin{Verbatim}"); continue; } if (d_match(line, "\\\\end\\{verbatim\\}$")) { d_printf("%s", d_before_match); d_print("\\end{Verbatim}"); continue; } /* Change cross references from: * \href{DUMMYREF}{foo\_bar\_baz} * to: * \alref{foo_bar_baz} */ while (d_match(line, "\\\\href\\{DUMMYREF\\}\\{([^}]*)\\}")) { const char *ref = d_submatch(1); d_printf("%s", d_before_match); d_printf("\\alref{", ref); print_sans_backslashes(ref); d_printf("}"); d_assign(line, d_after_match); } d_print(line); } } static void postprocess_texinfo(void) { dstr line; while (d_getline(line)) { /* Replace dummy references by real references (see make_dummy_refs). */ while (d_match(line, "@uref\\{DUMMYREF,")) { d_printf("%s@ref{", d_before_match); d_assign(line, d_after_match); } d_print(line); } } static void cat(void) { dstr line; while (d_getline(line)) d_print(line); } static void print_sans_backslashes(const char *p) { for (; *p; p++) { if (*p != '\\') fputc(*p, D_STDOUT); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/update_web.py0000755000175000001440000000261411566071435017534 0ustar tjadenusers#!/usr/bin/env python import optparse, subprocess, sys, os def main(argv): global options p = optparse.OptionParser() p.add_option("-p", "--path", help = "Path to the build directory.") p.add_option("-u", "--user", help = "Username to use.") p.add_option("-d", "--directory", help = "Remote directory to " + "use. Should be either 'trunk' which is the default or else " + "the version number.", default = "trunk") options, args = p.parse_args() if options.user: sf = "%s,alleg@web.sf.net" % options.user else: sys.stderr.write("SourceForge user name required (-u).\n") p.print_help() sys.exit(-1) if not options.path: sys.stderr.write("Build path required (-p).\n") p.print_help() sys.exit(-1) destdir = "/home/groups/a/al/alleg/htdocs_parts/staticweb/a5docs" destdir += "/" + options.directory def run(cmd): print ">", cmd return subprocess.call(cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) print "Copying files.." rsync = "rsync --delete -r -z" path = os.path.join(options.path, "docs/html/refman/") retcode = run("%s %s %s:%s" % (rsync, path, sf, destdir)) if retcode == 0: print("Updated A5 docs at: http://docs.liballeg.org") sys.exit(retcode) if __name__ == "__main__": main(sys.argv) allegro-5.0.10/docs/scripts/trex.h0000644000175000001440000000415511255341031016160 0ustar tjadenusers#ifndef _TREX_H_ #define _TREX_H_ /*************************************************************** T-Rex a tiny regular expression library Copyright (C) 2003-2006 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ****************************************************************/ #ifdef _UNICODE #define TRexChar unsigned short #define MAX_CHAR 0xFFFF #define _TREXC(c) L##c #define trex_strlen wcslen #define trex_printf wprintf #else #define TRexChar char #define MAX_CHAR 0xFF #define _TREXC(c) (c) #define trex_strlen strlen #define trex_printf printf #endif #ifndef TREX_API #define TREX_API extern #endif #define TRex_True 1 #define TRex_False 0 typedef unsigned int TRexBool; typedef struct TRex TRex; typedef struct { const TRexChar *begin; int len; } TRexMatch; TREX_API TRex *trex_compile(const TRexChar *pattern,const TRexChar **error); TREX_API void trex_free(TRex *exp); TREX_API TRexBool trex_match(TRex* exp,const TRexChar* text); TREX_API TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end); TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end); TREX_API int trex_getsubexpcount(TRex* exp); TREX_API TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp); #endif allegro-5.0.10/docs/scripts/check_consistency0000755000175000001440000000203411134322104020437 0ustar tjadenusers#!/bin/sh -e # # SYNOPSIS # # check_consistency [OPTION...] DOC-FILE... # # OPTION # # --protos FILE # # DESCRIPTION # # Check that functions and types marked in source code have corresponding # entries in the documentation, and vice versa. The protos file must be # present. # # ENVIRONMENT VARIABLES # # - PROTOS # export LC_ALL=C PROTOS=${PROTOS:-protos} case $1 in --protos) PROTOS=$2 shift 2 ;; esac if test ! -f "$PROTOS" then echo "check_consistency: missing protos file: $PROTOS" 1>&2 exit 1 fi TEMP_SRC=check_consistency.tmp1.$$ TEMP_DOC=check_consistency.tmp2.$$ trap 'rm -f $TEMP_SRC $TEMP_DOC' 0 1 2 3 13 15 cut -d':' -f1 "$PROTOS" | sort | uniq > $TEMP_SRC grep -h '# API: ' "$@" | cut -d' ' -f 3- | sort | uniq > $TEMP_DOC diff $TEMP_SRC $TEMP_DOC | while read -r marker name do case $marker in '>') echo "$name not in source (or missing Function: marker)" ;; '<') echo "$name not documented" ;; esac done # vim: set et: allegro-5.0.10/docs/scripts/make_doc.h0000644000175000001440000000114311255341031016732 0ustar tjadenusers#ifndef __included_make_doc_h #define __included_make_doc_h #include "dawk.h" extern dstr pandoc; extern dstr pandoc_options; extern dstr protos_file; extern dstr to_format; extern bool raise_sections; extern char tmp_preprocess_output[80]; extern char tmp_pandoc_output[80]; #define streq(a, b) (0 == strcmp((a), (b))) const char *lookup_prototype(const char *name); extern void call_pandoc(const char *input, const char *output, const char *extra_options); extern void make_single_doc(int argc, char *argv[]); extern void make_man_pages(int argc, char *argv[]); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/trex.txt0000644000175000001440000001261511255341031016550 0ustar tjadenusersT-REX 1.3 http://tiny-rex.sourceforge.net ---------------------------------------------------------------------- T-Rex a tiny regular expression library Copyright (C) 2003-2006 Alberto Demichelis This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ---------------------------------------------------------------------- TRex implements the following expressions \ Quote the next metacharacter ^ Match the beginning of the string . Match any character $ Match the end of the string | Alternation () Grouping (creates a capture) [] Character class ==GREEDY CLOSURES== * Match 0 or more times + Match 1 or more times ? Match 1 or 0 times {n} Match exactly n times {n,} Match at least n times {n,m} Match at least n but not more than m times ==ESCAPE CHARACTERS== \t tab (HT, TAB) \n newline (LF, NL) \r return (CR) \f form feed (FF) ==PREDEFINED CLASSES== \l lowercase next char \u uppercase next char \a letters \A non letters \w alphanimeric [0-9a-zA-Z] \W non alphanimeric \s space \S non space \d digits \D non nondigits \x exadecimal digits \X non exadecimal digits \c control charactrs \C non control charactrs \p punctation \P non punctation \b word boundary \B non word boundary ---------------------------------------------------------------------- API DOC ---------------------------------------------------------------------- TRex *trex_compile(const TRexChar *pattern,const TRexChar **error); compiles an expression and returns a pointer to the compiled version. in case of failure returns NULL.The returned object has to be deleted through the function trex_free(). pattern a pointer to a zero terminated string containing the pattern that has to be compiled. error apointer to a string pointer that will be set with an error string in case of failure. ---------------------------------------------------------------------- void trex_free(TRex *exp) deletes a expression structure created with trex_compile() exp the expression structure that has to be deleted ---------------------------------------------------------------------- TRexBool trex_match(TRex* exp,const TRexChar* text) returns TRex_True if the string specified in the parameter text is an exact match of the expression, otherwise returns TRex_False. exp the compiled expression text the string that has to be tested ---------------------------------------------------------------------- TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) searches the first match of the expressin in the string specified in the parameter text. if the match is found returns TRex_True and the sets out_begin to the beginning of the match and out_end at the end of the match; otherwise returns TRex_False. exp the compiled expression text the string that has to be tested out_begin a pointer to a string pointer that will be set with the beginning of the match out_end a pointer to a string pointer that will be set with the end of the match ---------------------------------------------------------------------- TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) searches the first match of the expressin in the string delimited by the parameter text_begin and text_end. if the match is found returns TRex_True and the sets out_begin to the beginning of the match and out_end at the end of the match; otherwise returns TRex_False. exp the compiled expression text_begin a pointer to the beginnning of the string that has to be tested text_end a pointer to the end of the string that has to be tested out_begin a pointer to a string pointer that will be set with the beginning of the match out_end a pointer to a string pointer that will be set with the end of the match ---------------------------------------------------------------------- int trex_getsubexpcount(TRex* exp) returns the number of sub expressions matched by the expression exp the compiled expression --------------------------------------------------------------------- TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *submatch) retrieve the begin and and pointer to the length of the sub expression indexed by n. The result is passed trhough the struct TRexMatch: typedef struct { const TRexChar *begin; int len; } TRexMatch; the function returns TRex_True if n is valid index otherwise TRex_False. exp the compiled expression n the index of the submatch submatch a pointer to structure that will store the result this function works also after a match operation has been performend. allegro-5.0.10/docs/scripts/make_protos.c0000644000175000001440000000226711332061121017511 0ustar tjadenusers/* * make_protos SOURCE-FILE... * * Extract all the function prototypes and type/enum declarations which have * Natural Docs tags Function: Type: Enum: and print them to standard output. */ #include "dawk.h" int main(int argc, char *argv[]) { bool found_tag = false; bool do_print = false; dstr line = ""; dstr prefix = ""; d_init(argc, argv); while (d_getline(line)) { if (d_match(line, "/[*] (Function|Type|Enum): (.*)")) { found_tag = true; do_print = false; d_assign(prefix, d_submatch(2)); continue; } if (found_tag && d_match(line, "^ ?\\*/")) { found_tag = false; do_print = true; continue; } if (d_match(line, "^\\{|^$")) { do_print = false; continue; } /* Prototype ends on blank line. */ /* TODO: Should the above regexp match it? If so it doesn't here... */ if (line[0] == 0) { do_print = false; continue; } if (do_print) { printf("%s: %s\n", prefix, line); } if (d_match(line, "\\{ *$|; *$")) { do_print = false; } } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/make_search_index.c0000644000175000001440000000156411255341031020623 0ustar tjadenusers/* * make_search_index html_refs > search_index.js * * Read html_refs and convert it to a Javascript index for autosuggest.js. */ #include #include "dawk.h" #define MAX_ENTRIES 1024 dstr names[MAX_ENTRIES]; dstr urls[MAX_ENTRIES]; int num_entries = 0; int main(int argc, char *argv[]) { dstr line; int i; d_init(argc, argv); while (d_getline(line)) { if (d_match(line, "^\\[(.*)\\]: (.*)")) { strcpy(names[num_entries], d_submatch(1)); strcpy(urls[num_entries], d_submatch(2)); num_entries++; } } printf("var search_index = [\n"); for (i = 0; i < num_entries; i++) { printf("'%s',", names[i]); } printf("]\n"); printf("var search_urls = [\n"); for (i = 0; i < num_entries; i++) { printf("'%s',", urls[i]); } printf("]\n"); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/aatree.h0000644000175000001440000000071111255341031016431 0ustar tjadenusers#ifndef __included_aatree_h #define __included_aatree_h typedef struct Aatree Aatree; struct Aatree { int level; Aatree *left; Aatree *right; char *key; char *value; }; extern Aatree aa_nil; Aatree *aa_singleton(const char *key, const char *value); Aatree *aa_insert(Aatree *T, const char *key, const char *value); const char *aa_search(const Aatree *T, const char *key); void aa_destroy(Aatree *T); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/make_man.c0000644000175000001440000000603111771523516016751 0ustar tjadenusers#include #include #include "aatree.h" #include "dawk.h" #include "make_doc.h" #define MAX_NAMES 64 static const char *SECTION = "3"; static const char *MANUAL = "Allegro reference manual"; static dstr last_header; static dstr names[MAX_NAMES]; static void man_page_header(const char *name) { d_printf("%% %s(%s) %s\n", name, SECTION, MANUAL); d_print("# NAME"); d_print(name); d_print(" \\- Allegro 5 API"); d_print("\n# SYNOPSIS"); d_print(last_header); d_print(lookup_prototype(name)); d_print("\n# DESCRIPTION"); } static void call_pandoc_for_man(const char *input, int name_count) { dstr output_filename; int i; for (i = 0; i < name_count; i++) { sprintf(output_filename, "%s.%s", names[i], SECTION); call_pandoc(input, output_filename, "--standalone"); } } void make_man_pages(int argc, char *argv[]) { int output_level = 0; int name_count = 0; dstr line; d_init(argc, argv); while (d_getline(line)) { /* Stop outputting the current man page at the first line beginning with * the same or few number of hashes, i.e. at the same level or above. */ if (d_match(line, "^(#+) ") && output_level > 0) { int n = strlen(d_submatch(1)); if (n <= output_level) { d_close_output(); call_pandoc_for_man(tmp_preprocess_output, name_count); name_count = 0; output_level = 0; } } if (d_match(line, "^ *#include ") && output_level == 0) { d_assign(last_header, line); continue; } if (d_match(line, "^(#+) API: *(.*)")) { const char *hashes = d_submatch(1); const char *name = d_submatch(2); if (output_level == 0) { output_level = strlen(hashes); d_open_output(tmp_preprocess_output); man_page_header(name); } else { d_printf("%s %s\n", hashes, name); } if (name_count < MAX_NAMES) { d_assign(names[name_count], name); name_count++; } continue; } if (!output_level) { continue; } if (d_match(line, "^\\*?Return [Vv]alue:\\*?")) { d_print("# RETURN VALUE"); d_assign(line, d_after_match); } if (d_match(line, "^\\*?Since:\\*?")) { d_print("# SINCE"); d_assign(line, d_after_match); } if (d_match(line, "^\\*?See [Aa]lso:\\*?")) { d_print("# SEE ALSO"); d_assign(line, d_after_match); } /* Replace [al_foo] and [ALLEGRO_foo] by al_foo(3) and ALLEGRO_foo(3). */ while (d_match(line, "\\[((al_|ALLEGRO_)[^\\]]*)\\]")) { d_printf("%s", d_before_match); d_printf("%s(%s)", d_submatch(1), SECTION); d_assign(line, d_after_match); } d_print(line); } if (output_level > 0) { d_close_output(); call_pandoc_for_man(tmp_preprocess_output, name_count); name_count = 0; output_level = 0; } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/dawk.c0000644000175000001440000001447011467632033016132 0ustar tjadenusers/* Support for awk-style processing in C. */ #include #include #include #include #include /* I'd prefer to use the POSIX regexp interface, but for portability we need a * fallback, and supporting two regexp implementations is asking for trouble. * T-Rex is small and quick enough so we use it everywhere. However it * doesn't seem to behave properly on some expressions (which we can work * around when the regexps are fixed) so I couldn't recommend it in general. */ #include "dawk.h" #include "trex.h" typedef struct { const char *regex; TRex *reg; } re_cache_t; void (*d_cleanup)(void); static int d_argc; static char **d_argv; static int d_file_num; static FILE *d_file; dstr d_filename; int d_line_num; FILE *d_stdout; #define D_STDOUT (d_stdout ? d_stdout : stdout) #define MAX_RE_CACHE 16 static re_cache_t d_regex_cache[MAX_RE_CACHE]; static dstr d_submatches[MAX_MATCH]; dstr d_before_match; dstr d_after_match; /* Abort with an error message. */ void d_doabort(const char *filename, int line, const char *msg1, const char *msg2) { fprintf(stderr, "%s:%d: %s%s\n", filename, line, msg1, msg2); if (d_cleanup) { d_cleanup(); } exit(EXIT_FAILURE); } /* Prepare to read input from the files listed in argv. */ void d_init(int argc, char *argv[]) { d_argc = argc; d_argv = argv; d_file_num = 0; d_close_input(); } /* Open a single file for reading. */ void d_open_input(const char *filename) { if (d_file) { fclose(d_file); } d_file = fopen(filename, "r"); if (!d_file) { d_abort("could not open file for reading: ", filename); } d_assign(d_filename, filename); d_line_num = 0; d_file_num = -1; } /* Close input file. */ void d_close_input(void) { if (d_file) { fclose(d_file); } d_file = NULL; d_assign(d_filename, ""); } /* Read the next line from the current input file(s). */ bool d_getline(dstr var) { char *p = var; int c; /* Open the next file if necessary. */ if (!d_file) { if (d_file_num == -1 || d_file_num + 1 >= d_argc) { return false; } d_file_num++; d_file = fopen(d_argv[d_file_num], "r"); if (!d_file) { d_abort("could not open file for reading: ", d_argv[d_file_num]); } d_assign(d_filename, d_argv[d_file_num]); d_line_num = 0; } for (;;) { c = fgetc(d_file); if (c == EOF || c == '\n') { break; } *p++ = c; if (p - var >= MAX_STRING - 1) { fprintf(stderr, "dawk: string length limit reached\n"); break; } } *p = '\0'; if (c == EOF) { fclose(d_file); d_file = NULL; if (p == var) { return d_getline(var); } } else if (c == '\n') { d_line_num++; /* Remove trailing CR if present. */ if (p > var && p[-1] == '\r') { p[-1] = '\0'; } } return true; } /* Open a file for writing. */ void d_open_output(const char *filename) { FILE *f; d_close_output(); f = fopen(filename, "w"); if (!f) { d_abort("error opening file for writing: ", filename); } d_stdout = f; } /* Close the output file, reverting to standard output. */ void d_close_output(void) { if (d_stdout && d_stdout != stdout) { fclose(d_stdout); } d_stdout = NULL; } /* Print a line to the output file, with newline. */ void d_print(const char *s) { fprintf(D_STDOUT, "%s\n", s); } /* Print formatted output to the output file. */ void d_printf(const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(D_STDOUT, format, ap); va_end(ap); } /* Assign a string. */ void d_assign(dstr to, const dstr from) { /* Might be overlapping. */ memmove(to, from, strlen(from) + 1); } /* Assign a length-delimited string. */ void d_assignn(dstr to, const dstr from, size_t n) { /* Might be overlapping. */ memmove(to, from, n); to[n] = '\0'; } static re_cache_t *compile_regex(const char *regex) { re_cache_t *re; int i; for (i = 0; i < MAX_RE_CACHE; i++) { re = &d_regex_cache[i]; if (re->regex == NULL) { re->regex = regex; re->reg = trex_compile(regex, NULL); if (re->reg == NULL) { d_abort("error compiling regular expression: ", regex); } } if (re->regex == regex) { return re; } } d_abort("too many regular expressions", ""); return NULL; } /* Match a string against the given regular expression. * Returns true on a successful match. */ bool d_match(dstr line, const char *regex) { re_cache_t *re; TRexMatch match; int i; re = compile_regex(regex); if (!trex_search(re->reg, line, NULL, NULL)) { return false; } trex_getsubexp(re->reg, 0, &match); d_assignn(d_before_match, line, match.begin - line); d_assign(d_after_match, match.begin + match.len); for (i = 0; i < MAX_MATCH; i++) { if (trex_getsubexp(re->reg, i, &match)) { strncpy(d_submatches[i], match.begin, match.len); d_submatches[i][match.len] = '\0'; } else { d_submatches[i][0] = '\0'; } } return true; } /* Return a submatch from the previous d_match call. */ const char *d_submatch(int i) { return d_submatches[i]; } static const char *strrchr2(const char *s, char c1, char c2) { const char *p = s + strlen(s); for (; p >= s; p--) { if (*p == c1 || *p == c2) return p; } return NULL; } void d_basename(const char *filename, const char *newext, dstr output) { const char *start; char *dot; start = strrchr2(filename, '/', '\\'); if (start) strcpy(output, start + 1); else strcpy(output, filename); if (newext) { dot = strrchr(output, '.'); if (dot) strcpy(dot, newext); else strcat(output, newext); } } void d_tolower(const dstr src, dstr dest) { const char *s = src; char *d = dest; for (; *s; s++, d++) { *d = tolower(*s); } *d = '\0'; } void d_delchr(dstr str, char c) { const char *r = str; char *w = str; for (; *r; r++) { if (*r != c) { *w = *r; w++; } } *w = '\0'; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/dawk.h0000644000175000001440000000300711467632033016131 0ustar tjadenusers#ifndef __included_dawk_h #define __included_dawk_h #ifdef _MSC_VER #define bool int #define true 1 #define false 0 #else #include #endif #include /* One line of the TexInfo output is nearly this long as it doesn't perform * word wrapping. */ #define MAX_STRING 3000 #define MAX_MATCH 8 typedef char dstr[MAX_STRING]; extern void (*d_cleanup)(void); extern dstr d_filename; extern int d_line_num; extern FILE *d_stdout; extern dstr d_before_match; extern dstr d_after_match; #define D_STDOUT (d_stdout ? d_stdout : stdout) #define d_abort(msg1, msg2) (d_doabort(__FILE__, __LINE__, (msg1), (msg2))) extern void d_doabort(const char *filename, int line, const char *msg1, const char *msg2); extern void d_init(int argc, char *argv[]); extern void d_open_input(const char *filename); extern void d_close_input(void); extern bool d_getline(dstr var); extern void d_open_output(const char *filename); extern void d_close_output(void); extern void d_print(const char *s); extern void d_printf(const char *format, ...); extern void d_assign(dstr to, const dstr from); extern void d_assignn(dstr to, const dstr from, size_t n); extern bool d_match(dstr line, const char *regex); extern const char *d_submatch(int i); extern void d_basename(const char *filename, const char *newext, dstr output); extern void d_tolower(const dstr src, dstr dest); extern void d_delchr(dstr str, char c); #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/aatree.c0000644000175000001440000000377411255341031016440 0ustar tjadenusers/* * AA tree, a type of self-balancing search tree. * * A. Andersson. "Balanced search trees made simple." * In Proc. Workshop on Algorithms and Data Structures, pages 60--71. * Springer Verlag, 1993. */ #include #include #include "aatree.h" Aatree aa_nil = { 0, &aa_nil, &aa_nil, "", "" }; static char *xstrdup(const char *s) { size_t n = strlen(s); char *p = malloc(n + 1); memcpy(p, s, n); p[n] = '\0'; return p; } static Aatree *skew(Aatree *T) { if (T == &aa_nil) return T; if (T->left->level == T->level) { Aatree *L = T->left; T->left = L->right; L->right = T; return L; } return T; } static Aatree *split(Aatree *T) { if (T == &aa_nil) return T; if (T->level == T->right->right->level) { Aatree *R = T->right; T->right = R->left; R->left = T; R->level = R->level + 1; return R; } return T; } Aatree *aa_singleton(const char *key, const char *value) { Aatree *T = malloc(sizeof(Aatree)); T->level = 1; T->left = &aa_nil; T->right = &aa_nil; T->key = xstrdup(key); T->value = xstrdup(value); return T; } Aatree *aa_insert(Aatree *T, const char *key, const char *value) { int cmp; if (T == &aa_nil) { return aa_singleton(key, value); } cmp = strcmp(key, T->key); if (cmp < 0) { T->left = aa_insert(T->left, key, value); } else if (cmp > 0) { T->right = aa_insert(T->right, key, value); } else { free(T->value); T->value = xstrdup(value); } T = skew(T); T = split(T); return T; } const char *aa_search(const Aatree *T, const char *key) { while (T != &aa_nil) { int cmp = strcmp(key, T->key); if (cmp == 0) return T->value; T = (cmp < 0) ? T->left : T->right; } return NULL; } void aa_destroy(Aatree *T) { if (T != &aa_nil) { aa_destroy(T->left); aa_destroy(T->right); free(T->key); free(T->value); free(T); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/make_dummy_refs.c0000644000175000001440000000142111655353332020344 0ustar tjadenusers/* * make_dummy_refs DOC-FILE... * * Generate a file containing dummy link definitions for each API * entry found. e.g. for "# API: foo" we generate: * * [foo]: DUMMYREF * * Then a reference in a source document will expand to something containing * "DUMMYREF" in the output. That makes it possible to post-process generated * TexInfo and LaTeX documents to fix up cross-references. It's unfortunately * necessary as Pandoc currently doesn't have very good cross-reference * support. */ #include "dawk.h" int main(int argc, char *argv[]) { dstr line; d_init(argc, argv); while ((d_getline(line))) { if (d_match(line, "^#+ API: *")) { d_printf("[%s]: DUMMYREF\n", d_after_match); } } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/make_index.c0000644000175000001440000000231411721435626017304 0ustar tjadenusers/* * make_index HTML-REFS-FILE... * * Generate a file containing a list of links to all API entries. * The links are sorted using strcmp. */ #include #include #include "dawk.h" #include "aatree.h" static char *xstrdup(const char *s) { size_t n = strlen(s); char *p = malloc(n + 1); memcpy(p, s, n); p[n] = '\0'; return p; } static void print_link(const char *value) { d_printf("* [%s]\n", value); /* Work around Pandoc issue #182. */ d_printf("\n"); } static void pre_order_traversal(Aatree *node, void (*doit)(const char *)) { if (node->left != &aa_nil) { pre_order_traversal(node->left, doit); } doit(node->value); if (node->right != &aa_nil) { pre_order_traversal(node->right, doit); } } int main(int argc, char *argv[]) { dstr line; Aatree * root = &aa_nil; d_init(argc, argv); d_printf("# Index\n"); while ((d_getline(line))) { if (d_match(line, "^\\[([^\\]]*)")) { const char *ref = d_submatch(1); char *s = xstrdup(ref); root = aa_insert(root, s, s); } } pre_order_traversal(root, print_link); aa_destroy(root); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/trex.c0000644000175000001440000004052211775716714016176 0ustar tjadenusers/* see copyright notice in trex.h */ /* This copy contains minor changes by Allegro developers to prevent some * compiler warnings. One change makes trex_compile non-reentrant. */ #include #include #include #include #include "trex.h" #ifdef _UINCODE #define scisprint iswprint #define scstrlen wcslen #define scprintf wprintf #define _SC(x) L(x) #else #define scisprint isprint #define scstrlen strlen #define scprintf printf #define _SC(x) (x) #endif #ifdef TREX_DEBUG #include static const TRexChar *g_nnames[] = { _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") }; #endif #define OP_GREEDY (MAX_CHAR+1) // * + ? {n} #define OP_OR (MAX_CHAR+2) #define OP_EXPR (MAX_CHAR+3) //parentesis () #define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) #define OP_DOT (MAX_CHAR+5) #define OP_CLASS (MAX_CHAR+6) #define OP_CCLASS (MAX_CHAR+7) #define OP_NCLASS (MAX_CHAR+8) //negates class the [^ #define OP_RANGE (MAX_CHAR+9) #define OP_CHAR (MAX_CHAR+10) #define OP_EOL (MAX_CHAR+11) #define OP_BOL (MAX_CHAR+12) #define OP_WB (MAX_CHAR+13) #define TREX_SYMBOL_ANY_CHAR ('.') #define TREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') #define TREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') #define TREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') #define TREX_SYMBOL_BRANCH ('|') #define TREX_SYMBOL_END_OF_STRING ('$') #define TREX_SYMBOL_BEGINNING_OF_STRING ('^') #define TREX_SYMBOL_ESCAPE_CHAR ('\\') typedef int TRexNodeType; typedef struct tagTRexNode{ TRexNodeType type; int left; int right; int next; }TRexNode; struct TRex{ const TRexChar *_eol; const TRexChar *_bol; const TRexChar *_p; int _first; int _op; TRexNode *_nodes; int _nallocated; int _nsize; int _nsubexpr; TRexMatch *_matches; int _currsubexp; void *_jmpbuf; const TRexChar **_error; }; static int trex_list(TRex *exp); static int trex_newnode(TRex *exp, TRexNodeType type) { TRexNode n; int newid; n.type = type; n.next = n.right = n.left = -1; if(type == OP_EXPR) n.right = exp->_nsubexpr++; if(exp->_nallocated < (exp->_nsize + 1)) { /* int oldsize = exp->_nallocated; */ exp->_nallocated *= 2; exp->_nodes = (TRexNode *)realloc(exp->_nodes, exp->_nallocated * sizeof(TRexNode)); } exp->_nodes[exp->_nsize++] = n; newid = exp->_nsize - 1; return (int)newid; } static void trex_error(TRex *exp,const TRexChar *error) { if(exp->_error) *exp->_error = error; longjmp(*((jmp_buf*)exp->_jmpbuf),-1); } static void trex_expect(TRex *exp, int n){ if((*exp->_p) != n) trex_error(exp, _SC("expected paren")); exp->_p++; } static TRexChar trex_escapechar(TRex *exp) { if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR){ exp->_p++; switch(*exp->_p) { case 'v': exp->_p++; return '\v'; case 'n': exp->_p++; return '\n'; case 't': exp->_p++; return '\t'; case 'r': exp->_p++; return '\r'; case 'f': exp->_p++; return '\f'; default: return (*exp->_p++); } } else if(!scisprint(*exp->_p)) trex_error(exp,_SC("letter expected")); return (*exp->_p++); } static int trex_charclass(TRex *exp,int classid) { int n = trex_newnode(exp,OP_CCLASS); exp->_nodes[n].left = classid; return n; } static int trex_charnode(TRex *exp,TRexBool isclass) { TRexChar t; if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR) { exp->_p++; switch(*exp->_p) { case 'n': exp->_p++; return trex_newnode(exp,'\n'); case 't': exp->_p++; return trex_newnode(exp,'\t'); case 'r': exp->_p++; return trex_newnode(exp,'\r'); case 'f': exp->_p++; return trex_newnode(exp,'\f'); case 'v': exp->_p++; return trex_newnode(exp,'\v'); case 'a': case 'A': case 'w': case 'W': case 's': case 'S': case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': case 'p': case 'P': case 'l': case 'u': { t = *exp->_p; exp->_p++; return trex_charclass(exp,t); } case 'b': case 'B': if(!isclass) { int node = trex_newnode(exp,OP_WB); exp->_nodes[node].left = *exp->_p; exp->_p++; return node; } //else default default: t = *exp->_p; exp->_p++; return trex_newnode(exp,t); } } else if(!scisprint(*exp->_p)) { trex_error(exp,_SC("letter expected")); } t = *exp->_p; exp->_p++; return trex_newnode(exp,t); } static int trex_class(TRex *exp) { int ret = -1; int first = -1,chain; if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING){ ret = trex_newnode(exp,OP_NCLASS); exp->_p++; }else ret = trex_newnode(exp,OP_CLASS); if(*exp->_p == ']') trex_error(exp,_SC("empty class")); chain = ret; while(*exp->_p != ']' && exp->_p != exp->_eol) { if(*exp->_p == '-' && first != -1){ int r,t; if(*exp->_p++ == ']') trex_error(exp,_SC("unfinished range")); r = trex_newnode(exp,OP_RANGE); if(first>*exp->_p) trex_error(exp,_SC("invalid range")); if(exp->_nodes[first].type == OP_CCLASS) trex_error(exp,_SC("cannot use character classes in ranges")); exp->_nodes[r].left = exp->_nodes[first].type; t = trex_escapechar(exp); exp->_nodes[r].right = t; exp->_nodes[chain].next = r; chain = r; first = -1; } else{ if(first!=-1){ int c = first; exp->_nodes[chain].next = c; chain = c; first = trex_charnode(exp,TRex_True); } else{ first = trex_charnode(exp,TRex_True); } } } if(first!=-1){ int c = first; exp->_nodes[chain].next = c; chain = c; first = -1; } /* hack? */ exp->_nodes[ret].left = exp->_nodes[ret].next; exp->_nodes[ret].next = -1; return ret; } static int trex_parsenumber(TRex *exp) { int ret = *exp->_p-'0'; int positions = 10; exp->_p++; while(isdigit(*exp->_p)) { ret = ret*10+(*exp->_p++-'0'); if(positions==1000000000) trex_error(exp,_SC("overflow in numeric constant")); positions *= 10; }; return ret; } static int trex_element(TRex *exp) { int ret = -1; switch(*exp->_p) { case '(': { int expr,newn; exp->_p++; if(*exp->_p =='?') { exp->_p++; trex_expect(exp,':'); expr = trex_newnode(exp,OP_NOCAPEXPR); } else expr = trex_newnode(exp,OP_EXPR); newn = trex_list(exp); exp->_nodes[expr].left = newn; ret = expr; trex_expect(exp,')'); } break; case '[': exp->_p++; ret = trex_class(exp); trex_expect(exp,']'); break; case TREX_SYMBOL_END_OF_STRING: exp->_p++; ret = trex_newnode(exp,OP_EOL);break; case TREX_SYMBOL_ANY_CHAR: exp->_p++; ret = trex_newnode(exp,OP_DOT);break; default: ret = trex_charnode(exp,TRex_False); break; } { TRexBool isgreedy = TRex_False; unsigned short p0 = 0, p1 = 0; switch(*exp->_p){ case TREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; case TREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; case TREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = TRex_True; break; case '{': exp->_p++; if(!isdigit(*exp->_p)) trex_error(exp,_SC("number expected")); p0 = (unsigned short)trex_parsenumber(exp); /*******************************/ switch(*exp->_p) { case '}': p1 = p0; exp->_p++; break; case ',': exp->_p++; p1 = 0xFFFF; if(isdigit(*exp->_p)){ p1 = (unsigned short)trex_parsenumber(exp); } trex_expect(exp,'}'); break; default: trex_error(exp,_SC(", or } expected")); } /*******************************/ isgreedy = TRex_True; break; } if(isgreedy) { int nnode = trex_newnode(exp,OP_GREEDY); exp->_nodes[nnode].left = ret; exp->_nodes[nnode].right = ((p0)<<16)|p1; ret = nnode; } } if((*exp->_p != TREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != TREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != TREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { int nnode = trex_element(exp); exp->_nodes[ret].next = nnode; } return ret; } static int trex_list(TRex *exp) { int ret=-1,e; if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING) { exp->_p++; ret = trex_newnode(exp,OP_BOL); } e = trex_element(exp); if(ret != -1) { exp->_nodes[ret].next = e; } else ret = e; if(*exp->_p == TREX_SYMBOL_BRANCH) { int temp,tright; exp->_p++; temp = trex_newnode(exp,OP_OR); exp->_nodes[temp].left = ret; tright = trex_list(exp); exp->_nodes[temp].right = tright; ret = temp; } return ret; } static TRexBool trex_matchcclass(int cclass,TRexChar c) { switch(cclass) { case 'a': return isalpha(c)?TRex_True:TRex_False; case 'A': return !isalpha(c)?TRex_True:TRex_False; case 'w': return (isalnum(c) || c == '_')?TRex_True:TRex_False; case 'W': return (!isalnum(c) && c != '_')?TRex_True:TRex_False; case 's': return isspace(c)?TRex_True:TRex_False; case 'S': return !isspace(c)?TRex_True:TRex_False; case 'd': return isdigit(c)?TRex_True:TRex_False; case 'D': return !isdigit(c)?TRex_True:TRex_False; case 'x': return isxdigit(c)?TRex_True:TRex_False; case 'X': return !isxdigit(c)?TRex_True:TRex_False; case 'c': return iscntrl(c)?TRex_True:TRex_False; case 'C': return !iscntrl(c)?TRex_True:TRex_False; case 'p': return ispunct(c)?TRex_True:TRex_False; case 'P': return !ispunct(c)?TRex_True:TRex_False; case 'l': return islower(c)?TRex_True:TRex_False; case 'u': return isupper(c)?TRex_True:TRex_False; } return TRex_False; /*cannot happen*/ } static TRexBool trex_matchclass(TRex* exp,TRexNode *node,TRexChar c) { do { switch(node->type) { case OP_RANGE: if(c >= node->left && c <= node->right) return TRex_True; break; case OP_CCLASS: if(trex_matchcclass(node->left,c)) return TRex_True; break; default: if(c == node->type)return TRex_True; } } while((node->next != -1) && (node = &exp->_nodes[node->next])); return TRex_False; } static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *str,TRexNode *next) { TRexNodeType type = node->type; switch(type) { case OP_GREEDY: { //TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; TRexNode *greedystop = NULL; int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; const TRexChar *s=str, *good = str; if(node->next != -1) { greedystop = &exp->_nodes[node->next]; } else { greedystop = next; } while((nmaches == 0xFFFF || nmaches < p1)) { const TRexChar *stop; if(!(s = trex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) break; nmaches++; good=s; if(greedystop) { //checks that 0 matches satisfy the expression(if so skips) //if not would always stop(for instance if is a '?') if(greedystop->type != OP_GREEDY || (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) { TRexNode *gnext = NULL; if(greedystop->next != -1) { gnext = &exp->_nodes[greedystop->next]; }else if(next && next->next != -1){ gnext = &exp->_nodes[next->next]; } stop = trex_matchnode(exp,greedystop,s,gnext); if(stop) { //if satisfied stop it if(p0 == p1 && p0 == nmaches) break; else if(nmaches >= p0 && p1 == 0xFFFF) break; else if(nmaches >= p0 && nmaches <= p1) break; } } } if(s >= exp->_eol) break; } if(p0 == p1 && p0 == nmaches) return good; else if(nmaches >= p0 && p1 == 0xFFFF) return good; else if(nmaches >= p0 && nmaches <= p1) return good; return NULL; } case OP_OR: { const TRexChar *asd = str; TRexNode *temp=&exp->_nodes[node->left]; while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { if(temp->next != -1) temp = &exp->_nodes[temp->next]; else return asd; } asd = str; temp = &exp->_nodes[node->right]; while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { if(temp->next != -1) temp = &exp->_nodes[temp->next]; else return asd; } return NULL; break; } case OP_EXPR: case OP_NOCAPEXPR:{ TRexNode *n = &exp->_nodes[node->left]; const TRexChar *cur = str; int capture = -1; if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { capture = exp->_currsubexp; exp->_matches[capture].begin = cur; exp->_currsubexp++; } do { TRexNode *subnext = NULL; if(n->next != -1) { subnext = &exp->_nodes[n->next]; }else { subnext = next; } if(!(cur = trex_matchnode(exp,n,cur,subnext))) { if(capture != -1){ exp->_matches[capture].begin = 0; exp->_matches[capture].len = 0; } return NULL; } } while((n->next != -1) && (n = &exp->_nodes[n->next])); if(capture != -1) exp->_matches[capture].len = cur - exp->_matches[capture].begin; return cur; } case OP_WB: if((str == exp->_bol && !isspace(*str)) || (str == exp->_eol && !isspace(*(str-1))) || (!isspace(*str) && isspace(*(str+1))) || (isspace(*str) && !isspace(*(str+1))) ) { return (node->left == 'b')?str:NULL; } return (node->left == 'b')?NULL:str; case OP_BOL: if(str == exp->_bol) return str; return NULL; case OP_EOL: if(str == exp->_eol) return str; return NULL; case OP_DOT:{ str++; } return str; case OP_NCLASS: case OP_CLASS: if(trex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?TRex_True:TRex_False):(type == OP_NCLASS?TRex_True:TRex_False)) { str++; return str; } return NULL; case OP_CCLASS: if(trex_matchcclass(node->left,*str)) { str++; return str; } return NULL; default: /* char */ if(*str != node->type) return NULL; str++; return str; } return NULL; } /* public api */ TRex *trex_compile(const TRexChar *pattern,const TRexChar **error) { /* Prevent warnings about variables being lost across setjmp. Of course * this makes the code non-reentrant but make_doc doesn't mind. --pw */ static TRex *exp; exp = (TRex *)malloc(sizeof(TRex)); exp->_eol = exp->_bol = NULL; exp->_p = pattern; exp->_nallocated = (int)scstrlen(pattern) * sizeof(TRexChar); exp->_nodes = (TRexNode *)malloc(exp->_nallocated * sizeof(TRexNode)); exp->_nsize = 0; exp->_matches = 0; exp->_nsubexpr = 0; exp->_first = trex_newnode(exp,OP_EXPR); exp->_error = error; exp->_jmpbuf = malloc(sizeof(jmp_buf)); if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { int res = trex_list(exp); exp->_nodes[exp->_first].left = res; if(*exp->_p!='\0') trex_error(exp,_SC("unexpected character")); #ifdef TREX_DEBUG { int nsize,i; TRexNode *t; nsize = exp->_nsize; t = &exp->_nodes[0]; scprintf(_SC("\n")); for(i = 0;i < nsize; i++) { if(exp->_nodes[i].type>MAX_CHAR) scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); else scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); } scprintf(_SC("\n")); } #endif exp->_matches = (TRexMatch *) malloc(exp->_nsubexpr * sizeof(TRexMatch)); memset(exp->_matches,0,exp->_nsubexpr * sizeof(TRexMatch)); } else{ trex_free(exp); return NULL; } return exp; } void trex_free(TRex *exp) { if(exp) { if(exp->_nodes) free(exp->_nodes); if(exp->_jmpbuf) free(exp->_jmpbuf); if(exp->_matches) free(exp->_matches); free(exp); } } TRexBool trex_match(TRex* exp,const TRexChar* text) { const TRexChar* res = NULL; exp->_bol = text; exp->_eol = text + scstrlen(text); exp->_currsubexp = 0; res = trex_matchnode(exp,exp->_nodes,text,NULL); if(res == NULL || res != exp->_eol) return TRex_False; return TRex_True; } TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) { const TRexChar *cur = NULL; int node = exp->_first; if(text_begin >= text_end) return TRex_False; exp->_bol = text_begin; exp->_eol = text_end; do { cur = text_begin; while(node != -1) { exp->_currsubexp = 0; cur = trex_matchnode(exp,&exp->_nodes[node],cur,NULL); if(!cur) break; node = exp->_nodes[node].next; } text_begin++; } while(cur == NULL && text_begin != text_end); if(cur == NULL) return TRex_False; --text_begin; if(out_begin) *out_begin = text_begin; if(out_end) *out_end = cur; return TRex_True; } TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) { return trex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); } int trex_getsubexpcount(TRex* exp) { return exp->_nsubexpr; } TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp) { if( n<0 || n >= exp->_nsubexpr) return TRex_False; *subexp = exp->_matches[n]; return TRex_True; } allegro-5.0.10/docs/scripts/make_doc.c0000644000175000001440000001052111467632033016737 0ustar tjadenusers/* * make_doc OPTIONS... [--] DOC-FILES * * Options are: * * --protos PROTOS-FILE * --to FORMAT (html, man, latex, texinfo, etc.) * --raise-sections * * Unknown options are passed through to Pandoc. * * Environment variables: PANDOC */ #include #include #include #if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || (_XOPEN_SOURCE >= 500) #include #endif #include "aatree.h" #include "dawk.h" #include "make_doc.h" dstr pandoc = "pandoc"; dstr pandoc_options = ""; dstr protos_file = "protos"; dstr to_format = "html"; bool raise_sections = false; char tmp_preprocess_output[80]; char tmp_pandoc_output[80]; static Aatree *protos = &aa_nil; static int process_options(int argc, char *argv[]); static void load_prototypes(const char *filename); static void generate_temp_file(char *filename); static void remove_temp_files(void); int main(int argc, char *argv[]) { argc = process_options(argc, argv); load_prototypes(protos_file); generate_temp_file(tmp_preprocess_output); generate_temp_file(tmp_pandoc_output); d_cleanup = remove_temp_files; if (0 == strcmp(to_format, "man")) make_man_pages(argc, argv); else make_single_doc(argc, argv); d_cleanup(); return 0; } static int process_options(int argc, char *argv[]) { char *p; int i; p = getenv("PANDOC"); if (p) { d_assign(pandoc, p); } for (i = 1; i < argc; ) { if (streq(argv[i], "--")) { i++; break; } if (argv[i][0] != '-') { break; } if (streq(argv[i], "--protos")) { d_assign(protos_file, argv[i + 1]); i += 2; } else if (streq(argv[i], "--to")) { d_assign(to_format, argv[i + 1]); i += 2; } else if (streq(argv[i], "--raise-sections")) { raise_sections = true; i++; } else { /* Other options are assumed to be Pandoc options. */ strcat(pandoc_options, " "); strcat(pandoc_options, argv[i]); i++; if (i < argc && argv[i][0] != '-') { strcat(pandoc_options, " "); strcat(pandoc_options, argv[i]); i++; } } } /* Shift arguments, including sentinel, but not the command name. */ memmove(argv + 1, argv + i, (argc - i + 1) * sizeof(char *)); return argc - (i - 1); } static void load_prototypes(const char *filename) { dstr line; const char *name; const char *newtext; dstr text; d_open_input(filename); while (d_getline(line)) { if (d_match(line, "([^:]*): (.*)")) { name = d_submatch(1); newtext = d_submatch(2); d_assign(text, lookup_prototype(name)); strcat(text, "\n "); strcat(text, newtext); protos = aa_insert(protos, name, text); } } d_close_input(); } const char *lookup_prototype(const char *name) { const char *r = aa_search(protos, name); return (r) ? r : ""; } void generate_temp_file(char *filename) { /* gcc won't shut up if we use tmpnam() so we'll use mkstemp() if it is * likely to be available. */ #if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || (_XOPEN_SOURCE >= 500) int fd; strcpy(filename, ",make_doc_tmp.XXXXXX"); fd = mkstemp(filename); if (fd == -1) { d_abort("could not generate temporary file name", ""); } close(fd); #else if (!tmpnam(filename)) { d_abort("could not generate temporary file name", ""); } #endif } static void remove_temp_files(void) { remove(tmp_preprocess_output); remove(tmp_pandoc_output); } void call_pandoc(const char *input, const char *output, const char *extra_options) { dstr cmd; dstr input_native; char *p; strcpy(input_native, input); /* Use native Windows syntax to avoid "c:/foo.txt" being treated as a * remote URI by Pandoc 1.5 and 1.6. */ if (strlen(input_native) > 2 && isalpha(input_native[0]) && input_native[1] == ':') { for (p = input_native; *p != '\0'; p++) { if (*p == '/') *p = '\\'; } } sprintf(cmd, "%s %s %s %s --to %s --output %s", pandoc, input_native, pandoc_options, extra_options, to_format, output); if (system(cmd) != 0) { d_abort("system call failed: ", cmd); } } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/scripts/insert_timestamp.c0000644000175000001440000000154411415465764020601 0ustar tjadenusers/* * Generate an fragment to be inserted at the bottom of HTML pages. * The timestamp follows RFC 3339. * We use UTC. */ #include #include #include #include "dawk.h" int main(int argc, char **argv) { time_t now; char buf[64]; char const *version = "unknown"; time(&now); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S UTC", gmtime(&now)); if (argc > 1) { dstr line; d_open_input(argv[1]); while (d_getline(line)) { if (d_match(line, "#define ALLEGRO_VERSION_STR *\"([^\"]*)\"")) { version = d_submatch(1); break; } } d_close_input(); } printf("

    \n"); printf("Allegro version %s\n", version); printf(" - Last updated: %s\n", buf); printf("

    \n"); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/docs/html/0000755000175000001440000000000012157230702014301 5ustar tjadenusersallegro-5.0.10/docs/html/refman/0000755000175000001440000000000012157230720015551 5ustar tjadenusersallegro-5.0.10/docs/html/refman/platform.html0000644000175000001440000001630112157230674020274 0ustar tjadenusers Platform-specific functions

    Windows

    These functions are declared in the following header file:

    #include <allegro5/allegro_windows.h>

    al_get_win_window_handle

    HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display)

    Returns the handle to the window that the passed display is using.

    Mac OS X

    These functions are declared in the following header file:

    #include <allegro5/allegro_osx.h>

    al_osx_get_window

    NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display)

    Retrieves the NSWindow handle associated with the Allegro display.

    Since: 5.0.8, 5.1.3

    iPhone

    These functions are declared in the following header file:

    #include <allegro5/allegro_iphone.h>

    al_iphone_program_has_halted

    void al_iphone_program_has_halted(void)

    Multitasking on iOS is different than on other platforms. When an application receives an ALLEGRO_DISPLAY_SWITCH_OUT or ALLEGRO_DISPLAY_CLOSE event on a multitasking-capable device, it should cease all activity and do nothing but check for an ALLEGRO_DISPLAY_SWITCH_IN event. To let the iPhone driver know that you've ceased all activity, call this function. You should call this function very soon after receiving the event telling you it's time to switch out (within a couple milliseconds). Certain operations, if done, will crash the program after this call, most notably any function which uses OpenGL. This function is needed because the "switch out" handler on iPhone can't return until these operations have stopped, or a crash as described before can happen.

    al_iphone_override_screen_scale

    void al_iphone_override_screen_scale(float scale)

    Original iPhones and iPod Touches had a screen resolution of 320x480 (in Portrait mode). When the iPhone 4 and iPod Touch 4th generation devices came out, they were backwards compatible with all old iPhone apps. This means that they assume a 320x480 screen resolution by default, while they actually have a 640x960 pixel screen (exactly 2x on each dimension). An API was added to allow access to the full (or in fact any fraction of the) resolution of the new devices. This function is normally not needed, as in the case when you want a scale of 2.0 for "retina display" resolution (640x960). In that case you would just call al_create_display with the larger width and height parameters. It is not limited to 2.0 scaling factors however. You can use 1.5 or 0.5 or other values in between, however if it's not an exact multiple of the original iPhone resolution, linear filtering will be applied to the final image.

    This function should be called BEFORE calling al_create_display.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:12 UTC

    allegro-5.0.10/docs/html/refman/audio.html0000644000175000001440000025565112157230675017567 0ustar tjadenusers Audio addon

    These functions are declared in the following header file. Link with allegro_audio.

    #include <allegro5/allegro_audio.h>

    Audio types

    ALLEGRO_AUDIO_DEPTH

    enum ALLEGRO_AUDIO_DEPTH

    Sample depth and type, and signedness. Mixers only use 32-bit signed float (-1..+1), or 16-bit signed integers. The unsigned value is a bit-flag applied to the depth value.

    • ALLEGRO_AUDIO_DEPTH_INT8
    • ALLEGRO_AUDIO_DEPTH_INT16
    • ALLEGRO_AUDIO_DEPTH_INT24
    • ALLEGRO_AUDIO_DEPTH_FLOAT32
    • ALLEGRO_AUDIO_DEPTH_UNSIGNED

    For convenience:

    • ALLEGRO_AUDIO_DEPTH_UINT8
    • ALLEGRO_AUDIO_DEPTH_UINT16
    • ALLEGRO_AUDIO_DEPTH_UINT24

    ALLEGRO_AUDIO_PAN_NONE

    #define ALLEGRO_AUDIO_PAN_NONE      (-1000.0f)

    A special value for the pan property of samples and audio streams. Use this value to disable panning on samples and audio streams, and play them without attentuation implied by panning support.

    ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) because, when panning is enabled, we try to maintain a constant sound power level as a sample is panned from left to right. A sound coming out of one speaker should sound as loud as it does when split over two speakers. As a consequence, a sample with pan value 0.0 will be 3 dB softer than the original level.

    (Please correct us if this is wrong.)

    ALLEGRO_CHANNEL_CONF

    enum ALLEGRO_CHANNEL_CONF

    Speaker configuration (mono, stereo, 2.1, etc).

    • ALLEGRO_CHANNEL_CONF_1
    • ALLEGRO_CHANNEL_CONF_2
    • ALLEGRO_CHANNEL_CONF_3
    • ALLEGRO_CHANNEL_CONF_4
    • ALLEGRO_CHANNEL_CONF_5_1
    • ALLEGRO_CHANNEL_CONF_6_1
    • ALLEGRO_CHANNEL_CONF_7_1

    ALLEGRO_MIXER

    typedef struct ALLEGRO_MIXER ALLEGRO_MIXER;

    A mixer is a type of stream which mixes together attached streams into a single buffer.

    ALLEGRO_MIXER_QUALITY

    enum ALLEGRO_MIXER_QUALITY
    • ALLEGRO_MIXER_QUALITY_POINT - point sampling
    • ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation
    • ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8, 5.1.4)

    ALLEGRO_PLAYMODE

    enum ALLEGRO_PLAYMODE

    Sample and stream playback mode.

    • ALLEGRO_PLAYMODE_ONCE
    • ALLEGRO_PLAYMODE_LOOP
    • ALLEGRO_PLAYMODE_BIDIR

    ALLEGRO_SAMPLE_ID

    typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID;

    An ALLEGRO_SAMPLE_ID represents a sample being played via al_play_sample. It can be used to later stop the sample with al_stop_sample.

    ALLEGRO_SAMPLE

    typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE;

    An ALLEGRO_SAMPLE object stores the data necessary for playing pre-defined digital audio. It holds information pertaining to data length, frequency, channel configuration, etc. You can have an ALLEGRO_SAMPLE object playing multiple times simultaneously. The object holds a user-specified PCM data buffer, of the format the object is created with.

    See also: ALLEGRO_SAMPLE_INSTANCE

    ALLEGRO_SAMPLE_INSTANCE

    typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE;

    An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a predefined sound effect. It holds information pertaining to the looping mode, loop start/end points, playing position, etc. An instance uses the data from an ALLEGRO_SAMPLE object. Multiple instances may be created from the same ALLEGRO_SAMPLE. An ALLEGRO_SAMPLE must not be destroyed while there are instances which reference it.

    To be played, an ALLEGRO_SAMPLE_INSTANCE object must be attached to an ALLEGRO_VOICE object, or to an ALLEGRO_MIXER object which is itself attached to an ALLEGRO_VOICE object (or to another ALLEGRO_MIXER object which is attached to an ALLEGRO_VOICE object, etc).

    See also: ALLEGRO_SAMPLE

    ALLEGRO_AUDIO_STREAM

    typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM;

    An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the sound device, in real-time. This is done by reading from a buffer, which is split into a number of fragments. Whenever a fragment has finished playing, the user can refill it with new data.

    As with ALLEGRO_SAMPLE_INSTANCE objects, streams store information necessary for playback, so you may not play the same stream multiple times simultaneously. Streams also need to be attached to an ALLEGRO_VOICE object, or to an ALLEGRO_MIXER object which, eventually, reaches an ALLEGRO_VOICE object.

    While playing, you must periodically fill fragments with new audio data. To know when a new fragment is ready to be filled, you can either directly check with al_get_available_audio_stream_fragments, or listen to events from the stream.

    You can register an audio stream event source to an event queue; see al_get_audio_stream_event_source. An ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event is generated whenever a new fragment is ready. When you receive an event, use al_get_audio_stream_fragment to obtain a pointer to the fragment to be filled. The size and format are determined by the parameters passed to al_create_audio_stream.

    If you're late with supplying new data, the stream will be silent until new data is provided. You must call al_drain_audio_stream when you're finished with supplying data to the stream.

    If the stream is created by al_load_audio_stream then it can also generate an ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event if it reaches the end of the file and is not set to loop.

    ALLEGRO_VOICE

    typedef struct ALLEGRO_VOICE ALLEGRO_VOICE;

    A voice represents an audio device on the system, which may be a real device, or an abstract device provided by the operating system. To play back audio, you would attach a mixer or sample or stream to a voice.

    See also: ALLEGRO_MIXER, ALLEGRO_SAMPLE, ALLEGRO_AUDIO_STREAM

    Setting up audio

    al_install_audio

    bool al_install_audio(void)

    Install the audio subsystem.

    Returns true on success, false on failure.

    Note: most users will call al_reserve_samples and al_init_acodec_addon after this.

    See also: al_reserve_samples, al_uninstall_audio, al_is_audio_installed, al_init_acodec_addon

    al_uninstall_audio

    void al_uninstall_audio(void)

    Uninstalls the audio subsystem.

    See also: al_install_audio

    al_is_audio_installed

    bool al_is_audio_installed(void)

    Returns true if al_install_audio was called previously and returned successfully.

    al_reserve_samples

    bool al_reserve_samples(int reserve_samples)

    Reserves a number of sample instances, attaching them to the default mixer. If no default mixer is set when this function is called, then it will automatically create a voice with an attached mixer, which becomes the default mixer. This diagram illustrates the structures that are set up:

                                  sample instance 1
                                / sample instance 2
    voice <-- default mixer <---         .
                                \        .
                                  sample instance N

    Returns true on success, false on error. al_install_audio must have been called first.

    See also: al_set_default_mixer, al_play_sample

    Misc audio functions

    al_get_allegro_audio_version

    uint32_t al_get_allegro_audio_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    al_get_audio_depth_size

    size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth)

    Return the size of a sample, in bytes, for the given format. The format is one of the values listed under ALLEGRO_AUDIO_DEPTH.

    al_get_channel_count

    size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf)

    Return the number of channels for the given channel configuration, which is one of the values listed under ALLEGRO_CHANNEL_CONF.

    Voice functions

    al_create_voice

    ALLEGRO_VOICE *al_create_voice(unsigned int freq,
       ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

    Creates a voice structure and allocates a voice from the digital sound driver. The passed frequency, sample format and channel configuration are used as a hint to what kind of data will be sent to the voice. However, the underlying sound driver is free to use non-matching values. For example it may be the native format of the sound hardware. If a mixer is attached to the voice, the mixer will convert from the mixer's format to the voice format and care does not have to be taken for this.

    However if you access the voice directly, make sure to not rely on the parameters passed to this function, but instead query the returned voice for the actual settings.

    See also: al_destroy_voice

    al_destroy_voice

    void al_destroy_voice(ALLEGRO_VOICE *voice)

    Destroys the voice and deallocates it from the digital driver. Does nothing if the voice is NULL.

    See also: al_create_voice

    al_detach_voice

    void al_detach_voice(ALLEGRO_VOICE *voice)

    Detaches the mixer or sample or stream from the voice.

    See also: al_attach_mixer_to_voice, al_attach_sample_instance_to_voice, al_attach_audio_stream_to_voice

    al_attach_audio_stream_to_voice

    bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream,
       ALLEGRO_VOICE *voice)

    Attaches an audio stream to a voice. The same rules as al_attach_sample_instance_to_voice apply. This may fail if the driver can't create a voice with the buffer count and buffer size the stream uses.

    An audio stream attached directly to a voice has a number of limitations. The audio stream plays immediately and cannot be stopped. The stream position, speed, gain, panning, cannot be changed. At this time, we don't recommend attaching audio streams directly to voices. Use a mixer in between.

    Returns true on success, false on failure.

    See also: al_detach_voice

    al_attach_mixer_to_voice

    bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice)

    Attaches a mixer to a voice. The same rules as al_attach_sample_instance_to_voice apply, with the exception of the depth requirement.

    Returns true on success, false on failure.

    See also: al_detach_voice

    al_attach_sample_instance_to_voice

    bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl,
       ALLEGRO_VOICE *voice)

    Attaches a sample to a voice, and allows it to play. The sample's volume and loop mode will be ignored, and it must have the same frequency and depth (including signed-ness) as the voice. This function may fail if the selected driver doesn't support preloading sample data.

    At this time, we don't recommend attaching samples directly to voices. Use a mixer in between.

    Returns true on success, false on failure.

    See also: al_detach_voice

    al_get_voice_frequency

    unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice)

    Return the frequency of the voice, e.g. 44100.

    al_get_voice_channels

    ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice)

    Return the channel configuration of the voice.

    See also: ALLEGRO_CHANNEL_CONF.

    al_get_voice_depth

    ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice)

    Return the audio depth of the voice.

    See also: ALLEGRO_AUDIO_DEPTH.

    al_get_voice_playing

    bool al_get_voice_playing(const ALLEGRO_VOICE *voice)

    Return true if the voice is currently playing.

    See also: al_set_voice_playing

    al_set_voice_playing

    bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val)

    Change whether a voice is playing or not. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance. On success the voice's current sample position is reset.

    Returns true on success, false on failure.

    See also: al_get_voice_playing

    al_get_voice_position

    unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice)

    When the voice has a non-streaming object attached to it, e.g. a sample, returns the voice's current sample position. Otherwise, returns zero.

    See also: al_set_voice_position.

    al_set_voice_position

    bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val)

    Set the voice position. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance.

    Returns true on success, false on failure.

    See also: al_get_voice_position.

    Sample functions

    al_create_sample

    ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples,
       unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
       ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)

    Create a sample data structure from the supplied buffer. If free_buf is true then the buffer will be freed with al_free when the sample data structure is destroyed. For portability (especially Windows), the buffer should have been allocated with al_malloc. Otherwise you should free the sample data yourself.

    To allocate a buffer of the correct size, you can use something like this:

    sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth);
    bytes = samples * sample_size;
    buffer = al_malloc(bytes);

    See also: al_destroy_sample, ALLEGRO_AUDIO_DEPTH, ALLEGRO_CHANNEL_CONF

    al_destroy_sample

    void al_destroy_sample(ALLEGRO_SAMPLE *spl)

    Free the sample data structure. If it was created with the free_buf parameter set to true, then the buffer will be freed with al_free.

    This function will stop any sample instances which may be playing the buffer referenced by the ALLEGRO_SAMPLE.

    See also: al_destroy_sample_instance, al_stop_sample, al_stop_samples

    al_play_sample

    bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed,
       ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)

    Plays a sample on one of the sample instances created by al_reserve_samples. Returns true on success, false on failure. Playback may fail because all the reserved sample instances are currently used.

    Parameters:

    • gain - relative volume at which the sample is played; 1.0 is normal.
    • pan - 0.0 is centred, -1.0 is left, 1.0 is right, or ALLEGRO_AUDIO_PAN_NONE.
    • speed - relative speed at which the sample is played; 1.0 is normal.
    • loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or ALLEGRO_PLAYMODE_BIDIR
    • ret_id - if non-NULL the variable which this points to will be assigned an id representing the sample being played.

    See also: ALLEGRO_PLAYMODE, ALLEGRO_AUDIO_PAN_NONE, ALLEGRO_SAMPLE_ID, al_stop_sample, al_stop_samples.

    al_stop_sample

    void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id)

    Stop the sample started by al_play_sample.

    See also: al_stop_samples

    al_stop_samples

    void al_stop_samples(void)

    Stop all samples started by al_play_sample.

    See also: al_stop_sample

    al_get_sample_channels

    ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl)

    Return the channel configuration.

    See also: ALLEGRO_CHANNEL_CONF, al_get_sample_depth, al_get_sample_frequency, al_get_sample_length, al_get_sample_data

    al_get_sample_depth

    ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl)

    Return the audio depth.

    See also: ALLEGRO_AUDIO_DEPTH, al_get_sample_channels, al_get_sample_frequency, al_get_sample_length, al_get_sample_data

    al_get_sample_frequency

    unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl)

    Return the frequency of the sample.

    See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_length, al_get_sample_data

    al_get_sample_length

    unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl)

    Return the length of the sample in sample values.

    See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_frequency, al_get_sample_data

    al_get_sample_data

    void *al_get_sample_data(const ALLEGRO_SAMPLE *spl)

    Return a pointer to the raw sample data.

    See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_frequency, al_get_sample_length

    Sample instance functions

    al_create_sample_instance

    ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data)

    Creates a sample stream, using the supplied data. This must be attached to a voice or mixer before it can be played. The argument may be NULL. You can then set the data later with al_set_sample.

    See also: al_destroy_sample_instance

    al_destroy_sample_instance

    void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

    Detaches the sample stream from anything it may be attached to and frees it (the sample data is not freed!).

    See also: al_create_sample_instance

    al_play_sample_instance

    bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

    Play an instance of a sample data. Returns true on success, false on failure.

    See also: al_stop_sample_instance

    al_stop_sample_instance

    bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

    Stop an sample instance playing.

    See also: al_play_sample_instance

    al_get_sample_instance_channels

    ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels(
       const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the channel configuration.

    See also: ALLEGRO_CHANNEL_CONF.

    al_get_sample_instance_depth

    ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the audio depth.

    See also: ALLEGRO_AUDIO_DEPTH.

    al_get_sample_instance_frequency

    unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the frequency of the sample instance.

    al_get_sample_instance_length

    unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the length of the sample instance in sample values.

    See also: al_set_sample_instance_length, al_get_sample_instance_time

    al_set_sample_instance_length

    bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl,
       unsigned int val)

    Set the length of the sample instance in sample values.

    Return true on success, false on failure. Will fail if the sample instance is currently playing.

    See also: al_get_sample_instance_length

    al_get_sample_instance_position

    unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Get the playback position of a sample instance.

    See also: al_set_sample_instance_position

    al_set_sample_instance_position

    bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl,
       unsigned int val)

    Set the playback position of a sample instance.

    Returns true on success, false on failure.

    See also: al_get_sample_instance_position

    al_get_sample_instance_speed

    float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the relative playback speed.

    See also: al_set_sample_instance_speed

    al_set_sample_instance_speed

    bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

    Set the relative playback speed. 1.0 is normal speed.

    Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_sample_instance_speed

    al_get_sample_instance_gain

    float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the playback gain.

    See also: al_set_sample_instance_gain

    al_set_sample_instance_gain

    bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

    Set the playback gain.

    Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_sample_instance_gain

    al_get_sample_instance_pan

    float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Get the pan value.

    See also: al_set_sample_instance_pan.

    al_set_sample_instance_pan

    bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

    Set the pan value on a sample instance. A value of -1.0 means to play the sample only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE disables panning and plays the sample at its original level. This will be louder than a pan value of 0.0.

    Note: panning samples with more than two channels doesn't work yet.

    Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_sample_instance_pan, ALLEGRO_AUDIO_PAN_NONE

    al_get_sample_instance_time

    float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the length of the sample instance in seconds, assuming a playback speed of 1.0.

    See also: al_get_sample_instance_length

    al_get_sample_instance_playmode

    ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the playback mode.

    See also: ALLEGRO_PLAYMODE, al_set_sample_instance_playmode

    al_set_sample_instance_playmode

    bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl,
       ALLEGRO_PLAYMODE val)

    Set the playback mode.

    Returns true on success, false on failure.

    See also: ALLEGRO_PLAYMODE, al_get_sample_instance_playmode

    al_get_sample_instance_playing

    bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return true if the sample instance is playing.

    See also: al_set_sample_instance_playing

    al_set_sample_instance_playing

    bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val)

    Change whether the sample instance is playing.

    Returns true on success, false on failure.

    See also: al_get_sample_instance_playing

    al_get_sample_instance_attached

    bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl)

    Return whether the sample instance is attached to something.

    See also: al_attach_sample_instance_to_mixer, al_attach_sample_instance_to_voice, al_detach_sample_instance

    al_detach_sample_instance

    bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

    Detach the sample instance from whatever it's attached to, if anything.

    Returns true on success.

    See also: al_attach_sample_instance_to_mixer, al_attach_sample_instance_to_voice, al_get_sample_instance_attached

    al_get_sample

    ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl)

    Return the sample data that the sample instance plays.

    Note this returns a pointer to an internal structure, not the ALLEGRO_SAMPLE that you may have passed to al_set_sample. You may, however, check which sample buffer is being played by the sample instance with al_get_sample_data, and so on.

    See also: al_set_sample

    al_set_sample

    bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)

    Change the sample data that a sample instance plays. This can be quite an involved process.

    First, the sample is stopped if it is not already.

    Next, if data is NULL, the sample is detached from its parent (if any).

    If data is not NULL, the sample may be detached and reattached to its parent (if any). This is not necessary if the old sample data and new sample data have the same frequency, depth and channel configuration. Reattaching may not always succeed.

    On success, the sample remains stopped. The playback position and loop end points are reset to their default values. The loop mode remains unchanged.

    Returns true on success, false on failure. On failure, the sample will be stopped and detached from its parent.

    See also: al_get_sample

    Mixer functions

    al_create_mixer

    ALLEGRO_MIXER *al_create_mixer(unsigned int freq,
       ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

    Creates a mixer stream, to attach sample streams or other mixers to. It will mix into a buffer at the requested frequency and channel count.

    The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 and ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete).

    Returns true on success, false on error.

    See also: al_destroy_mixer, ALLEGRO_AUDIO_DEPTH, ALLEGRO_CHANNEL_CONF

    al_destroy_mixer

    void al_destroy_mixer(ALLEGRO_MIXER *mixer)

    Destroys the mixer stream.

    See also: al_create_mixer

    al_get_default_mixer

    ALLEGRO_MIXER *al_get_default_mixer(void)

    Return the default mixer, or NULL if one has not been set. Although different configurations of mixers and voices can be used, in most cases a single mixer attached to a voice is what you want. The default mixer is used by al_play_sample.

    See also: al_reserve_samples, al_play_sample, al_set_default_mixer, al_restore_default_mixer

    al_set_default_mixer

    bool al_set_default_mixer(ALLEGRO_MIXER *mixer)

    Sets the default mixer. All samples started with al_play_sample will be stopped. If you are using your own mixer, this should be called before al_reserve_samples.

    Returns true on success, false on error.

    See also: al_reserve_samples, al_play_sample, al_get_default_mixer, al_restore_default_mixer

    al_restore_default_mixer

    bool al_restore_default_mixer(void)

    Restores Allegro's default mixer. All samples started with al_play_sample will be stopped. Returns true on success, false on error.

    See also: al_get_default_mixer, al_set_default_mixer, al_reserve_samples.

    al_attach_mixer_to_mixer

    bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer)

    Attaches a mixer onto another mixer. The same rules as with al_attach_sample_instance_to_mixer apply, with the added caveat that both mixers must be the same frequency. Returns true on success, false on error.

    Currently both mixers must have the same audio depth, otherwise the function fails.

    See also: al_detach_mixer.

    al_attach_sample_instance_to_mixer

    bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl,
       ALLEGRO_MIXER *mixer)

    Attach a sample instance to a mixer. The instance must not already be attached to anything.

    Returns true on success, false on failure.

    See also: al_detach_sample_instance.

    al_attach_audio_stream_to_mixer

    bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer)

    Attach a stream to a mixer.

    Returns true on success, false on failure.

    See also: al_detach_audio_stream.

    al_get_mixer_frequency

    unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer)

    Return the mixer frequency.

    See also: al_set_mixer_frequency

    al_set_mixer_frequency

    bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val)

    Set the mixer frequency. This will only work if the mixer is not attached to anything.

    Returns true on success, false on failure.

    See also: al_get_mixer_frequency

    al_get_mixer_channels

    ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer)

    Return the mixer channel configuration.

    See also: ALLEGRO_CHANNEL_CONF.

    al_get_mixer_depth

    ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer)

    Return the mixer audio depth.

    See also: ALLEGRO_AUDIO_DEPTH.

    al_get_mixer_gain

    float al_get_mixer_gain(const ALLEGRO_MIXER *mixer)

    Return the mixer gain (amplification factor). The default is 1.0.

    Since: 5.0.6, 5.1.0

    See also: al_set_mixer_gain.

    al_set_mixer_gain

    bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain)

    Set the mixer gain (amplification factor).

    Returns true on success, false on failure.

    Since: 5.0.6, 5.1.0

    See also: al_get_mixer_gain

    al_get_mixer_quality

    ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer)

    Return the mixer quality.

    See also: ALLEGRO_MIXER_QUALITY, al_set_mixer_quality

    al_set_mixer_quality

    bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality)

    Set the mixer quality. This can only succeed if the mixer does not have anything attached to it.

    Returns true on success, false on failure.

    See also: ALLEGRO_MIXER_QUALITY, al_get_mixer_quality

    al_get_mixer_playing

    bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer)

    Return true if the mixer is playing.

    See also: al_set_mixer_playing.

    al_set_mixer_playing

    bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val)

    Change whether the mixer is playing.

    Returns true on success, false on failure.

    See also: al_get_mixer_playing.

    al_get_mixer_attached

    bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer)

    Return true if the mixer is attached to something.

    See also: al_attach_sample_instance_to_mixer, al_attach_audio_stream_to_mixer, al_attach_mixer_to_mixer, al_detach_mixer

    al_detach_mixer

    bool al_detach_mixer(ALLEGRO_MIXER *mixer)

    Detach the mixer from whatever it is attached to, if anything.

    See also: al_attach_mixer_to_mixer.

    al_set_mixer_postprocess_callback

    bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer,
       void (*pp_callback)(void *buf, unsigned int samples, void *data),
       void *pp_callback_userdata)

    Sets a post-processing filter function that's called after the attached streams have been mixed. The buffer's format will be whatever the mixer was created with. The sample count and user-data pointer is also passed.

    Stream functions

    al_create_audio_stream

    ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count,
       unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
       ALLEGRO_CHANNEL_CONF chan_conf)

    Creates an ALLEGRO_AUDIO_STREAM. The stream will be set to play by default. It will feed audio data from a buffer, which is split into a number of fragments.

    Parameters:

    • fragment_count - How many fragments to use for the audio stream. Usually only two fragments are required - splitting the audio buffer in two halves. But it means that the only time when new data can be supplied is whenever one half has finished playing. When using many fragments, you usually will use fewer samples for one, so there always will be (small) fragments available to be filled with new data.

    • frag_samples - The size of a fragment in samples. See note below.

    • freq - The frequency, in Hertz.

    • depth - Must be one of the values listed for ALLEGRO_AUDIO_DEPTH.

    • chan_conf - Must be one of the values listed for ALLEGRO_CHANNEL_CONF.

    The choice of fragment_count, frag_samples and freq directly influences the audio delay. The delay in seconds can be expressed as:

    delay = fragment_count * frag_samples / freq

    This is only the delay due to Allegro's streaming, there may be additional delay caused by sound drivers and/or hardware.

    Note: If you know the fragment size in bytes, you can get the size in samples like this:

    sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth);
    samples = bytes_per_fragment / sample_size;

    The size of the complete buffer is:

    buffer_size = bytes_per_fragment * fragment_count

    Note: unlike many Allegro objects, audio streams are not implicitly destroyed when Allegro is shut down. You must destroy them manually with al_destroy_audio_stream before the audio system is shut down.

    al_destroy_audio_stream

    void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

    Destroy an audio stream which was created with al_create_audio_stream or al_load_audio_stream.

    Note: If the stream is still attached to a mixer or voice, al_detach_audio_stream is automatically called on it first.

    See also: al_drain_audio_stream.

    al_get_audio_stream_event_source

    ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source(
       ALLEGRO_AUDIO_STREAM *stream)

    Retrieve the associated event source.

    See al_get_audio_stream_fragment for a description of the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event that audio streams emit.

    al_drain_audio_stream

    void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

    You should call this to finalise an audio stream that you will no longer be feeding, to wait for all pending buffers to finish playing. The stream's playing state will change to false.

    See also: al_destroy_audio_stream

    al_rewind_audio_stream

    bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

    Set the streaming file playing position to the beginning. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

    al_get_audio_stream_frequency

    unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream)

    Return the stream frequency.

    al_get_audio_stream_channels

    ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels(
       const ALLEGRO_AUDIO_STREAM *stream)

    Return the stream channel configuration.

    See also: ALLEGRO_CHANNEL_CONF.

    al_get_audio_stream_depth

    ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth(
       const ALLEGRO_AUDIO_STREAM *stream)

    Return the stream audio depth.

    See also: ALLEGRO_AUDIO_DEPTH.

    al_get_audio_stream_length

    unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream)

    Return the stream length in samples.

    al_get_audio_stream_speed

    float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream)

    Return the relative playback speed.

    See also: al_set_audio_stream_speed.

    al_set_audio_stream_speed

    bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val)

    Set the relative playback speed. 1.0 is normal speed.

    Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_audio_stream_speed.

    al_get_audio_stream_gain

    float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream)

    Return the playback gain.

    See also: al_set_audio_stream_gain.

    al_set_audio_stream_gain

    bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val)

    Set the playback gain.

    Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_audio_stream_gain.

    al_get_audio_stream_pan

    float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream)

    Get the pan value.

    See also: al_set_audio_stream_pan.

    al_set_audio_stream_pan

    bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val)

    Set the pan value on an audio stream. A value of -1.0 means to play the stream only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE disables panning and plays the stream at its original level. This will be louder than a pan value of 0.0.

    Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

    See also: al_get_audio_stream_pan, ALLEGRO_AUDIO_PAN_NONE

    al_get_audio_stream_playing

    bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream)

    Return true if the stream is playing.

    See also: al_set_audio_stream_playing.

    al_set_audio_stream_playing

    bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val)

    Change whether the stream is playing.

    Returns true on success, false on failure.

    See also: al_get_audio_stream_playing

    al_get_audio_stream_playmode

    ALLEGRO_PLAYMODE al_get_audio_stream_playmode(
       const ALLEGRO_AUDIO_STREAM *stream)

    Return the playback mode.

    See also: ALLEGRO_PLAYMODE, al_set_audio_stream_playmode.

    al_set_audio_stream_playmode

    bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream,
       ALLEGRO_PLAYMODE val)

    Set the playback mode.

    Returns true on success, false on failure.

    See also: ALLEGRO_PLAYMODE, al_get_audio_stream_playmode.

    al_get_audio_stream_attached

    bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream)

    Return whether the stream is attached to something.

    See also: al_attach_audio_stream_to_mixer, al_attach_audio_stream_to_voice, al_detach_audio_stream.

    al_detach_audio_stream

    bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

    Detach the stream from whatever it's attached to, if anything.

    See also: al_attach_audio_stream_to_mixer, al_attach_audio_stream_to_voice, al_get_audio_stream_attached.

    al_get_audio_stream_fragment

    void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream)

    When using Allegro's audio streaming, you will use this function to continuously provide new sample data to a stream.

    If the stream is ready for new data, the function will return the address of an internal buffer to be filled with audio data. The length and format of the buffer are specified with al_create_audio_stream or can be queried with the various functions described here. Once the buffer is filled, you must signal this to Allegro by passing the buffer to al_set_audio_stream_fragment.

    If the stream is not ready for new data, the function will return NULL.

    Note: If you listen to events from the stream, an ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event will be generated whenever a new fragment is ready. However, getting an event is not a guarantee that al_get_audio_stream_fragment will not return NULL, so you still must check for it.

    See also: al_set_audio_stream_fragment, al_get_audio_stream_event_source, al_get_audio_stream_frequency, al_get_audio_stream_channels, al_get_audio_stream_depth, al_get_audio_stream_length

    al_set_audio_stream_fragment

    bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val)

    This function needs to be called for every successful call of al_get_audio_stream_fragment to indicate that the buffer is filled with new data.

    See also: al_get_audio_stream_fragment

    al_get_audio_stream_fragments

    unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream)

    Returns the number of fragments this stream uses. This is the same value as passed to al_create_audio_stream when a new stream is created.

    See also: al_get_available_audio_stream_fragments

    al_get_available_audio_stream_fragments

    unsigned int al_get_available_audio_stream_fragments(
       const ALLEGRO_AUDIO_STREAM *stream)

    Returns the number of available fragments in the stream, that is, fragments which are not currently filled with data for playback.

    See also: al_get_audio_stream_fragment, al_get_audio_stream_fragments

    al_seek_audio_stream_secs

    bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time)

    Set the streaming file playing position to time. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

    See also: al_get_audio_stream_position_secs, al_get_audio_stream_length_secs

    al_get_audio_stream_position_secs

    double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream)

    Return the position of the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream.

    See also: al_get_audio_stream_length_secs

    al_get_audio_stream_length_secs

    double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream)

    Return the length of the stream in seconds, if known. Otherwise returns zero.

    Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

    See also: al_get_audio_stream_position_secs

    al_set_audio_stream_loop_secs

    bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream,
       double start, double end)

    Sets the loop points for the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

    Audio file I/O

    al_register_sample_loader

    bool al_register_sample_loader(const char *ext,
       ALLEGRO_SAMPLE *(*loader)(const char *filename))

    Register a handler for al_load_sample. The given function will be used to handle the loading of sample files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_sample_loader_f, al_register_sample_saver

    al_register_sample_loader_f

    bool al_register_sample_loader_f(const char *ext,
       ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp))

    Register a handler for al_load_sample_f. The given function will be used to handle the loading of sample files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_sample_loader

    al_register_sample_saver

    bool al_register_sample_saver(const char *ext,
       bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))

    Register a handler for al_save_sample. The given function will be used to handle the saving of sample files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The saver argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_sample_saver_f, al_register_sample_loader

    al_register_sample_saver_f

    bool al_register_sample_saver_f(const char *ext,
       bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl))

    Register a handler for al_save_sample_f. The given function will be used to handle the saving of sample files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The saver argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_sample_saver

    al_register_audio_stream_loader

    bool al_register_audio_stream_loader(const char *ext,
       ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename,
          size_t buffer_count, unsigned int samples))

    Register a handler for al_load_audio_stream. The given function will be used to open streams from files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The stream_loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_audio_stream_loader_f

    al_register_audio_stream_loader_f

    bool al_register_audio_stream_loader_f(const char *ext,
       ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp,
          size_t buffer_count, unsigned int samples))

    Register a handler for al_load_audio_stream_f. The given function will be used to open streams from files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The stream_loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_audio_stream_loader

    al_load_sample

    ALLEGRO_SAMPLE *al_load_sample(const char *filename)

    Loads a few different audio file formats based on their extension.

    Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream.

    Returns the sample on success, NULL on failure.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_register_sample_loader, al_init_acodec_addon

    al_load_sample_f

    ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident)

    Loads an audio file from an ALLEGRO_FILE stream into an ALLEGRO_SAMPLE. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot.

    Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream_f.

    Returns the sample on success, NULL on failure. The file remains open afterwards.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_register_sample_loader_f, al_init_acodec_addon

    al_load_audio_stream

    ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename,
       size_t buffer_count, unsigned int samples)

    Loads an audio file from disk as it is needed.

    Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain buffer_count buffers with samples samples.

    The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM for more details.

    Returns the stream on success, NULL on failure.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_load_audio_stream_f, al_register_audio_stream_loader, al_init_acodec_addon

    al_load_audio_stream_f

    ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident,
       size_t buffer_count, unsigned int samples)

    Loads an audio file from ALLEGRO_FILE stream as it is needed.

    Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain buffer_count buffers with samples samples.

    The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot.

    The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM for more details.

    Returns the stream on success, NULL on failure. On success the file should be considered owned by the audio stream, and will be closed when the audio stream is destroyed. On failure the file will be closed.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_load_audio_stream, al_register_audio_stream_loader_f, al_init_acodec_addon

    al_save_sample

    bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl)

    Writes a sample into a file. Currently, wav is the only supported format, and the extension must be ".wav".

    Returns true on success, false on error.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_save_sample_f, al_register_sample_saver, al_init_acodec_addon

    al_save_sample_f

    bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl)

    Writes a sample into a ALLEGRO_FILE filestream. Currently, wav is the only supported format, and the extension must be ".wav".

    Returns true on success, false on error. The file remains open afterwards.

    Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

    See also: al_save_sample, al_register_sample_saver_f, al_init_acodec_addon

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:13 UTC

    allegro-5.0.10/docs/html/refman/primitives.html0000644000175000001440000013042012157230677020645 0ustar tjadenusers Primitives addon

    These functions are declared in the following header file. Link with allegro_primitives.

    #include <allegro5/allegro_primitives.h>

    General

    al_get_allegro_primitives_version

    uint32_t al_get_allegro_primitives_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    al_init_primitives_addon

    bool al_init_primitives_addon(void)

    Initializes the primitives addon.

    Returns: True on success, false on failure.

    See also: al_shutdown_primitives_addon

    al_shutdown_primitives_addon

    void al_shutdown_primitives_addon(void)

    Shut down the primitives addon. This is done automatically at program exit, but can be called any time the user wishes as well.

    See also: al_init_primitives_addon

    High level drawing routines

    High level drawing routines encompass the most common usage of this addon: to draw geometric primitives, both smooth (variations on the circle theme) and piecewise linear. Outlined primitives support the concept of thickness with two distinct modes of output: hairline lines and thick lines. Hairline lines are specifically designed to be exactly a pixel wide, and are commonly used for drawing outlined figures that need to be a pixel wide. Hairline thickness is designated as thickness less than or equal to 0. Unfortunately, the exact rasterization rules for drawing these hairline lines vary from one video card to another, and sometimes leave gaps where the lines meet. If that matters to you, then you should use thick lines. In many cases, having a thickness of 1 will produce 1 pixel wide lines that look better than hairline lines. Obviously, hairline lines cannot replicate thicknesses greater than 1. Thick lines grow symmetrically around the generating shape as thickness is increased.

    Pixel-precise output

    While normally you should not be too concerned with which pixels are displayed when the high level primitives are drawn, it is nevertheless possible to control that precisely by carefully picking the coordinates at which you draw those primitives.

    To be able to do that, however, it is critical to understand how GPU cards convert shapes to pixels. Pixels are not the smallest unit that can be addressed by the GPU. Because the GPU deals with floating point coordinates, it can in fact assign different coordinates to different parts of a single pixel. To a GPU, thus, a screen is composed of a grid of squares that have width and length of 1. The top left corner of the top left pixel is located at (0, 0). Therefore, the center of that pixel is at (0.5, 0.5). The basic rule that determines which pixels are associated with which shape is then as follows: a pixel is treated to belong to a shape if the pixel's center is located in that shape. The figure below illustrates the above concepts:

    Diagram showing a how pixel output is calculated by the GPU given the mathematical description of several shapes.

    Diagram showing a how pixel output is calculated by the GPU given the mathematical description of several shapes.

    This figure depicts three shapes drawn at the top left of the screen: an orange and green rectangles and a purple circle. On the left are the mathematical descriptions of pixels on the screen and the shapes to be drawn. On the right is the screen output. Only a single pixel has its center inside the circle, and therefore only a single pixel is drawn on the screen. Similarly, two pixels are drawn for the orange rectangle. Since there are no pixels that have their centers inside the green rectangle, the output image has no green pixels.

    Here is a more practical example. The image below shows the output of this code:

    /* blue vertical line */
    al_draw_line(0.5, 0, 0.5, 6, color_blue, 1);
    /* red horizontal line */
    al_draw_line(2, 1, 6, 1, color_red, 2);
    /* green filled rectangle */
    al_draw_filled_rectangle(3, 4, 5, 5, color_green);
    /* purple outlined rectangle */
    al_draw_rectangle(2.5, 3.5, 5.5, 5.5, color_purple, 1);
    Diagram showing a practical example of pixel output resulting from the invocation of several primitives addon functions.

    Diagram showing a practical example of pixel output resulting from the invocation of several primitives addon functions.

    It can be seen that lines are generated by making a rectangle based on the dashed line between the two endpoints. The thickness causes the rectangle to grow symmetrically about that generating line, as can be seen by comparing the red and blue lines. Note that to get proper pixel coverage, the coordinates passed to the al_draw_line had to be offset by 0.5 in the appropriate dimensions.

    Filled rectangles are generated by making a rectangle between the endpoints passed to the al_draw_filled_rectangle.

    Outlined rectangles are generated by symmetrically expanding an outline of a rectangle. With a thickness of 1, as depicted in the diagram, this means that an offset of 0.5 is needed for both sets of endpoint coordinates to exactly line up with the pixels of the display raster.

    The above rules only apply when multisampling is turned off. When multisampling is turned on, the area of a pixel that is covered by a shape is taken into account when choosing what color to draw there. This also means that shapes no longer have to contain the pixel's center to affect its color. For example, the green rectangle in the first diagram may in fact be drawn as two (or one) semi-transparent pixels. The advantages of multisampling is that slanted shapes will look smoother because they will not have jagged edges. A disadvantage of multisampling is that it may make vertical and horizontal edges blurry. While the exact rules for multisampling are unspecified, and may vary from GPU to GPU it is usually safe to assume that as long as a pixel is either completely covered by a shape or completely not covered, then the shape edges will be sharp. The offsets used in the second diagram were chosen so that this is the case: if you use those offsets, your shapes (if they are oriented the same way as they are on the diagram) should look the same whether multisampling is turned on or off.

    al_draw_line

    void al_draw_line(float x1, float y1, float x2, float y2,
       ALLEGRO_COLOR color, float thickness)

    Draws a line segment between two points.

    Parameters:

    • x1, y1, x2, y2 - Start and end points of the line
    • color - Color of the line
    • thickness - Thickness of the line, pass <= 0 to draw hairline lines

    See also: al_draw_soft_line

    al_draw_triangle

    void al_draw_triangle(float x1, float y1, float x2, float y2,
       float x3, float y3, ALLEGRO_COLOR color, float thickness)

    Draws an outlined triangle.

    Parameters:

    • x1, y1, x2, y2, x3, y3 - Three points of the triangle
    • color - Color of the triangle
    • thickness - Thickness of the lines, pass <= 0 to draw hairline lines

    See also: al_draw_filled_triangle, al_draw_soft_triangle

    al_draw_filled_triangle

    void al_draw_filled_triangle(float x1, float y1, float x2, float y2,
       float x3, float y3, ALLEGRO_COLOR color)

    Draws a filled triangle.

    Parameters:

    • x1, y1, x2, y2, x3, y3 - Three points of the triangle
    • color - Color of the triangle

    See also: al_draw_triangle

    al_draw_rectangle

    void al_draw_rectangle(float x1, float y1, float x2, float y2,
       ALLEGRO_COLOR color, float thickness)

    Draws an outlined rectangle.

    Parameters:

    • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
    • color - Color of the rectangle
    • thickness - Thickness of the lines, pass <= 0 to draw hairline lines

    See also: al_draw_filled_rectangle, al_draw_rounded_rectangle

    al_draw_filled_rectangle

    void al_draw_filled_rectangle(float x1, float y1, float x2, float y2,
       ALLEGRO_COLOR color)

    Draws a filled rectangle.

    Parameters:

    • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
    • color - Color of the rectangle

    See also: al_draw_rectangle, al_draw_filled_rounded_rectangle

    al_draw_rounded_rectangle

    void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2,
       float rx, float ry, ALLEGRO_COLOR color, float thickness)

    Draws an outlined rounded rectangle.

    Parameters:

    • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
    • color - Color of the rectangle
    • rx, ry - The radii of the round
    • thickness - Thickness of the lines, pass <= 0 to draw hairline lines

    See also: al_draw_filled_rounded_rectangle, al_draw_rectangle

    al_draw_filled_rounded_rectangle

    void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2,
       float rx, float ry, ALLEGRO_COLOR color)

    Draws an filled rounded rectangle.

    Parameters:

    • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
    • color - Color of the rectangle
    • rx, ry - The radii of the round

    See also: al_draw_rounded_rectangle, al_draw_filled_rectangle

    al_calculate_arc

    void al_calculate_arc(float* dest, int stride, float cx, float cy,
       float rx, float ry, float start_theta, float delta_theta, float thickness,
       int num_segments)

    Calculates an elliptical arc, and sets the vertices in the destination buffer to the calculated positions. If thickness <= 0, then num_points of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of stride bytes) doublets of floats, corresponding to x and y coordinates of the vertices.

    Parameters:

    • dest - The destination buffer
    • stride - Distance (in bytes) between starts of successive pairs of coordinates
    • cx, cy - Center of the arc
    • rx, ry - Radii of the arc
    • start_theta - The initial angle from which the arc is calculated
    • delta_theta - Angular span of the arc (pass a negative number to switch direction)
    • thickness - Thickness of the arc
    • num_points - The number of points to calculate

    See also: al_draw_arc, al_calculate_spline, al_calculate_ribbon

    al_draw_pieslice

    void al_draw_pieslice(float cx, float cy, float r, float start_theta,
       float delta_theta, ALLEGRO_COLOR color, float thickness)

    Draws a pieslice (outlined circular sector).

    Parameters:

    • cx, cy - Center of the pieslice
    • r - Radius of the pieslice
    • color - Color of the pieslice
    • start_theta - The initial angle from which the pieslice is drawn
    • delta_theta - Angular span of the pieslice (pass a negative number to switch direction)
    • thickness - Thickness of the circle, pass <= 0 to draw hairline pieslice

    Since: 5.0.6, 5.1.0

    See also: al_draw_filled_pieslice

    al_draw_filled_pieslice

    void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
       float delta_theta, ALLEGRO_COLOR color)

    Draws a filled pieslice (filled circular sector).

    Parameters:

    • cx, cy - Center of the pieslice
    • r - Radius of the pieslice
    • color - Color of the pieslice
    • start_theta - The initial angle from which the pieslice is drawn
    • delta_theta - Angular span of the pieslice (pass a negative number to switch direction)

    Since: 5.0.6, 5.1.0

    See also: al_draw_pieslice

    al_draw_ellipse

    void al_draw_ellipse(float cx, float cy, float rx, float ry,
       ALLEGRO_COLOR color, float thickness)

    Draws an outlined ellipse.

    Parameters:

    • cx, cy - Center of the ellipse
    • rx, ry - Radii of the ellipse
    • color - Color of the ellipse
    • thickness - Thickness of the ellipse, pass <= 0 to draw a hairline ellipse

    See also: al_draw_filled_ellipse, al_draw_circle

    al_draw_filled_ellipse

    void al_draw_filled_ellipse(float cx, float cy, float rx, float ry,
       ALLEGRO_COLOR color)

    Draws a filled ellipse.

    Parameters:

    • cx, cy - Center of the ellipse
    • rx, ry - Radii of the ellipse
    • color - Color of the ellipse

    See also: al_draw_ellipse, al_draw_filled_circle

    al_draw_circle

    void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color,
       float thickness)

    Draws an outlined circle.

    Parameters:

    • cx, cy - Center of the circle
    • r - Radius of the circle
    • color - Color of the circle
    • thickness - Thickness of the circle, pass <= 0 to draw a hairline circle

    See also: al_draw_filled_circle, al_draw_ellipse

    al_draw_filled_circle

    void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color)

    Draws a filled circle.

    Parameters:

    • cx, cy - Center of the circle
    • r - Radius of the circle
    • color - Color of the circle

    See also: al_draw_circle, al_draw_filled_ellipse

    al_draw_arc

    void al_draw_arc(float cx, float cy, float r, float start_theta,
       float delta_theta, ALLEGRO_COLOR color, float thickness)

    Draws an arc.

    Parameters:

    • cx, cy - Center of the arc
    • r - Radius of the arc
    • color - Color of the arc
    • start_theta - The initial angle from which the arc is calculated
    • delta_theta - Angular span of the arc (pass a negative number to switch direction)
    • thickness - Thickness of the arc, pass <= 0 to draw hairline arc

    See also: al_calculate_arc, al_draw_elliptical_arc

    al_draw_elliptical_arc

    void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta,
       float delta_theta, ALLEGRO_COLOR color, float thickness)

    Draws an elliptical arc.

    Parameters:

    • cx, cy - Center of the arc
    • rx, ry - Radii of the arc
    • color - Color of the arc
    • start_theta - The initial angle from which the arc is calculated
    • delta_theta - Angular span of the arc (pass a negative number to switch direction)
    • thickness - Thickness of the arc, pass <= 0 to draw hairline arc

    Since: 5.0.6, 5.1.0

    See also: al_calculate_arc, al_draw_arc

    al_calculate_spline

    void al_calculate_spline(float* dest, int stride, float points[8],
       float thickness, int num_segments)

    Calculates a Bézier spline given 4 control points. If thickness <= 0, then num_segments of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of stride bytes) doublets of floats, corresponding to x and y coordinates of the vertices.

    Parameters:

    • dest - The destination buffer
    • stride - Distance (in bytes) between starts of successive pairs of coordinates
    • points - An array of 4 pairs of coordinates of the 4 control points
    • thickness - Thickness of the spline ribbon
    • num_segments - The number of points to calculate

    See also: al_draw_spline, al_calculate_arc, al_calculate_ribbon

    al_draw_spline

    void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness)

    Draws a Bézier spline given 4 control points.

    Parameters:

    • points - An array of 4 pairs of coordinates of the 4 control points
    • color - Color of the spline
    • thickness - Thickness of the spline, pass <= 0 to draw a hairline spline

    See also: al_calculate_spline

    al_calculate_ribbon

    void al_calculate_ribbon(float* dest, int dest_stride, const float *points,
       int points_stride, float thickness, int num_segments)

    Calculates a ribbon given an array of points. The ribbon will go through all of the passed points. If thickness <= 0, then num_segments of points are required in the destination buffer, otherwise twice as many are needed. The destination and the points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.

    Parameters:

    • dest - Pointer to the destination buffer
    • dest_stride - Distance (in bytes) between starts of successive pairs of coordinates in the destination buffer
    • points - An array of pairs of coordinates for each point
    • points_stride - Distance (in bytes) between starts successive pairs of coordinates in the points buffer
    • thickness - Thickness of the spline ribbon
    • num_segments - The number of points to calculate

    See also: al_draw_ribbon, al_calculate_arc, al_calculate_spline

    al_draw_ribbon

    void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color,
       float thickness, int num_segments)

    Draws a series of straight lines given an array of points. The ribbon will go through all of the passed points.

    Parameters:

    • points - An array of coordinate pairs (x and y) for each point
    • color - Color of the spline
    • thickness - Thickness of the spline, pass <= 0 to draw hairline spline

    See also: al_calculate_ribbon

    Low level drawing routines

    Low level drawing routines allow for more advanced usage of the addon, allowing you to pass arbitrary sequences of vertices to draw to the screen. These routines also support using textures on the primitives with the following restrictions:

    For maximum portability, you should only use textures that have dimensions that are a power of two, as not every videocard supports them completely. This warning is relaxed, however, if the texture coordinates never exit the boundaries of a single bitmap (i.e. you are not having the texture repeat/tile). As long as that is the case, any texture can be used safely. Sub-bitmaps work as textures, but cannot be tiled.

    Some platforms also dictate a minimum texture size, which means that textures smaller than that size will not tile properly. The minimum size that will work on all platforms is 32 by 32.

    A note about pixel coordinates. In OpenGL the texture coordinate (0, 0) refers to the top left corner of the pixel. This confuses some drivers, because due to rounding errors the actual pixel sampled might be the pixel to the top and/or left of the (0, 0) pixel. To make this error less likely it is advisable to offset the texture coordinates you pass to the al_draw_prim by (0.5, 0.5) if you need precise pixel control. E.g. to refer to pixel (5, 10) you'd set the u and v to 5.5 and 10.5 respectively.

    See also: Pixel-precise output

    al_draw_prim

    int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
       ALLEGRO_BITMAP* texture, int start, int end, int type)

    Draws a subset of the passed vertex buffer.

    Parameters:

    • texture - Texture to use, pass 0 to use only color shaded primitves
    • vtxs - Pointer to an array of vertices
    • decl - Pointer to a vertex declaration. If set to NULL, the vertices are assumed to be of the ALLEGRO_VERTEX type
    • start - Start index of the subset of the vertex buffer to draw
    • end - One past the last index of subset of the vertex buffer to draw
    • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw

    Returns: Number of primitives drawn

    For example to draw a textured triangle you could use:

    ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1);
    ALLEGRO_VERTEX v[] = {
        {.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0},
        {.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256},
        {.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}};
    al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST);

    See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_indexed_prim

    al_draw_indexed_prim

    int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
       ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)

    Draws a subset of the passed vertex buffer. This function uses an index array to specify which vertices to use.

    Parameters:

    • texture - Texture to use, pass 0 to use only shaded primitves
    • vtxs - Pointer to an array of vertices
    • decl - Pointer to a vertex declaration. If set to 0, the vtxs are assumed to be of the ALLEGRO_VERTEX type
    • indices - An array of indices into the vertex buffer
    • num_vtx - Number of indices from the indices array you want to draw
    • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw

    Returns: Number of primitives drawn

    See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_prim

    al_create_vertex_decl

    ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride)

    Creates a vertex declaration, which describes a custom vertex format.

    Parameters:

    • elements - An array of ALLEGRO_VERTEX_ELEMENT structures.
    • stride - Size of the custom vertex structure

    Returns: Newly created vertex declaration.

    See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_destroy_vertex_decl

    al_destroy_vertex_decl

    void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl)

    Destroys a vertex declaration.

    Parameters:

    • decl - Vertex declaration to destroy

    See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_create_vertex_decl

    al_draw_soft_triangle

    void al_draw_soft_triangle(
       ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state,
       void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
       void (*first)(uintptr_t, int, int, int, int),
       void (*step)(uintptr_t, int),
       void (*draw)(uintptr_t, int, int, int))

    Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/tri_soft.c. The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of each segment may be absent if two vertices are horizontally collinear.

    Parameters:

    • v1, v2, v3 - The three vertices of the triangle
    • state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions
    • init - Called once per call before any drawing is done. The three points passed to it may be altered by clipping.
    • first - Called twice per call, once per triangle segment. It is passed 4 parameters, the first two are the coordinates of the initial pixel drawn in the segment. The second two are the left minor and the left major steps, respectively. They represent the sizes of two steps taken by the rasterizer as it walks on the left side of the triangle. From then on, the each step will either be classified as a minor or a major step, corresponding to the above values.
    • step - Called once per scanline. The last parameter is set to 1 if the step is a minor step, and 0 if it is a major step.
    • draw - Called once per scanline. The function is expected to draw the scanline starting with a point specified by the first two parameters (corresponding to x and y values) going to the right until it reaches the value of the third parameter (the x value of the end point). All coordinates are inclusive.

    See also: al_draw_triangle

    al_draw_soft_line

    void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state,
       void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
       void (*step)(uintptr_t, int),
       void (*draw)(uintptr_t, int, int))

    Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/line_soft.c. The line is drawn top to bottom.

    Parameters:

    • v1, v2 - The two vertices of the line
    • state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions
    • first - Called before drawing the first pixel of the line. It is passed the coordinates of this pixel, as well as the two vertices above. The passed vertices may have been altered by clipping.
    • step - Called once per pixel. The second parameter is set to 1 if the step is a minor step, and 0 if this step is a major step. Minor steps are taken only either in x or y directions. Major steps are taken in both directions diagonally. In all cases, the the absolute value of the change in coordinate is at most 1 in either direction.
    • draw - Called once per pixel. The function is expected to draw the pixel at the coordinates passed to it.

    Structures and types

    ALLEGRO_VERTEX

    typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX;

    Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set z to 0. Note that when you must initialize all members of this struct when you're using it. One exception to this rule are the u and v variables which can be left uninitialized when you are not using textures.

    Fields:

    • x, y, z - Position of the vertex (float)
    • color - ALLEGRO_COLOR structure, storing the color of the vertex
    • u, v - Texture coordinates measured in pixels (float)

    See also: ALLEGRO_PRIM_ATTR

    ALLEGRO_VERTEX_DECL

    typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL;

    A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions.

    See also: al_create_vertex_decl, al_destroy_vertex_decl, ALLEGRO_VERTEX_ELEMENT

    ALLEGRO_VERTEX_ELEMENT

    typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT;

    A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the al_create_vertex_decl function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the attribute field equal to 0, to signify that it is the end of the array. Here is an example code that would create a declaration describing the ALLEGRO_VERTEX structure (passing this as vertex declaration to al_draw_prim would be identical to passing NULL):

    /* On compilers without the offsetof keyword you need to obtain the
     * offset with sizeof and make sure to account for packing.
     */
    ALLEGRO_VERTEX_ELEMENT elems[] = {
       {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)},
       {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)},
       {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)},
       {0, 0, 0}
    };
    ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX));

    Fields:

    • attribute - A member of the ALLEGRO_PRIM_ATTR enumeration, specifying what this attribute signifies
    • storage - A member of the ALLEGRO_PRIM_STORAGE enumeration, specifying how this attribute is stored
    • offset - Offset in bytes from the beginning of the custom vertex structure. C function offsetof is very useful here.

    See also: al_create_vertex_decl, ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_ATTR, ALLEGRO_PRIM_STORAGE

    ALLEGRO_PRIM_TYPE

    typedef enum ALLEGRO_PRIM_TYPE

    Enumerates the types of primitives this addon can draw.

    • ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point

    • ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices define disjointed lines

    • ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a strip of lines

    • ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first and the last vertices are also connected by a line

    • ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of vertices define disjointed triangles

    • ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices define a strip of triangles

    • ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the first vertex

    ALLEGRO_PRIM_ATTR

    typedef enum ALLEGRO_PRIM_ATTR

    Enumerates the types of vertex attributes that a custom vertex may have.

    • ALLEGRO_PRIM_POSITION - Position information, can be stored only in ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3.

    • ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an ALLEGRO_COLOR. The storage field of ALLEGRO_VERTEX_ELEMENT is ignored

    • ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are normalized by the width and height of the texture, meaning that the bottom-right corner has texture coordinates of (1, 1).

    • ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are measured in pixels.

    See also: ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_STORAGE

    ALLEGRO_PRIM_STORAGE

    typedef enum ALLEGRO_PRIM_STORAGE

    Enumerates the types of storage an attribute of a custom vertex may be stored in.

    • ALLEGRO_PRIM_FLOAT_2 - A doublet of floats
    • ALLEGRO_PRIM_FLOAT_3 - A triplet of floats
    • ALLEGRO_PRIM_SHORT_2 - A doublet of shorts

    See also: ALLEGRO_PRIM_ATTR

    ALLEGRO_VERTEX_CACHE_SIZE

    #define ALLEGRO_VERTEX_CACHE_SIZE 256

    Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high-level primitives. This corresponds to the maximum number of line segments that will be used to form them.

    ALLEGRO_PRIM_QUALITY

    #define ALLEGRO_PRIM_QUALITY 10

    Defines the quality of the quadratic primitives. At 10, this roughly corresponds to error of less than half of a pixel.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:15 UTC

    allegro-5.0.10/docs/html/refman/timer.html0000644000175000001440000002473312157230674017600 0ustar tjadenusers Timer routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_TIMER

    typedef struct ALLEGRO_TIMER ALLEGRO_TIMER;

    This is an abstract data type representing a timer object.

    ALLEGRO_USECS_TO_SECS

    #define ALLEGRO_USECS_TO_SECS(x)      ((x) / 1000000.0)

    Convert microseconds to seconds.

    ALLEGRO_MSECS_TO_SECS

    #define ALLEGRO_MSECS_TO_SECS(x)      ((x) / 1000.0)

    Convert milliseconds to seconds.

    ALLEGRO_BPS_TO_SECS

    #define ALLEGRO_BPS_TO_SECS(x)        (1.0 / (x))

    Convert beats per second to seconds.

    ALLEGRO_BPM_TO_SECS

    #define ALLEGRO_BPM_TO_SECS(x)        (60.0 / (x))

    Convert beats per minute to seconds.

    al_create_timer

    ALLEGRO_TIMER *al_create_timer(double speed_secs)

    Allocates and initializes a timer. If successful, a pointer to a new timer object is returned, otherwise NULL is returned. speed_secs is in seconds per "tick", and must be positive. The new timer is initially stopped.

    Usage note: typical granularity is on the order of microseconds, but with some drivers might only be milliseconds.

    See also: al_start_timer, al_destroy_timer

    al_start_timer

    void al_start_timer(ALLEGRO_TIMER *timer)

    Start the timer specified. From then, the timer's counter will increment at a constant rate, and it will begin generating events. Starting a timer that is already started does nothing.

    See also: al_stop_timer, al_get_timer_started

    al_stop_timer

    void al_stop_timer(ALLEGRO_TIMER *timer)

    Stop the timer specified. The timer's counter will stop incrementing and it will stop generating events. Stopping a timer that is already stopped does nothing.

    See also: al_start_timer, al_get_timer_started

    al_get_timer_started

    bool al_get_timer_started(const ALLEGRO_TIMER *timer)

    Return true if the timer specified is currently started.

    al_destroy_timer

    void al_destroy_timer(ALLEGRO_TIMER *timer)

    Uninstall the timer specified. If the timer is started, it will automatically be stopped before uninstallation. It will also automatically unregister the timer with any event queues.

    Does nothing if passed the NULL pointer.

    See also: al_create_timer

    al_get_timer_count

    int64_t al_get_timer_count(const ALLEGRO_TIMER *timer)

    Return the timer's counter value. The timer can be started or stopped.

    See also: al_set_timer_count

    al_set_timer_count

    void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count)

    Set the timer's counter value. The timer can be started or stopped. The count value may be positive or negative, but will always be incremented by +1 at each tick.

    See also: al_get_timer_count, al_add_timer_count

    al_add_timer_count

    void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff)

    Add diff to the timer's counter value. This is similar to writing:

    al_set_timer_count(timer, al_get_timer_count(timer) + diff);

    except that the addition is performed atomically, so no ticks will be lost.

    See also: al_set_timer_count

    al_get_timer_speed

    double al_get_timer_speed(const ALLEGRO_TIMER *timer)

    Return the timer's speed, in seconds. (The same value passed to al_create_timer or al_set_timer_speed.)

    See also: al_set_timer_speed

    al_set_timer_speed

    void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs)

    Set the timer's speed, i.e. the rate at which its counter will be incremented when it is started. This can be done when the timer is started or stopped. If the timer is currently running, it is made to look as though the speed change occurred precisely at the last tick.

    speed_secs has exactly the same meaning as with al_create_timer.

    See also: al_get_timer_speed

    al_get_timer_event_source

    ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer)

    Retrieve the associated event source.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:12 UTC

    allegro-5.0.10/docs/html/refman/memfile.html0000644000175000001440000001201112157230676020062 0ustar tjadenusers Memfile interface

    The memfile interface allows you to treat a fixed block of contiguous memory as a file that can be used with Allegro's I/O functions.

    These functions are declared in the following header file. Link with allegro_memfile.

    #include <allegro5/allegro_memfile.h>

    al_open_memfile

    ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode)

    Returns a file handle to the block of memory. All read and write operations act upon the memory directly, so it must not be freed while the file remains open.

    The mode can be any combination of "r" (readable) and "w" (writable). Regardless of the mode, the file always opens at position 0. The file size is fixed and cannot be expanded.

    It should be closed with al_fclose. After the file is closed, you are responsible for freeing the memory (if needed).

    al_get_allegro_memfile_version

    uint32_t al_get_allegro_memfile_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:14 UTC

    allegro-5.0.10/docs/html/refman/opengl.html0000644000175000001440000003241712157230675017743 0ustar tjadenusers OpenGL integration

    These functions are declared in the following header file:

    #include <allegro5/allegro_opengl.h>

    al_get_opengl_extension_list

    ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void)

    Returns the list of OpenGL extensions supported by Allegro, for the given display.

    Allegro will keep information about all extensions it knows about in a structure returned by al_get_opengl_extension_list.

    For example:

    if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) {
        use it
    }

    The extension will be set to true if available for the given display and false otherwise. This means to use the definitions and functions from an OpenGL extension, all you need to do is to check for it as above at run time, after acquiring the OpenGL display from Allegro.

    Under Windows, this will also work with WGL extensions, and under Unix with GLX extensions.

    In case you want to manually check for extensions and load function pointers yourself (say, in case the Allegro developers did not include it yet), you can use the al_have_opengl_extension and al_get_opengl_proc_address functions instead.

    al_get_opengl_proc_address

    void *al_get_opengl_proc_address(const char *name)

    Helper to get the address of an OpenGL symbol

    Example:

    How to get the function glMultiTexCoord3fARB that comes with ARB's Multitexture extension:

    // define the type of the function
       ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC,
          (GLenum, GLfloat, GLfloat, GLfloat));
    // declare the function pointer
       MULTI_TEX_FUNC glMultiTexCoord3fARB;
    // get the address of the function
       glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address(
          "glMultiTexCoord3fARB");

    If glMultiTexCoord3fARB is not NULL then it can be used as if it has been defined in the OpenGL core library.

    Note: Under Windows, OpenGL functions may need a special calling convention, so it's best to always use the ALLEGRO_DEFINE_PROC_TYPE macro when declaring function pointer types for OpenGL functions.

    Parameters:

    name - The name of the symbol you want to link to.

    Return value:

    A pointer to the symbol if available or NULL otherwise.

    al_get_opengl_texture

    GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap)

    Returns the OpenGL texture id internally used by the given bitmap if it uses one, else 0.

    Example:

    bitmap = al_load_bitmap("my_texture.png");
    texture = al_get_opengl_texture(bitmap);
    if (texture != 0)
        glBindTexture(GL_TEXTURE_2D, texture);

    al_get_opengl_texture_size

    void al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h)

    Retrieves the size of the texture used for the bitmap. This can be different from the bitmap size if OpenGL only supports power-of-two sizes or if it is a sub-bitmap. 0's are returned if the bitmap is not an OpenGL bitmap.

    See also: al_get_opengl_texture_position

    al_get_opengl_texture_position

    void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)

    Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels.

    See also: al_get_opengl_texture_size

    al_get_opengl_fbo

    GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap)

    Returns the OpenGL FBO id internally used by the given bitmap if it uses one, otherwise returns zero. No attempt will be made to create an FBO if the bitmap is not owned by the current display.

    The FBO returned by this function will only be freed when the bitmap is destroyed, or if you call al_remove_opengl_fbo on the bitmap.

    Note: In Allegro 5.0.0 this function only returned an FBO which had previously been created by calling al_set_target_bitmap. It would not attempt to create an FBO itself. This has since been changed.

    See also: al_remove_opengl_fbo, al_set_target_bitmap

    al_remove_opengl_fbo

    void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap)

    Explicitly free an OpenGL FBO created for a bitmap, if it has one. Usually you do not need to worry about freeing FBOs, unless you use al_get_opengl_fbo.

    See also: al_get_opengl_fbo, al_set_target_bitmap

    al_have_opengl_extension

    bool al_have_opengl_extension(const char *extension)

    This function is a helper to determine whether an OpenGL extension is available on the given display or not.

    Example:

    bool packedpixels = al_have_opengl_extension("GL_EXT_packed_pixels");

    If packedpixels is true then you can safely use the constants related to the packed pixels extension.

    Returns true if the extension is available; false otherwise.

    al_get_opengl_version

    uint32_t al_get_opengl_version(void)

    Returns the OpenGL or OpenGL ES version number of the client (the computer the program is running on), for the current display. "1.0" is returned as 0x01000000, "1.2.1" is returned as 0x01020100, and "1.2.2" as 0x01020200, etc.

    A valid OpenGL context must exist for this function to work, which means you may not call it before al_create_display.

    See also: al_get_opengl_variant

    al_get_opengl_variant

    int al_get_opengl_variant(void)

    Returns the variant or type of OpenGL used on the running platform. This function can be called before creating a display or setting properties for new displays. Possible values are:

    ALLEGRO_DESKTOP_OPENGL

    Regular OpenGL as seen on desktop/laptop computers.

    ALLEGRO_OPENGL_ES

    Trimmed down version of OpenGL used on many small consumer electronic devices such as handheld (and sometimes full size) consoles.

    See also: al_get_opengl_version

    al_set_current_opengl_context

    void al_set_current_opengl_context(ALLEGRO_DISPLAY *display)

    Make the OpenGL context associated with the given display current for the calling thread. If there is a current target bitmap which belongs to a different OpenGL context, the target bitmap will be changed to NULL.

    Normally you do not need to use this function, as the context will be made current when you call al_set_target_bitmap or al_set_target_backbuffer. You might need if it you created an OpenGL "forward compatible" context. Then al_get_backbuffer only returns NULL, so it would not work to pass that to al_set_target_bitmap.

    OpenGL configuration

    You can disable the detection of any OpenGL extension by Allegro with a section like this in allegro5.cfg:

    [opengl_disabled_extensions]
    GL_ARB_texture_non_power_of_two=0
    GL_EXT_framebuffer_object=0

    Any extension which appears in the section is treated as not available (it does not matter if you set it to 0 or any other value).

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:13 UTC

    allegro-5.0.10/docs/html/refman/utf8.html0000644000175000001440000015105612157230674017345 0ustar tjadenusers UTF-8 string routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    About UTF-8 string routines

    Some parts of the Allegro API, such as the font rountines, expect Unicode strings encoded in UTF-8. The following basic routines are provided to help you work with UTF-8 strings, however it does not mean you need to use them. You should consider another library (e.g. ICU) if you require more functionality.

    Briefly, Unicode is a standard consisting of a large character set of over 100,000 characters, and rules, such as how to sort strings. A code point is the integer value of a character, but not all code points are characters, as some code points have other uses. Unlike legacy character sets, the set of code points is open ended and more are assigned with time.

    Clearly it is impossible represent each code point with a 8-bit byte (limited to 256 code points) or even a 16-bit integer (limited to 65536 code points). It is possible to store code points in a 32-bit integers but it is space inefficient, and not actually that useful (at least, when handling the full complexity of Unicode; Allegro only does the very basics). There exist different Unicode Transformation Formats for encoding code points into smaller code units. The most important transformation formats are UTF-8 and UTF-16.

    UTF-8 is a variable-length encoding which encodes each code point to between one and four 8-bit bytes each. UTF-8 has many nice properties, but the main advantages are that it is backwards compatible with C strings, and ASCII characters (code points in the range 0-127) are encoded in UTF-8 exactly as they would be in ASCII.

    UTF-16 is another variable-length encoding, but encodes each code point to one or two 16-bit words each. It is, of course, not compatible with traditional C strings. Allegro does not generally use UTF-16 strings.

    Here is a diagram of the representation of the word "ål", with a NUL terminator, in both UTF-8 and UTF-16.

                       ---------------- ---------------- --------------
               String         å                l              NUL
                       ---------------- ---------------- --------------
          Code points    U+00E5 (229)     U+006C (108)     U+0000 (0)
                       ---------------- ---------------- --------------
          UTF-8 bytes     0xC3, 0xA5          0x6C            0x00
                       ---------------- ---------------- --------------
       UTF-16LE bytes     0xE5, 0x00       0x6C, 0x00      0x00, 0x00
                       ---------------- ---------------- --------------

    You can see the aforementioned properties of UTF-8. The first code point U+00E5 ("å") is outside of the ASCII range (0-127) so is encoded to multiple code units -- it requires two bytes. U+006C ("l") and U+0000 (NUL) both exist in the ASCII range so take exactly one byte each, as in a pure ASCII string. A zero byte never appears except to represent the NUL character, so many functions which expect C-style strings will work with UTF-8 strings without modification.

    On the other hand, UTF-16 represents each code point by either one or two 16-bit code units (two or four bytes). The representation of each 16-bit code unit depends on the byte order; here we have demonstrated little endian.

    Both UTF-8 and UTF-16 are self-synchronising. Starting from any offset within a string, it is efficient to find the beginning of the previous or next code point.

    Not all sequences of bytes or 16-bit words are valid UTF-8 and UTF-16 strings respectively. UTF-8 also has an additional problem of overlong forms, where a code point value is encoded using more bytes than is strictly necessary. This is invalid and needs to be guarded against.

    In the following "ustr" functions, be careful whether a function takes code unit (byte) or code point indices. In general, all position parameters are in code unit offsets. This may be surprising, but if you think about, is required for good performance. (It also means some functions will work even if they do not contain UTF-8, since they only care about storing bytes, so you may actually store arbitrary data in the ALLEGRO_USTRs.)

    For actual text processing, where you want to specify positions with code point indices, you should use al_ustr_offset to find the code unit offset position. However, most of the time you would probably just work with byte offsets.

    UTF-8 string types

    ALLEGRO_USTR

    typedef struct _al_tagbstring ALLEGRO_USTR;

    An opaque type representing a string. ALLEGRO_USTRs normally contain UTF-8 encoded strings, but they may be used to hold any byte sequences, including NULs.

    ALLEGRO_USTR_INFO

    typedef struct _al_tagbstring ALLEGRO_USTR_INFO;

    A type that holds additional information for an ALLEGRO_USTR that references an external memory buffer.

    See also: al_ref_cstr, al_ref_buffer and al_ref_ustr.

    Creating and destroying strings

    al_ustr_new

    ALLEGRO_USTR *al_ustr_new(const char *s)

    Create a new string containing a copy of the C-style string s. The string must eventually be freed with al_ustr_free.

    See also: al_ustr_new_from_buffer, al_ustr_newf, al_ustr_dup, al_ustr_new_from_utf16

    al_ustr_new_from_buffer

    ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size)

    Create a new string containing a copy of the buffer pointed to by s of the given size in bytes. The string must eventually be freed with al_ustr_free.

    See also: al_ustr_new

    al_ustr_newf

    ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...)

    Create a new string using a printf-style format string.

    Notes:

    The "%s" specifier takes C string arguments, not ALLEGRO_USTRs. Therefore to pass an ALLEGRO_USTR as a parameter you must use al_cstr, and it must be NUL terminated. If the string contains an embedded NUL byte everything from that byte onwards will be ignored.

    The "%c" specifier outputs a single byte, not the UTF-8 encoding of a code point. Therefore it is only usable for ASCII characters (value <= 127) or if you really mean to output byte values from 128--255. To insert the UTF-8 encoding of a code point, encode it into a memory buffer using al_utf8_encode then use the "%s" specifier. Remember to NUL terminate the buffer.

    See also: al_ustr_new, al_ustr_appendf

    al_ustr_free

    void al_ustr_free(ALLEGRO_USTR *us)

    Free a previously allocated string. Does nothing if the argument is NULL.

    See also: al_ustr_new, al_ustr_new_from_buffer, al_ustr_newf

    al_cstr

    const char *al_cstr(const ALLEGRO_USTR *us)

    Get a char * pointer to the data in a string. This pointer will only be valid while the ALLEGRO_USTR object is not modified and not destroyed. The pointer may be passed to functions expecting C-style strings, with the following caveats:

    • ALLEGRO_USTRs are allowed to contain embedded NUL ('') bytes. That means al_ustr_size(u) and strlen(al_cstr(u)) may not agree.

    • An ALLEGRO_USTR may be created in such a way that it is not NUL terminated. A string which is dynamically allocated will always be NUL terminated, but a string which references the middle of another string or region of memory will not be NUL terminated.

    • If the ALLEGRO_USTR references another string, the returned C string will point into the referenced string. Again, no NUL terminator will be added to the referenced string.

    See also: al_ustr_to_buffer, al_cstr_dup

    al_ustr_to_buffer

    void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size)

    Write the contents of the string into a pre-allocated buffer of the given size in bytes. The result will always be NUL terminated, so a maximum of size - 1 bytes will be copied.

    See also: al_cstr, al_cstr_dup

    al_cstr_dup

    char *al_cstr_dup(const ALLEGRO_USTR *us)

    Create a NUL ('') terminated copy of the string. Any embedded NUL bytes will still be presented in the returned string. The new string must eventually be freed with al_free.

    If an error occurs NULL is returned.

    See also: al_cstr, al_ustr_to_buffer, al_free

    al_ustr_dup

    ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us)

    Return a duplicate copy of a string. The new string will need to be freed with al_ustr_free.

    See also: al_ustr_dup_substr, al_ustr_free

    al_ustr_dup_substr

    ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos,
       int end_pos)

    Return a new copy of a string, containing its contents in the byte interval [start_pos, end_pos). The new string will be NUL terminated and will need to be freed with al_ustr_free.

    If necessary, use al_ustr_offset to find the byte offsets for a given code point that you are interested in.

    See also: al_ustr_dup, al_ustr_free

    Predefined strings

    al_ustr_empty_string

    const ALLEGRO_USTR *al_ustr_empty_string(void)

    Return a pointer to a static empty string. The string is read only and must not be freed.

    Creating strings by referencing other data

    al_ref_cstr

    const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s)

    Create a string that references the storage of a C-style string. The information about the string (e.g. its size) is stored in the structure pointed to by the info parameter. The string will not have any other storage allocated of its own, so if you allocate the info structure on the stack then no explicit "free" operation is required.

    The string is valid until the underlying C string disappears.

    Example:

    ALLEGRO_USTR_INFO info;
    ALLEGRO_USTR *us = al_ref_cstr(&info, "my string");

    See also: al_ref_buffer, al_ref_ustr

    al_ref_buffer

    const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size)

    Create a string that references the storage of an underlying buffer. The size of the buffer is given in bytes. You can use it to reference only part of a string or an arbitrary region of memory.

    The string is valid while the underlying memory buffer is valid.

    See also: al_ref_cstr, al_ref_ustr

    al_ref_ustr

    const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us,
       int start_pos, int end_pos)

    Create a read-only string that references the storage of another ALLEGRO_USTR string. The information about the string (e.g. its size) is stored in the structure pointed to by the info parameter. The new string will not have any other storage allocated of its own, so if you allocate the info structure on the stack then no explicit "free" operation is required.

    The referenced interval is [start_pos, end_pos). Both are byte offsets.

    The string is valid until the underlying string is modified or destroyed.

    If you need a range of code-points instead of bytes, use al_ustr_offset to find the byte offsets.

    See also: al_ref_cstr, al_ref_buffer

    Sizes and offsets

    al_ustr_size

    size_t al_ustr_size(const ALLEGRO_USTR *us)

    Return the size of the string in bytes. This is equal to the number of code points in the string if the string is empty or contains only 7-bit ASCII characters.

    See also: al_ustr_length

    al_ustr_length

    size_t al_ustr_length(const ALLEGRO_USTR *us)

    Return the number of code points in the string.

    See also: al_ustr_size, al_ustr_offset

    al_ustr_offset

    int al_ustr_offset(const ALLEGRO_USTR *us, int index)

    Return the byte offset (from the start of the string) of the code point at the specified index in the string. A zero index parameter will return the first character of the string. If index is negative, it counts backward from the end of the string, so an index of -1 will return an offset to the last code point.

    If the index is past the end of the string, returns the offset of the end of the string.

    See also: al_ustr_length

    al_ustr_next

    bool al_ustr_next(const ALLEGRO_USTR *us, int *pos)

    Find the byte offset of the next code point in string, beginning at *pos. *pos does not have to be at the beginning of a code point.

    Returns true on success, and the value pointed to by pos will be updated to the found offset. Otherwise returns false if *pos was already at the end of the string, and *pos is unmodified.

    This function just looks for an appropriate byte; it doesn't check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes.

    See also: al_ustr_prev

    al_ustr_prev

    bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos)

    Find the byte offset of the previous code point in string, before *pos. *pos does not have to be at the beginning of a code point. Returns true on success, then value pointed to by pos will be updated to the found offset. Otherwise returns false if *pos was already at the end of the string, then *pos is unmodified.

    This function just looks for an appropriate byte; it doesn't check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes.

    See also: al_ustr_next

    Getting code points

    al_ustr_get

    int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos)

    Return the code point in us beginning at byte offset pos.

    On success returns the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2.

    See also: al_ustr_get_next, al_ustr_prev_get

    al_ustr_get_next

    int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos)

    Find the code point in us beginning at byte offset *pos, then advance to the next code point.

    On success return the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with al_ustr_next, invalid byte sequences may be skipped while advancing.

    See also: al_ustr_get, al_ustr_prev_get

    al_ustr_prev_get

    int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos)

    Find the beginning of a code point before byte offset *pos, then return it. Note this performs a pre-increment.

    On success returns the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with al_ustr_prev, invalid byte sequences may be skipped while advancing.

    See also: al_ustr_get_next

    Inserting into strings

    al_ustr_insert

    bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2)

    Insert us2 into us1 beginning at byte offset pos. pos cannot be less than 0. If pos is past the end of us1 then the space between the end of the string and pos will be padded with NUL ('') bytes.

    If required, use al_ustr_offset to find the byte offset for a given code point index.

    Returns true on success, false on error.

    See also: al_ustr_insert_cstr, al_ustr_insert_chr, al_ustr_append, al_ustr_offset

    al_ustr_insert_cstr

    bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s)

    Like al_ustr_insert but inserts a C-style string at byte offset pos.

    See also: al_ustr_insert, al_ustr_insert_chr

    al_ustr_insert_chr

    size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c)

    Insert a code point into us beginning at byte offset pos. pos cannot be less than 0. If pos is past the end of us then the space between the end of the string and pos will be padded with NUL ('') bytes.

    Returns the number of bytes inserted, or 0 on error.

    See also: al_ustr_insert, al_ustr_insert_cstr

    Appending to strings

    al_ustr_append

    bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    Append us2 to the end of us1.

    Returns true on success, false on error.

    This function can be used to append an arbitrary buffer:

    ALLEGRO_USTR_INFO info;
    al_ustr_append(us, al_ref_buffer(&info, buf, size));

    See also: al_ustr_append_cstr, al_ustr_append_chr, al_ustr_appendf, al_ustr_vappendf

    al_ustr_append_cstr

    bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s)

    Append C-style string s to the end of us.

    Returns true on success, false on error.

    See also: al_ustr_append

    al_ustr_append_chr

    size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c)

    Append a code point to the end of us.

    Returns the number of bytes added, or 0 on error.

    See also: al_ustr_append

    al_ustr_appendf

    bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...)

    This function appends formatted output to the string us. fmt is a printf-style format string. See al_ustr_newf about the "%s" and "%c" specifiers.

    Returns true on success, false on error.

    See also: al_ustr_vappendf, al_ustr_append

    al_ustr_vappendf

    bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap)

    Like al_ustr_appendf but you pass the variable argument list directly, instead of the arguments themselves. See al_ustr_newf about the "%s" and "%c" specifiers.

    Returns true on success, false on error.

    See also: al_ustr_appendf, al_ustr_append

    Removing parts of strings

    al_ustr_remove_chr

    bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos)

    Remove the code point beginning at byte offset pos. Returns true on success. If pos is out of range or pos is not the beginning of a valid code point, returns false leaving the string unmodified.

    Use al_ustr_offset to find the byte offset for a code-points offset.

    See also: al_ustr_remove_range

    al_ustr_remove_range

    bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos)

    Remove the interval [start_pos, end_pos) from a string. start_pos and end_pos are byte offsets. Both may be past the end of the string but cannot be less than 0 (the start of the string).

    Returns true on success, false on error.

    See also: al_ustr_remove_chr, al_ustr_truncate

    al_ustr_truncate

    bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos)

    Truncate a portion of a string at byte offset start_pos onwards. start_pos can be past the end of the string (has no effect) but cannot be less than 0.

    Returns true on success, false on error.

    See also: al_ustr_remove_range, al_ustr_ltrim_ws, al_ustr_rtrim_ws, al_ustr_trim_ws

    al_ustr_ltrim_ws

    bool al_ustr_ltrim_ws(ALLEGRO_USTR *us)

    Remove leading whitespace characters from a string, as defined by the C function isspace().

    Returns true on success, or false on error.

    See also: al_ustr_rtrim_ws, al_ustr_trim_ws

    al_ustr_rtrim_ws

    bool al_ustr_rtrim_ws(ALLEGRO_USTR *us)

    Remove trailing ("right") whitespace characters from a string, as defined by the C function isspace().

    Returns true on success, or false on error.

    See also: al_ustr_ltrim_ws, al_ustr_trim_ws

    al_ustr_trim_ws

    bool al_ustr_trim_ws(ALLEGRO_USTR *us)

    Remove both leading and trailing whitespace characters from a string.

    Returns true on success, or false on error.

    See also: al_ustr_ltrim_ws, al_ustr_rtrim_ws

    Assigning one string to another

    al_ustr_assign

    bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    Overwrite the string us1 with another string us2. Returns true on success, false on error.

    See also: al_ustr_assign_substr, al_ustr_assign_cstr

    al_ustr_assign_substr

    bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2,
       int start_pos, int end_pos)

    Overwrite the string us1 with the contents of us2 in the byte interval [start_pos, end_pos). The end points will be clamed to the bounds of us2.

    Usually you will first have to use al_ustr_offset to find the byte offsets.

    Returns true on success, false on error.

    See also: al_ustr_assign, al_ustr_assign_cstr

    al_ustr_assign_cstr

    bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s)

    Overwrite the string us with the contents of the C-style string s. Returns true on success, false on error.

    See also: al_ustr_assign_substr, al_ustr_assign_cstr

    Replacing parts of string

    al_ustr_set_chr

    size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c)

    Replace the code point beginning at byte offset pos with c. pos cannot be less than 0. If pos is past the end of us1 then the space between the end of the string and pos will be padded with NUL ('') bytes. If pos is not the start of a valid code point, that is an error and the string will be unmodified.

    On success, returns the number of bytes written, i.e. the offset to the following code point. On error, returns 0.

    See also: al_ustr_replace_range

    al_ustr_replace_range

    bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1,
       const ALLEGRO_USTR *us2)

    Replace the part of us1 in the byte interval [start_pos, end_pos) with the contents of us2. start_pos cannot be less than 0. If start_pos is past the end of us1 then the space between the end of the string and start_pos will be padded with NUL ('') bytes.

    Use al_ustr_offset to find the byte offsets.

    Returns true on success, false on error.

    See also: al_ustr_set_chr

    Searching

    al_ustr_find_chr

    int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c)

    Search for the encoding of code point c in us from byte offset start_pos (inclusive).

    Returns the position where it is found or -1 if it is not found.

    See also: al_ustr_rfind_chr

    al_ustr_rfind_chr

    int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c)

    Search for the encoding of code point c in us backwards from byte offset end_pos (exclusive). Returns the position where it is found or -1 if it is not found.

    See also: al_ustr_find_chr

    al_ustr_find_set

    int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos,
       const ALLEGRO_USTR *accept)

    This function finds the first code point in us, beginning from byte offset start_pos, that matches any code point in accept. Returns the position if a code point was found. Otherwise returns -1.

    See also: al_ustr_find_set_cstr, al_ustr_find_cset

    al_ustr_find_set_cstr

    int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos,
       const char *accept)

    Like al_ustr_find_set but takes a C-style string for accept.

    See also: al_ustr_find_set, al_ustr_find_cset_cstr

    al_ustr_find_cset

    int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos,
       const ALLEGRO_USTR *reject)

    This function finds the first code point in us, beginning from byte offset start_pos, that does not match any code point in reject. In other words it finds a code point in the complementary set of reject. Returns the byte position of that code point, if any. Otherwise returns -1.

    See also: al_ustr_find_cset_cstr, al_ustr_find_set

    al_ustr_find_cset_cstr

    int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos,
       const char *reject)

    Like al_ustr_find_cset but takes a C-style string for reject.

    See also: al_ustr_find_cset, al_ustr_find_set_cstr

    al_ustr_find_str

    int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos,
       const ALLEGRO_USTR *needle)

    Find the first occurrence of string needle in haystack, beginning from byte offset pos (inclusive). Return the byte offset of the occurrence if it is found, otherwise return -1.

    See also: al_ustr_find_cstr, al_ustr_rfind_str, al_ustr_find_replace

    al_ustr_find_cstr

    int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos,
       const char *needle)

    Like al_ustr_find_str but takes a C-style string for needle.

    See also: al_ustr_find_str, al_ustr_rfind_cstr

    al_ustr_rfind_str

    int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos,
       const ALLEGRO_USTR *needle)

    Find the last occurrence of string needle in haystack before byte offset end_pos (exclusive). Return the byte offset of the occurrence if it is found, otherwise return -1.

    See also: al_ustr_rfind_cstr, al_ustr_find_str

    al_ustr_rfind_cstr

    int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos,
       const char *needle)

    Like al_ustr_rfind_str but takes a C-style string for needle.

    See also: al_ustr_rfind_str, al_ustr_find_cstr

    al_ustr_find_replace

    bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos,
       const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)

    Replace all occurrences of find in us with replace, beginning at byte offset start_pos. The find string must be non-empty. Returns true on success, false on error.

    See also: al_ustr_find_replace_cstr

    al_ustr_find_replace_cstr

    bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos,
       const char *find, const char *replace)

    Like al_ustr_find_replace but takes C-style strings for find and replace.

    Comparing

    al_ustr_equal

    bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    Return true iff the two strings are equal. This function is more efficient than al_ustr_compare so is preferable if ordering is not important.

    See also: al_ustr_compare

    al_ustr_compare

    int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    This function compares us1 and us2 by code point values. Returns zero if the strings are equal, a positive number if us1 comes after us2, else a negative number.

    This does not take into account locale-specific sorting rules. For that you will need to use another library.

    See also: al_ustr_ncompare, al_ustr_equal

    al_ustr_ncompare

    int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n)

    Like al_ustr_compare but only compares up to the first n code points of both strings.

    Returns zero if the strings are equal, a positive number if us1 comes after us2, else a negative number.

    See also: al_ustr_compare, al_ustr_equal

    al_ustr_has_prefix

    bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    Returns true iff us1 begins with us2.

    See also: al_ustr_has_prefix_cstr, al_ustr_has_suffix

    al_ustr_has_prefix_cstr

    bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2)

    Returns true iff us1 begins with s2.

    See also: al_ustr_has_prefix, al_ustr_has_suffix_cstr

    al_ustr_has_suffix

    bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

    Returns true iff us1 ends with us2.

    See also: al_ustr_has_suffix_cstr, al_ustr_has_prefix

    al_ustr_has_suffix_cstr

    bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2)

    Returns true iff us1 ends with s2.

    See also: al_ustr_has_suffix, al_ustr_has_prefix_cstr

    UTF-16 conversion

    al_ustr_new_from_utf16

    ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s)

    Create a new string containing a copy of the 0-terminated string s which must be encoded as UTF-16. The string must eventually be freed with al_ustr_free.

    See also: al_ustr_new

    al_ustr_size_utf16

    size_t al_ustr_size_utf16(const ALLEGRO_USTR *us)

    Returns the number of bytes required to encode the string in UTF-16 (including the terminating 0). Usually called before al_ustr_encode_utf16 to determine the size of the buffer to allocate.

    See also: al_ustr_size

    al_ustr_encode_utf16

    size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s,
       size_t n)

    Encode the string into the given buffer, in UTF-16. Returns the number of bytes written. There are never more than n bytes written. The minimum size to encode the complete string can be queried with al_ustr_size_utf16. If the n parameter is smaller than that, the string will be truncated but still always 0 terminated.

    See also: al_ustr_size_utf16, al_utf16_encode

    Low-level UTF-8 routines

    al_utf8_width

    size_t al_utf8_width(int c)

    Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-8. This is between 1 and 4 bytes for legal code point values. Otherwise returns 0.

    See also: al_utf8_encode, al_utf16_width

    al_utf8_encode

    size_t al_utf8_encode(char s[], int32_t c)

    Encode the specified code point to UTF-8 into the buffer s. The buffer must have enough space to hold the encoding, which takes between 1 and 4 bytes. This routine will refuse to encode code points above 0x10FFFF.

    Returns the number of bytes written, which is the same as that returned by al_utf8_width.

    See also: al_utf16_encode

    Low-level UTF-16 routines

    al_utf16_width

    size_t al_utf16_width(int c)

    Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-16. This is either 2 or 4 bytes for legal code point values. Otherwise returns 0.

    See also: al_utf16_encode, al_utf8_width

    al_utf16_encode

    size_t al_utf16_encode(uint16_t s[], int32_t c)

    Encode the specified code point to UTF-16 into the buffer s. The buffer must have enough space to hold the encoding, which takes either 2 or 4 bytes. This routine will refuse to encode code points above 0x10FFFF.

    Returns the number of bytes written, which is the same as that returned by al_utf16_width.

    See also: al_utf8_encode, al_ustr_encode_utf16

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:12 UTC

    allegro-5.0.10/docs/html/refman/fullscreen_mode.html0000644000175000001440000001412012157230671021610 0ustar tjadenusers Fullscreen modes

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_DISPLAY_MODE

    typedef struct ALLEGRO_DISPLAY_MODE

    Used for fullscreen mode queries. Contains information about a supported fullscreen modes.

    typedef struct ALLEGRO_DISPLAY_MODE {
       int width;          // Screen width
       int height;         // Screen height
       int format;         // The pixel format of the mode
       int refresh_rate;   // The refresh rate of the mode
    } ALLEGRO_DISPLAY_MODE;

    The refresh_rate may be zero if unknown.

    See also: al_get_display_mode

    al_get_display_mode

    ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode)

    Retrieves a fullscreen mode. Display parameters should not be changed between a call of al_get_num_display_modes and al_get_display_mode. index must be between 0 and the number returned from al_get_num_display_modes-1. mode must be an allocated ALLEGRO_DISPLAY_MODE structure. This function will return NULL on failure, and the mode parameter that was passed in on success.

    See also: ALLEGRO_DISPLAY_MODE, al_get_num_display_modes

    al_get_num_display_modes

    int al_get_num_display_modes(void)

    Get the number of available fullscreen display modes for the current set of display parameters. This will use the values set with al_set_new_display_refresh_rate, and al_set_new_display_flags to find the number of modes that match. Settings the new display parameters to zero will give a list of all modes for the default driver.

    See also: al_get_display_mode

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/threads.html0000644000175000001440000004006112157230673020101 0ustar tjadenusers Threads

    Allegro includes a simple cross-platform threading interface. It is a thin layer on top of two threading APIs: Windows threads and POSIX Threads (pthreads). Enforcing a consistent semantics on all platforms would be difficult at best, hence the behaviour of the following functions will differ subtly on different platforms (more so than usual). Your best bet is to be aware of this and code to the intersection of the semantics and avoid edge cases.

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_THREAD

    typedef struct ALLEGRO_THREAD ALLEGRO_THREAD;

    An opaque structure representing a thread.

    ALLEGRO_MUTEX

    typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX;

    An opaque structure representing a mutex.

    ALLEGRO_COND

    typedef struct ALLEGRO_COND ALLEGRO_COND;

    An opaque structure representing a condition variable.

    al_create_thread

    ALLEGRO_THREAD *al_create_thread(
       void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)

    Spawn a new thread which begins executing proc. The new thread is passed its own thread handle and the value arg.

    Returns a pointer to the thread on success. Otherwise, returns NULL if there was an error.

    See also: al_start_thread, al_join_thread.

    al_start_thread

    void al_start_thread(ALLEGRO_THREAD *thread)

    When a thread is created, it is initially in a suspended state. Calling al_start_thread will start its actual execution.

    Starting a thread which has already been started does nothing.

    See also: al_create_thread.

    al_join_thread

    void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)

    Wait for the thread to finish executing. This implicitly calls al_set_thread_should_stop first.

    If ret_value is non-NULL, the value returned by the thread function will be stored at the location pointed to by ret_value.

    See also: al_set_thread_should_stop, al_get_thread_should_stop, al_destroy_thread.

    al_set_thread_should_stop

    void al_set_thread_should_stop(ALLEGRO_THREAD *thread)

    Set the flag to indicate thread should stop. Returns immediately.

    See also: al_join_thread, al_get_thread_should_stop.

    al_get_thread_should_stop

    bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)

    Check if another thread is waiting for thread to stop. Threads which run in a loop should check this periodically and act on it when convenient.

    Returns true if another thread has called al_join_thread or al_set_thread_should_stop on this thread.

    See also: al_join_thread, al_set_thread_should_stop.

    Note: We don't support forceful killing of threads.

    al_destroy_thread

    void al_destroy_thread(ALLEGRO_THREAD *thread)

    Free the resources used by a thread. Implicitly performs al_join_thread on the thread if it hasn't been done already.

    Does nothing if thread is NULL.

    See also: al_join_thread.

    al_run_detached_thread

    void al_run_detached_thread(void *(*proc)(void *arg), void *arg)

    Runs the passed function in its own thread, with arg passed to it as only parameter. This is similar to calling al_create_thread, al_start_thread and (after the thread has finished) al_destroy_thread - but you don't have the possibility of ever calling al_join_thread on the thread any longer.

    al_create_mutex

    ALLEGRO_MUTEX *al_create_mutex(void)

    Create the mutex object (a mutual exclusion device). The mutex may or may not support "recursive" locking.

    Returns the mutex on success or NULL on error.

    See also: al_create_mutex_recursive.

    al_create_mutex_recursive

    ALLEGRO_MUTEX *al_create_mutex_recursive(void)

    Create the mutex object (a mutual exclusion device), with support for "recursive" locking. That is, the mutex will count the number of times it has been locked by the same thread. If the caller tries to acquire a lock on the mutex when it already holds the lock then the count is incremented. The mutex is only unlocked when the thread releases the lock on the mutex an equal number of times, i.e. the count drops down to zero.

    See also: al_create_mutex.

    al_lock_mutex

    void al_lock_mutex(ALLEGRO_MUTEX *mutex)

    Acquire the lock on mutex. If the mutex is already locked by another thread, the call will block until the mutex becomes available and locked.

    If the mutex is already locked by the calling thread, then the behaviour depends on whether the mutex was created with al_create_mutex or al_create_mutex_recursive. In the former case, the behaviour is undefined; the most likely behaviour is deadlock. In the latter case, the count in the mutex will be incremented and the call will return immediately.

    See also: al_unlock_mutex.

    We don't yet have al_mutex_trylock.

    al_unlock_mutex

    void al_unlock_mutex(ALLEGRO_MUTEX *mutex)

    Release the lock on mutex if the calling thread holds the lock on it.

    If the calling thread doesn't hold the lock, or if the mutex is not locked, undefined behaviour results.

    See also: al_lock_mutex.

    al_destroy_mutex

    void al_destroy_mutex(ALLEGRO_MUTEX *mutex)

    Free the resources used by the mutex. The mutex should be unlocked. Destroying a locked mutex results in undefined behaviour.

    Does nothing if mutex is NULL.

    al_create_cond

    ALLEGRO_COND *al_create_cond(void)

    Create a condition variable.

    Returns the condition value on success or NULL on error.

    al_destroy_cond

    void al_destroy_cond(ALLEGRO_COND *cond)

    Destroy a condition variable.

    Destroying a condition variable which has threads block on it results in undefined behaviour.

    Does nothing if cond is NULL.

    al_wait_cond

    void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)

    On entering this function, mutex must be locked by the calling thread. The function will atomically release mutex and block on cond. The function will return when cond is "signalled", acquiring the lock on the mutex in the process.

    Example of proper use:

    al_lock_mutex(mutex);
    while (something_not_true) {
        al_wait_cond(cond, mutex);
    }
    do_something();
    al_unlock_mutex(mutex);

    The mutex should be locked before checking the condition, and should be rechecked al_wait_cond returns. al_wait_cond can return for other reasons than the condition becoming true (e.g. the process was signalled). If multiple threads are blocked on the condition variable, the condition may no longer be true by the time the second and later threads are unblocked. Remember not to unlock the mutex prematurely.

    See also: al_wait_cond_until, al_broadcast_cond, al_signal_cond.

    al_wait_cond_until

    int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex,
       const ALLEGRO_TIMEOUT *timeout)

    Like al_wait_cond but the call can return if the absolute time passes timeout before the condition is signalled.

    Returns zero on success, non-zero if the call timed out.

    See also: al_wait_cond

    al_broadcast_cond

    void al_broadcast_cond(ALLEGRO_COND *cond)

    Unblock all threads currently waiting on a condition variable. That is, broadcast that some condition which those threads were waiting for has become true.

    See also: al_signal_cond.

    Note: The pthreads spec says to lock the mutex associated with cond before signalling for predictable scheduling behaviour.

    al_signal_cond

    void al_signal_cond(ALLEGRO_COND *cond)

    Unblock at least one thread waiting on a condition variable.

    Generally you should use al_broadcast_cond but al_signal_cond may be more efficient when it's applicable.

    See also: al_broadcast_cond.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/transformations.html0000644000175000001440000003653012157230674021707 0ustar tjadenusers Transformations

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    The transformations are combined in the order of the function invocations. Thus to create a transformation that first rotates a point and then translates it, you would (starting with an identity transformation) call al_rotate_transform and then al_translate_transform. This approach is opposite of what OpenGL uses but similar to what Direct3D uses.

    For those who known the matrix algebra going behind the scenes, what the transformation functions in Allegro do is "pre-multiply" the successive transformations. So, for example, if you have code that does:

    al_identity_transform(&T);
    
    al_compose_transform(&T, &T1);
    al_compose_transform(&T, &T2);
    al_compose_transform(&T, &T3);
    al_compose_transform(&T, &T4);

    The resultant matrix multiplication expression will look like this:

    T4 * T3 * T2 * T1

    Since the point coordinate vector term will go on the right of that sequence of factors, the transformation that is called first, will also be applied first.

    This means if you have code like this:

    al_identity_transform(&T1);
    al_scale_transform(&T1, 2, 2);
    al_identity_transform(&T2);
    al_translate_transform(&T2, 100, 0);
    
    al_identity_transform(&T);
    
    al_compose_transform(&T, &T1);
    al_compose_transform(&T, &T2);
    
    al_use_transform(T);

    it does exactly the same as:

    al_identity_transform(&T);
    al_scale_transform(&T, 2, 2);
    al_translate_transform(&T, 100, 0);
    al_use_transform(T);

    ALLEGRO_TRANSFORM

    typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM;

    Defines the generic transformation type, a 4x4 matrix. 2D transforms use only a small subsection of this matrix, namely the top left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values.

    Fields:

    • m - A 4x4 float matrix

    al_copy_transform

    void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src)

    Makes a copy of a transformation.

    Parameters:

    • dest - Source transformation
    • src - Destination transformation

    al_use_transform

    void al_use_transform(const ALLEGRO_TRANSFORM *trans)

    Sets the transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own transformation). Every drawing operation after this call will be transformed using this transformation. Call this function with an identity transformation to return to the default behaviour.

    This function does nothing if there is no target bitmap.

    The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables.

    void setup_my_transformation(void)
    {
       ALLEGRO_TRANSFORM transform;
       al_translate_transform(&transform, 5, 10);
       al_use_transform(&transform);
    }

    Parameters:

    • trans - Transformation to use

    See also: al_get_current_transform, al_transform_coordinates

    al_get_current_transform

    const ALLEGRO_TRANSFORM *al_get_current_transform(void)

    Returns the transformation of the current target bitmap, as set by al_use_transform. If there is no target bitmap, this function returns NULL.

    Returns: A pointer to the current transformation.

    al_invert_transform

    void al_invert_transform(ALLEGRO_TRANSFORM *trans)

    Inverts the passed transformation. If the transformation is nearly singular (close to not having an inverse) then the returned transformation may be invalid. Use al_check_inverse to ascertain if the transformation has an inverse before inverting it if you are in doubt.

    Parameters:

    • trans - Transformation to invert

    See also: al_check_inverse

    al_check_inverse

    int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol)

    Checks if the transformation has an inverse using the supplied tolerance. Tolerance should be a small value between 0 and 1, with 1e-7 being sufficient for most applications.

    In this function tolerance specifies how close the determinant can be to 0 (if the determinant is 0, the transformation has no inverse). Thus the smaller the tolerance you specify, the "worse" transformations will pass this test. Using a tolerance of 1e-7 will catch errors greater than 1/1000's of a pixel, but let smaller errors pass. That means that if you transformed a point by a transformation and then transformed it again by the inverse transformation that passed this check, the resultant point should less than 1/1000's of a pixel away from the original point.

    Note that this check is superfluous most of the time if you never touched the transformation matrix values yourself. The only thing that would cause the transformation to not have an inverse is if you applied a 0 (or very small) scale to the transformation or you have a really large translation. As long as the scale is comfortably above 0, the transformation will be invertible.

    Parameters:

    • trans - Transformation to check
    • tol - Tolerance

    Returns: 1 if the transformation is invertible, 0 otherwise

    See also: al_invert_transform

    al_identity_transform

    void al_identity_transform(ALLEGRO_TRANSFORM *trans)

    Sets the transformation to be the identity transformation. This is the default transformation. Use al_use_transform on an identity transformation to return to the default.

    ALLEGRO_TRANSFORM t;
    al_identity_transform(&t);
    al_use_transform(&t);

    Parameters:

    • trans - Transformation to alter

    See also: al_translate_transform, al_rotate_transform, al_scale_transform

    al_build_transform

    void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y,
       float sx, float sy, float theta)

    Builds a transformation given some parameters. This call is equivalent to calling the transformations in this order: make identity, scale, rotate, translate. This method is faster, however, than actually calling those functions.

    Parameters:

    • trans - Transformation to alter
    • x, y - Translation
    • sx, sy - Scale
    • theta - Rotation angle in radians

    See also: al_translate_transform, al_rotate_transform, al_scale_transform, al_compose_transform

    al_translate_transform

    void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y)

    Apply a translation to a transformation.

    Parameters:

    • trans - Transformation to alter
    • x, y - Translation

    See also: al_rotate_transform, al_scale_transform, al_build_transform

    al_rotate_transform

    void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta)

    Apply a rotation to a transformation.

    Parameters:

    • trans - Transformation to alter
    • theta - Rotation angle in radians

    See also: al_translate_transform, al_scale_transform, al_build_transform

    al_scale_transform

    void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy)

    Apply a scale to a transformation.

    Parameters:

    • trans - Transformation to alter
    • sx, sy - Scale

    See also: al_translate_transform, al_rotate_transform, al_build_transform

    al_transform_coordinates

    void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y)

    Transform a pair of coordinates.

    Parameters:

    • trans - Transformation to use
    • x, y - Pointers to the coordinates

    See also: al_use_transform

    al_compose_transform

    void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other)

    Compose (combine) two transformations by a matrix multiplication.

    trans := trans other

    Note that the order of matrix multiplications is important. The effect of applying the combined transform will be as if first applying trans and then applying other and not the other way around.

    Parameters:

    • trans - Transformation to alter
    • other - Transformation used to transform trans

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:12 UTC

    allegro-5.0.10/docs/html/refman/pandoc.css0000644000175000001440000000756612157230664017554 0ustar tjadenusers/* We use this style sheet for HTML documents generated with Pandoc. */ body { background-color: #fcfcfc; padding-left: 0.1em; color: #222; font-family: sans-serif; } pre { border: 1px solid #ddd; background-color: #f3f3f8; padding: 0.6em; padding-left: 0.8em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } blockquote { border: 1px solid #ddd; background-color: #fff8e0; padding: 0.6em; padding-left: 0.8em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } blockquote p { padding: 0; margin: 0; } blockquote p em:first-child { font-style: normal; font-weight: bold; color: #400000; } code { font-family: monospace; } h1, h2, h3, h4, h5 { color: #348; margin-top: 2.5em; border-top: 1px solid #eee; padding-top: 0.8em; } h1 { font-size: 130%; } h2 { font-size: 110%; } h3 { font-size: 95%; } h4 { font-size: 90%; font-style: italic; } h5 { font-size: 90%; font-style: italic; } h1.title { font-size: 200%; font-weight: bold; margin-top: 0; padding-top: 0.2em; padding-bottom: 0.2em; text-align: left; border: none; } a { text-decoration: none; color: #348; } dl dt { font-weight: bold; } dt code { font-weight: bold; } dd p { margin-top: 0; } ul { padding-left: 1.5em; } table { background-color: #f8f8fa; border-top: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0; } table th { font-weight: bold; border-bottom: 1px solid #e0e0e0; padding: 0.5em; } /* Side bar */ div.sidebar { background-color: #f0f0fa; border: solid 1px #e0e0ea; float: left; width: 150px; margin-right: 1em; line-height: 110%; -moz-border-radius: 5px; -webkit-border-radius: 5px; } div.sidebar ul { list-style-type: none; padding: 0; margin-left: 0.5em; font-size: small; } div.sidebar ul a:hover { background: #fffff0; } div.searchbox { margin-left: 5px; margin-right: 5px; margin-bottom: 0.8em; font-size: small; } /* font-size isn't inherited (at least not in Firefox and Chrome) */ input#q { font-size: small; } /* Body of page */ div.content { margin-left: 165px; max-width: 50em; line-height: 135%; } div#TOC { display: table; border: 1px solid #ddd; background-color: #f3f3fa; padding-right: 1em; -moz-border-radius: 5px; -webkit-border-radius: 5px; } div#TOC ul { padding-left: 1em; list-style-type: none; } p.timestamp { margin-top: 3em; border-top: solid 1px #eee; padding: 0.7em; padding-left: 0.3em; color: #999; text-align: left; } /* Below is the autosuggest.css from autosuggest.js version 2.4. */ .autosuggest-body { position: absolute; border: 1px solid black; z-index: 100; font-size: small; } .autosuggest-body iframe { display: block; position: absolute; z-index: 999; filter: alpha(opacity=0); } .autosuggest-body table { width: 100%; background-color: #FFFFF0; } .autosuggest-body tr { cursor: hand; cursor: pointer; color: black; text-align: left; } .autosuggest-body tr.up { height: 10px; background: #656291 url("arrow-up.gif") center center no-repeat; } .autosuggest-body tr.down { height: 10px; background: #656291 url("arrow-down.gif") center center no-repeat; } .autosuggest-body tr.up-disabled { height: 10px; background: #656291 url("arrow-up-d.gif") center center no-repeat; cursor: default; } .autosuggest-body tr.down-disabled { height: 10px; background: #656291 url("arrow-down-d.gif") center center no-repeat; cursor: default; } .autosuggest-body tr.selected { background-color: #D6D7E7; color: red; } .autosuggest-body td { white-space: nowrap; } .autosuggest-body span.match { font-weight: bold; } allegro-5.0.10/docs/html/refman/file.html0000644000175000001440000007154312157230671017375 0ustar tjadenusers File I/O

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_FILE

    typedef struct ALLEGRO_FILE ALLEGRO_FILE;

    An opaque object representing an open file. This could be a real file on disk or a virtual file.

    ALLEGRO_FILE_INTERFACE

    typedef struct ALLEGRO_FILE_INTERFACE

    A structure containing function pointers to handle a type of "file", real or virtual. See the full discussion in al_set_new_file_interface.

    The fields are:

    void*         (*fi_fopen)(const char *path, const char *mode);
    void          (*fi_fclose)(ALLEGRO_FILE *f);
    size_t        (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size);
    size_t        (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size);
    bool          (*fi_fflush)(ALLEGRO_FILE *f);
    int64_t       (*fi_ftell)(ALLEGRO_FILE *f);
    bool          (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence);
    bool          (*fi_feof)(ALLEGRO_FILE *f);
    bool          (*fi_ferror)(ALLEGRO_FILE *f);
    void          (*fi_fclearerr)(ALLEGRO_FILE *f);
    int           (*fi_fungetc)(ALLEGRO_FILE *f, int c);
    off_t         (*fi_fsize)(ALLEGRO_FILE *f);

    The fi_open function must allocate memory for whatever userdata structure it needs. The pointer to that memory must be returned; it will then be associated with the file. The other functions can access that data by calling al_get_file_userdata on the file handle. If fi_open returns NULL then al_fopen will also return NULL.

    The fi_fclose function must clean up and free the userdata, but Allegro will free the ALLEGRO_FILE handle.

    If fi_fungetc is NULL, then Allegro's default implementation of a 16 char long buffer will be used.

    ALLEGRO_SEEK

    typedef enum ALLEGRO_SEEK
    • ALLEGRO_SEEK_SET - seek relative to beginning of file
    • ALLEGRO_SEEK_CUR - seek relative to current file position
    • ALLEGRO_SEEK_END - seek relative to end of file

    See also: al_fseek

    al_fopen

    ALLEGRO_FILE *al_fopen(const char *path, const char *mode)

    Creates and opens a file (real or virtual) given the path and mode. The current file interface is used to open the file.

    Parameters:

    • path - path to the file to open
    • mode - access mode to open the file in ("r", "w", etc.)

    Depending on the stream type and the mode string, files may be opened in "text" mode. The handling of newlines is particularly important. For example, using the default stdio-based streams on DOS and Windows platforms, where the native end-of-line terminators are CR+LF sequences, a call to al_fgetc may return just one character ('\n') where there were two bytes (CR+LF) in the file. When writing out '\n', two bytes would be written instead. (As an aside, '\n' is not defined to be equal to LF either.)

    Newline translations can be useful for text files but is disastrous for binary files. To avoid this behaviour you need to open file streams in binary mode by using a mode argument containing a "b", e.g. "rb", "wb".

    Returns a file handle on success, or NULL on error.

    See also: al_set_new_file_interface, al_fclose.

    al_fopen_interface

    ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv,
       const char *path, const char *mode)

    Opens a file using the specified interface, instead of the interface set with al_set_new_file_interface.

    See also: al_fopen

    al_fopen_slice

    ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode)

    Opens a slice (subset) of an already open random access file as if it were a stand alone file. While the slice is open, the parent file handle must not be used in any way.

    The slice is opened at the current location of the parent file, up through initial_size bytes. The initial_size may be any non-negative integer that will not exceed the bounds of the parent file.

    Seeking with ALLEGRO_SEEK_SET will be relative to this starting location. ALLEGRO_SEEK_END will be relative to the starting location plus the size of the slice.

    The mode can be any combination of:

    • r: read access
    • w: write access
    • e: expandable

    For example, a mode of "rw" indicates the file can be read and written. (Note that this is slightly different from the stdio modes.) Keep in mind that the parent file must support random access and be open in normal write mode (not append) for the slice to work in a well defined way.

    If the slice is marked as expandable, then reads and writes can happen after the initial end point, and the slice will grow accordingly. Otherwise, all activity is restricted to the initial size of the slice.

    A slice must be closed with al_fclose. The parent file will then be positioned immediately after the end of the slice.

    Since: 5.0.6, 5.1.0

    See also: al_fopen

    al_fclose

    void al_fclose(ALLEGRO_FILE *f)

    Close the given file, writing any buffered output data (if any).

    al_fread

    size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size)

    Read 'size' bytes into the buffer pointed to by 'ptr', from the given file.

    Returns the number of bytes actually read. If an error occurs, or the end-of-file is reached, the return value is a short byte count (or zero).

    al_fread() does not distinguish between EOF and other errors. Use al_feof and al_ferror to determine which occurred.

    See also: al_fgetc, al_fread16be, al_fread16le, al_fread32be, al_fread32le

    al_fwrite

    size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size)

    Write 'size' bytes from the buffer pointed to by 'ptr' into the given file.

    Returns the number of bytes actually written. If an error occurs, the return value is a short byte count (or zero).

    See also: al_fputc, al_fputs, al_fwrite16be, al_fwrite16le, al_fwrite32be, al_fwrite32le

    al_fflush

    bool al_fflush(ALLEGRO_FILE *f)

    Flush any pending writes to the given file.

    Returns true on success, false otherwise. errno is set to indicate the error.

    See also: al_get_errno

    al_ftell

    int64_t al_ftell(ALLEGRO_FILE *f)

    Returns the current position in the given file, or -1 on error. errno is set to indicate the error.

    On some platforms this function may not support large files.

    See also: al_fseek, al_get_errno

    al_fseek

    bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence)

    Set the current position of the given file to a position relative to that specified by 'whence', plus 'offset' number of bytes.

    'whence' can be:

    • ALLEGRO_SEEK_SET - seek relative to beginning of file
    • ALLEGRO_SEEK_CUR - seek relative to current file position
    • ALLEGRO_SEEK_END - seek relative to end of file

    Returns true on success, false on failure. errno is set to indicate the error.

    After a successful seek, the end-of-file indicator is cleared and all pushback bytes are forgotten.

    On some platforms this function may not support large files.

    See also: al_ftell, al_get_errno

    al_feof

    bool al_feof(ALLEGRO_FILE *f)

    Returns true if the end-of-file indicator has been set on the file, i.e. we have attempted to read past the end of the file.

    This does not return true if we simply are at the end of the file. The following code correctly reads two bytes, even when the file contains exactly two bytes:

    int b1 = al_fgetc(f);
    int b2 = al_fgetc(f);
    if (al_feof(f)) {
       /* At least one byte was unsuccessfully read. */
       report_error();
    }

    See also: al_ferror, al_fclearerr

    al_ferror

    bool al_ferror(ALLEGRO_FILE *f)

    Returns true if the error indicator is set on the given file, i.e. there was some sort of previous error.

    See also: al_feof, al_fclearerr

    al_fclearerr

    void al_fclearerr(ALLEGRO_FILE *f)

    Clear the error indicator for the given file.

    The standard I/O backend also clears the end-of-file indicator, and other backends should try to do this. However, they may not if it would require too much effort (e.g. PhysicsFS backend), so your code should not rely on it if you need your code to be portable to other backends.

    See also: al_ferror, al_feof

    al_fungetc

    int al_fungetc(ALLEGRO_FILE *f, int c)

    Ungets a single byte from a file. Pushed-back bytes are not written to the file, only made available for subsequent reads, in reverse order.

    The number of pushbacks depends on the backend. The standard I/O backend only guarantees a single pushback; this depends on the libc implementation.

    For backends that follow the standard behavior, the pushback buffer will be cleared after any seeking or writing; also calls to al_fseek and al_ftell are relative to the number of pushbacks. If a pushback causes the position to become negative, the behavior of al_fseek and al_ftell are undefined.

    See also: al_fgetc, al_get_errno

    al_fsize

    int64_t al_fsize(ALLEGRO_FILE *f)

    Return the size of the file, if it can be determined, or -1 otherwise.

    al_fgetc

    int al_fgetc(ALLEGRO_FILE *f)

    Read and return next byte in the given file. Returns EOF on end of file or if an error occurred.

    See also: al_fungetc

    al_fputc

    int al_fputc(ALLEGRO_FILE *f, int c)

    Write a single byte to the given file. The byte written is the value of c cast to an unsigned char.

    Parameters:

    • c - byte value to write
    • f - file to write to

    Returns the written byte (cast back to an int) on success, or EOF on error.

    al_fread16le

    int16_t al_fread16le(ALLEGRO_FILE *f)

    Reads a 16-bit word in little-endian format (LSB first).

    On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

    See also: al_fread16be

    al_fread16be

    int16_t al_fread16be(ALLEGRO_FILE *f)

    Reads a 16-bit word in big-endian format (MSB first).

    On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

    See also: al_fread16le

    al_fwrite16le

    size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w)

    Writes a 16-bit word in little-endian format (LSB first).

    Returns the number of bytes written: 2 on success, less than 2 on an error.

    See also: al_fwrite16be

    al_fwrite16be

    size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w)

    Writes a 16-bit word in big-endian format (MSB first).

    Returns the number of bytes written: 2 on success, less than 2 on an error.

    See also: al_fwrite16le

    al_fread32le

    int32_t al_fread32le(ALLEGRO_FILE *f)

    Reads a 32-bit word in little-endian format (LSB first).

    On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

    See also: al_fread32be

    al_fread32be

    int32_t al_fread32be(ALLEGRO_FILE *f)

    Read a 32-bit word in big-endian format (MSB first).

    On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

    See also: al_fread32le

    al_fwrite32le

    size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l)

    Writes a 32-bit word in little-endian format (LSB first).

    Returns the number of bytes written: 4 on success, less than 4 on an error.

    See also: al_fwrite32be

    al_fwrite32be

    size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l)

    Writes a 32-bit word in big-endian format (MSB first).

    Returns the number of bytes written: 4 on success, less than 4 on an error.

    See also: al_fwrite32le

    al_fgets

    char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max)

    Read a string of bytes terminated with a newline or end-of-file into the buffer given. The line terminator(s), if any, are included in the returned string. A maximum of max-1 bytes are read, with one byte being reserved for a NUL terminator.

    Parameters:

    • f - file to read from
    • buf - buffer to fill
    • max - maximum size of buffer

    Returns the pointer to buf on success. Returns NULL if an error occurred or if the end of file was reached without reading any bytes.

    See al_fopen about translations of end-of-line characters.

    See also: al_fget_ustr

    al_fget_ustr

    ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f)

    Read a string of bytes terminated with a newline or end-of-file. The line terminator(s), if any, are included in the returned string.

    On success returns a pointer to a new ALLEGRO_USTR structure. This must be freed eventually with al_ustr_free. Returns NULL if an error occurred or if the end of file was reached without reading any bytes.

    See al_fopen about translations of end-of-line characters.

    See also: al_fgetc, al_fgets

    al_fputs

    int al_fputs(ALLEGRO_FILE *f, char const *p)

    Writes a string to file. Apart from the return value, this is equivalent to:

    al_fwrite(f, p, strlen(p));

    Parameters:

    • f - file handle to write to
    • p - string to write

    Returns a non-negative integer on success, EOF on error.

    Note: depending on the stream type and the mode passed to al_fopen, newline characters in the string may or may not be automatically translated to native end-of-line sequences, e.g. CR/LF instead of LF.

    See also: al_fwrite

    Standard I/O specific routines

    al_fopen_fd

    ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode)

    Create an ALLEGRO_FILE object that operates on an open file descriptor using stdio routines. See the documentation of fdopen() for a description of the 'mode' argument.

    Returns an ALLEGRO_FILE object on success or NULL on an error. On an error, the Allegro errno will be set and the file descriptor will not be closed.

    The file descriptor will be closed by al_fclose so you should not call close() on it.

    See also: al_fopen

    al_make_temp_file

    ALLEGRO_FILE *al_make_temp_file(const char *template, ALLEGRO_PATH **ret_path)

    Make a temporary randomly named file given a filename 'template'.

    'template' is a string giving the format of the generated filename and should include one or more capital Xs. The Xs are replaced with random alphanumeric characters, produced using a simple pseudo-random number generator only. There should be no path separators.

    If 'ret_path' is not NULL, the address it points to will be set to point to a new path structure with the name of the temporary file.

    Returns the opened ALLEGRO_FILE on success, NULL on failure.

    Alternative file streams

    By default, the Allegro file I/O routines use the C library I/O routines, hence work with files on the local filesystem, but can be overridden so that you can read and write to other streams. For example, you can work with block of memory or sub-files inside .zip files.

    There are two ways to get an ALLEGRO_FILE that doesn't use stdio. An addon library may provide a function that returns a new ALLEGRO_FILE directly, after which, all al_f* calls on that object will use overridden functions for that type of stream. Alternatively, al_set_new_file_interface changes which function will handle the following al_fopen calls for the current thread.

    al_set_new_file_interface

    void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface)

    Set the ALLEGRO_FILE_INTERFACE table for the calling thread. This will change the handler for later calls to al_fopen.

    See also: al_set_standard_file_interface, al_store_state, al_restore_state.

    al_set_standard_file_interface

    void al_set_standard_file_interface(void)

    Set the ALLEGRO_FILE_INTERFACE table to the default, for the calling thread. This will change the handler for later calls to al_fopen.

    See also: al_set_new_file_interface

    al_get_new_file_interface

    const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void)

    Return a pointer to the ALLEGRO_FILE_INTERFACE table in effect for the calling thread.

    See also: al_store_state, al_restore_state.

    al_create_file_handle

    ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv,
       void *userdata)

    Creates an empty, opened file handle with some abstract user data. This allows custom interfaces to extend the ALLEGRO_FILE struct with their own data. You should close the handle with the standard al_fclose function when you are finished with it.

    See also: al_fopen, al_fclose, al_set_new_file_interface

    al_get_file_userdata

    void *al_get_file_userdata(ALLEGRO_FILE *f)

    Returns a pointer to the custom userdata that is attached to the file handle. This is intended to be used by functions that extend ALLEGRO_FILE_INTERFACE.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/config.html0000644000175000001440000003627412157230670017724 0ustar tjadenusers Configuration files

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    Allegro supports reading and writing of configuration files with a simple, INI file-like format.

    A configuration file consists of key-value pairs separated by newlines. Keys are separated from values by an equals sign (=). All whitespace before the key, after the value and immediately adjacent to the equals sign is ignored. Keys and values may have whitespace characters within them. Keys do not need to be unique, but all but the last one are ignored.

    The hash (#) character is used a comment when it is the first non-whitespace character on the line. All characters following that character are ignored to the end of the line. The hash character anywhere else on the line has no special significance.

    Key-value pairs can be optionally grouped into sections, which are declared by surrounding a section name with square brackets ([ and ]) on a single line. Whitespace before the opening bracket is ignored. All characters after the trailing bracket are also ignored.

    All key-value pairs that follow a section declaration belong to the last declared section. Key-value pairs that don't follow any section declarations belong to the global section. Sections do not nest.

    Here is an example configuration file:

    # Monster description
    monster name = Allegro Developer
    
    [weapon 0]
    damage = 443
    
    [weapon 1]
    damage = 503

    It can then be accessed like this (make sure to check for errors in an actual program):

    ALLEGRO_CONFIG* cfg = al_load_config_file("test.cfg");
    printf("%s\n", al_get_config_value(cfg, "", "monster name")); /* Prints: Allegro Developer */
    printf("%s\n", al_get_config_value(cfg, "weapon 0", "damage")); /* Prints: 443 */
    printf("%s\n", al_get_config_value(cfg, "weapon 1", "damage")); /* Prints: 503 */
    al_destroy_config(cfg);

    ALLEGRO_CONFIG

    typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG;

    An abstract configuration structure.

    al_create_config

    ALLEGRO_CONFIG *al_create_config(void)

    Create an empty configuration structure.

    See also: al_load_config_file, al_destroy_config

    al_destroy_config

    void al_destroy_config(ALLEGRO_CONFIG *config)

    Free the resources used by a configuration structure. Does nothing if passed NULL.

    See also: al_create_config, al_load_config_file

    al_load_config_file

    ALLEGRO_CONFIG *al_load_config_file(const char *filename)

    Read a configuration file from disk. Returns NULL on error. The configuration structure should be destroyed with al_destroy_config.

    See also: al_load_config_file_f, al_save_config_file

    al_load_config_file_f

    ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)

    Read a configuration file from an already open file.

    Returns NULL on error. The configuration structure should be destroyed with al_destroy_config. The file remains open afterwards.

    See also: al_load_config_file

    al_save_config_file

    bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)

    Write out a configuration file to disk. Returns true on success, false on error.

    See also: al_save_config_file_f, al_load_config_file

    al_save_config_file_f

    bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)

    Write out a configuration file to an already open file.

    Returns true on success, false on error. The file remains open afterwards.

    See also: al_save_config_file

    al_add_config_section

    void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)

    Add a section to a configuration structure with the given name. If the section already exists then nothing happens.

    al_add_config_comment

    void al_add_config_comment(ALLEGRO_CONFIG *config,
       const char *section, const char *comment)

    Add a comment in a section of a configuration. If the section doesn't yet exist, it will be created. The section can be NULL or "" for the global section.

    The comment may or may not begin with a hash character. Any newlines in the comment string will be replaced by space characters.

    See also: al_add_config_section

    al_get_config_value

    const char *al_get_config_value(const ALLEGRO_CONFIG *config,
       const char *section, const char *key)

    Gets a pointer to an internal character buffer that will only remain valid as long as the ALLEGRO_CONFIG structure is not destroyed. Copy the value if you need a copy. The section can be NULL or "" for the global section. Returns NULL if the section or key do not exist.

    See also: al_set_config_value

    al_set_config_value

    void al_set_config_value(ALLEGRO_CONFIG *config,
       const char *section, const char *key, const char *value)

    Set a value in a section of a configuration. If the section doesn't yet exist, it will be created. If a value already existed for the given key, it will be overwritten. The section can be NULL or "" for the global section.

    For consistency with the on-disk format of config files, any leading and trailing whitespace will be stripped from the value. If you have significant whitespace you wish to preserve, you should add your own quote characters and remove them when reading the values back in.

    See also: al_get_config_value

    al_get_first_config_section

    char const *al_get_first_config_section(ALLEGRO_CONFIG const *config,
       ALLEGRO_CONFIG_SECTION **iterator)

    Returns the name of the first section in the given config file. Usually this will return an empty string for the global section. The iterator parameter will receive an opaque iterator which is used by al_get_next_config_section to iterate over the remaining sections.

    The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG.

    See also: al_get_next_config_section

    al_get_next_config_section

    char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator)

    Returns the name of the next section in the given config file or NULL if there are no more sections. The iterator must have been obtained with al_get_first_config_section first.

    See also: al_get_first_config_section

    al_get_first_config_entry

    char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config,
       char const *section, ALLEGRO_CONFIG_ENTRY **iterator)

    Returns the name of the first key in the given section in the given config or NULL if the section is empty. The iterator works like the one for al_get_first_config_section.

    The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG.

    See also: al_get_next_config_entry

    al_get_next_config_entry

    char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator)

    Returns the next key for the iterator obtained by al_get_first_config_entry. The iterator works like the one for al_get_next_config_section.

    al_merge_config

    ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1,
        const ALLEGRO_CONFIG *cfg2)

    Merge two configuration structures, and return the result as a new configuration. Values in configuration 'cfg2' override those in 'cfg1'. Neither of the input configuration structures are modified. Comments from 'cfg2' are not retained.

    See also: al_merge_config_into

    al_merge_config_into

    void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)

    Merge one configuration structure into another. Values in configuration 'add' override those in 'master'. 'master' is modified. Comments from 'add' are not retained.

    See also: al_merge_config

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:08 UTC

    allegro-5.0.10/docs/html/refman/graphics.html0000644000175000001440000021472712157230672020262 0ustar tjadenusers Graphics routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    Colors

    ALLEGRO_COLOR

    typedef struct ALLEGRO_COLOR ALLEGRO_COLOR;

    An ALLEGRO_COLOR structure describes a color in a device independent way. Use al_map_rgb et al. and al_unmap_rgb et al. to translate from and to various color representations.

    al_map_rgb

    ALLEGRO_COLOR al_map_rgb(
       unsigned char r, unsigned char g, unsigned char b)

    Convert r, g, b (ranging from 0-255) into an ALLEGRO_COLOR, using 255 for alpha.

    See also: al_map_rgba, al_map_rgba_f, al_map_rgb_f

    al_map_rgb_f

    ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b)

    Convert r, g, b, (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR, using 1.0f for alpha.

    See also: al_map_rgba, al_map_rgb, al_map_rgba_f

    al_map_rgba

    ALLEGRO_COLOR al_map_rgba(
       unsigned char r, unsigned char g, unsigned char b, unsigned char a)

    Convert r, g, b, a (ranging from 0-255) into an ALLEGRO_COLOR.

    See also: al_map_rgb, al_map_rgba_f, al_map_rgb_f

    al_map_rgba_f

    ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a)

    Convert r, g, b, a (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR.

    See also: al_map_rgba, al_map_rgb, al_map_rgb_f

    al_unmap_rgb

    void al_unmap_rgb(ALLEGRO_COLOR color,
       unsigned char *r, unsigned char *g, unsigned char *b)

    Retrieves components of an ALLEGRO_COLOR, ignoring alpha Components will range from 0-255.

    See also: al_unmap_rgba, al_unmap_rgba_f, al_unmap_rgb_f

    al_unmap_rgb_f

    void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b)

    Retrieves components of an ALLEGRO_COLOR, ignoring alpha. Components will range from 0.0f-1.0f.

    See also: al_unmap_rgba, al_unmap_rgb, al_unmap_rgba_f

    al_unmap_rgba

    void al_unmap_rgba(ALLEGRO_COLOR color,
       unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)

    Retrieves components of an ALLEGRO_COLOR. Components will range from 0-255.

    See also: al_unmap_rgb, al_unmap_rgba_f, al_unmap_rgb_f

    al_unmap_rgba_f

    void al_unmap_rgba_f(ALLEGRO_COLOR color,
       float *r, float *g, float *b, float *a)

    Retrieves components of an ALLEGRO_COLOR. Components will range from 0.0f-1.0f.

    See also: al_unmap_rgba, al_unmap_rgb, al_unmap_rgb_f

    Locking and pixel formats

    ALLEGRO_LOCKED_REGION

    typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION;

    Users who wish to manually edit or read from a bitmap are required to lock it first. The ALLEGRO_LOCKED_REGION structure represents the locked region of the bitmap. This call will work with any bitmap, including memory bitmaps.

    typedef struct ALLEGRO_LOCKED_REGION {
        void *data;
        int format;
        int pitch;
        int pixel_size;
    } ALLEGRO_LOCKED_REGION;
    • data points to the leftmost pixel of the first row (row 0) of the locked region.

    • format indicates the pixel format of the data.

    • pitch gives the size in bytes of a single row (also known as the stride). The pitch may be greater than width * pixel_size due to padding; this is not uncommon. It is also not uncommon for the pitch to be negative (the bitmap may be upside down).

    • pixel_size is the number of bytes used to represent a single pixel.

    See also: al_lock_bitmap, al_lock_bitmap_region, al_unlock_bitmap, ALLEGRO_PIXEL_FORMAT

    ALLEGRO_PIXEL_FORMAT

    typedef enum ALLEGRO_PIXEL_FORMAT

    Pixel formats. Each pixel format specifies the exact size and bit layout of a pixel in memory. Components are specified from high bits to low bits, so for example a fully opaque red pixel in ARGB_8888 format is 0xFFFF0000.

    Note:

    The pixel format is independent of endianness. That is, in the above example you can always get the red component with

    (pixel & 0x00ff0000) >> 16

    But you can not rely on this code:

    *(pixel + 2)

    It will return the red component on little endian systems, but the green component on big endian systems.

    Also note that Allegro's naming is different from OpenGL naming here, where a format of GL_RGBA8 merely defines the component order and the exact layout including endianness treatment is specified separately. Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on little endian systems, so care must be taken (note the reversal of RGBA <-> ABGR).

    The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will always have the components as 4 bytes corresponding to red, green, blue and alpha, in this order, independent of the endianness.

    • ALLEGRO_PIXEL_FORMAT_ANY - Let the driver choose a format. This is the default format at program start.
    • ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format without alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - Let the driver choose a format with alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - Let the driver choose a 15 bit format without alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - Let the driver choose a 16 bit format without alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - Let the driver choose a 16 bit format with alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - Let the driver choose a 24 bit format without alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - Let the driver choose a 32 bit format without alpha.
    • ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - Let the driver choose a 32 bit format with alpha.
    • ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit
    • ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit
    • ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit
    • ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit
    • ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit
    • ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit
    • ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit
    • ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit
    • ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit
    • ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit
    • ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit
    • ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE - Like the version without _LE, but the component order is guaranteed to be red, green, blue, alpha. This only makes a difference on big endian systems, on little endian it is just an alias.
    • ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit

    See also: al_set_new_bitmap_format, al_get_bitmap_format

    al_get_pixel_size

    int al_get_pixel_size(int format)

    Return the number of bytes that a pixel of the given format occupies.

    See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_format_bits

    al_get_pixel_format_bits

    int al_get_pixel_format_bits(int format)

    Return the number of bits that a pixel of the given format occupies.

    See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_size

    al_lock_bitmap

    ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap,
       int format, int flags)

    Lock an entire bitmap for reading or writing. If the bitmap is a display bitmap it will be updated from system memory after the bitmap is unlocked (unless locked read only). Returns NULL if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked.

    Flags are:

    • ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card.

    • ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. This can be faster if the bitmap is a video texture, as no data need to be read from the video card. You are required to fill in all pixels before unlocking the bitmap again, so be careful when using this flag.

    • ALLEGRO_LOCK_READWRITE - The locked region can be written to and read from. Use this flag if a partial number of pixels need to be written to, even if reading is not needed.

    'format' indicates the pixel format that the returned buffer will be in. To lock in the same format as the bitmap stores it's data internally, call with al_get_bitmap_format(bitmap) as the format or use ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster.

    Note: While a bitmap is locked, you can not use any drawing operations on it (with the sole exception of al_put_pixel and al_put_blended_pixel).

    See also: ALLEGRO_LOCKED_REGION, ALLEGRO_PIXEL_FORMAT, al_unlock_bitmap

    al_lock_bitmap_region

    ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap,
       int x, int y, int width, int height, int format, int flags)

    Like al_lock_bitmap, but only locks a specific area of the bitmap. If the bitmap is a display bitmap, only that area of the texture will be updated when it is unlocked. Locking only the region you indend to modify will be faster than locking the whole bitmap.

    See also: ALLEGRO_LOCKED_REGION, ALLEGRO_PIXEL_FORMAT, al_unlock_bitmap

    al_unlock_bitmap

    void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap)

    Unlock a previously locked bitmap or bitmap region. If the bitmap is a display bitmap, the texture will be updated to match the system memory copy (unless it was locked read only).

    See also: al_lock_bitmap, al_lock_bitmap_region

    Bitmap creation

    ALLEGRO_BITMAP

    typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP;

    Abstract type representing a bitmap (2D image).

    al_create_bitmap

    ALLEGRO_BITMAP *al_create_bitmap(int w, int h)

    Creates a new bitmap using the bitmap format and flags for the current thread. Blitting between bitmaps of differing formats, or blitting between memory bitmaps and display bitmaps may be slow.

    Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created for the current display. Blitting to another display may be slow.

    If a display bitmap is created, there may be limitations on the allowed dimensions. For example a DirectX or OpenGL backend usually has a maximum allowed texture size - so if bitmap creation fails for very large dimensions, you may want to re-try with a smaller bitmap. Some platforms also dictate a minimum texture size, which is relevant if you plan to use this bitmap with the primitives addon. If you try to create a bitmap smaller than this, this call will not fail but the returned bitmap will be a section of a larger bitmap with the minimum size. The minimum size that will work on all platforms is 32 by 32.

    Some platforms do not directly support display bitmaps whose dimensions are not powers of two. Allegro handles this by creating a larger bitmap that has dimensions that are powers of two and then returning a section of that bitmap with the dimensions you requested. This can be relevant if you plan to use this bitmap with the primitives addon but shouldn't be an issue otherwise.

    See also: al_set_new_bitmap_format, al_set_new_bitmap_flags, al_clone_bitmap, al_create_sub_bitmap, al_destroy_bitmap

    al_create_sub_bitmap

    ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent,
       int x, int y, int w, int h)

    Creates a sub-bitmap of the parent, at the specified coordinates and of the specified size. A sub-bitmap is a bitmap that shares drawing memory with a pre-existing (parent) bitmap, but possibly with a different size and clipping settings.

    The sub-bitmap may originate off or extend past the parent bitmap.

    See the discussion in al_get_backbuffer about using sub-bitmaps of the backbuffer.

    The parent bitmap's clipping rectangles are ignored.

    If a sub-bitmap was not or cannot be created then NULL is returned.

    Note that destroying parents of sub-bitmaps will not destroy the sub-bitmaps; instead the sub-bitmaps become invalid and should no longer be used.

    See also: al_create_bitmap

    al_clone_bitmap

    ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap)

    Create a new bitmap with al_create_bitmap, and copy the pixel data from the old bitmap across.

    See also: al_create_bitmap, al_set_new_bitmap_format, al_set_new_bitmap_flags

    al_destroy_bitmap

    void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap)

    Destroys the given bitmap, freeing all resources used by it. This function does nothing if the bitmap argument is NULL.

    As a convenience, if the calling thread is currently targets the bitmap then the bitmap will be untargeted first. The new target bitmap is unspecified. (since: 5.0.10, 5.1.6)

    Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) is the target bitmap of any thread.

    See also: al_create_bitmap

    al_get_new_bitmap_flags

    int al_get_new_bitmap_flags(void)

    Returns the flags used for newly created bitmaps.

    See also: al_set_new_bitmap_flags

    al_get_new_bitmap_format

    int al_get_new_bitmap_format(void)

    Returns the format used for newly created bitmaps.

    See also: ALLEGRO_PIXEL_FORMAT, al_set_new_bitmap_format

    al_set_new_bitmap_flags

    void al_set_new_bitmap_flags(int flags)

    Sets the flags to use for newly created bitmaps. Valid flags are:

    ALLEGRO_VIDEO_BITMAP

    Creates a bitmap that resides in the video card memory. These types of bitmaps receive the greatest benefit from hardware acceleration. al_set_new_bitmap_flags will implicitly set this flag unless ALLEGRO_MEMORY_BITMAP is present.

    ALLEGRO_MEMORY_BITMAP

    Create a bitmap residing in system memory. Operations on, and with, memory bitmaps will not be hardware accelerated. However, direct pixel access can be relatively quick compared to video bitmaps, which depend on the display driver in use.

    Note: Allegro's software rendering routines are currently very unoptimised.

    ALLEGRO_KEEP_BITMAP_FORMAT

    Only used when loading bitmaps from disk files, forces the resulting ALLEGRO_BITMAP to use the same format as the file.

    This is not yet honoured.

    ALLEGRO_FORCE_LOCKING

    When drawing to a bitmap with this flag set, always use pixel locking and draw to it using Allegro's software drawing primitives. This should never be used if you plan to draw to the bitmap using Allegro's graphics primitives as it would cause severe performance penalties. However if you know that the bitmap will only ever be accessed by locking it, no unneeded FBOs will be created for it in the OpenGL drivers.

    ALLEGRO_NO_PRESERVE_TEXTURE

    Normally, every effort is taken to preserve the contents of bitmaps, since Direct3D may forget them. This can take extra processing time. If you know it doesn't matter if a bitmap keeps its pixel data, for example its a temporary buffer, use this flag to tell Allegro not to attempt to preserve its contents. This can increase performance of your game or application, but there is a catch. See ALLEGRO_EVENT_DISPLAY_LOST for further information.

    ALLEGRO_ALPHA_TEST

    This is a driver hint only. It tells the graphics driver to do alpha testing instead of alpha blending on bitmaps created with this flag. Alpha testing is usually faster and preferred if your bitmaps have only one level of alpha (0). This flag is currently not widely implemented (i.e., only for memory bitmaps).

    ALLEGRO_MIN_LINEAR

    When drawing a scaled down version of the bitmap, use linear filtering. This usually looks better. You can also combine it with the MIPMAP flag for even better quality.

    ALLEGRO_MAG_LINEAR

    When drawing a magnified version of a bitmap, use linear filtering. This will cause the picture to get blurry instead of creating a big rectangle for each pixel. It depends on how you want things to look like whether you want to use this or not.

    ALLEGRO_MIPMAP

    This can only be used for bitmaps whose width and height is a power of two. In that case, it will generate mipmaps and use them when drawing scaled down versions. For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled down version of the original.

    ALLEGRO_NO_PREMULTIPLIED_ALPHA

    By default, Allegro pre-multiplies the alpha channel of an image with the images color data when it loads it. Typically that would look something like this:

    r = get_float_byte();
    g = get_float_byte();
    b = get_float_byte();
    a = get_float_byte();
    
    r = r * a;
    g = g * a;
    b = b * a;
    
    set_image_pixel(x, y, r, g, b, a);

    The reason for this can be seen in the Allegro example ex_premulalpha, ie, using pre-multiplied alpha gives more accurate color results in some cases. To use alpha blending with images loaded with pre-multiplied alpha, you would use the default blending mode, which is set with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA).

    The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that images are not loaded with alpha pre-multiplied, but are loaded with color values direct from the image. That looks like this:

    r = get_float_byte();
    g = get_float_byte();
    b = get_float_byte();
    a = get_float_byte();
    
    set_image_pixel(x, y, r, g, b, a);

    To draw such an image using regular alpha blending, you would use al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) to set the correct blender. This has some caveats. First, as mentioned above, drawing such an image can result in less accurate color blending (when drawing an image with linear filtering on, the edges will be darker than they should be). Second, the behaviour is somewhat confusing, which is explained in the example below.

    // Load and create bitmaps with an alpha channel
    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA);
    // Load some bitmap with alpha in it
    bmp = al_load_bitmap("some_alpha_bitmap.png");
    // We will draw to this buffer and then draw this buffer to the screen
    tmp_buffer = al_create_bitmap(SCREEN_W, SCREEN_H);
    // Set the buffer as the target and clear it
    al_set_target_bitmap(tmp_buffer);
    al_clear_to_color(al_map_rgba_f(0, 0, 0, 1));
    // Draw the bitmap to the temporary buffer
    al_draw_bitmap(bmp, 0, 0, 0);
    // Finally, draw the buffer to the screen
    // The output will look incorrect (may take close inspection
    // depending on the bitmap -- it may also be very obvious)
    al_set_target_bitmap(al_get_backbuffer(display));
    al_draw_bitmap(tmp_buffer, 0, 0, 0);

    To explain further, if you have a pixel with 0.5 alpha, and you're using (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, the formula is:

        a = da * dst + sa * src

    Expands to:

        result_a = dst_a * (1-0.5) + 0.5 * 0.5;

    So if you draw the image to the temporary buffer, it is blended once resulting in 0.75 alpha, then drawn again to the screen, blended in the same way, resulting in a pixel has 0.1875 as an alpha value.

    See also: al_get_new_bitmap_flags, al_get_bitmap_flags

    al_add_new_bitmap_flag

    void al_add_new_bitmap_flag(int flag)

    A convenience function which does the same as

    al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag);

    See also: al_set_new_bitmap_flags, al_get_new_bitmap_flags, al_get_bitmap_flags

    al_set_new_bitmap_format

    void al_set_new_bitmap_format(int format)

    Sets the pixel format for newly created bitmaps. The default format is 0 and means the display driver will choose the best format.

    See also: ALLEGRO_PIXEL_FORMAT, al_get_new_bitmap_format, al_get_bitmap_format

    Bitmap properties

    al_get_bitmap_flags

    int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap)

    Return the flags used to create the bitmap.

    See also: al_set_new_bitmap_flags

    al_get_bitmap_format

    int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap)

    Returns the pixel format of a bitmap.

    See also: ALLEGRO_PIXEL_FORMAT, al_set_new_bitmap_flags

    al_get_bitmap_height

    int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap)

    Returns the height of a bitmap in pixels.

    al_get_bitmap_width

    int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap)

    Returns the width of a bitmap in pixels.

    al_get_pixel

    ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y)

    Get a pixel's color value from the specified bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap.

    See also: ALLEGRO_COLOR, al_put_pixel, al_lock_bitmap

    al_is_bitmap_locked

    bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap)

    Returns whether or not a bitmap is already locked.

    See also: al_lock_bitmap, al_lock_bitmap_region, al_unlock_bitmap

    al_is_compatible_bitmap

    bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap)

    D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each ALLEGRO_BITMAP created with al_create_bitmap however is usually tied to a single ALLEGRO_DISPLAY. This function can be used to know if the bitmap is compatible with the given display, even if it is a different display to the one it was created with. It returns true if the bitmap is compatible (things like a cached texture version can be used) and false otherwise (blitting in the current display will be slow).

    The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both.

    Returns true if the bitmap is compatible with the current display, false otherwise. If there is no current display, false is returned.

    al_is_sub_bitmap

    bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap)

    Returns true if the specified bitmap is a sub-bitmap, false otherwise.

    See also: al_create_sub_bitmap, al_get_parent_bitmap

    al_get_parent_bitmap

    ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap)

    Returns the bitmap this bitmap is a sub-bitmap of. Returns NULL if this bitmap is not a sub-bitmap.

    Since: 5.0.6, 5.1.2

    See also: al_create_sub_bitmap, al_is_sub_bitmap

    Drawing operations

    All drawing operations draw to the current "target bitmap" of the current thread. Initially, the target bitmap will be the backbuffer of the last display created in a thread.

    al_clear_to_color

    void al_clear_to_color(ALLEGRO_COLOR color)

    Clear the complete target bitmap, but confined by the clipping rectangle.

    See also: ALLEGRO_COLOR, al_set_clipping_rectangle

    al_draw_bitmap

    void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)

    Draws an unscaled, unrotated bitmap at the given position to the current target bitmap (see al_set_target_bitmap).

    flags can be a combination of:

    • ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis
    • ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis

    Note: The current target bitmap must be a different bitmap. Drawing a bitmap to itself (or to a sub-bitmap of itself) or drawing a sub-bitmap to its parent (or another sub-bitmap of its parent) are not currently supported. To copy part of a bitmap into the same bitmap simply use a temporary bitmap instead.

    Note: The backbuffer (or a sub-bitmap thereof) can not be transformed, blended or tinted. If you need to draw the backbuffer draw it to a temporary bitmap first with no active transformation (except translation). Blending and tinting settings/parameters will be ignored. This does not apply when drawing into a memory bitmap.

    See also: al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap

    al_draw_tinted_bitmap

    void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
       float dx, float dy, int flags)

    Like al_draw_bitmap but multiplies all colors in the bitmap with the given color. For example:

    al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0);

    The above will draw the bitmap 50% transparently (r/g/b values need to be pre-multiplied with the alpha component with the default blend mode).

    al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0);

    The above will only draw the red component of the bitmap.

    See also: al_draw_bitmap

    al_draw_bitmap_region

    void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
       float sx, float sy, float sw, float sh, float dx, float dy, int flags)

    Draws a region of the given bitmap to the target bitmap.

    • sx - source x
    • sy - source y
    • sw - source width (width of region to blit)
    • sh - source height (height of region to blit)
    • dx - destination x
    • dy - destination y
    • flags - same as for al_draw_bitmap

    See also: al_draw_bitmap, al_draw_scaled_bitmap, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap

    al_draw_tinted_bitmap_region

    void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR tint,
       float sx, float sy, float sw, float sh, float dx, float dy,
       int flags)

    Like al_draw_bitmap_region but multiplies all colors in the bitmap with the given color.

    See also: al_draw_tinted_bitmap

    al_draw_pixel

    void al_draw_pixel(float x, float y, ALLEGRO_COLOR color)

    Draws a single pixel at x, y. This function, unlike al_put_pixel, does blending and, unlike al_put_blended_pixel, respects the transformations. This function can be slow if called often; if you need to draw a lot of pixels consider using al_draw_prim with ALLEGRO_PRIM_POINT_LIST from the primitives addon.

    • x - destination x
    • y - destination y
    • color - color of the pixel

    Note: This function may not draw exactly where you expect it to. See the pixel-precise output section on the primitives addon documentation for details on how to control exactly where the pixel is drawn.

    See also: ALLEGRO_COLOR, al_put_pixel

    al_draw_rotated_bitmap

    void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
       float cx, float cy, float dx, float dy, float angle, int flags)

    Draws a rotated version of the given bitmap to the target bitmap. The bitmap is rotated by 'angle' radians clockwise.

    The point at cx/cy relative to the upper left corner of the bitmap will be drawn at dx/dy and the bitmap is rotated around this point. If cx,cy is 0,0 the bitmap will rotate around its upper left corner.

    • cx - center x (relative to the bitmap)
    • cy - center y (relative to the bitmap)
    • dx - destination x
    • dy - destination y
    • angle - angle by which to rotate (radians)
    • flags - same as for al_draw_bitmap

    Example

    float w = al_get_bitmap_width(bitmap);
    float h = al_get_bitmap_height(bitmap);
    al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0);

    The above code draws the bitmap centered on x/y and rotates it 90° clockwise.

    See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_scaled_rotated_bitmap

    al_draw_tinted_rotated_bitmap

    void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR tint,
       float cx, float cy, float dx, float dy, float angle, int flags)

    Like al_draw_rotated_bitmap but multiplies all colors in the bitmap with the given color.

    See also: al_draw_tinted_bitmap

    al_draw_scaled_rotated_bitmap

    void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
       float cx, float cy, float dx, float dy, float xscale, float yscale,
       float angle, int flags)

    Like al_draw_rotated_bitmap, but can also scale the bitmap.

    The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap is rotated and scaled around this point.

    • cx - center x
    • cy - center y
    • dx - destination x
    • dy - destination y
    • xscale - how much to scale on the x-axis (e.g. 2 for twice the size)
    • yscale - how much to scale on the y-axis
    • angle - angle by which to rotate (radians)
    • flags - same as for al_draw_bitmap

    See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_rotated_bitmap

    al_draw_tinted_scaled_rotated_bitmap

    void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR tint,
       float cx, float cy, float dx, float dy, float xscale, float yscale,
       float angle, int flags)

    Like al_draw_scaled_rotated_bitmap but multiplies all colors in the bitmap with the given color.

    See also: al_draw_tinted_bitmap

    al_draw_tinted_scaled_rotated_bitmap_region

    void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap,
       float sx, float sy, float sw, float sh,
       ALLEGRO_COLOR tint,
       float cx, float cy, float dx, float dy, float xscale, float yscale,
       float angle, int flags)

    Like al_draw_tinted_scaled_rotated_bitmap but you specify an area within the bitmap to be drawn.

    You can get the same effect with a sub bitmap:

    al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint,
        cx, cy, dx, dy, xscale, yscale, angle, flags);
    
    /* This draws the same: */
    sub_bitmap = al_create_sub_bitmap(bitmap, sx, sy, sw, sh);
    al_draw_tinted_scaled_rotated_bitmap(sub_bitmap, tint, cx, cy,
        dx, dy, xscale, yscale, angle, flags);

    Since: 5.0.6, 5.1.0

    See also: al_draw_tinted_bitmap

    al_draw_scaled_bitmap

    void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
       float sx, float sy, float sw, float sh,
       float dx, float dy, float dw, float dh, int flags)

    Draws a scaled version of the given bitmap to the target bitmap.

    • sx - source x
    • sy - source y
    • sw - source width
    • sh - source height
    • dx - destination x
    • dy - destination y
    • dw - destination width
    • dh - destination height
    • flags - same as for al_draw_bitmap

    See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap,

    al_draw_tinted_scaled_bitmap

    void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR tint,
       float sx, float sy, float sw, float sh,
       float dx, float dy, float dw, float dh, int flags)

    Like al_draw_scaled_bitmap but multiplies all colors in the bitmap with the given color.

    See also: al_draw_tinted_bitmap

    al_get_target_bitmap

    ALLEGRO_BITMAP *al_get_target_bitmap(void)

    Return the target bitmap of the calling thread.

    See also: al_set_target_bitmap

    al_put_pixel

    void al_put_pixel(int x, int y, ALLEGRO_COLOR color)

    Draw a single pixel on the target bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. This function is not affected by the transformations or the color blenders.

    See also: ALLEGRO_COLOR, al_get_pixel, al_put_blended_pixel, al_lock_bitmap

    al_put_blended_pixel

    void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color)

    Like al_put_pixel, but the pixel color is blended using the current blenders before being drawn.

    See also: ALLEGRO_COLOR, al_put_pixel

    al_set_target_bitmap

    void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap)

    This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using al_get_backbuffer. As a convenience, you may also use al_set_target_backbuffer.

    Each video bitmap is tied to a display. When a video bitmap is set to as the target bitmap, the display that the bitmap belongs to is automatically made "current" for the calling thread (if it is not current already). Then drawing other bitmaps which are tied to the same display can be hardware accelerated.

    A single display cannot be current for multiple threads simultaneously. If you need to release a display, so it is not current for the calling thread, call al_set_target_bitmap(NULL);

    Setting a memory bitmap as the target bitmap will not change which display is current for the calling thread.

    OpenGL note:

    Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is very fast. When using an OpenGL display, if all of the following conditions are met an FBO will be created for use with the bitmap:

    • The GL_EXT_framebuffer_object OpenGL extension is available.
    • The bitmap is not a memory bitmap.
    • The bitmap is not currently locked.

    In Allegro 5.0.0, you had to be careful as an FBO would be kept around until the bitmap is destroyed or you explicitly called al_remove_opengl_fbo on the bitmap, wasting resources. In newer versions, FBOs will be freed automatically when the bitmap is no longer the target bitmap, unless you have called al_get_opengl_fbo to retrieve the FBO id.

    In the following example, no FBO will be created:

    lock = al_lock_bitmap(bitmap);
    al_set_target_bitmap(bitmap);
    al_put_pixel(x, y, color);
    al_unlock_bitmap(bitmap);

    The above allows using al_put_pixel on a locked bitmap without creating an FBO.

    In this example an FBO is created however:

    al_set_target_bitmap(bitmap);
    al_draw_line(x1, y1, x2, y2, color, 0);

    An OpenGL command will be used to directly draw the line into the bitmap's associated texture.

    See also: al_get_target_bitmap, al_set_target_backbuffer

    al_set_target_backbuffer

    void al_set_target_backbuffer(ALLEGRO_DISPLAY *display)

    Same as al_set_target_bitmap(al_get_backbuffer(display));

    See also: al_set_target_bitmap, al_get_backbuffer

    al_get_current_display

    ALLEGRO_DISPLAY *al_get_current_display(void)

    Return the display that is "current" for the calling thread, or NULL if there is none.

    See also: al_set_target_bitmap

    Blending modes

    al_get_blender

    void al_get_blender(int *op, int *src, int *dst)

    Returns the active blender for the current thread. You can pass NULL for values you are not interested in.

    See also: al_set_blender, al_get_separate_blender

    al_get_separate_blender

    void al_get_separate_blender(int *op, int *src, int *dst,
       int *alpha_op, int *alpha_src, int *alpha_dst)

    Returns the active blender for the current thread. You can pass NULL for values you are not interested in.

    See also: al_set_separate_blender, al_get_blender

    al_set_blender

    void al_set_blender(int op, int src, int dst)

    Sets the function to use for blending for the current thread.

    Blending means, the source and destination colors are combined in drawing operations.

    Assume the source color (e.g. color of a rectangle to draw, or pixel of a bitmap to draw) is given as its red/green/blue/alpha components (if the bitmap has no alpha it always is assumed to be fully opaque, so 255 for 8-bit or 1.0 for floating point): sr, sg, sb, sa. And this color is drawn to a destination, which already has a color: dr, dg, db, da.

    The conceptional formula used by Allegro to draw any pixel then depends on the op parameter:

    • ALLEGRO_ADD

       r = dr * dst + sr * src
       g = dg * dst + sg * src
       b = db * dst + sb * src
       a = da * dst + sa * src
    • ALLEGRO_DEST_MINUS_SRC

       r = dr * dst - sr * src
       g = dg * dst - sg * src
       b = db * dst - sb * src
       a = da * dst - sa * src
    • ALLEGRO_SRC_MINUS_DEST

       r = sr * src - dr * dst
       g = sg * src - dg * dst
       b = sb * src - db * dst
       a = sa * src - da * dst

    Valid values for src and dst passed to this function are

    • ALLEGRO_ZERO

       src = 0
       dst = 0
    • ALLEGRO_ONE

       src = 1
       dst = 1
    • ALLEGRO_ALPHA

       src = sa
       dst = sa
    • ALLEGRO_INVERSE_ALPHA

       src = 1 - sa
       dst = 1 - sa
    • ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0)

       f = s.r, s.g, s.b, s.a
    • ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8)

       f = d.r, d.g, d.b, d.a
    • ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0)

       f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a
    • ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8)

       f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a

    Blending examples:

    So for example, to restore the default of using premultiplied alpha blending, you would use (pseudo code)

    al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA)

    If you are using non-pre-multiplied alpha, you could use

    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA)

    Additive blending would be achieved with

    al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE)

    Copying the source to the destination (including alpha) unmodified

    al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO)

    Multiplying source and destination components

    al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO)

    See also: al_set_separate_blender, al_get_blender

    al_set_separate_blender

    void al_set_separate_blender(int op, int src, int dst,
       int alpha_op, int alpha_src, int alpha_dst)

    Like al_set_blender, but allows specifying a separate blending operation for the alpha channel. This is useful if your target bitmap also has an alpha channel and the two alpha channels need to be combined in a different way than the color components.

    See also: al_set_blender, al_get_blender, al_get_separate_blender

    Clipping

    al_get_clipping_rectangle

    void al_get_clipping_rectangle(int *x, int *y, int *w, int *h)

    Gets the clipping rectangle of the target bitmap.

    See also: al_set_clipping_rectangle

    al_set_clipping_rectangle

    void al_set_clipping_rectangle(int x, int y, int width, int height)

    Set the region of the target bitmap or display that pixels get clipped to. The default is to clip pixels to the entire bitmap.

    See also: al_get_clipping_rectangle, al_reset_clipping_rectangle

    al_reset_clipping_rectangle

    void al_reset_clipping_rectangle(void)

    Equivalent to calling `al_set_clipping_rectangle(0, 0, w, h)' where w and h are the width and height of the target bitmap respectively.

    Does nothing if there is no target bitmap.

    See also: al_set_clipping_rectangle

    Since: 5.0.6, 5.1.0

    Graphics utility functions

    al_convert_mask_to_alpha

    void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)

    Convert the given mask color to an alpha channel in the bitmap. Can be used to convert older 4.2-style bitmaps with magic pink to alpha-ready bitmaps.

    See also: ALLEGRO_COLOR

    Deferred drawing

    al_hold_bitmap_drawing

    void al_hold_bitmap_drawing(bool hold)

    Enables or disables deferred bitmap drawing. This allows for efficient drawing of many bitmaps that share a parent bitmap, such as sub-bitmaps from a tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls such that the parent bitmap is the same for large number of those calls. While deferred bitmap drawing is enabled, the only functions that can be used are the bitmap drawing functions and font drawing functions. Changing the state such as the blending modes will result in undefined behaviour. One exception to this rule are the transformations. It is possible to set a new transformation while the drawing is held.

    No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function's usage is to enable the deferred bitmap drawing, draw as many bitmaps as possible, taking care to stagger bitmaps that share parent bitmaps, and then disable deferred drawing. As mentioned above, this function also works with bitmap and truetype fonts, so if multiple lines of text need to be drawn, this function can speed things up.

    See also: al_is_bitmap_drawing_held

    al_is_bitmap_drawing_held

    bool al_is_bitmap_drawing_held(void)

    Returns whether the deferred bitmap drawing mode is turned on or off.

    See also: al_hold_bitmap_drawing

    Image I/O

    al_register_bitmap_loader

    bool al_register_bitmap_loader(const char *extension,
       ALLEGRO_BITMAP *(*loader)(const char *filename))

    Register a handler for al_load_bitmap. The given function will be used to handle the loading of bitmaps files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_bitmap_saver, al_register_bitmap_loader_f

    al_register_bitmap_saver

    bool al_register_bitmap_saver(const char *extension,
       bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp))

    Register a handler for al_save_bitmap. The given function will be used to handle the loading of bitmaps files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The saver argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_bitmap_loader, al_register_bitmap_saver_f

    al_register_bitmap_loader_f

    bool al_register_bitmap_loader_f(const char *extension,
       ALLEGRO_BITMAP *(*loader_f)(ALLEGRO_FILE *fp))

    Register a handler for al_load_bitmap_f. The given function will be used to handle the loading of bitmaps files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The fs_loader argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_bitmap_loader

    al_register_bitmap_saver_f

    bool al_register_bitmap_saver_f(const char *extension,
       bool (*saver_f)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp))

    Register a handler for al_save_bitmap_f. The given function will be used to handle the loading of bitmaps files with the given extension.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The saver_f argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_register_bitmap_saver

    al_load_bitmap

    ALLEGRO_BITMAP *al_load_bitmap(const char *filename)

    Loads an image file into an ALLEGRO_BITMAP. The file type is determined by the extension.

    Returns NULL on error.

    Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

    See also: al_load_bitmap_f, al_register_bitmap_loader, al_set_new_bitmap_format, al_set_new_bitmap_flags, al_init_image_addon

    al_load_bitmap_f

    ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident)

    Loads an image from an ALLEGRO_FILE stream into an ALLEGRO_BITMAP. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot.

    Returns NULL on error. The file remains open afterwards.

    Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

    See also: al_load_bitmap, al_register_bitmap_loader_f, al_init_image_addon

    al_save_bitmap

    bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap)

    Saves an ALLEGRO_BITMAP to an image file. The file type is determined by the extension.

    Returns true on success, false on error.

    Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

    See also: al_save_bitmap_f, al_register_bitmap_saver, al_init_image_addon

    al_save_bitmap_f

    bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident,
       ALLEGRO_BITMAP *bitmap)

    Saves an ALLEGRO_BITMAP to an ALLEGRO_FILE stream. The file type is determined by the passed 'ident' parameter, which is a file name extension including the leading dot.

    Returns true on success, false on error. The file remains open afterwards.

    Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

    See also: al_save_bitmap, al_register_bitmap_saver_f, al_init_image_addon

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/physfs.html0000644000175000001440000001356512157230677020000 0ustar tjadenusers PhysicsFS integration

    PhysicsFS is a library to provide abstract access to various archives. See http://icculus.org/physfs/ for more information.

    This addon makes it possible to read and write files (on disk or inside archives) using PhysicsFS, through Allegro's file I/O API. For example, that means you can use the Image I/O addon to load images from .zip files.

    You must set up PhysicsFS through its own API. When you want to open an ALLEGRO_FILE using PhysicsFS, first call al_set_physfs_file_interface, then al_fopen or another function that calls al_fopen.

    These functions are declared in the following header file. Link with allegro_physfs.

    #include <allegro5/allegro_physfs.h>

    al_set_physfs_file_interface

    void al_set_physfs_file_interface(void)

    After calling this, subsequent calls to al_fopen will be handled by PHYSFS_open(). Operations on the files returned by al_fopen will then be performed through PhysicsFS.

    At the same time, all filesystem functions like al_read_directory or al_create_fs_entry will use PhysicsFS.

    This functions only affects the thread it was called from.

    To remember and restore another file I/O backend, you can use al_store_state/al_restore_state.

    See also: al_set_new_file_interface.

    al_get_allegro_physfs_version

    uint32_t al_get_allegro_physfs_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:14 UTC

    allegro-5.0.10/docs/html/refman/font.html0000644000175000001440000006557312157230675017436 0ustar tjadenusers Font addons

    These functions are declared in the following header file. Link with allegro_font.

    #include <allegro5/allegro_font.h>

    General font routines

    ALLEGRO_FONT

    typedef struct ALLEGRO_FONT ALLEGRO_FONT;

    A handle identifying any kind of font. Usually you will create it with al_load_font which supports loading all kinds of TrueType fonts supported by the FreeType library. If you instead pass the filename of a bitmap file, it will be loaded with al_load_bitmap and a font in Allegro's bitmap font format will be created from it with al_grab_font_from_bitmap.

    al_init_font_addon

    void al_init_font_addon(void)

    Initialise the font addon.

    Note that if you intend to load bitmap fonts, you will need to initialise allegro_image separately (unless you are using another library to load images).

    See also: al_init_image_addon, al_init_ttf_addon, al_shutdown_font_addon

    al_shutdown_font_addon

    void al_shutdown_font_addon(void)

    Shut down the font addon. This is done automatically at program exit, but can be called any time the user wishes as well.

    See also: al_init_font_addon

    al_load_font

    ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags)

    Loads a font from disk. This will use al_load_bitmap_font if you pass the name of a known bitmap format, or else al_load_ttf_font.

    Bitmap and TTF fonts are affected by the current bitmap flags at the time the font is loaded.

    See also: al_destroy_font, al_init_font_addon, al_register_font_loader

    al_destroy_font

    void al_destroy_font(ALLEGRO_FONT *f)

    Frees the memory being used by a font structure. Does nothing if passed NULL.

    See also: al_load_font

    al_register_font_loader

    bool al_register_font_loader(char const *extension,
       ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags))

    Informs Allegro of a new font file type, telling it how to load files of this format.

    The extension should include the leading dot ('.') character. It will be matched case-insensitively.

    The load_font argument may be NULL to unregister an entry.

    Returns true on success, false on error. Returns false if unregistering an entry that doesn't exist.

    See also: al_init_font_addon

    al_get_font_line_height

    int al_get_font_line_height(const ALLEGRO_FONT *f)

    Returns the usual height of a line of text in the specified font. For bitmap fonts this is simply the height of all glyph bitmaps. For truetype fonts it is whatever the font file specifies. In particular, some special glyphs may be higher than the height returned here.

    If the X is the position you specify to draw text, the meaning of ascent and descent and the line height is like in the figure below.

    X------------------------
        /\         |        |
       /  \        |        |
      /____\       ascent   |
     /      \      |        |
    /        \     |        height
    ----------------        |
                   |        |
                   descent  |
                   |        |
    -------------------------

    See also: al_get_text_width, al_get_text_dimensions

    al_get_font_ascent

    int al_get_font_ascent(const ALLEGRO_FONT *f)

    Returns the ascent of the specified font.

    See also: al_get_font_descent, al_get_font_line_height

    al_get_font_descent

    int al_get_font_descent(const ALLEGRO_FONT *f)

    Returns the descent of the specified font.

    See also: al_get_font_ascent, al_get_font_line_height

    al_get_text_width

    int al_get_text_width(const ALLEGRO_FONT *f, const char *str)

    Calculates the length of a string in a particular font, in pixels.

    See also: al_get_ustr_width, al_get_font_line_height, al_get_text_dimensions

    al_get_ustr_width

    int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr)

    Like al_get_text_width but expects an ALLEGRO_USTR.

    See also: al_get_text_width, al_get_ustr_dimensions

    al_draw_text

    void al_draw_text(const ALLEGRO_FONT *font,
       ALLEGRO_COLOR color, float x, float y, int flags,
       char const *text) 

    Writes the NUL-terminated string text onto the target bitmap at position x, y, using the specified font.

    The flags parameter can be 0 or one of the following flags:

    • ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0).
    • ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given position.
    • ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given position.

    It can also be combined with this flag:

    • ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer pixel position. This is formerly the default behaviour. Since: 5.0.8, 5.1.4

    See also: al_draw_ustr, al_draw_textf, al_draw_justified_text

    al_draw_ustr

    void al_draw_ustr(const ALLEGRO_FONT *font,
       ALLEGRO_COLOR color, float x, float y, int flags,
       const ALLEGRO_USTR *ustr) 

    Like al_draw_text, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

    See also: al_draw_text, al_draw_justified_ustr

    al_draw_justified_text

    void al_draw_justified_text(const ALLEGRO_FONT *font,
       ALLEGRO_COLOR color, float x1, float x2,
       float y, float diff, int flags, const char *text)

    Like al_draw_text, but justifies the string to the region x1-x2.

    The diff parameter is the maximum amount of horizontal space to allow between words. If justisfying the text would exceed diff pixels, or the string contains less than two words, then the string will be drawn left aligned.

    The flags parameter can be 0 or one of the following flags:

    • ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel positions. Since: 5.0.8, 5.1.5

    See also: al_draw_justified_textf, al_draw_justified_ustr

    al_draw_justified_ustr

    void al_draw_justified_ustr(const ALLEGRO_FONT *font,
       ALLEGRO_COLOR color, float x1, float x2,
       float y, float diff, int flags, const ALLEGRO_USTR *ustr)

    Like al_draw_justified_text, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

    See also: al_draw_justified_text, al_draw_justified_textf.

    al_draw_textf

    void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color,
       float x, float y, int flags,
       const char *format, ...)

    Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_text otherwise.

    See also: al_draw_text, al_draw_ustr

    al_draw_justified_textf

    void al_draw_justified_textf(const ALLEGRO_FONT *f,
       ALLEGRO_COLOR color, float x1, float x2, float y,
       float diff, int flags, const char *format, ...)

    Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_justified_text otherwise.

    See also: al_draw_justified_text, al_draw_justified_ustr.

    al_get_text_dimensions

    void al_get_text_dimensions(const ALLEGRO_FONT *f,
       char const *text,
       int *bbx, int *bby, int *bbw, int *bbh)

    Sometimes, the al_get_text_width and al_get_font_line_height functions are not enough for exact text placement, so this function returns some additional information.

    Returned variables (all in pixel):

    • x, y - Offset to upper left corner of bounding box.
    • w, h - Dimensions of bounding box.

    Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values.

    See also: al_get_text_width, al_get_font_line_height, al_get_ustr_dimensions

    al_get_ustr_dimensions

    void al_get_ustr_dimensions(const ALLEGRO_FONT *f,
       ALLEGRO_USTR const *ustr,
       int *bbx, int *bby, int *bbw, int *bbh)

    Sometimes, the al_get_ustr_width and al_get_font_line_height functions are not enough for exact text placement, so this function returns some additional information.

    See also: al_get_text_dimensions

    al_get_allegro_font_version

    uint32_t al_get_allegro_font_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Bitmap fonts

    al_grab_font_from_bitmap

    ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp,
       int ranges_n, const int ranges[])

    Creates a new font from an Allegro bitmap. You can delete the bitmap after the function returns as the font will contain a copy for itself.

    Parameters:

    • bmp: The bitmap with the glyphs drawn onto it
    • n: Number of unicode ranges in the bitmap.
    • ranges: 'n' pairs of first and last unicode point to map glyphs to for each range.

    The bitmap format is as in the following example, which contains three glyphs for 1, 2 and 3.

    .............
    . 1 .222.333.
    . 1 .  2.  3.
    . 1 .222.333.
    . 1 .2  .  3.
    . 1 .222.333.
    .............

    In the above illustration, the dot is for pixels having the background color. It is determined by the color of the top left pixel in the bitmap. There should be a border of at least 1 pixel with this color to the bitmap edge and between all glyphs.

    Each glyph is inside a rectangle of pixels not containing the background color. The height of all glyph rectangles should be the same, but the width can vary.

    The placement of the rectangles does not matter, except that glyphs are scanned from left to right and top to bottom to match them to the specified unicode codepoints.

    The glyphs will simply be drawn using al_draw_bitmap, so usually you will want the rectangles filled with full transparency and the glyphs drawn in opaque white.

    Examples:

    int ranges[] = {32, 126};
    al_grab_font_from_bitmap(bitmap, 1, ranges)
    
    int ranges[] = {
        0x0020, 0x007F,  /* ASCII */
        0x00A1, 0x00FF,  /* Latin 1 */
        0x0100, 0x017F,  /* Extended-A */
        0x20AC, 0x20AC}; /* Euro */
    al_grab_font_from_bitmap(bitmap, 4, ranges)

    The first example will grab glyphs for the 95 standard printable ASCII characters, beginning with the space character (32) and ending with the tilde character (126). The second example will map the first 96 glyphs found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to Extended-A, and the last glyph to the Euro character. (This is just the characters found in the Allegro 4 font.)

    See also: al_load_bitmap, al_grab_font_from_bitmap

    al_load_bitmap_font

    ALLEGRO_FONT *al_load_bitmap_font(const char *fname)

    Load a bitmap font from. It does this by first calling al_load_bitmap and then al_grab_font_from_bitmap. If you want to for example load an old A4 font, you could load the bitmap yourself, then call al_convert_mask_to_alpha on it and only then pass it to al_grab_font_from_bitmap.

    al_create_builtin_font

    ALLEGRO_FONT *al_create_builtin_font(void)

    Creates a monochrome bitmap font (8x8 pixels per character).

    This font is primarily intended to be used for displaying information in environments or during early runtime states where no external font data is available or loaded (e.g. for debugging).

    The builtin font contains the following unicode character ranges:

    0x0020 to 0x007F (ASCII)
    0x00A1 to 0x00FF (Latin 1)
    0x0100 to 0x017F (Extended A)
    0x20AC to 0x20AC (euro currency symbol)

    Returns NULL on an error.

    The font memory must be freed the same way as for any other font, using al_destroy_font.

    Since: 5.0.8, 5.1.3

    See also: al_load_bitmap_font, al_destroy_font

    TTF fonts

    These functions are declared in the following header file. Link with allegro_ttf.

    #include <allegro5/allegro_ttf.h>

    al_init_ttf_addon

    bool al_init_ttf_addon(void)

    Call this after al_init_font_addon to make al_load_font recognize ".ttf" and other formats supported by al_load_ttf_font.

    Returns true on success, false on failure.

    al_shutdown_ttf_addon

    void al_shutdown_ttf_addon(void)

    Unloads the ttf addon again. You normally don't need to call this.

    al_load_ttf_font

    ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags)

    Loads a TrueType font from a file using the FreeType library. Quoting from the FreeType FAQ this means support for many different font formats:

    TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and others

    The size parameter determines the size the font will be rendered at, specified in pixels. The standard font size is measured in units per EM, if you instead want to specify the size as the total height of glyphs in pixels, pass it as a negative value.

    Note: If you want to display text at multiple sizes, load the font multiple times with different size parameters.

    The following flags are supported:

    • ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font file supports it.

    • ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no anti-aliasing of the font is done).

    • ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled by default in newer versions of FreeType. Since: 5.0.6, 5.1.2

    See also: al_init_ttf_addon, al_load_ttf_font_f

    al_load_ttf_font_f

    ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file,
        char const *filename, int size, int flags)

    Like al_load_ttf_font, but the font is read from the file handle. The filename is only used to find possible additional files next to a font file.

    Note: The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.

    al_load_ttf_font_stretch

    ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h,
        int flags)

    Like al_load_ttf_font, except it takes separate width and height parameters instead of a single size parameter.

    If the height is a positive value, and the width zero or positive, then font will be stretched according to those parameters. The width must not be negative if the height is positive.

    As with al_load_ttf_font, the height may be a negative value to specify the total height in pixels. Then the width must also be a negative value, or zero.

    The behaviour is undefined the height is positive while width is negative, or if the height is negative while the width is positive.

    Since: 5.0.6, 5.1.0

    See also: al_load_ttf_font, al_load_ttf_font_stretch_f

    al_load_ttf_font_stretch_f

    ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file,
        char const *filename, int w, int h, int flags)

    Like al_load_ttf_font_stretch, but the font is read from the file handle. The filename is only used to find possible additional files next to a font file.

    Note: The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.

    Since: 5.0.6, 5.1.0

    See also: al_load_ttf_font_stretch

    al_get_allegro_ttf_version

    uint32_t al_get_allegro_ttf_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:13 UTC

    allegro-5.0.10/docs/html/refman/mouse.html0000644000175000001440000004173212157230673017605 0ustar tjadenusers Mouse routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_MOUSE_STATE

    typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE;

    Public fields (read only):

    • x - mouse x position
    • y - mouse y position
    • w, z - mouse wheel position (2D 'ball')
    • buttons - mouse buttons bitfield

    The zeroth bit is set if the primary mouse button is held down, the first bit is set if the secondary mouse button is held down, and so on.

    See also: al_get_mouse_state, al_get_mouse_state_axis, al_mouse_button_down

    al_install_mouse

    bool al_install_mouse(void)

    Install a mouse driver.

    Returns true if successful. If a driver was already installed, nothing happens and true is returned.

    al_is_mouse_installed

    bool al_is_mouse_installed(void)

    Returns true if al_install_mouse was called successfully.

    al_uninstall_mouse

    void al_uninstall_mouse(void)

    Uninstalls the active mouse driver, if any. This will automatically unregister the mouse event source with any event queues.

    This function is automatically called when Allegro is shut down.

    al_get_mouse_num_axes

    unsigned int al_get_mouse_num_axes(void)

    Return the number of buttons on the mouse. The first axis is 0.

    See also: al_get_mouse_num_buttons

    al_get_mouse_num_buttons

    unsigned int al_get_mouse_num_buttons(void)

    Return the number of buttons on the mouse. The first button is 1.

    See also: al_get_mouse_num_axes

    al_get_mouse_state

    void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state)

    Save the state of the mouse specified at the time the function is called into the given structure.

    Example:

    ALLEGRO_MOUSE_STATE state;
    
    al_get_mouse_state(&state);
    if (state.buttons & 1) {
        /* Primary (e.g. left) mouse button is held. */
        printf("Mouse position: (%d, %d)\n", state.x, state.y);
    }
    if (state.buttons & 2) {
        /* Secondary (e.g. right) mouse button is held. */
    }
    if (state.buttons & 4) {
        /* Tertiary (e.g. middle) mouse button is held. */
    }

    See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state_axis, al_mouse_button_down

    al_get_mouse_state_axis

    int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis)

    Extract the mouse axis value from the saved state. The axes are numbered from 0, in this order: x-axis, y-axis, z-axis, w-axis.

    See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state, al_mouse_button_down

    al_mouse_button_down

    bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button)

    Return true if the mouse button specified was held down in the state specified. Unlike most things, the first mouse button is numbered 1.

    See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state, al_get_mouse_state_axis

    al_set_mouse_xy

    bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y)

    Try to position the mouse at the given coordinates on the given display. The mouse movement resulting from a successful move will generate an ALLEGRO_EVENT_MOUSE_WARPED event.

    Returns true on success, false on failure.

    See also: al_set_mouse_z, al_set_mouse_w

    al_set_mouse_z

    bool al_set_mouse_z(int z)

    Set the mouse wheel position to the given value.

    Returns true on success, false on failure.

    See also: al_set_mouse_w

    al_set_mouse_w

    bool al_set_mouse_w(int w)

    Set the second mouse wheel position to the given value.

    Returns true on success, false on failure.

    See also: al_set_mouse_z

    al_set_mouse_axis

    bool al_set_mouse_axis(int which, int value)

    Set the given mouse axis to the given value.

    The axis number must not be 0 or 1, which are the X and Y axes. Use al_set_mouse_xy for that.

    Returns true on success, false on failure.

    See also: al_set_mouse_xy, al_set_mouse_z, al_set_mouse_w

    al_get_mouse_event_source

    ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void)

    Retrieve the mouse event source.

    Returns NULL if the mouse subsystem was not installed.

    Mouse cursors

    al_create_mouse_cursor

    ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp,
       int x_focus, int y_focus)

    Create a mouse cursor from the bitmap provided.

    Returns a pointer to the cursor on success, or NULL on failure.

    See also: al_set_mouse_cursor, al_destroy_mouse_cursor

    al_destroy_mouse_cursor

    void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor)

    Free the memory used by the given cursor.

    Has no effect if cursor is NULL.

    See also: al_create_mouse_cursor

    al_set_mouse_cursor

    bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor)

    Set the given mouse cursor to be the current mouse cursor for the given display.

    If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible.

    Returns true on success, false on failure.

    See also: al_set_system_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor

    al_set_system_mouse_cursor

    bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display,
       ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)

    Set the given system mouse cursor to be the current mouse cursor for the given display. If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible.

    If the cursor doesn't exist on the current platform another cursor will be silently be substituted.

    The cursors are:

    • ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT
    • ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE

    Returns true on success, false on failure.

    See also: al_set_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor

    al_get_mouse_cursor_position

    bool al_get_mouse_cursor_position(int *ret_x, int *ret_y)

    On platforms where this information is available, this function returns the global location of the mouse cursor, relative to the desktop. You should not normally use this function, as the information is not useful except for special scenarios as moving a window.

    Returns true on success, false on failure.

    al_hide_mouse_cursor

    bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display)

    Hide the mouse cursor in the given display. This has no effect on what the current mouse cursor looks like; it just makes it disappear.

    Returns true on success (or if the cursor already was hidden), false otherwise.

    See also: al_show_mouse_cursor

    al_show_mouse_cursor

    bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display)

    Make a mouse cursor visible in the given display.

    Returns true if a mouse cursor is shown as a result of the call (or one already was visible), false otherwise.

    See also: al_hide_mouse_cursor

    al_grab_mouse

    bool al_grab_mouse(ALLEGRO_DISPLAY *display)

    Confine the mouse cursor to the given display. The mouse cursor can only be confined to one display at a time.

    Returns true if successful, otherwise returns false. Do not assume that the cursor will remain confined until you call al_ungrab_mouse. It may lose the confined status at any time for other reasons.

    Note: not yet implemented on Mac OS X.

    See also: al_ungrab_mouse

    al_ungrab_mouse

    bool al_ungrab_mouse(void)

    Stop confining the mouse cursor to any display belonging to the program.

    Note: not yet implemented on Mac OS X.

    See also: al_grab_mouse

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/memory.html0000644000175000001440000002330712157230672017762 0ustar tjadenusers Memory management routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    al_malloc

    #define al_malloc(n) \
       (al_malloc_with_context((n), __LINE__, __FILE__, __func__))

    Like malloc() in the C standard library, but the implementation may be overridden.

    This is a macro.

    See also: al_free, al_realloc, al_calloc, al_malloc_with_context, al_set_memory_interface

    al_free

    #define al_free(p) \
       (al_free_with_context((p), __LINE__, __FILE__, __func__))

    Like free() in the C standard library, but the implementation may be overridden.

    Additionally, on Windows, a memory block allocated by one DLL must be freed from the same DLL. In the few places where an Allegro function returns a pointer that must be freed, you must use al_free for portability to Windows.

    This is a macro.

    See also: al_malloc, al_free_with_context

    al_realloc

    #define al_realloc(p, n) \
       (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__))

    Like realloc() in the C standard library, but the implementation may be overridden.

    This is a macro.

    See also: al_malloc, al_realloc_with_context

    al_calloc

    #define al_calloc(c, n) \
       (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__))

    Like calloc() in the C standard library, but the implementation may be overridden.

    This is a macro.

    See also: al_malloc, al_calloc_with_context

    al_malloc_with_context

    void *al_malloc_with_context(size_t n,
       int line, const char *file, const char *func)

    This calls malloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

    Generally you should use the al_malloc macro.

    al_free_with_context

    void al_free_with_context(void *ptr,
       int line, const char *file, const char *func)

    This calls free() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface.

    Generally you should use the al_free macro.

    al_realloc_with_context

    void *al_realloc_with_context(void *ptr, size_t n,
       int line, const char *file, const char *func)

    This calls realloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

    Generally you should use the al_realloc macro.

    al_calloc_with_context

    void *al_calloc_with_context(size_t count, size_t n,
       int line, const char *file, const char *func)

    This calls calloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

    Generally you should use the al_calloc macro.

    ALLEGRO_MEMORY_INTERFACE

    typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE;

    This structure has the following fields.

    void *(*mi_malloc)(size_t n, int line, const char *file, const char *func);
    void (*mi_free)(void *ptr, int line, const char *file, const char *func);
    void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file,
                        const char *func);
    void *(*mi_calloc)(size_t count, size_t n, int line, const char *file,
                       const char *func);

    See also: al_set_memory_interface

    al_set_memory_interface

    void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface)

    Override the memory management functions with implementations of al_malloc_with_context, al_free_with_context, al_realloc_with_context and al_calloc_with_context. The context arguments may be used for debugging.

    If the pointer is NULL, the default behaviour will be restored.

    See also: ALLEGRO_MEMORY_INTERFACE

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:10 UTC

    allegro-5.0.10/docs/html/refman/monitor.html0000644000175000001440000001551412157230673020143 0ustar tjadenusers Monitors

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_MONITOR_INFO

    typedef struct ALLEGRO_MONITOR_INFO

    Describes a monitors size and position relative to other monitors. x1, y1 will be 0, 0 on the primary display. Other monitors can have negative values if they are to the left or above the primary display.

    typedef struct ALLEGRO_MONITOR_INFO
    {
       int x1;
       int y1;
       int x2;
       int y2;
    } ALLEGRO_MONITOR_INFO;

    See also: al_get_monitor_info

    al_get_new_display_adapter

    int al_get_new_display_adapter(void)

    Gets the video adapter index where new displays will be created by the calling thread, if previously set with al_set_new_display_adapter. Otherwise returns ALLEGRO_DEFAULT_DISPLAY_ADAPTER.

    See also: al_set_new_display_adapter

    al_set_new_display_adapter

    void al_set_new_display_adapter(int adapter)

    Sets the adapter to use for new displays created by the calling thread. The adapter has a monitor attached to it. Information about the monitor can be gotten using al_get_num_video_adapters and al_get_monitor_info.

    To return to the default behaviour, pass ALLEGRO_DEFAULT_DISPLAY_ADAPTER.

    See also: al_get_num_video_adapters, al_get_monitor_info

    al_get_monitor_info

    bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info)

    Get information about a monitor's position on the desktop. adapter is a number from 0 to al_get_num_video_adapters()-1.

    Returns true on success, false on failure.

    See also: ALLEGRO_MONITOR_INFO, al_get_num_video_adapters

    al_get_num_video_adapters

    int al_get_num_video_adapters(void)

    Get the number of video "adapters" attached to the computer. Each video card attached to the computer counts as one or more adapters. An adapter is thus really a video port that can have a monitor connected to it.

    See also: al_get_monitor_info

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:10 UTC

    allegro-5.0.10/docs/html/refman/fixed.html0000644000175000001440000005613412157230671017554 0ustar tjadenusers Fixed point math routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    al_fixed

    typedef int32_t al_fixed;

    A fixed point number.

    Allegro provides some routines for working with fixed point numbers, and defines the type al_fixed to be a signed 32-bit integer. The high word is used for the integer part and the low word for the fraction, giving a range of -32768 to 32767 and an accuracy of about four or five decimal places. Fixed point numbers can be assigned, compared, added, subtracted, negated and shifted (for multiplying or dividing by powers of two) using the normal integer operators, but you should take care to use the appropriate conversion routines when mixing fixed point with integer or floating point values. Writing fixed_point_1 + fixed_point_2 is OK, but fixed_point + integer is not.

    The only advantage of fixed point math routines is that you don't require a floating point coprocessor to use them. This was great in the time period of i386 and i486 machines, but stopped being so useful with the coming of the Pentium class of processors. From Pentium onwards, CPUs have increased their strength in floating point operations, equaling or even surpassing integer math performance.

    Depending on the type of operations your program may need, using floating point types may be faster than fixed types if you are targeting a specific machine class. Many embedded processors have no FPUs so fixed point maths can be useful there.

    al_itofix

    al_fixed al_itofix(int x);

    Converts an integer to fixed point. This is the same thing as x<<16. Remember that overflows (trying to convert an integer greater than 32767) and underflows (trying to convert an integer lesser than -32768) are not detected even in debug builds! The values simply "wrap around".

    Example:

        al_fixed number;
    
        /* This conversion is OK. */
        number = al_itofix(100);
        assert(al_fixtoi(number) == 100);
    
        number = al_itofix(64000);
    
        /* This check will fail in debug builds. */
        assert(al_fixtoi(number) == 64000);

    Return value: Returns the value of the integer converted to fixed point ignoring overflows.

    See also: al_fixtoi, al_ftofix, al_fixtof.

    al_fixtoi

    int al_fixtoi(al_fixed x);

    Converts fixed point to integer, rounding as required to the nearest integer.

    Example:

        int result;
    
        /* This will put 33 into `result'. */
        result = al_fixtoi(al_itofix(100) / 3);
    
        /* But this will round up to 17. */
        result = al_fixtoi(al_itofix(100) / 6);

    See also: al_itofix, al_ftofix, al_fixtof, al_fixfloor, al_fixceil.

    al_fixfloor

    int al_fixfloor(al_fixed x);

    Returns the greatest integer not greater than x. That is, it rounds towards negative infinity.

    Example:

        int result;
    
        /* This will put 33 into `result'. */
        result = al_fixfloor(al_itofix(100) / 3);
    
        /* And this will round down to 16. */
        result = al_fixfloor(al_itofix(100) / 6);

    See also: al_fixtoi, al_fixceil.

    al_fixceil

    int al_fixceil(al_fixed x);

    Returns the smallest integer not less than x. That is, it rounds towards positive infinity.

    Example:

        int result;
    
        /* This will put 34 into `result'. */
        result = al_fixceil(al_itofix(100) / 3);
    
        /* This will round up to 17. */
        result = al_fixceil(al_itofix(100) / 6);

    See also: al_fixtoi, al_fixfloor.

    al_ftofix

    al_fixed al_ftofix(double x);

    Converts a floating point value to fixed point. Unlike al_itofix, this function clamps values which could overflow the type conversion, setting Allegro's errno to ERANGE in the process if this happens.

    Example:

        al_fixed number;
    
        number = al_itofix(-40000);
        assert(al_fixfloor(number) == -32768);
    
        number = al_itofix(64000);
        assert(al_fixfloor(number) == 32767);
        assert(!al_get_errno()); /* This will fail. */

    Return value: Returns the value of the floating point value converted to fixed point clamping overflows (and setting Allegro's errno).

    See also: al_fixtof, al_itofix, al_fixtoi, al_get_errno

    al_fixtof

    double al_fixtof(al_fixed x);

    Converts fixed point to floating point.

    Example:

        float result;
    
        /* This will put 33.33333 into `result'. */
        result = al_fixtof(al_itofix(100) / 3);
    
        /* This will put 16.66666 into `result'. */
        result = al_fixtof(al_itofix(100) / 6);

    See also: al_ftofix, al_itofix, al_fixtoi.

    al_fixmul

    al_fixed al_fixmul(al_fixed x, al_fixed y);

    A fixed point value can be multiplied or divided by an integer with the normal * and / operators. To multiply two fixed point values, though, you must use this function.

    If an overflow occurs, Allegro's errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for overflow you should call al_set_errno(0) before calling al_fixmul.

    Example:

        al_fixed result;
    
        /* This will put 30000 into `result'. */
        result = al_fixmul(al_itofix(10), al_itofix(3000));
    
        /* But this overflows, and sets errno. */
        result = al_fixmul(al_itofix(100), al_itofix(3000));
        assert(!al_get_errno());

    Return value: Returns the clamped result of multiplying x by y, setting Allegro's errno to ERANGE if there was an overflow.

    See also: al_fixadd, al_fixsub, al_fixdiv, al_get_errno.

    al_fixdiv

    al_fixed al_fixdiv(al_fixed x, al_fixed y);

    A fixed point value can be divided by an integer with the normal / operator. To divide two fixed point values, though, you must use this function. If a division by zero occurs, Allegro's errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for division by zero you should call al_set_errno(0) before calling al_fixdiv.

    Example:

        al_fixed result;
    
        /* This will put 0.06060 `result'. */
        result = al_fixdiv(al_itofix(2), al_itofix(33));
    
        /* This will put 0 into `result'. */
        result = al_fixdiv(0, al_itofix(-30));
    
        /* Sets errno and puts -32768 into `result'. */
        result = al_fixdiv(al_itofix(-100), al_itofix(0));
        assert(!al_get_errno()); /* This will fail. */

    Return value: Returns the result of dividing x by y. If y is zero, returns the maximum possible fixed point value and sets Allegro's errno to ERANGE.

    See also: al_fixadd, al_fixsub, al_fixmul, al_get_errno.

    al_fixadd

    al_fixed al_fixadd(al_fixed x, al_fixed y);

    Although fixed point numbers can be added with the normal + integer operator, that doesn't provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro's errno and clamp the result, rather than just letting it wrap.

    Example:

        al_fixed result;
    
        /* This will put 5035 into `result'. */
        result = al_fixadd(al_itofix(5000), al_itofix(35));
    
        /* Sets errno and puts -32768 into `result'. */
        result = al_fixadd(al_itofix(-31000), al_itofix(-3000));
        assert(!al_get_errno()); /* This will fail. */

    Return value: Returns the clamped result of adding x to y, setting Allegro's errno to ERANGE if there was an overflow.

    See also: al_fixsub, al_fixmul, al_fixdiv.

    al_fixsub

    al_fixed al_fixsub(al_fixed x, al_fixed y);

    Although fixed point numbers can be subtracted with the normal - integer operator, that doesn't provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro's errno and clamp the result, rather than just letting it wrap.

    Example:

        al_fixed result;
    
        /* This will put 4965 into `result'. */
        result = al_fixsub(al_itofix(5000), al_itofix(35));
    
        /* Sets errno and puts -32768 into `result'. */
        result = al_fixsub(al_itofix(-31000), al_itofix(3000));
        assert(!al_get_errno()); /* This will fail. */

    Return value: Returns the clamped result of subtracting y from x, setting Allegro's errno to ERANGE if there was an overflow.

    See also: al_fixadd, al_fixmul, al_fixdiv, al_get_errno.

    Fixed point trig

    The fixed point square root, sin, cos, tan, inverse sin, and inverse cos functions are implemented using lookup tables, which are very fast but not particularly accurate. At the moment the inverse tan uses an iterative search on the tan table, so it is a lot slower than the others. On machines with good floating point processors using these functions could be slower Always profile your code.

    Angles are represented in a binary format with 256 equal to a full circle, 64 being a right angle and so on. This has the advantage that a simple bitwise 'and' can be used to keep the angle within the range zero to a full circle.

    al_fixtorad_r

    const al_fixed al_fixtorad_r = (al_fixed)1608;

    This constant gives a ratio which can be used to convert a fixed point number in binary angle format to a fixed point number in radians.

    Example:

        al_fixed rad_angle, binary_angle;
    
        /* Set the binary angle to 90 degrees. */
        binary_angle = 64;
    
        /* Now convert to radians (about 1.57). */
        rad_angle = al_fixmul(binary_angle, al_fixtorad_r);

    See also: al_fixmul, al_radtofix_r.

    al_radtofix_r

    const al_fixed al_radtofix_r = (al_fixed)2670177;

    This constant gives a ratio which can be used to convert a fixed point number in radians to a fixed point number in binary angle format.

    Example:

        al_fixed rad_angle, binary_angle;
        ...
        binary_angle = al_fixmul(rad_angle, radtofix_r);

    See also: al_fixmul, al_fixtorad_r.

    al_fixsin

    al_fixed al_fixsin(al_fixed x);

    This function finds the sine of a value using a lookup table. The input value must be a fixed point binary angle.

    Example:

        al_fixed angle;
        int result;
    
        /* Set the binary angle to 90 degrees. */
        angle = al_itofix(64);
    
        /* The sine of 90 degrees is one. */
        result = al_fixtoi(al_fixsin(angle));
        assert(result == 1);

    Return value: Returns the sine of a fixed point binary format angle. The return value will be in radians.

    al_fixcos

    al_fixed al_fixcos(al_fixed x);

    This function finds the cosine of a value using a lookup table. The input value must be a fixed point binary angle.

    Example:

        al_fixed angle;
        float result;
    
        /* Set the binary angle to 45 degrees. */
        angle = al_itofix(32);
    
        /* The cosine of 45 degrees is about 0.7071. */
        result = al_fixtof(al_fixcos(angle));
        assert(result > 0.7 && result < 0.71);

    Return value: Returns the cosine of a fixed point binary format angle. The return value will be in radians.

    al_fixtan

    al_fixed al_fixtan(al_fixed x);

    This function finds the tangent of a value using a lookup table. The input value must be a fixed point binary angle.

    Example:

        al_fixed angle, res_a, res_b;
        float dif;
    
        angle = al_itofix(37);
        /* Prove that tan(angle) == sin(angle) / cos(angle). */
        res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle));
        res_b = al_fixtan(angle);
        dif = al_fixtof(al_fixsub(res_a, res_b));
        printf("Precision error: %f\n", dif);

    Return value: Returns the tangent of a fixed point binary format angle. The return value will be in radians.

    al_fixasin

    al_fixed al_fixasin(al_fixed x);

    This function finds the inverse sine of a value using a lookup table. The input value must be a fixed point value. The inverse sine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro's errno to EDOM and return zero.

    Example:

        float angle;
        al_fixed val;
    
        /* Sets `val' to a right binary angle (64). */
        val = al_fixasin(al_itofix(1));
    
        /* Sets `angle' to 0.2405. */
        angle = al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)), al_fixtorad_r));
    
        /* This will trigger the assert. */
        val = al_fixasin(al_ftofix(-1.09));
        assert(!al_get_errno());

    Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of the range. All return values of this function will be in the range -64 to 64.

    al_fixacos

    al_fixed al_fixacos(al_fixed x);

    This function finds the inverse cosine of a value using a lookup table. The input value must be a fixed point radian. The inverse cosine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro's errno to EDOM and return zero.

    Example:

        al_fixed result;
    
        /* Sets result to binary angle 128. */
        result = al_fixacos(al_itofix(-1));

    Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range. All return values of this function will be in the range 0 to 128.

    al_fixatan

    al_fixed al_fixatan(al_fixed x)

    This function finds the inverse tangent of a value using a lookup table. The input value must be a fixed point radian. The inverse tangent is the value whose tangent is x.

    Example:

        al_fixed result;
    
        /* Sets result to binary angle 13. */
        result = al_fixatan(al_ftofix(0.326));

    Return value: Returns the inverse tangent of a fixed point value, measured as a fixed point binary format angle.

    al_fixatan2

    al_fixed al_fixatan2(al_fixed y, al_fixed x)

    This is a fixed point version of the libc atan2() routine. It computes the arc tangent of y / x, but the signs of both arguments are used to determine the quadrant of the result, and x is permitted to be zero. This function is useful to convert Cartesian coordinates to polar coordinates.

    Example:

        al_fixed result;
    
        /* Sets `result' to binary angle 64. */
        result = al_fixatan2(al_itofix(1), 0);
    
        /* Sets `result' to binary angle -109. */
        result = al_fixatan2(al_itofix(-1), al_itofix(-2));
    
        /* Fails the assert. */
        result = al_fixatan2(0, 0);
        assert(!al_get_errno());

    Return value: Returns the arc tangent of y / x in fixed point binary format angle, from -128 to 128. If both x and y are zero, returns zero and sets Allegro's errno to EDOM.

    al_fixsqrt

    al_fixed al_fixsqrt(al_fixed x)

    This finds out the non negative square root of x. If x is negative, Allegro's errno is set to EDOM and the function returns zero.

    al_fixhypot

    al_fixed al_fixhypot(al_fixed x, al_fixed y)

    Fixed point hypotenuse (returns the square root of x*x + y*y). This should be better than calculating the formula yourself manually, since the error is much smaller.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/main.html0000644000175000001440000001103712157230676017377 0ustar tjadenusers Main addon

    The main addon has no public API, but contains functionality to enable programs using Allegro to build and run without platform-specific changes.

    On platforms that require this functionality (e.g. OSX) this addon contains a C main function that invokes al_run_main with the user's own main function, where the user's main function has had its name mangled to something else. The file that defines the user main function must include the header file allegro5/allegro.h; that header performs the name mangling using some macros.

    If the user main function is defined in C++, then it must have the following signature for this addon to work:

    int main(int argc, char **argv)

    This addon does nothing on platforms that don't require its functionality, but you should keep it in mind in case you need to port to platforms that do require it.

    Link with allegro_main.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:14 UTC

    allegro-5.0.10/docs/html/refman/direct3d.html0000644000175000001440000001611612157230675020156 0ustar tjadenusers Direct3D integration

    These functions are declared in the following header file:

    #include <allegro5/allegro_direct3d.h>

    al_get_d3d_device

    LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display)

    Returns the Direct3D device of the display. The return value is undefined if the display was not created with the Direct3D flag.

    Returns: A pointer to the Direct3D device.

    al_get_d3d_system_texture

    LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap)

    Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). This texture is used for the render-to-texture feature set.

    Returns: A pointer to the Direct3D system texture.

    al_get_d3d_video_texture

    LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap)

    Returns the video texture (stored with the D3DPOOL_DEFAULT or D3DPOOL_MANAGED flags depending on whether render-to-texture is enabled or disabled respectively).

    Returns: A pointer to the Direct3D video texture.

    al_have_d3d_non_pow2_texture_support

    bool al_have_d3d_non_pow2_texture_support(void)

    Returns whether the Direct3D device supports textures whose dimensions are not powers of two.

    Returns: True if device suports NPOT textures, false otherwise.

    al_have_d3d_non_square_texture_support

    bool al_have_d3d_non_square_texture_support(void)

    Returns whether the Direct3D device supports textures that are not square.

    Returns: True if the Direct3D device suports non-square textures, false otherwise.

    al_get_d3d_texture_position

    void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)

    Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels.

    Parameters:

    • bitmap - ALLEGRO_BITMAP to examine
    • u - Will hold the returned u coordinate
    • v - Will hold the returned v coordinate

    al_is_d3d_device_lost

    bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display)

    Returns a boolean indicating whether or not the Direct3D device belonging to the given display is in a lost state.

    Parameters:

    • display - The display that the device you wish to check is attached to

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:12 UTC

    allegro-5.0.10/docs/html/refman/events.html0000644000175000001440000011740412157230671017757 0ustar tjadenusers Event system and events

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_EVENT

    typedef union ALLEGRO_EVENT ALLEGRO_EVENT;

    An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common:

    type (ALLEGRO_EVENT_TYPE)

    Indicates the type of event.

    any.source (ALLEGRO_EVENT_SOURCE *)

    The event source which generated the event.

    any.timestamp (double)

    When the event was generated.

    By examining the type field you can then access type-specific fields. The any.source field tells you which event source generated that particular event. The any.timestamp field tells you when the event was generated. The time is referenced to the same starting point as al_get_time.

    Each event is of one of the following types, with the usable fields given.

    ALLEGRO_EVENT_JOYSTICK_AXIS

    A joystick axis value changed.

    joystick.id (ALLEGRO_JOYSTICK *)

    The joystick which generated the event. This is not the same as the event source joystick.source.

    joystick.stick (int)

    The stick number, counting from zero. Axes on a joystick are grouped into "sticks".

    joystick.axis (int)

    The axis number on the stick, counting from zero.

    joystick.pos (float)

    The axis position, from -1.0 to +1.0.

    ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN

    A joystick button was pressed.

    joystick.id (ALLEGRO_JOYSTICK *)

    The joystick which generated the event.

    joystick.button (int)

    The button which was pressed, counting from zero.

    ALLEGRO_EVENT_JOYSTICK_BUTTON_UP

    A joystick button was released.

    joystick.id (ALLEGRO_JOYSTICK *)

    The joystick which generated the event.

    joystick.button (int)

    The button which was released, counting from zero.

    ALLEGRO_EVENT_JOYSTICK_CONFIGURATION

    A joystick was plugged in or unplugged. See al_reconfigure_joysticks for details.

    ALLEGRO_EVENT_KEY_DOWN

    A keyboard key was pressed.

    keyboard.keycode (int)

    The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants.

    keyboard.display (ALLEGRO_DISPLAY *)

    The display which had keyboard focus when the event occurred.

    Note: this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input.

    ALLEGRO_EVENT_KEY_UP

    A keyboard key was released.

    keyboard.keycode (int)

    The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants.

    keyboard.display (ALLEGRO_DISPLAY *)

    The display which had keyboard focus when the event occurred.

    ALLEGRO_EVENT_KEY_CHAR

    A character was typed on the keyboard, or a character was auto-repeated.

    keyboard.keycode (int)

    The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants.

    keyboard.unichar (int)

    A Unicode code point (character). This may be zero or negative if the event was generated for a non-visible "character", such as an arrow or Function key. In that case you can act upon the keycode field.

    Some special keys will set the unichar field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the unichar field will have the values 1 to 26. For example Ctrl-A will set unichar to 1 and Ctrl-H will set it to 8.

    As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the keycode field.

    keyboard.modifiers (unsigned)

    This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants.

    keyboard.repeat (bool)

    Indicates if this is a repeated character.

    keyboard.display (ALLEGRO_DISPLAY *)

    The display which had keyboard focus when the event occurred.

    Note: in many input methods, characters are not entered one-for-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce 'é'. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases.

    ALLEGRO_EVENT_MOUSE_AXES

    One or more mouse axis values changed.

    mouse.x (int)

    x-coordinate

    mouse.y (int)

    y-coordinate

    mouse.z (int)

    z-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative.

    mouse.w (int)

    w-coordinate. This usually means the horizontal axis of a mouse wheel.

    mouse.dx (int)

    Change in the x-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event.

    mouse.dy (int)

    Change in the y-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event.

    mouse.dz (int)

    Change in the z-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event.

    mouse.dw (int)

    Change in the w-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event.

    mouse.display (ALLEGRO_DISPLAY *)

    The display which had mouse focus.

    Note: Calling al_set_mouse_xy also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead.

    Note: currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis.

    ALLEGRO_EVENT_MOUSE_BUTTON_DOWN

    A mouse button was pressed.

    mouse.x (int)

    x-coordinate

    mouse.y (int)

    y-coordinate

    mouse.z (int)

    z-coordinate

    mouse.w (int)

    w-coordinate

    mouse.button (unsigned)

    The mouse button which was pressed, numbering from 1.

    mouse.display (ALLEGRO_DISPLAY *)

    The display which had mouse focus.

    ALLEGRO_EVENT_MOUSE_BUTTON_UP

    A mouse button was released.

    mouse.x (int)

    x-coordinate

    mouse.y (int)

    y-coordinate

    mouse.z (int)

    z-coordinate

    mouse.w (int)

    w-coordinate

    mouse.button (unsigned)

    The mouse button which was released, numbering from 1.

    mouse.display (ALLEGRO_DISPLAY *)

    The display which had mouse focus.

    ALLEGRO_EVENT_MOUSE_WARPED

    al_set_mouse_xy was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise.

    ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY

    The mouse cursor entered a window opened by the program.

    mouse.x (int)

    x-coordinate

    mouse.y (int)

    y-coordinate

    mouse.z (int)

    z-coordinate

    mouse.w (int)

    w-coordinate

    mouse.display (ALLEGRO_DISPLAY *)

    The display which had mouse focus.

    ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY

    The mouse cursor leave the boundaries of a window opened by the program.

    mouse.x (int)

    x-coordinate

    mouse.y (int)

    y-coordinate

    mouse.z (int)

    z-coordinate

    mouse.w (int)

    w-coordinate

    mouse.display (ALLEGRO_DISPLAY *)

    The display which had mouse focus.

    ALLEGRO_EVENT_TIMER

    A timer counter incremented.

    timer.source (ALLEGRO_TIMER *)

    The timer which generated the event.

    timer.count (int64_t)

    The timer count value.

    ALLEGRO_EVENT_DISPLAY_EXPOSE

    The display (or a portion thereof) has become visible.

    display.source (ALLEGRO_DISPLAY *)

    The display which was exposed.

    display.x (int)
     
    display.y (int)
     

    The top-left corner of the display which was exposed.

    display.width (int)
     
    display.height (int)

    The width and height of the rectangle which was exposed.

    Note: The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated.

    ALLEGRO_EVENT_DISPLAY_RESIZE

    The window has been resized.

    display.source (ALLEGRO_DISPLAY *)

    The display which was resized.

    display.x (int)
     
    display.y (int)

    The position of the top-level corner of the display.

    display.width (int)

    The new width of the display.

    display.height (int)

    The new height of the display.

    You should normally respond to these events by calling al_acknowledge_resize. Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information.

    ALLEGRO_EVENT_DISPLAY_CLOSE

    The close button of the window has been pressed.

    display.source (ALLEGRO_DISPLAY *)
    The display which was closed.

    ALLEGRO_EVENT_DISPLAY_LOST

    When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap's pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof.

    To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps -- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps.

    display.source (ALLEGRO_DISPLAY *)
    The display which was lost.

    ALLEGRO_EVENT_DISPLAY_FOUND

    Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST.

    display.source (ALLEGRO_DISPLAY *)
    The display which was found.

    ALLEGRO_EVENT_DISPLAY_SWITCH_OUT

    The window is no longer active, that is the user might have clicked into another window or "tabbed" away.

    display.source (ALLEGRO_DISPLAY *)
    The display which was switched out of.

    ALLEGRO_EVENT_DISPLAY_SWITCH_IN

    The window is the active one again.

    display.source (ALLEGRO_DISPLAY *)
    The display which was switched into.

    ALLEGRO_EVENT_DISPLAY_ORIENTATION

    Generated when the rotation or orientation of a display changes.

    display.source (ALLEGRO_DISPLAY *)

    The display which generated the event.

    event.display.orientation

    Contains one of the following values:

    • ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
    • ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
    • ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
    • ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
    • ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
    • ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN

    See also: ALLEGRO_EVENT_SOURCE, ALLEGRO_EVENT_TYPE, ALLEGRO_USER_EVENT, ALLEGRO_GET_EVENT_TYPE

    ALLEGRO_USER_EVENT

    typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT;

    An event structure that can be emitted by user event sources. These are the public fields:

    • ALLEGRO_EVENT_SOURCE *source;
    • intptr_t data1;
    • intptr_t data2;
    • intptr_t data3;
    • intptr_t data4;

    Like all other event types this structure is a part of the ALLEGRO_EVENT union. To access the fields in an ALLEGRO_EVENT variable ev, you would use:

    • ev.user.source
    • ev.user.data1
    • ev.user.data2
    • ev.user.data3
    • ev.user.data4

    To create a new user event you would do this:

    ALLEGRO_EVENT_SOURCE my_event_source;
    ALLEGRO_EVENT my_event;
    float some_var;
    
    al_init_user_event_source(&my_event_source);
    
    my_event.user.type = ALLEGRO_GET_EVENT_TYPE('M','I','N','E');
    my_event.user.data1 = 1;
    my_event.user.data2 = &some_var;
    
    al_emit_user_event(&my_event_source, &my_event, NULL);

    Event type identifiers for user events are assigned by the user. Please see the documentation for ALLEGRO_GET_EVENT_TYPE for the rules you should follow when assigning identifiers.

    See also: al_emit_user_event, ALLEGRO_GET_EVENT_TYPE

    ALLEGRO_EVENT_QUEUE

    typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE;

    An event queue holds events that have been generated by event sources that are registered with the queue. Events are stored in the order they are generated. Access is in a strictly FIFO (first-in-first-out) order.

    See also: al_create_event_queue, al_destroy_event_queue

    ALLEGRO_EVENT_SOURCE

    typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE;

    An event source is any object which can generate events. For example, an ALLEGRO_DISPLAY can generate events, and you can get the ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with al_get_display_event_source.

    You may create your own "user" event sources that emit custom events.

    See also: ALLEGRO_EVENT, al_init_user_event_source, al_emit_user_event

    ALLEGRO_EVENT_TYPE

    typedef unsigned int ALLEGRO_EVENT_TYPE;

    An integer used to distinguish between different types of events.

    See also: ALLEGRO_EVENT, ALLEGRO_GET_EVENT_TYPE, ALLEGRO_EVENT_TYPE_IS_USER

    ALLEGRO_GET_EVENT_TYPE

    #define ALLEGRO_GET_EVENT_TYPE(a, b, c, d)   AL_ID(a, b, c, d)

    Make an event type identifier, which is a 32-bit integer. Usually, but not necessarily, this will be made from four 8-bit character codes, for example:

    #define MY_EVENT_TYPE   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')

    IDs less than 1024 are reserved for Allegro or its addons. Don't use anything lower than ALLEGRO_GET_EVENT_TYPE(0, 0, 4, 0).

    You should try to make your IDs unique so they don't clash with any 3rd party code you may be using. Be creative. Numbering from 1024 is not creative.

    If you need multiple identifiers, you could define them like this:

    #define BASE_EVENT   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')
    #define BARK_EVENT   (BASE_EVENT + 0)
    #define MEOW_EVENT   (BASE_EVENT + 1)
    #define SQUAWK_EVENT (BASE_EVENT + 2)
    
    /* Alternatively */
    enum {
       BARK_EVENT = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'),
       MEOW_EVENT,
       SQUAWK_EVENT
    };

    See also: ALLEGRO_EVENT, ALLEGRO_USER_EVENT, ALLEGRO_EVENT_TYPE_IS_USER

    ALLEGRO_EVENT_TYPE_IS_USER

    #define ALLEGRO_EVENT_TYPE_IS_USER(t)        ((t) >= 512)

    A macro which evaluates to true if the event type is not a builtin event type, i.e. one of those described in ALLEGRO_EVENT_TYPE.

    al_create_event_queue

    ALLEGRO_EVENT_QUEUE *al_create_event_queue(void)

    Create a new, empty event queue, returning a pointer to object if successful. Returns NULL on error.

    See also: al_register_event_source, al_destroy_event_queue, ALLEGRO_EVENT_QUEUE

    al_destroy_event_queue

    void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)

    Destroy the event queue specified. All event sources currently registered with the queue will be automatically unregistered before the queue is destroyed.

    See also: al_create_event_queue, ALLEGRO_EVENT_QUEUE

    al_register_event_source

    void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue,
       ALLEGRO_EVENT_SOURCE *source)

    Register the event source with the event queue specified. An event source may be registered with any number of event queues simultaneously, or none. Trying to register an event source with the same event queue more than once does nothing.

    See also: al_unregister_event_source, ALLEGRO_EVENT_SOURCE

    al_unregister_event_source

    void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue,
       ALLEGRO_EVENT_SOURCE *source)

    Unregister an event source with an event queue. If the event source is not actually registered with the event queue, nothing happens.

    If the queue had any events in it which originated from the event source, they will no longer be in the queue after this call.

    See also: al_register_event_source

    al_is_event_queue_empty

    bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue)

    Return true if the event queue specified is currently empty.

    See also: al_get_next_event, al_peek_next_event

    al_get_next_event

    bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

    Take the next event out of the event queue specified, and copy the contents into ret_event, returning true. The original event will be removed from the queue. If the event queue is empty, return false and the contents of ret_event are unspecified.

    See also: ALLEGRO_EVENT, al_peek_next_event, al_wait_for_event

    al_peek_next_event

    bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

    Copy the contents of the next event in the event queue specified into ret_event and return true. The original event packet will remain at the head of the queue. If the event queue is actually empty, this function returns false and the contents of ret_event are unspecified.

    See also: ALLEGRO_EVENT, al_get_next_event, al_drop_next_event

    al_drop_next_event

    bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue)

    Drop (remove) the next event from the queue. If the queue is empty, nothing happens. Returns true if an event was dropped.

    See also: al_flush_event_queue, al_is_event_queue_empty

    al_flush_event_queue

    void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue)

    Drops all events, if any, from the queue.

    See also: al_drop_next_event, al_is_event_queue_empty

    al_wait_for_event

    void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

    Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

    See also: ALLEGRO_EVENT, al_wait_for_event_timed, al_wait_for_event_until, al_get_next_event

    al_wait_for_event_timed

    bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue,
       ALLEGRO_EVENT *ret_event, float secs)

    Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

    timeout_msecs determines approximately how many seconds to wait. If the call times out, false is returned. Otherwise true is returned.

    See also: ALLEGRO_EVENT, al_wait_for_event, al_wait_for_event_until

    al_wait_for_event_until

    bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue,
       ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout)

    Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

    timeout determines how long to wait. If the call times out, false is returned. Otherwise true is returned.

    See also: ALLEGRO_EVENT, ALLEGRO_TIMEOUT, al_init_timeout, al_wait_for_event, al_wait_for_event_timed

    al_init_user_event_source

    void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src)

    Initialise an event source for emitting user events. The space for the event source must already have been allocated.

    One possible way of creating custom event sources is to derive other structures with ALLEGRO_EVENT_SOURCE at the head, e.g.

    typedef struct THING THING;
    
    struct THING {
        ALLEGRO_EVENT_SOURCE event_source;
        int field1;
        int field2;
        /* etc. */
    };
    
    THING *create_thing(void)
    {
        THING *thing = malloc(sizeof(THING));
    
        if (thing) {
            al_init_user_event_source(&thing->event_source);
            thing->field1 = 0;
            thing->field2 = 0;
        }
    
        return thing;
    }

    The advantage here is that the THING pointer will be the same as the ALLEGRO_EVENT_SOURCE pointer. Events emitted by the event source will have the event source pointer as the source field, from which you can get a pointer to a THING by a simple cast (after ensuring checking the event is of the correct type).

    However, it is only one technique and you are not obliged to use it.

    The user event source will never be destroyed automatically. You must destroy it manually with al_destroy_user_event_source.

    See also: ALLEGRO_EVENT_SOURCE, al_destroy_user_event_source, al_emit_user_event, ALLEGRO_USER_EVENT

    al_destroy_user_event_source

    void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src)

    Destroy an event source initialised with al_init_user_event_source.

    This does not free the memory, as that was user allocated to begin with.

    See also: ALLEGRO_EVENT_SOURCE

    al_emit_user_event

    bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src,
       ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *))

    Emit a user event. The event source must have been initialised with al_init_user_event_source. Returns false if the event source isn't registered with any queues, hence the event wouldn't have been delivered into any queues.

    Events are copied in and out of event queues, so after this function returns the memory pointed to by event may be freed or reused. Some fields of the event being passed in may be modified by the function.

    Reference counting will be performed if dtor is not NULL. Whenever a copy of the event is made, the reference count increases. You need to call al_unref_user_event to decrease the reference count once you are done with a user event that you have received from al_get_next_event, al_peek_next_event, al_wait_for_event, etc.

    Once the reference count drops to zero dtor will be called with a copy of the event as an argument. It should free the resources associated with the event, but not the event itself (since it is just a copy).

    If dtor is NULL then reference counting will not be performed. It is safe, but unnecessary, to call al_unref_user_event on non-reference counted user events.

    See also: ALLEGRO_USER_EVENT, al_unref_user_event

    al_unref_user_event

    void al_unref_user_event(ALLEGRO_USER_EVENT *event)

    Decrease the reference count of a user-defined event. This must be called on any user event that you get from al_get_next_event, al_peek_next_event, al_wait_for_event, etc. which is reference counted. This function does nothing if the event is not reference counted.

    See also: al_emit_user_event, ALLEGRO_USER_EVENT

    al_get_event_source_data

    intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source)

    Returns the abstract user data associated with the event source. If no data was previously set, returns NULL.

    See also: al_set_event_source_data

    al_set_event_source_data

    void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data)

    Assign the abstract user data to the event source. Allegro does not use the data internally for anything; it is simply meant as a convenient way to associate your own data or objects with events.

    See also: al_get_event_source_data

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/images/0000755000175000001440000000000012157230720017016 5ustar tjadenusersallegro-5.0.10/docs/html/refman/images/primitives1.png0000644000175000001440000003727212157230670022017 0ustar tjadenusersPNG  IHDR|sRGB pHYsss"tIME .0> IDATxg|Te_f&^' EPJ(RHtފU"PBҤI/HB 'e~0)fr>Nr9|sfLEO' ' @~ ?@~ ?O ?O' ' @~ ?@~ ?O ?O' ' @~ @~ ?Dc߬d{챱i׮]Ν0QQQG֭[ڵU3glڴ)&&ںnݺ pqqQN9􀀀:,۷o߱cGNN3<ӫW/FClٲe˖juEGGkڠ_~_9?wݻ_բE>}TP~~~xxUHHHpp3D VXWI&F rss*|||k׮]NCݻrto5mTRu-77W!ſpBv&N_rU``Oʩk45k6h@VH&M+^I4Ξ=;22;vؙ3g>y ΣG^bŜ9s Ν;|(V^~Ğ={YfժU Xoֹs>tM6͘1C!ŷ0`vZ)SRRR.^cF3tЌ bccRSSǍwӧ3TNլYqƦ%EEE:tPk֬Q:v("W\Qf<("C;{%-Z\rqq!::ZO;vlٲEOKKիOҥKqqqݺu3-h4;w޹sN[1a9rDDڵkGO۷oСiIncbbGGGe?**}hxJkDrʥ$%%(C96m3xxx(7nٷoߺuFg0f׮]3 (((XtӦMU+Wjڃ[k׮ sO "RR ORRR2`/RQzj~ m۶:u.o_fUPǟ>}zե/ R~zUٳ+_xpBV+ >L:n;vo4h׮];== :p]QaoKi&O`wywJ+{zzիW/^X~+VʃViiifu K.;wAV|JVz#G~YYY~-?ѣG ,WZecc3ogvqq4iRrr.Y$777))ID>lS G0###njcn…<| PF۷]Vӽ;f{g_~t K@@޽{s1CZ]bb߿ %رc\޴iS|royZjUC󹹹-_\QſHێ;P)Sq5g%?%%iӦGjԨWZ04lcccyPxSnxnnnpp0q(/_jUV߬RQ'rrrzGզR5??~YfnnnO=ѣGԩS/SN.]Rl'OrJ֭ʹgvZN\]]===׭[(lR56jԨ]v)K,>}bҥݻӧOm۶`Ŋ?SQQQvN}6lPKӧOEz[#G<_~}HHHCCC? ̙aÆ}{ƍZv֬Y욁G從Я_0?6s |齌%\tiҥҥիNJOdյk &t:9|pxxx``믿^SIIɲeڶmhXRr尰+VoGoժՌ3^{yyۑغuk#""|ġ /6 }ݷo_ll,<;vx}s>;}ŋvڼy+WSb5kVzaf6o|5SƍSRR&MTPP0o;qDNWVH[[r-dСC"2cƌ gΜ)"iIAAm)*WԩS 裏Dm۶w999"2t o-QFݗZ58883&33UVHPNO[l{^x4۩S'O6k֬z=k֬С2A77ڵk+/_k߾}*...**J988T^}ԨQ}`80c /N#Dd۶ms8ƏbŊF)vQvm%<Μ9SO)WsΞ={׫}zdd[l+6lذf͚=WB`4tܦMfonFDԩ};p˗/ǏNLLlҤa{^reſ[^^^;v4%<@~zN>dzjݺuMOJJU˗/裏ի7z?">>*880۰a[+]JLL\|yxxxڵ=jZ|7OEGGרQ4[TTdggg3=8ʕ+*JD֭[׫W޽{wnQTTVM޿'Ϛ5˰>G? ._KP{FFi6 Ӧٓ'Oz{{Z;*!|Ȱ$==t'~٦MSrrMFQzzիW M:uLoU{2)QEGG׫Wʊ R˗/:::СC?GDD?>$$}"rܹ={nݺrʑ!!!qqq_}Cxxc?W^yjutt_tRêqY[[Ϙ1CD&LЭ[7WW_/,}]TTs@~z{?5JDUuO?ܹs5j1cƅ 6mk.___fGG,=\k###}}}[lYQ_^zꕱŋGQQooo_v*vO'  d>\]]\[h2XY^{p ƟO' Ox.f\= 33u)ڄj@~꽲DfGNT`V8~@~x8~Nc>!!dԨQ 69rüZ9'X7;|ÿO'  @~ ?p/?t_UTT7xzz_~~W2DXŶ47PWпx[ TO'(?>m49q℈=LJ0sׯ_;v\pADNh"5 #V(">>>>>>YYYYYY*`]IIaeoo߶m[1z* ?=^-ZP}PX4___v_Jc@~ ?Ow~V[t >I]'RV=7Aڎ OBuId%)IMWVgyq0}@Ks̩^z=L>+@~ypKGu:ۮtU ?O'O' @~eIHHTBvgJ'FKbWM-Jc,8{r˿j|[.Ph/{9'IIIYdIBBU>00044wݽ{wqq1|p8Kշo_y饗?>uTgg{k׮]v~<>?rJZ-"٫W~WCBB@~;{WZhT*N3,:uj6m<<</Z3>}ZJRT})Heee/C 0 JٳA):|pNNN(KJ&N8i$+++^_z!KĉSNupph޼yn ROO'7uȔ"">] D,769VD2], 8qr)WܹsΝ&LhԨQݻtOk4%KN:u111w۠iӦ/?\9vU.>.~5ɸvNՉ'N81^xᣏ>b8 8-[j#MS$=^ڌ*!e޵A6JnUâ+յ"{߾qݺuڵ+OOg~į]@s^1om/mFumfDm:emcv]aʢGw Ħ\]] zm@~Pe'VVV-[''#P[.] CM>>>-<4ibxK-Lw^5jԂ D4E ?ȑ#?>iҤ.]4)1G@IDATk֌&'(KFFƔ)S<<< ''*U<) wƟp\1IzLWO' @~ @~ ?O ?O'O' @~ dhrss7mtѤUvܹUV4WTTm۶}j_,??iҤD}Dd˦-ʬs8h6'(*Kt#TrZ}VnBBB6?m޼/8p`6mJ/Vipng酊RൎɎ+"Z"+]!oh/""nnnܪHffRJdG.::_o޼[VEDjݗɻKj)wjJ꯾zݗJחBΝ֭}v''2lҤɱc-Z4devA77?ȋ~Iynf2dHHHȸqsȩ-""JEdŊ ,عs'ŌSxWߞ={VZƖC]h`0V)F{q6mŋ,X?3ڵkg{]v^ZvxVXXTx嚟?޹s瀀m۶yxxP,ŵkڷos:uP!0N7,m$?ѷx\*HDD)֊QmYe""Wӭm%ԩӿe(19?IlҖVDzj%ww *!Pf:xm-t|Z&KI6=?UwCN(j S҈'KC_u䟇‹PF~ I fE':]0N'}O>QC("?.(t*5ww7xʼ.W>@~ ]{t06aNF  ?IwRxXӔޮo[DD_, $g{?ovuq-.O8Mrv=Ь""r%{+27XDD&miU8w nwϧ-FQnK֖mzk/M%g?QDDlĥ6mD%ݸt'nrs Tǧ$HZqjE$""kavצsu`O"nO٭k8f͚2^w[{Yn)e_DF]J#@~0p#+;0Qy._W+qz-\'"RpN .ok[hѢE2^oOVaTv*vO9{8EDDĭ}*J4EegcWOlD#"V|<,? ?}q"︤-UzoӞ ?݉KGqh ݮW}A?tӍ-(Snyr@~ PqgNb|nſe#tr1My~Ϝ9su//GS$gJq$~&*E3VK7jSɁG !!!***!!ťAAAA @~*k޼;F>|ܹsTQ>{E$)0hHeVWAbbbkrrrZEfD_֮]lٲ__Zj߿CCCEdѢEqošzz̙I]vmB}1x3gjm۶ll߾~7n\͚5~2669aVW۶m׬YO:u-3g|||*v={믿޻w LX?.`xpwT$ҍV5cѾ}}Μ9\(;F:tزeV}嫾Ldm8WtME/"vEI;ŝ>}O*##?tww}vZD."//H榊r\{)v3&ק?AoٲED䧇6qĘ✜_5""";;_.O)5~6>ɤ$[b{H n-ݢԭ2ӏ?XRYYYTHǹ~'^}NߒXZ^%͔o8IOovԩ"bmmmSN/f㓒k׮ .hڪU6k֬FYTb(qo2X I5bk1/K#$uqZatctҞ={Ν;ШQƍS-<ɖ֩=$=%?JD$wD7kš4UQ#9nY҇ήcǎ;v*V`jOn<̪0^>#kf7Ó} >HxTnevk]._ο$6>[}m9J ?Ŷ:Sy)R} !EVȩry%wȋ;HLt7\#*'.'%v7/dMd=//oT +X6,xJ ӓ;) mt)I3E}_)#RN7KR=i'/c ?+x?Yƅ)r$L5%+~ZzKaNJ4/d4ODB[@~;NWc{_ĉ؛-$> dĿ)9DH 9Z K%wUnUV'ZQq`O""V2zf(h-^*rb%r/K毢/|;,ޗSdmdJ쑚rYu> XV_fLRRRB>>'Oefz~ԩSXիW8pӦMmoTΜ9ӳgϘ eϯ\rrrZ6G=i$r^^^M4XkkkOOϦMR@dO"q`2o#OcǎС- ?֭[+rPo̙#ܪUBCCϝ;Gs%111~a]\\h3f+ 0-zׯ_vm ?=FZ;jժo nĉsss @~zZlVM;իWoٲeٶ4sh}EEE͛7oĉ~~~TPw{˫[nHHڵki-7oNMM6mڤ8qښ*3uG)**Og͚ES[NKK;w܏?{sS VZ矿[իWX[ly7_xۯ&P˗/:88x{{>}ޞ`t:[IIDGGWR:*3ZjʕfΜIx`I{Ue˖yyy> tI֨QaÆ7oXg}6))ɓ666P!ikM81;;{޼y?۷'<r}m۶͘1cʕjբXNk׮#GL8qҤIaaa P+WKmjԨQ*U3sL+++ ?HEO' ' @~ ?@~ ?O ?O' ' @~ ?@~ ?O ?O' ' @~ @~ ?O ?Of%HIENDB`allegro-5.0.10/docs/html/refman/images/primitives2.png0000644000175000001440000006231512157230670022014 0ustar tjadenusersPNG  IHDR}isRGB pHYsss"tIMEY2 IDATxw|SO6^Жhe]YRhd\YEp\Q(׉R "*^ZFeZ{ifiC I_=眜s|ϐ L """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """"""DDDDDĢXT """""bQADDDDDĢXT """""bQADDDDDĢXT """""bQADDDDDĢXT """""l҇tضm<\}b}a~:<==ѽ{w : Zo:#G/k.:u 2 :ts=z19T#R^zg SCǏGll,^ gggoGB`r,dժU(((жm[&dggc8~8aÆ! ɩPGT*aȐ!D" +:NץK(nZݺuJ%d@ >^YTX`/H Lݷ[ Lv wآXp~zA JR裏BXX􀲲OOO駟fQGGG]v˗텅ŋ; ԁ4oNNN3kZx{{cǎe͛775Vt-[Ŀoc&b׮]3f \\\/B29Tcz)c#""pM\|INT OOOA*cjj֭زe ;ѷo_j HHH@YY8q~~~tܶ-[ //>,QC.\@TT>s1!ի___~ .]ARl\v|C̙38qy^1}t[ bBPNN ТE ?hӦ 1c 0IuHKK0y \rr2L֭[^cBj@㥗^ A0|p&>rssvZlڴ :tܹsg1ITmJ )NT矇3{m믿̝;ɰ6e8p-[;w"<<_|f͚$A.=9oW]UF644666زe r9Rh&$$0R,jڵx-FjMp )FRgkװ}vxyy1)5k.^x)}zp]`ҤIL}jOf;99jP54w\_}Zhڴqx ɩwԾH˗!y+c(11j-Zddׯ_Gqq1x5c&55YYYhժuu """"Gr'""""bܝVO55N 慈HER^B !TS.^q""eeeP*&7H$""Oqqqڵ+.]ԩS~1jԨM x^ӂn!㳠"99 Zhzd4HMMEhh(\]]Q~}_J]uEFFbL]}aA ;vMڿ{c˖-IP^^z쉳goaÆ~4Z-;d>}U҃KIIիW RT8ydm۶!88l}_cǎXlmU*~7 >CGvmŌᗞ?R? FqeZ`B4GTWhwHLLoml1e 8Cek"99֭͛7/fH۔pT*̙3zagĉ2d0sLQ}VќS?O>0X~=k>8Vx>+r\Űx}[eh; I:6_]~>(*.?k QհQS ^ޙ7::?1cϯܹs1|;v EEE;v,&Mj5kzÇ'|+WYfL=4{ヒ~a„ hѢEwmltR :k֬AHHѭ[7lذ66:5Z4HII?͛?dܻヒE!))ɤ݅t`#8s :tp19Nt2wppȏVJtI'MP(&Ɵ=P Dp! dU򽽱{ڴ?ıcǠP(֭[c޼yݻ=PThѢ<<>;w8;;#00sAXX޽{#99zؽ{7D/є8ǖ{xx+oKKK3)*j f@8V1ŗT0ZW˚;v 8,\B Jiii8x lmm1|w,.1yd,X}5kXPԂbuj~R\pEp GmPWYRr'N|p׫Θ1#GDƍUQQXXh Wr III=W͛Hq#(dU0r?11gϞ^7nH >ʝ$!ˑd<ĿM T5k*mnAG{qD3=D?|xDg 2'>*+ZEV"”)S0b7}0`=zƪUXT܍/TyTL  `dg8mi*^ < g&'DWD$%!^1uuEUĚ$@֬U섉2y矿%&&"44mڴM`oo?ĉyӵGqŶ)DD5Ѯ];ˌWG~~> ^]vA6m ̚5F?l9 mڴ1RΝ;ѲeG+GzpjYEy%vb¢ "qw%K-bbkA^p!(J;vLnRRR#++ w6pppm﷨2e \իW֭[ .`ʔ)$W{ǗLgRW:R&5 = C;x &L;vl@:w+V :mJYYIQwQ5jT6DDѣGX4n5k֠gϞy~c}:>#߿ވE{DDտT6tPHUTE=~W\GNç~ɓ'C.?X_Jd2p> htj4H$ +<ػw/rrr`KYqQ>}:O.x;=Gf""ޑXT """""RB5rг)ADDDDĢ>%.@Qe֒d ~U},5QǩD%Y+"""37 *+)*o.yyȘ7>Vel,2C?>֜eː1o/HMEƼyȊ E{s7<>ٜ """"/)[K@nqpJQ^TInWuh33Z+VlX 7oFUڣp=p۷bMDq'+ccx{ezzũ1]^37s&Iכ:349r!!\nݕ+QE"͡ζg ڝj_lÂN]vq2\^<1QTJ%"#qkWn\QTdeƈH '("""\*0+`ϛᇸsegW9^(+CƜ99r$WvE_e _eˆXTԮl%5ؕP?ki\ӫK 7o6;}Í7nDqR[m8 ';;Vz|-r}7ڵkΝ;s8= \wGpCud"Pss7"Ǚ@# VkNRDgFcTFпTTX櫕-o AU44 EEbb"bj5,+ o=J$%¦}Nž*ڟMHOaY{w+))p=IvhFGJ`;zRS8;׮]Ȫt<~>/#Tw^&F] *ޓsbbbpuNtL8VS}9.;>PE:- -~yXpGh+6}a~~hQE/L8Vݖ;؄xs/m^/ OS"3pb$6+xG}#1[2Rx\V Spo)_$'0wkm $\y@]ܽ,>$bG>?WLv]\://l|}=f̀;W?vS##Wx|i`#4p z4͘~0kخ z4Əaի&K͚㏙45~VAjooRT*QΜj SΡwo #FBޢbc!o⎯ZzE=~wvWb y&L*=,>^QQ&'K 'OwU!""'j9ED)"O>˗ID @mғ"(CDD􈰧\O|\ݎ=PR[AADDDDd=DDDDDĢXT """""zDj,xps`.XT԰zy """" oS^ZK.}7q)0Ek3DkSOR` ue !""SQ @rYh?Hdȧ.?d貲ğ֔h!TSPINՕ+"":=DDDDDĢjgW O5<Lh߽|UG=_8W*S&L0yms X,Aم Ҹ81XehZϜiҦMO,[Nu̘ZUk ~"\rRwށiS~iXTX.[SG*6[T"**ʬ}߾};wI[Ν1bĈZE&LբBcG':NJx{jQ!Tw̩26dXVEEYBB jYǴi """nTW aogɆ+%OVqaɒ%fsέ6w |!Z"ۄ p8\w/J탢M nl:9jR''~t99p;f͌!!CHIt} $ Vs%DDDĢnV_E͋ .]Ú$cQUEoKmeFEd>صm+XNNf_]N/8gRaSoNt󟈈j_ """""5<<n%Kf6jH1J wn}7o.X킃!usMqJa߽;\x< nZG_||QȧIp4*btY17on5󟈈XTXD}' @DDDDTSADDDDD,*E """"OԮ"p"l<|Uƞj8u5 """""bQADDDDD!s*A}i&:u hԨ3gёsذa>7oAٳ'fϞ ///&ȂDS~a˖-qU̟?O<JKK9ñb "<<Xlڵk4&.vvvXz5/`ŊHNNɓ+WrnQ-^7nm_Xl233h"&.7nlmmm3g:ub 8< xl6uT8886.}* $)S:7FNl\  E^JObv\YBnV߫6]e{*++JB`` ADdAA'={ٳh֬xZ޽{CprL.<-'6| 7 Scujb7n"##:_ǧ~]v!44lQdz*` [׆lL8-[4|H8w6mSbq1%FeeP rKJ'ITGbi):ulK.eQ(}ᇘ?>.]ٳgصkqDF}s AR_m◝l~!M1?ax8DȪh4A_ZlzM4A-X+yf >ǏǪU|T*ß| v 4(xwtw=w~^̞=CE=Ľ_~?sqFddd`ƌ_ԩSѾ}{Qy ̙3?hٻ{{{cǎun+/1y* J h8fcc:Nd֧nxZOx饗h"z?l'a~ Dmƍg}777Qya쎍O?EA܋&;v`ׯV^z\ !%m_%Kcǎ5))I ˭"Vgggt }u.\+Wbƌ3f]Whi~D\E~B޳F>v]pUĺs( k33gĂ*믿0tPt[nB`RzQzjL:#F5k .e?\p!"3<:`prrbR駟0qD 2֭L&E\W;os!"ѺukܹDDd9HNN /`׿e2m۶x9LjZáT*ၩSsww_$յ8A.''lO&""q)JYYMi4&.ػw/Y)DD) """""-Psg.ng[@҇QUSADDDDD,*E """""T`y ҥKVgzz:S rUĚb`XT<~iV޽{ȜZZ?uݸqEcb.XT"a U5޼LVxNSSSqQ6OOO4mڴbիWM._ FR֭[ťbMHH@aa=s*ѩSZSɓ&mj7o4kzz:Laoo|mɉ+""""(zZ,dgg٤Yfknn.S;;;FRiXVP(L[l/7 +?XyyŐ!Cڏ=Ze{m D``I[ii),X{e9U(f1󢋵iӦf=e APPW:DDD,*/PXQMDDDDD,*jX5ha1*޽;\]]S y6bԫW/xzzrCDDĢg-:wlq6nܘ90L&虜EDDDßEö *#悈EE @q,c.XT """""bQADDDDD,**dggcڵHKKc23OE5> x:1DDwR~}# mڴAxx8ѣGpsCDĢ1@Dt/Ç5 qqqXx11h cD1<,^Xlذ2 PTT͛7㥗^/[ojL """s=6nHRz㸳gbݻ7ի#GbժU<EaÆaƍJJ+67 B/8q"d/9tOE{^퀢tqj{ ;h+VkG}oCq'xi~0JN]j''N@Trq;,X(H$`"C9sXx1Э[7DDD_ "bQuzYdZ%)2uV[dв"\%w7t,tå~_Fa.c-8 cUnhz{{W{vҤI֥*%%%ػw/݋9s}Tt:iZZrrr"VJ+WMq&%%AZs̩kYT<0b,\^L8V6΋(g} 8Ia'swN-2Uiqh(i }4ݡى:N^ 7toέlO,3 hժ~4'DTl(\T<:WZ-JKK$T*HR( ZPPH$(UVHbbyWkۡCDDD}/tAӡDINX0Ͻضy藇';ŐӳCDg*0&[Dh,A< sW>ֱx]Wq&d]s*辴 87;bG>&LGpp0f͚%X켑t1 4mY+k?pEQWruu5bРA-#sGsADt"22+VN0dXT<&ѽ ӧ#..QQQ C׮]ADĢz^zL ""$='MDDDDD,*j si|OǮ/:6dQADDDDĢH$́KU  D"""",*: w)ox@ڤvcw?C戈Dj8u^`]Vt1 t dEAz-zi/!@2b-9-8ˮ6""=ՐQhx,Q[Gϟ]LY+Qxh1P^z H?bҋ4qǩ+0T Q] zJNiW +W 7^zW ߘ hR7""""uHF͙p'/ ܿb>ùr1oDDDDւ?UayZNDcRbII{)9^ܩ kc ~@٭\*  +xD 1'o告m~Lʀ-.t.0\zpN[<:i%G+bpxa,Y1 ( h2+Ʒ~oP';L!s̝;פs1bģRJT o5UTS1Wh^^YhAL:cTmWͧ@[q\h3Qʒ ~(*.d@@Cqtx(gp 4:k (W"_ouY$CR||Յۆ/4U]6&-j &I0 """u@F@i%/C@.8dsV^+$|o~Vox@p /9PjŰ@ўlNك {>Ӱ<+ CPz P0"N$ @\[ULlCH^yÊ_z-*=wRr4m筂 áb[Appݯz%s1~7 EP Kx=p0Un$jݧn24w;BDDdx6=twPI/bIV0oDDDD,*N~\Ԅ"'bϊś؊aW =TwI!""bQ-1<ZG);tϣ ńbʭ`g]aLq57}\xL jmxln%WYh _u<5ˣ޾3,>Z4+&>oJ5 V>iZ상:"""D9 T7Oe """"Dw%7ܻKXeeW{7^c.XTՐ~,Pr "":oܛh\XuHdH(\xL jc#˲m t{Mݛ2I"؃9 ""bQ߿NBƍrnyW1qDKgTOޏxbH7CO]Ks!66x"ǡHOOǐ!CZ-*vlk%}Odg5ŚbUnww( \ ص0\Z/see9r$ "0^)22ݺumǒW.ep?54flaRPWZ`shhq*/Bz@\У{AբeKv=6EƍsNXskaXnqxf;a/{ {; Xp3\^H?b҉COovvvLC ßrrr+`ѢE *qk#|K?pssCpp0 pZ뱨(݋/B wwQV]n8@e/I~{JEgPXW}N/k@%Qcݯ݊G"!%b܋,:`L6έoESm6lܸ'NL&wE$fUmT"XOGA' ( ZfNYNG` IDATbCC\Q?g7|rպ:s;G;@_h0Sf4"ts,=Q\.[ݝwF XhͭxC ;69|=̀CUB;BA U_Y I-/>T#N(n @v2MDSQPP֭[^%KLvSqn۪PEb; <4d;!X}OGw!9Y MAGǐ: 8s N})ۦ85W`mhN;uSipC!ck)&v':w :|^ADk [Ekuwgz={7njlWO&NUVsnKD^EӞ{mzϟ';ŐӳLEF۠/ypC7>\+:EfA:W O>Сbbb ==111hժU\KģW^@ҕt l:WG/i7+O4 j:Ö3LX? 1+lh\-5)*ƍq1|&۔ &&ҥ EDT<`̘1fN:C;ùFhU"F_֞Y=I{Ӕi}O1R8c&N$*CGw!A1cFQF᧟~b,@4]t)lmm<̞=sNOͧd4qobYxXPḲ/em@='NrҶm[4jyyy("=;I&[r)ȥ o(9TeStsœ87T2))2ErM(V*PҴI~B[BOȣ9'srwN'#9Rt:tV?"44ƃ@BEid9SG#mlRnx#M7#nndZyN:f/a=ܖToX_wz~=JSm%Pg!f/xRGZ${M])x_H}Y׵N-ٳD*&Hظӂxs|@ +e=7H_QHdj@<ӂЂ:sII1'JˤBE#c%Uu&Jz@мN5g!TudT>@ Tl1sH;z0`ǟ&TЂ:cObGv|z^uM/R2_f @h,I7eH #;.KEz%Oqf/u*wn+<4ԵziT5_c@0`LE _҈ɓM_cicSbvSVMQөM5ѦW.SөM?=E_ TT~4famPz%{i,̲: `bp?)e??,DZhr+//2f)4>k?O'׷g65)] ֞>t$i˔1_llx>.;yLWZ꜂IW=]Gh|Vk?CO}%AQMمn_@Ea=UO?ݻnZ󤓛{뷯{hwqE\TuyʪS~7`azh:r뤑~(}[rHsFcCSL2Gv~}({ҋ#{Ks'Wwzzym/=moSgS;4y,~@}>5kWɞ.^%~FEj Tm?BٳtdZ0FIRBTnJ3Oa*<#˓.Sk;rԼ=j T)ϣ = Hnfl0ӧ[^J؞cuI%Ό;uRbRL]gxW)zҜ F⑁ҝKQͿ4?@SO1yA _ľBE#4.+# :T-;Wڞ)^ 8Rzao-5g|Wxja@Zy !mAirE]=XOz0[^ԕRbK1rI΋&15уo*-hw㪓ZR` ^Uj{;-6`/_ݨi TU UR}U-  1#PHx uc|M/̤@_( Go2_5'ow&Rޫ?s&E;0zQ *za&㖎Ӂ$,s=6$]{SV,j^u+"-븩II8=}e׾xz=QJL.+IZ2,>x6hWNK_j:,]~7w,/_ _Pe=c="w$i: F0ۤZ1q²M[kyi?$W3oM[맥ӈW۬_2c|zϽOcbO:*Gyd.1#!r}){`{Rvn/7F~l֝uvǏ?Olѣ5k,Y6Y~"BCCM2wj1}V='fZ=r L0{.wȐ!eҮ7heox5ZOdܴ~[-Us_rh=-س@^k^G˗/WJw$)j`]? hSNVݬsu|q=S'|XwHV~#K|7wi3MϛEޣ^>sa}lW_|MGBјi~UoGn]t#(A*,L[pJכ7o:h%^WiDiƌ?G}T;LQҥ/_*#Icݭ[7-_\=R{o4 }k6NN 1 PhnmDaGCCRܵ%b:%)\QrXD6Kk-qY-VO{@eR3INŦh4U:  %I/}IMr̢v1֖4fɘӷC[.X4|R>J4e)3Z`F3T3g3IR\?)rr㬎(%Ia0ͺqVi[jzsTVZ^{kɵRL#o*:D8= / ~IZt)ϓ% ,RR?h\z޷U׶HרQ4 HbLj$6IYx׍zu>c(Sripɞ"%Nfx40e`PI*#G)6u@0VRRzQg|?F.u+K/ T4Cu.h<@-ʥKy G*P?id ,vzKBZHw@m6fRC/#_X ^@Aԕ)#T1)v~&^5G4D)Kw64zFO̓ҷUҡ)5U}nRR>ҡi.Ro TK+0]dktL7^L]ҷJo4Y!}3N6+^*Y>BE*-s9AkG*t"-cW.C pi["mQR:)Pf uXʯNeiJ*H_5Q~D*;6+$.)4QE,Rx3/GRh:,!R%]/2ڒ 1}r}kIeIerr- PkHK)m><.U:$_Tq$7{Wܹ ;8b GNnRۚ޷V6r Չe8:!A2Tˈ҉5yQWIşHo*fx"zo{bl ؄Im:BvoTa͜93`^ǎuW[߿#6yoҖ6U?zed "-s,3R#nmcu2[S^t.Z.X~:RRh+ RUor4ݸ>b*vL iFʟ+2RސʏIΰJy{sΟI%koIik@Wޮ-:Z6MRw_#)utrw)itQS[\e"w ߴiSZ5x8bp*HƑO8B!;:UF 3+ޙ$2wTT{bӿ YʮpfH֊ur_Mwq߯!I%y敶tсTɞh8;8RaYp;RH2)_Y#E:$ozhc8zaqJSURفVRHE ҷJnFVt#*QeIa+(SZ"`EPͺ3plir[1iZRe~tttS;)㨃$u=TeؚHWmJ8WWgNG?,sv^jmr[y3qU{>Ry2Oۖfo3Oj2fi\IjX9rWm1.Չ?|qdU2>>SA4 Ԯw[7ي~lz}R@!IQ G*Wa —wInuIi[g㛶Oi6P@CÑ w'㔒g?N9Yq";0Pؓ G*j`D)0;vk m%ohl+)&cٵ[`"6%7fuon6Bj=?*J>]||k+ (w<#ĵKiP|i7W;BE;YfV6,DjN?Z)fq150s)~@s%Ts Pqns  PQť[_H.ne\N1T8p@_~\.:vLY, ?-9K9柷;"!wW-//Ok׮ѣGնm[C45T?~\Çג%KO0ASN 5Y-IӖI>/pLLo4s֢̀Ehcpݻ߯_~Y\sN6o,}Aj͗Ƽtm')t@ZU:ThFulH`Fz/^'xBvZh;wj޽45Tkھ}.\n`T2;CEHWD-ݑ%%6ec3Yb-ZSj„ KzAgUNEm!n6ҥ-~jpIr?6 &tbysHt2c5J(HБއzƨ2oşCGH43gt;W\W^yEvR4f :x<曧Oг_]V5< eH)hP\Iº{ tݻ}j޼z)M6M7nTrrcj: wUAA_]VZ_/wd=kӯ?O(M5{J $O4}5JQAqN__|Nۺuk 0 9R#ϧ?Xsѐ!Cԯ_?k6l8~8o^,Xpzi _l\`P!B€}ùl(77Wn[_4f͞=[=nݪ_-_\8=+IJV{S9:z(NX1F%-rM]gD5Z{]nJ>XSݝW)SY|X uٳgP ؼyu&Iz5l0I+??_PӦgEt֩X;vT\\YIi_Jvg|I:^$E}޳gBBB[RHvV}.Txx7|߯K23M۱c"##hZ?e)n:9T[)5^X7fn[C>OOH2ތ+rJ_^?=zf͚'jʔ)3gʕ+5o<ӯkܸq馛L]gNN222tqtʔ)ɩr33տ?O_bZ9RѪU+IS[nE_yf"[6l#ȑ#Ϻ)Қ}PJjxIw}c*$iܸWL6Fa#fVYi>Tt>yV\m 7vu\wr:_h}3gdvѣZ6lV\5kdԌiayr8WDD:H2ޅ>Xiz DBƎ+Ţ'jǎ*))̙3b [CHV˙o-Q!) ѽ+өS>Syy[o)))IIPGL=={ٳ5zh-ZH***R5{lY, RGX4VLiriC.im|WI66 0-Zhɒ%ջwo5iDjӦΝH*$oW߾}gڵ'¿qAv6hHݻwO?޽{Lv@JNN6UM hZhaS@Cg@@8{^Fs +BŞ={YVZZg}6`SO=%Cs!rG:t($ĸK_ԧO09N͝;t#ݮ4Tc*zNw^=5 뮻N_}$i˖-NS1C\Լysу5 #Gj5&~_h bРA $ƞ~2l*""Bg`_0ݡ &hڶmbccYZ{wtkׯ *+ 2Dwfɓ'#Gf;IDAT8tGy5 8gNSӦM#PO#w  o T3FW^ye:uzB6'=sTAAAegg+33SvQl"66V}80z5h ӟ ` ڸq֬Y0Pcǎ_:(PѫW/Iի3F[?̚H޽}N4iN8~&@0,l'wyG˖-?04Fe͘1C&MR||9ӧzN׮]4w\}'F*\.3h„ jӦ kpN[lƏngǟrssplR۷od ΚULL<$iǎJJJ1pAsuJLLTII{9OVTRR{@?!hTm۶ҥ.]ʚg:|n*NCG4i4c *̞=[}>{(**_|˗駟վ}{*y^}Zn&Mɓ'k4jAi6lt]wZ۲ev$r-zdXh {P@@@@BBBB*****PPPP T T T T@@@@BBBB***˕߼;IENDB`allegro-5.0.10/docs/html/refman/time.html0000644000175000001440000001320112157230674017402 0ustar tjadenusers Time routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_TIMEOUT

    typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT;

    Represent a timeout value. The size of the structure is known so can be statically allocated. The contents are private.

    See also: al_init_timeout

    al_get_time

    double al_get_time(void)

    Return the number of seconds since the Allegro library was initialised. The return value is undefined if Allegro is uninitialised. The resolution depends on the used driver, but typically can be in the order of microseconds.

    al_current_time

    Alternate spelling of al_get_time.

    al_init_timeout

    void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds)

    Set timeout value of some number of seconds after the function call.

    See also: ALLEGRO_TIMEOUT, al_wait_for_event_until

    al_rest

    void al_rest(double seconds)

    Waits for the specified number seconds. This tells the system to pause the current thread for the given amount of time. With some operating systems, the accuracy can be in the order of 10ms. That is, even

    al_rest(0.000001)

    might pause for something like 10ms. Also see the section on easier ways to time your program without using up all CPU.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/color.html0000644000175000001440000003735212157230675017600 0ustar tjadenusers Color addon

    These functions are declared in the following header file. Link with allegro_color.

    #include <allegro5/allegro_color.h>

    al_color_cmyk

    ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k)

    Return an ALLEGRO_COLOR structure from CMYK values (cyan, magenta, yellow, black).

    See also: al_color_cmyk_to_rgb, al_color_rgb_to_cmyk

    al_color_cmyk_to_rgb

    void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow,
        float key, float *red, float *green, float *blue)

    Convert CMYK values to RGB values.

    See also: al_color_cmyk, al_color_rgb_to_cmyk

    al_color_hsl

    ALLEGRO_COLOR al_color_hsl(float h, float s, float l)

    Return an ALLEGRO_COLOR structure from HSL (hue, saturation, lightness) values.

    See also: al_color_hsl_to_rgb, al_color_hsv

    al_color_hsl_to_rgb

    void al_color_hsl_to_rgb(float hue, float saturation, float lightness,
       float *red, float *green, float *blue)

    Convert values in HSL color model to RGB color model.

    Parameters:

    • hue - Color hue angle in the range 0..360.
    • saturation - Color saturation in the range 0..1.
    • lightness - Color lightness in the range 0..1.
    • red, green, blue - returned RGB values in the range 0..1.

    See also: al_color_rgb_to_hsl, al_color_hsl, al_color_hsv_to_rgb

    al_color_hsv

    ALLEGRO_COLOR al_color_hsv(float h, float s, float v)

    Return an ALLEGRO_COLOR structure from HSV (hue, saturation, value) values.

    See also: al_color_hsv_to_rgb, al_color_hsl

    al_color_hsv_to_rgb

    void al_color_hsv_to_rgb(float hue, float saturation, float value,
       float *red, float *green, float *blue)

    Convert values in HSV color model to RGB color model.

    Parameters:

    • hue - Color hue angle in the range 0..360.
    • saturation - Color saturation in the range 0..1.
    • value - Color value in the range 0..1.
    • red, green, blue - returned RGB values in the range 0..1.

    See also: al_color_rgb_to_hsv, al_color_hsv, al_color_hsl_to_rgb

    al_color_html

    ALLEGRO_COLOR al_color_html(char const *string)

    Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0.

    See also: al_color_html_to_rgb, al_color_rgb_to_html

    al_color_html_to_rgb

    void al_color_html_to_rgb(char const *string,
       float *red, float *green, float *blue)

    Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0.

    See also: al_color_html, al_color_rgb_to_html

    al_color_rgb_to_html

    void al_color_rgb_to_html(float red, float green, float blue,
        char *string)

    Create an HTML-style string representation of an ALLEGRO_COLOR, e.g. #00faff.

    Parameters:

    • red, green, blue - The color components in the range 0..1.
    • string - A pointer to a buffer of at least 8 bytes, into which the result will be written (including the NUL terminator).

    Example:

    char html[8];
    al_color_rgb_to_html(1, 0, 0, html);

    Now html will contain "#ff0000".

    See also: al_color_html, al_color_html_to_rgb

    al_color_name

    ALLEGRO_COLOR al_color_name(char const *name)

    Return an ALLEGRO_COLOR with the given name. If the color is not found then black is returned.

    See al_color_name_to_rgb for the list of names.

    al_color_name_to_rgb

    bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b)

    Parameters:

    • name - The (lowercase) name of the color.
    • r, g, b - If one of the recognized color names below is passed, the corresponding RGB values in the range 0..1 are written.

    The recognized names are:

    aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, purple, purwablue, red, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen

    They are taken from http://www.w3.org/TR/2010/PR-css3-color-20101028/#svg-color.

    Returns: true if a name from the list above was passed, else false.

    See also: al_color_name

    al_color_rgb_to_cmyk

    void al_color_rgb_to_cmyk(float red, float green, float blue,
       float *cyan, float *magenta, float *yellow, float *key)

    Each RGB color can be represented in CMYK with a K component of 0 with the following formula:

    C = 1 - R
    M = 1 - G
    Y = 1 - B
    K = 0

    This function will instead find the representation with the maximal value for K and minimal color components.

    See also: al_color_cmyk, al_color_cmyk_to_rgb

    al_color_rgb_to_hsl

    void al_color_rgb_to_hsl(float red, float green, float blue,
       float *hue, float *saturation, float *lightness)

    Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and lightness in the range 0..1.

    See also: al_color_hsl_to_rgb, al_color_hsl

    al_color_rgb_to_hsv

    void al_color_rgb_to_hsv(float red, float green, float blue,
       float *hue, float *saturation, float *value)

    Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and value in the range 0..1.

    See also: al_color_hsv_to_rgb, al_color_hsv

    al_color_rgb_to_name

    char const *al_color_rgb_to_name(float r, float g, float b)

    Given an RGB triplet with components in the range 0..1, find a color name describing it approximately.

    See also: al_color_name_to_rgb, al_color_name

    al_color_rgb_to_yuv

    void al_color_rgb_to_yuv(float red, float green, float blue,
       float *y, float *u, float *v)

    Convert RGB values to YUV color space.

    See also: al_color_yuv, al_color_yuv_to_rgb

    al_color_yuv

    ALLEGRO_COLOR al_color_yuv(float y, float u, float v)

    Return an ALLEGRO_COLOR structure from YUV values.

    See also: al_color_yuv_to_rgb, al_color_rgb_to_yuv

    al_color_yuv_to_rgb

    void al_color_yuv_to_rgb(float y, float u, float v,
        float *red, float *green, float *blue)

    Convert YUV color values to RGB color space.

    See also: al_color_yuv, al_color_rgb_to_yuv

    al_get_allegro_color_version

    uint32_t al_get_allegro_color_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:13 UTC

    allegro-5.0.10/docs/html/refman/path.html0000644000175000001440000004247312157230673017414 0ustar tjadenusers Path structures

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    We define a path as an optional drive, followed by zero or more directory components, followed by an optional filename. The filename may be broken up into a basename and an extension, where the basename includes the start of the filename up to, but not including, the last dot (.) character. If no dot character exists the basename is the whole filename. The extension is everything from the last dot character to the end of the filename.

    al_create_path

    ALLEGRO_PATH *al_create_path(const char *str)

    Create a path structure from a string. The last component, if it is followed by a directory separator and is neither "." nor "..", is treated as the last directory name in the path. Otherwise the last component is treated as the filename. The string may be NULL for an empty path.

    See also: al_create_path, al_destroy_path

    al_create_path_for_directory

    ALLEGRO_PATH *al_create_path_for_directory(const char *str)

    This is the same as al_create_path, but interprets the passed string as a directory path. The filename component of the returned path will always be empty.

    See also: al_create_path, al_destroy_path

    al_destroy_path

    void al_destroy_path(ALLEGRO_PATH *path)

    Free a path structure. Does nothing if passed NULL.

    See also: al_create_path, al_create_path_for_directory

    al_clone_path

    ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path)

    Clones an ALLEGRO_PATH structure. Returns NULL on failure.

    See also: al_destroy_path

    al_join_paths

    bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)

    Concatenate two path structures. The first path structure is modified. If 'tail' is an absolute path, this function does nothing.

    If 'tail' is a relative path, all of its directory components will be appended to 'path'. tail's filename will also overwrite path's filename, even if it is just the empty string.

    Tail's drive is ignored.

    Returns true if 'tail' was a relative path and so concatenated to 'path', otherwise returns false.

    See also: al_rebase_path

    al_rebase_path

    bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)

    Concatenate two path structures, modifying the second path structure. If tail is an absolute path, this function does nothing. Otherwise, the drive and path components in head are inserted at the start of tail.

    For example, if head is "/anchor/" and tail is "data/file.ext", then after the call tail becomes "/anchor/data/file.ext".

    See also: al_join_paths

    al_get_path_drive

    const char *al_get_path_drive(const ALLEGRO_PATH *path)

    Return the drive letter on a path, or the empty string if there is none.

    The "drive letter" is only used on Windows, and is usually a string like "c:", but may be something like "\\Computer Name" in the case of UNC (Uniform Naming Convention) syntax.

    al_get_path_num_components

    int al_get_path_num_components(const ALLEGRO_PATH *path)

    Return the number of directory components in a path.

    The directory components do not include the final part of a path (the filename).

    See also: al_get_path_component

    al_get_path_component

    const char *al_get_path_component(const ALLEGRO_PATH *path, int i)

    Return the i'th directory component of a path, counting from zero. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

    See also: al_get_path_num_components, al_get_path_tail

    al_get_path_tail

    const char *al_get_path_tail(const ALLEGRO_PATH *path)

    Returns the last directory component, or NULL if there are no directory components.

    al_get_path_filename

    const char *al_get_path_filename(const ALLEGRO_PATH *path)

    Return the filename part of the path, or the empty string if there is none.

    The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

    See also: al_get_path_basename, al_get_path_extension, al_get_path_component

    al_get_path_basename

    const char *al_get_path_basename(const ALLEGRO_PATH *path)

    Return the basename, i.e. filename with the extension removed. If the filename doesn't have an extension, the whole filename is the basename. If there is no filename part then the empty string is returned.

    The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

    See also: al_get_path_filename, al_get_path_extension

    al_get_path_extension

    const char *al_get_path_extension(const ALLEGRO_PATH *path)

    Return a pointer to the start of the extension of the filename, i.e. everything from the final dot ('.') character onwards. If no dot exists, returns an empty string.

    The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

    See also: al_get_path_filename, al_get_path_basename

    al_set_path_drive

    void al_set_path_drive(ALLEGRO_PATH *path, const char *drive)

    Set the drive string on a path. The drive may be NULL, which is equivalent to setting the drive string to the empty string.

    See also: al_get_path_drive

    al_append_path_component

    void al_append_path_component(ALLEGRO_PATH *path, const char *s)

    Append a directory component.

    See also: al_insert_path_component

    al_insert_path_component

    void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s)

    Insert a directory component at index i. If the index is negative then count from the right, i.e. -1 refers to the last path component.

    It is an error to pass an index i which is not within these bounds: 0 <= i <= al_get_path_num_components(path).

    See also: al_append_path_component, al_replace_path_component, al_remove_path_component

    al_replace_path_component

    void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s)

    Replace the i'th directory component by another string. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

    See also: al_insert_path_component, al_remove_path_component

    al_remove_path_component

    void al_remove_path_component(ALLEGRO_PATH *path, int i)

    Delete the i'th directory component. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

    See also: al_insert_path_component, al_replace_path_component, al_drop_path_tail

    al_drop_path_tail

    void al_drop_path_tail(ALLEGRO_PATH *path)

    Remove the last directory component, if any.

    See also: al_remove_path_component

    al_set_path_filename

    void al_set_path_filename(ALLEGRO_PATH *path, const char *filename)

    Set the optional filename part of the path. The filename may be NULL, which is equivalent to setting the filename to the empty string.

    See also: al_set_path_extension, al_get_path_filename

    al_set_path_extension

    bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension)

    Replaces the extension of the path with the given one, i.e. replaces everything from the final dot ('.') character onwards, including the dot. If the filename of the path has no extension, the given one is appended. Usually the new extension you supply should include a leading dot.

    Returns false if the path contains no filename part, i.e. the filename part is the empty string.

    See also: al_set_path_filename, al_get_path_extension

    al_path_cstr

    const char *al_path_cstr(const ALLEGRO_PATH *path, char delim)

    Convert a path to its string representation, i.e. optional drive, followed by directory components separated by 'delim', followed by an optional filename.

    To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP for 'delim'.

    The returned pointer is valid only until the path is modified in any way, or until the path is destroyed.

    al_make_path_canonical

    bool al_make_path_canonical(ALLEGRO_PATH *path)

    Removes any leading '..' directory components in absolute paths. Removes all '.' directory components.

    Note that this does not collapse "x/../y" sections into "y". This is by design. If "/foo" on your system is a symlink to "/bar/baz", then "/foo/../quux" is actually "/bar/quux", not "/quux" as a naive removal of ".." components would give you.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/display.html0000644000175000001440000010014712157230670020113 0ustar tjadenusers Displays

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    Display creation

    ALLEGRO_DISPLAY

    typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY;

    An opaque type representing an open display or window.

    al_create_display

    ALLEGRO_DISPLAY *al_create_display(int w, int h)

    Create a display, or window, with the specified dimensions. The parameters of the display are determined by the last calls to al_set_new_display_*. Default parameters are used if none are set explicitly. Creating a new display will automatically make it the active one, with the backbuffer selected for drawing.

    Returns NULL on error.

    Each display has a distinct OpenGL rendering context associated with it. See al_set_target_bitmap for the discussion about rendering contexts.

    See also: al_set_new_display_flags, al_set_new_display_option, al_set_new_display_refresh_rate, al_set_new_display_adapter, al_set_window_position

    al_destroy_display

    void al_destroy_display(ALLEGRO_DISPLAY *display)

    Destroy a display.

    If the target bitmap of the calling thread is tied to the display, then it implies a call to "al_set_target_bitmap(NULL);" before the display is destroyed.

    That special case notwithstanding, you should make sure no threads are currently targeting a bitmap which is tied to the display before you destroy it.

    See also: al_set_target_bitmap

    al_get_new_display_flags

    int al_get_new_display_flags(void)

    Get the display flags to be used when creating new displays on the calling thread.

    See also: al_set_new_display_flags, al_set_display_flag

    al_set_new_display_flags

    void al_set_new_display_flags(int flags)

    Sets various flags to be used when creating new displays on the calling thread. flags is a bitfield containing any reasonable combination of the following:

    ALLEGRO_WINDOWED

    Prefer a windowed mode.

    Under multi-head X (not XRandR/TwinView), the use of more than one adapter is impossible due to bugs in X and GLX. al_create_display will fail if more than one adapter is attempted to be used.

    ALLEGRO_FULLSCREEN

    Prefer a fullscreen mode.

    Under X the use of more than one FULLSCREEN display when using multi-head X, or true Xinerama is not possible due to bugs in X and GLX, display creation will fail if more than one adapter is attempted to be used.

    ALLEGRO_FULLSCREEN_WINDOW

    Make the window span the entire screen. Unlike ALLEGRO_FULLSCREEN this will never attempt to modify the screen resolution. Instead the pixel dimensions of the created display will be the same as the desktop.

    The passed width and height are only used if the window is switched out of fullscreen mode later but will be ignored initially.

    Under Windows and X11 a fullscreen display created with this flag will behave differently from one created with the ALLEGRO_FULLSCREEN flag - even if the ALLEGRO_FULLSCREEN display is passed the desktop dimensions. The exact difference is platform dependent, but some things which may be different is how alt-tab works, how fast you can toggle between fullscreen/windowed mode or how additional monitors behave while your display is in fullscreen mode.

    Additionally under X, the use of more than one adapter in multi-head mode or with true Xinerama enabled is impossible due to bugs in X/GLX, creation will fail if more than one adapter is attempted to be used.

    ALLEGRO_RESIZABLE

    The display is resizable (only applicable if combined with ALLEGRO_WINDOWED).

    ALLEGRO_OPENGL

    Require the driver to provide an initialized OpenGL context after returning successfully.

    ALLEGRO_OPENGL_3_0

    Require the driver to provide an initialized OpenGL context compatible with OpenGL version 3.0.

    ALLEGRO_OPENGL_FORWARD_COMPATIBLE

    If this flag is set, the OpenGL context created with ALLEGRO_OPENGL_3_0 will be forward compatible only, meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not be supported. Currently, a display created with this flag will not be compatible with Allegro drawing routines; the display option ALLEGRO_COMPATIBLE_DISPLAY will be set to false.

    ALLEGRO_DIRECT3D

    Require the driver to do rendering with Direct3D and provide a Direct3D device.

    ALLEGRO_FRAMELESS

    Try to create a window without a frame (i.e. no border or titlebar). This usually does nothing for fullscreen modes, and even in windowed modes it depends on the underlying platform whether it is supported or not. Since: 5.0.7, 5.1.2

    ALLEGRO_NOFRAME

    Original name for ALLEGRO_FRAMELESS. This works with older versions of Allegro.

    ALLEGRO_GENERATE_EXPOSE_EVENTS

    Let the display generate expose events.

    0 can be used for default values.

    See also: al_set_new_display_option, al_get_display_option, [al_change_display_option]

    al_get_new_display_option

    int al_get_new_display_option(int option, int *importance)

    Retrieve an extra display setting which was previously set with al_set_new_display_option.

    al_set_new_display_option

    void al_set_new_display_option(int option, int value, int importance)

    Set an extra display option, to be used when creating new displays on the calling thread. Display options differ from display flags, and specify some details of the context to be created within the window itself. These mainly have no effect on Allegro itself, but you may want to specify them, for example if you want to use multisampling.

    The 'importance' parameter can be either:

    • ALLEGRO_REQUIRE - The display will not be created if the setting can not be met.
    • ALLEGRO_SUGGEST - If the setting is not available, the display will be created anyway. FIXME: We need a way to query the settings back from a created display.
    • ALLEGRO_DONTCARE - If you added a display option with one of the above two settings before, it will be removed again. Else this does nothing.

    The supported options are:

    ALLEGRO_COLOR_SIZE

    This can be used to ask for a specific bit depth. For example to force a 16-bit framebuffer set this to 16.

    ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE

    Individual color component size in bits.

    ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT

    Together with the previous settings these can be used to specify the exact pixel layout the display should use. Normally there is no reason to use these.

    ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE

    This can be used to define the required accumulation buffer size.

    ALLEGRO_STEREO

    Whether the display is a stereo display.

    ALLEGRO_AUX_BUFFERS

    Number of auxiliary buffers the display should have.

    ALLEGRO_DEPTH_SIZE

    How many depth buffer (z-buffer) bits to use.

    ALLEGRO_STENCIL_SIZE

    How many bits to use for the stencil buffer.

    ALLEGRO_SAMPLE_BUFFERS

    Whether to use multisampling (1) or not (0).

    ALLEGRO_SAMPLES

    If the above is 1, the number of samples to use per pixel. Else 0.

    ALLEGRO_RENDER_METHOD:

    0 if hardware acceleration is not used with this display.

    ALLEGRO_FLOAT_COLOR

    Whether to use floating point color components.

    ALLEGRO_FLOAT_DEPTH

    Whether to use a floating point depth buffer.

    ALLEGRO_SINGLE_BUFFER

    Whether the display uses a single buffer (1) or another update method (0).

    ALLEGRO_SWAP_METHOD

    If the above is 0, this is set to 1 to indicate the display is using a copying method to make the next buffer in the flip chain available, or to 2 to indicate a flipping or other method.

    ALLEGRO_COMPATIBLE_DISPLAY

    Indicates if Allegro's graphics functions can use this display. If you request a display not useable by Allegro, you can still use for example OpenGL to draw graphics.

    ALLEGRO_UPDATE_DISPLAY_REGION

    Set to 1 if the display is capable of updating just a region, and 0 if calling al_update_display_region is equivalent to al_flip_display.

    ALLEGRO_VSYNC

    Set to 1 to tell the driver to wait for vsync in al_flip_display, or to 2 to force vsync off. The default of 0 means that Allegro does not try to modify the vsync behavior so it may be on or off. Note that even in the case of 1 or 2 it is possible to override the vsync behavior in the graphics driver so you should not rely on it.

    ALLEGRO_MAX_BITMAP_SIZE

    When queried this returns the maximum size (width as well as height) a bitmap can have for this display. Calls to al_create_bitmap or al_load_bitmap for bitmaps larger than this size will fail. It does not apply to memory bitmaps which always can have arbitrary size (but are slow for drawing).

    ALLEGRO_SUPPORT_NPOT_BITMAP

    Set to 1 if textures used for bitmaps on this display can have a size which is not a power of two. This is mostly useful if you use Allegro to load textures as otherwise only power-of-two textures will be used internally as bitmap storage.

    ALLEGRO_CAN_DRAW_INTO_BITMAP

    Set to 1 if you can use al_set_target_bitmap on bitmaps of this display to draw into them. If this is not the case software emulation will be used when drawing into display bitmaps (which can be very slow).

    ALLEGRO_SUPPORT_SEPARATE_ALPHA

    This is set to 1 if the al_set_separate_blender function is supported. Otherwise the alpha parameters will be ignored.

    See also: al_set_new_display_flags

    al_reset_new_display_options

    void al_reset_new_display_options(void)

    This undoes any previous call to al_set_new_display_option on the calling thread.

    al_get_new_window_position

    void al_get_new_window_position(int *x, int *y)

    Get the position where new non-fullscreen displays created by the calling thread will be placed.

    See also: al_set_new_window_position

    al_set_new_window_position

    void al_set_new_window_position(int x, int y)

    Sets where the top left pixel of the client area of newly created windows (non-fullscreen) will be on screen, for displays created by the calling thread. Negative values allowed on some multihead systems.

    To reset to the default behaviour, pass (INT_MAX, INT_MAX).

    See also: al_get_new_window_position

    al_get_new_display_refresh_rate

    int al_get_new_display_refresh_rate(void)

    Get the requested refresh rate to be used when creating new displays on the calling thread.

    See also: al_set_new_display_refresh_rate

    al_set_new_display_refresh_rate

    void al_set_new_display_refresh_rate(int refresh_rate)

    Sets the refresh rate to use when creating new displays on the calling thread. If the refresh rate is not available, al_create_display will fail. A list of modes with refresh rates can be found with al_get_num_display_modes and al_get_display_mode.

    The default setting is zero (don't care).

    See also: al_get_new_display_refresh_rate

    Display operations

    al_get_display_event_source

    ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display)

    Retrieve the associated event source.

    al_get_backbuffer

    ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display)

    Return a special bitmap representing the back-buffer of the display.

    Care should be taken when using the backbuffer bitmap (and its sub-bitmaps) as the source bitmap (e.g as the bitmap argument to al_draw_bitmap). Only untransformed operations are hardware accelerated. This consists of al_draw_bitmap and al_draw_bitmap_region when the current transformation is the identity. If the tranformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the al_draw_bitmap and al_draw_bitmap_region), and then use that temporary bitmap as the source bitmap.

    al_flip_display

    void al_flip_display(void)

    Copies or updates the front and back buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back buffer bitmap remain valid and retain their semantics as the back buffer, although the contents may have changed.

    Several display options change how this function behaves:

    • With ALLEGRO_SINGLE_BUFFER, no flipping is done. You still have to call this function to display graphics, depending on how the used graphics system works.

    • The ALLEGRO_SWAP_METHOD option may have additional information about what kind of operation is used internally to flip the front and back buffers.

    • If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. If ALLEGRO_VSYNC is 2, this function will not wait for vsync. With many drivers the vsync behavior is controlled by the user and not the application, and ALLEGRO_VSYNC will not be set; in this case al_flip_display will wait for vsync depending on the settings set in the system's graphics preferences.

    See also: al_set_new_display_flags, al_set_new_display_option

    al_update_display_region

    void al_update_display_region(int x, int y, int width, int height)

    Does the same as al_flip_display, but tries to update only the specified region. With many drivers this is not possible, but for some it can improve performance.

    The ALLEGRO_UPDATE_DISPLAY_REGION option (see al_get_display_option) will specify the behavior of this function in the display.

    See also: al_flip_display, al_get_display_option

    al_wait_for_vsync

    bool al_wait_for_vsync(void)

    Wait for the beginning of a vertical retrace. Some driver/card/monitor combinations may not be capable of this.

    Note how al_flip_display usually already waits for the vertical retrace, so unless you are doing something special, there is no reason to call this function.

    Returns false if not possible, true if successful.

    See also: al_flip_display

    Display size and position

    al_get_display_width

    int al_get_display_width(ALLEGRO_DISPLAY *display)

    Gets the width of the display. This is like SCREEN_W in Allegro 4.x.

    See also: al_get_display_height

    al_get_display_height

    int al_get_display_height(ALLEGRO_DISPLAY *display)

    Gets the height of the display. This is like SCREEN_H in Allegro 4.x.

    See also: al_get_display_width

    al_resize_display

    bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height)

    Resize the display. Returns true on success, or false on error. This works on both fullscreen and windowed displays, regardless of the ALLEGRO_RESIZABLE flag.

    Adjusts the clipping rectangle to the full size of the backbuffer.

    See also: al_acknowledge_resize

    al_acknowledge_resize

    bool al_acknowledge_resize(ALLEGRO_DISPLAY *display)

    When the user receives a resize event from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display. Returns true on success.

    Adjusts the clipping rectangle to the full size of the backbuffer.

    Note that a resize event may be outdated by the time you acknowledge it; there could be further resize events generated in the meantime.

    See also: al_resize_display, ALLEGRO_EVENT

    al_get_window_position

    void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y)

    Gets the position of a non-fullscreen display.

    See also: al_set_window_position

    al_set_window_position

    void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y)

    Sets the position on screen of a non-fullscreen display.

    See also: al_get_window_position

    Display settings

    al_get_display_flags

    int al_get_display_flags(ALLEGRO_DISPLAY *display)

    Gets the flags of the display.

    In addition to the flags set for the display at creation time with al_set_new_display_flags it can also have the ALLEGRO_MINIMIZED flag set, indicating that the window is currently minimized. This flag is very platform-dependent as even a minimized application may still render a preview version so normally you should not care whether it is minimized or not.

    See also: al_set_new_display_flags, al_set_display_flag

    al_set_display_flag

    bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)

    Enable or disable one of the display flags. The flags are the same as for al_set_new_display_flags. The only flags that can be changed after creation are:

    • ALLEGRO_FULLSCREEN_WINDOW
    • ALLEGRO_FRAMELESS

    Returns true if the driver supports toggling the specified flag else false. You can use al_get_display_flags to query whether the given display property actually changed.

    Since: 5.0.7, 5.1.2

    See also: al_set_new_display_flags, al_get_display_flags

    al_toggle_display_flag

    bool al_toggle_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)

    Deprecated synonym for al_set_display_flag.

    al_get_display_option

    int al_get_display_option(ALLEGRO_DISPLAY *display, int option)

    Return an extra display setting of the display.

    See also: al_set_new_display_option

    al_get_display_format

    int al_get_display_format(ALLEGRO_DISPLAY *display)

    Gets the pixel format of the display.

    See also: ALLEGRO_PIXEL_FORMAT

    al_get_display_refresh_rate

    int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display)

    Gets the refresh rate of the display.

    See also: al_set_new_display_refresh_rate

    al_set_window_title

    void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title)

    Set the title on a display.

    See also: al_set_display_icon, al_set_display_icons

    al_set_display_icon

    void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)

    Changes the icon associated with the display (window). Same as al_set_display_icons with one icon.

    See also: al_set_display_icons, al_set_window_title

    al_set_display_icons

    void al_set_display_icons(ALLEGRO_DISPLAY *display,
       int num_icons, ALLEGRO_BITMAP *icons[])

    Changes the icons associated with the display (window). Multiple icons can be provided for use in different contexts, e.g. window frame, taskbar, alt-tab popup. The number of icons must be at least one.

    Note: If the underlying OS requires an icon of a size not provided then one of the bitmaps will be scaled up or down to the required size. The choice of bitmap is implementation dependent.

    Since: 5.0.9, 5.1.5

    See also: al_set_display_icon, al_set_window_title

    Screensaver

    al_inhibit_screensaver

    bool al_inhibit_screensaver(bool inhibit)

    This function allows the user to stop the system screensaver from starting up if true is passed, or resets the system back to the default state (the state at program start) if false is passed. It returns true if the state was set successfully, otherwise false.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:08 UTC

    allegro-5.0.10/docs/html/refman/image.html0000644000175000001440000001236712157230676017544 0ustar tjadenusers Image I/O addon

    These functions are declared in the following header file. Link with allegro_image.

    #include <allegro5/allegro_image.h>

    al_init_image_addon

    bool al_init_image_addon(void)

    Initializes the image addon. This registers bitmap format handlers for al_load_bitmap, al_load_bitmap_f, al_save_bitmap, al_save_bitmap_f.

    The following types are built into the Allegro image addon and guaranteed to be available: BMP, PCX, TGA. Every platform also supports JPEG and PNG via external dependencies.

    Other formats may be available depending on the operating system and installed libraries, but are not guaranteed and should not be assumed to be universally available.

    al_shutdown_image_addon

    void al_shutdown_image_addon(void)

    Shut down the image addon. This is done automatically at program exit, but can be called any time the user wishes as well.

    al_get_allegro_image_version

    uint32_t al_get_allegro_image_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    allegro-5.0.10/docs/html/refman/system.html0000644000175000001440000003276312157230673020005 0ustar tjadenusers System routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    al_install_system

    bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))

    Initialize the Allegro system. No other Allegro functions can be called before this (with one or two exceptions).

    The version field should always be set to ALLEGRO_VERSION_INT.

    If atexit_ptr is non-NULL, and if hasn't been done already, al_uninstall_system will be registered as an atexit function.

    Returns true if Allegro was successfully initialized by this function call (or already was initialized previously), false if Allegro cannot be used.

    See also: al_init

    al_init

    #define al_init()    (al_install_system(ALLEGRO_VERSION_INT, atexit))

    Like al_install_system, but automatically passes in the version and uses the atexit function visible in the current compilation unit.

    See also: al_install_system

    al_uninstall_system

    void al_uninstall_system(void)

    Closes down the Allegro system.

    Note: al_uninstall_system() can be called without a corresponding al_install_system call, e.g. from atexit().

    al_is_system_installed

    bool al_is_system_installed(void)

    Returns true if Allegro is initialized, otherwise returns false.

    al_get_allegro_version

    uint32_t al_get_allegro_version(void)

    Returns the (compiled) version of the Allegro library, packed into a single integer as groups of 8 bits in the form (major << 24) | (minor << 16) | (revision << 8) | release.

    You can use code like this to extract them:

    uint32_t version = al_get_allegro_version();
    int major = version >> 24;
    int minor = (version >> 16) & 255;
    int revision = (version >> 8) & 255;
    int release = version & 255;

    The release number is 0 for an unofficial version and 1 or greater for an official release. For example "5.0.2[1]" would be the (first) official 5.0.2 release while "5.0.2[0]" would be a compile of a version from the "5.0.2" branch before the official release.

    al_get_standard_path

    ALLEGRO_PATH *al_get_standard_path(int id)

    Gets a system path, depending on the id parameter. Some of these paths may be affected by the organization and application name, so be sure to set those before calling this function.

    The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may be the same on some platforms), so you should be sure your filenames are unique if you need to avoid naming collisions. Also, a returned path may not actually exist on the file system.

    ALLEGRO_RESOURCES_PATH

    If you bundle data in a location relative to your executable, then you should use this path to locate that data. On most platforms, this is the directory that contains the executable file.

    If ran from an OS X app bundle, then this will point to the internal resource directory (/Contents/Resources). To maintain consistency, if you put your resources into a directory called "data" beneath the executable on some other platform (like Windows), then you should also create a directory called "data" under the OS X app bundle's resource folder.

    You should not try to write to this path, as it is very likely read-only.

    If you install your resources in some other system directory (e.g., in /usr/share or C:\ProgramData), then you are responsible for keeping track of that yourself.

    ALLEGRO_TEMP_PATH

    Path to the directory for temporary files.

    ALLEGRO_USER_HOME_PATH

    This is the user's home directory. You should not normally write files into this directory directly, or create any sub folders in it, without explicit permission from the user. One practical application of this path would be to use it as the starting place of a file selector in a GUI.

    ALLEGRO_USER_DOCUMENTS_PATH

    This location is easily accessible by the user, and is the place to store documents and files that the user might want to later open with an external program or transfer to another place.

    You should not save files here unless the user expects it, usually by explicit permission.

    ALLEGRO_USER_DATA_PATH

    If your program saves any data that the user doesn't need to access externally, then you should place it here. This is generally the least intrusive place to store data.

    ALLEGRO_USER_SETTINGS_PATH

    If you are saving configuration files (especially if the user may want to edit them outside of your program), then you should place them here.

    ALLEGRO_EXENAME_PATH

    The full path to the executable.

    Returns NULL on failure. The returned path should be freed with al_destroy_path.

    See also: al_set_app_name, al_set_org_name, al_destroy_path, al_set_exe_name

    al_set_exe_name

    void al_set_exe_name(char const *path)

    This override the executable name used by al_get_standard_path for ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH.

    One possibility where changing this can be useful is if you use the Python wrapper. Allegro would then by default think that the system's Python executable is the current executable - but you can set it to the .py file being executed instead.

    Since: 5.0.6, 5.1.0

    See also: al_get_standard_path

    al_set_app_name

    void al_set_app_name(const char *app_name)

    Sets the global application name.

    The application name is used by al_get_standard_path to build the full path to an application's files.

    This function may be called before al_init or al_install_system.

    See also: al_get_app_name, al_set_org_name

    al_set_org_name

    void al_set_org_name(const char *org_name)

    Sets the global organization name.

    The organization name is used by al_get_standard_path to build the full path to an application's files.

    This function may be called before al_init or al_install_system.

    See also: al_get_org_name, al_set_app_name

    al_get_app_name

    const char *al_get_app_name(void)

    Returns the global application name string.

    See also: al_set_app_name

    al_get_org_name

    const char *al_get_org_name(void)

    Returns the global organization name string.

    See also: al_set_org_name

    al_get_system_config

    ALLEGRO_CONFIG *al_get_system_config(void)

    Returns the current system configuration structure, or NULL if there is no active system driver. The returned configuration should not be destroyed with al_destroy_config. This is mainly used for configuring Allegro and its addons.

    al_register_assert_handler

    void al_register_assert_handler(void (*handler)(char const *expr,
       char const *file, int line, char const *func))

    Register a function to be called when an internal Allegro assertion fails. Pass NULL to reset to the default behaviour, which is to do whatever the standard assert() macro does.

    Since: 5.0.6, 5.1.0

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/acodec.html0000644000175000001440000001275612157230675017701 0ustar tjadenusers Audio codecs addon

    These functions are declared in the following header file. Link with allegro_acodec.

    #include <allegro5/allegro_acodec.h>

    al_init_acodec_addon

    bool al_init_acodec_addon(void)

    This function registers all the known audio file type handlers for al_load_sample, al_save_sample, al_load_audio_stream, etc.

    Depending on what libraries are available, the full set of recognised extensions is: .wav, .flac, .ogg, .it, .mod, .s3m, .xm.

    Limitations:

    • Saving is only supported for wav files.

    • Wav file loader currently only supports 8/16 bit little endian PCM files. 16 bits are used when saving wav files. Use flac files if more precision is required.

    • Module files (.it, .mod, .s3m, .xm) are often composed with streaming in mind, and sometimes cannot be easily rendered into a finite length sample. Therefore they cannot be loaded with al_load_sample/al_load_sample_f and must be streamed with al_load_audio_stream or al_load_audio_stream_f.

    Return true on success.

    al_get_allegro_acodec_version

    uint32_t al_get_allegro_acodec_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:13 UTC

    allegro-5.0.10/docs/html/refman/index.html0000644000175000001440000001330512157230677017563 0ustar tjadenusers Allegro 5.0 reference manual allegro-5.0.10/docs/html/refman/fshook.html0000644000175000001440000004723212157230671017745 0ustar tjadenusers File system routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    These functions allow access to the filesystem. This can either be the real filesystem like your harddrive, or a virtual filesystem like a .zip archive (or whatever else you or an addon makes it do).

    ALLEGRO_FS_ENTRY

    typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY;

    Opaque filesystem entry object. Represents a file or a directory (check with al_get_fs_entry_mode). There are no user accessible member variables.

    ALLEGRO_FILE_MODE

    typedef enum ALLEGRO_FILE_MODE

    Filesystem modes/types

    • ALLEGRO_FILEMODE_READ - Readable
    • ALLEGRO_FILEMODE_WRITE - Writable
    • ALLEGRO_FILEMODE_EXECUTE - Executable
    • ALLEGRO_FILEMODE_HIDDEN - Hidden
    • ALLEGRO_FILEMODE_ISFILE - Regular file
    • ALLEGRO_FILEMODE_ISDIR - Directory

    al_create_fs_entry

    ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path)

    Creates an ALLEGRO_FS_ENTRY object pointing to path on the filesystem. 'path' can be a file or a directory and must not be NULL.

    al_destroy_fs_entry

    void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh)

    Destroys a fs entry handle. The file or directory represented by it is not destroyed. If the entry was opened, it is closed before being destroyed.

    Does nothing if passed NULL.

    al_get_fs_entry_name

    const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e)

    Returns the entry's filename path. Note that the filesystem encoding may not be known and the conversion to UTF-8 could in very rare cases cause this to return an invalid path. Therefore it's always safest to access the file over its ALLEGRO_FS_ENTRY and not the path.

    On success returns a read only string which you must not modify or destroy. Returns NULL on failure.

    Note: prior to 5.1.5 it was written: "... the path will not be an absolute path if the entry wasn't created from an absolute path". This is no longer true.

    al_update_fs_entry

    bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e)

    Updates file status information for a filesystem entry. File status information is automatically updated when the entry is created, however you may update it again with this function, e.g. in case it changed.

    Returns true on success, false on failure. Fills in errno to indicate the error.

    See also: al_get_errno, al_get_fs_entry_atime, al_get_fs_entry_ctime, al_get_fs_entry_mode

    al_get_fs_entry_mode

    uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e)

    Returns the entry's mode flags, i.e. permissions and whether the entry refers to a file or directory.

    See also: al_get_errno, ALLEGRO_FILE_MODE

    al_get_fs_entry_atime

    time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e)

    Returns the time in seconds since the epoch since the entry was last accessed.

    Warning: some filesystem either don't support this flag, or people turn it off to increase performance. It may not be valid in all circumstances.

    See also: al_get_fs_entry_ctime, al_get_fs_entry_mtime, al_update_fs_entry

    al_get_fs_entry_ctime

    time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e)

    Returns the time in seconds since the epoch this entry was created on the filesystem.

    See also: al_get_fs_entry_atime, al_get_fs_entry_mtime, al_update_fs_entry

    al_get_fs_entry_mtime

    time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e)

    Returns the time in seconds since the epoch since the entry was last modified.

    See also: al_get_fs_entry_atime, al_get_fs_entry_ctime, al_update_fs_entry

    al_get_fs_entry_size

    off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e)

    Returns the size, in bytes, of the given entry. May not return anything sensible for a directory entry.

    See also: al_update_fs_entry

    al_fs_entry_exists

    bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e)

    Check if the given entry exists on in the filesystem. Returns true if it does exist or false if it doesn't exist, or an error occurred. Error is indicated in Allegro's errno.

    See also: al_filename_exists

    al_remove_fs_entry

    bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e)

    Delete this filesystem entry from the filesystem. Only files and empty directories may be deleted.

    Returns true on success, and false on failure, error is indicated in Allegro's errno.

    See also: al_filename_exists

    al_filename_exists

    bool al_filename_exists(const char *path)

    Check if the path exists on the filesystem, without creating an ALLEGRO_FS_ENTRY object explicitly.

    See also: al_fs_entry_exists

    al_remove_filename

    bool al_remove_filename(const char *path)

    Delete the given path from the filesystem, which may be a file or an empty directory. This is the same as al_remove_fs_entry, except it expects the path as a string.

    Returns true on success, and false on failure. Allegro's errno is filled in to indicate the error.

    See also: al_remove_fs_entry

    Directory functions

    al_open_directory

    bool al_open_directory(ALLEGRO_FS_ENTRY *e)

    Opens a directory entry object. You must call this before using al_read_directory on an entry and you must call al_close_directory when you no longer need it.

    Returns true on success.

    See also: al_read_directory, al_close_directory

    al_read_directory

    ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e)

    Reads the next directory item and returns a filesystem entry for it.

    Returns NULL if there are no more entries or if an error occurs. Call al_destroy_fs_entry on the returned entry when you are done with it.

    See also: al_open_directory, al_close_directory

    al_close_directory

    bool al_close_directory(ALLEGRO_FS_ENTRY *e)

    Closes a previously opened directory entry object.

    Returns true on success, false on failure and fills in Allegro's errno to indicate the error.

    See also: al_open_directory, al_read_directory

    al_get_current_directory

    char *al_get_current_directory(void)

    Returns the path to the current working directory, or NULL on failure. The returned path is dynamically allocated and must be destroyed with al_free.

    Allegro's errno is filled in to indicate the error if there is a failure. This function may not be implemented on some (virtual) filesystems.

    See also: al_get_errno, al_free

    al_change_directory

    bool al_change_directory(const char *path)

    Changes the current working directory to 'path'.

    Returns true on success, false on error.

    al_make_directory

    bool al_make_directory(const char *path)

    Creates a new directory on the filesystem. This function also creates any parent directories as needed.

    Returns true on success (including if the directory already exists), otherwise returns false on error. Fills in Allegro's errno to indicate the error.

    See also: al_get_errno

    al_open_fs_entry

    ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode)

    Open an ALLEGRO_FILE handle to a filesystem entry, for the given access mode. This is like calling al_fopen with the name of the filesystem entry, but uses the appropriate file interface, not whatever was set with the latest call to al_set_new_file_interface.

    Returns the handle on success, NULL on error.

    See also: al_fopen

    Alternative filesystem functions

    By default, Allegro uses platform specific filesystem functions for things like directory access. However if for example the files of your game are not in the local filesystem but inside some file archive, you can provide your own set of functions (or use an addon which does this for you, for example our physfs addon allows access to the most common archive formats).

    ALLEGRO_FS_INTERFACE

    typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE;

    The available functions you can provide for a filesystem. They are:

       ALLEGRO_FS_ENTRY *  fs_create_entry   (const char *path);
       void                fs_destroy_entry  (ALLEGRO_FS_ENTRY *e);
       const char *        fs_entry_name     (ALLEGRO_FS_ENTRY *e);
       bool                fs_update_entry   (ALLEGRO_FS_ENTRY *e);
       uint32_t            fs_entry_mode     (ALLEGRO_FS_ENTRY *e);
       time_t              fs_entry_atime    (ALLEGRO_FS_ENTRY *e);
       time_t              fs_entry_mtime    (ALLEGRO_FS_ENTRY *e);
       time_t              fs_entry_ctime    (ALLEGRO_FS_ENTRY *e);
       off_t               fs_entry_size     (ALLEGRO_FS_ENTRY *e);
       bool                fs_entry_exists   (ALLEGRO_FS_ENTRY *e);
       bool                fs_remove_entry   (ALLEGRO_FS_ENTRY *e);
    
       bool                fs_open_directory (ALLEGRO_FS_ENTRY *e);
       ALLEGRO_FS_ENTRY *  fs_read_directory (ALLEGRO_FS_ENTRY *e);
       bool                fs_close_directory(ALLEGRO_FS_ENTRY *e);
    
       bool                fs_filename_exists(const char *path);
       bool                fs_remove_filename(const char *path);
       char *              fs_get_current_directory(void);
       bool                fs_change_directory(const char *path);
       bool                fs_make_directory(const char *path);
    
       ALLEGRO_FILE *      fs_open_file(ALLEGRO_FS_ENTRY *e);

    al_set_fs_interface

    void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface)

    Set the ALLEGRO_FS_INTERFACE table for the calling thread.

    See also: al_set_standard_fs_interface, al_store_state, al_restore_state.

    al_set_standard_fs_interface

    void al_set_standard_fs_interface(void)

    Return the ALLEGRO_FS_INTERFACE table to the default, for the calling thread.

    See also: al_set_fs_interface.

    al_get_fs_interface

    const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void)

    Return a pointer to the ALLEGRO_FS_INTERFACE table in effect for the calling thread.

    See also: al_store_state, al_restore_state.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:09 UTC

    allegro-5.0.10/docs/html/refman/native_dialog.html0000644000175000001440000003761612157230676021273 0ustar tjadenusers Native dialogs support

    These functions are declared in the following header file. Link with allegro_dialog.

    #include <allegro5/allegro_native_dialog.h>

    ALLEGRO_FILECHOOSER

    typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER;

    Opaque handle to a native file dialog.

    ALLEGRO_TEXTLOG

    typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG;

    Opaque handle to a text log window.

    al_init_native_dialog_addon

    bool al_init_native_dialog_addon(void)

    Initialise the native dialog addon.

    Returns true on success, false on error.

    Since: 5.0.9, 5.1.0

    Note: Prior to Allegro 5.1.0 native dialog functions could be called without explicit initialisation, but that is now deprecated. Future functionality may require explicit initialisation. An exception is al_show_native_message_box, which may be useful to show an error message if Allegro fails to initialise.

    See also: al_shutdown_native_dialog_addon

    al_shutdown_native_dialog_addon

    void al_shutdown_native_dialog_addon(void)

    Shut down the native dialog addon.

    Since: 5.0.9, 5.1.5

    See also: al_init_native_dialog_addon

    al_create_native_file_dialog

    ALLEGRO_FILECHOOSER *al_create_native_file_dialog(
       char const *initial_path,
       char const *title,
       char const *patterns,
       int mode)

    Creates a new native file dialog. You should only have one such dialog opened at a time.

    Parameters:

    • initial_path: The initial search path and filename. Can be NULL. To start with a blank file name the string should end with a directory separator (this should be the common case).

    • title: Title of the dialog.

    • patterns: A list of semi-colon separated patterns to match. You should always include the pattern "*.*" as usually the MIME type and not the file pattern is relevant. If no file patterns are supported by the native dialog, this parameter is ignored.

    • mode: 0, or a combination of the flags below.

    Possible flags for the 'flags' parameter are:

    ALLEGRO_FILECHOOSER_FILE_MUST_EXIST
    If supported by the native dialog, it will not allow entering new names, but just allow existing files to be selected. Else it is ignored.
    ALLEGRO_FILECHOOSER_SAVE
    If the native dialog system has a different dialog for saving (for example one which allows creating new directories), it is used. Else ignored.
    ALLEGRO_FILECHOOSER_FOLDER
    If there is support for a separate dialog to select a folder instead of a file, it will be used.
    ALLEGRO_FILECHOOSER_PICTURES
    If a different dialog is available for selecting pictures, it is used. Else ignored.
    ALLEGRO_FILECHOOSER_SHOW_HIDDEN
    If the platform supports it, also hidden files will be shown.
    ALLEGRO_FILECHOOSER_MULTIPLE
    If supported, allow selecting multiple files.

    Returns:

    A handle to the dialog which you can pass to al_show_native_file_dialog to display it, and from which you then can query the results. When you are done, call al_destroy_native_file_dialog on it.

    If a dialog window could not be created then this function returns NULL.

    al_show_native_file_dialog

    bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
       ALLEGRO_FILECHOOSER *dialog)

    Show the dialog window. The display may be NULL, otherwise the given display is treated as the parent if possible.

    This function blocks the calling thread until it returns, so you may want to spawn a thread with al_create_thread and call it from inside that thread.

    Returns true on success, false on failure.

    al_get_native_file_dialog_count

    int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog)

    Returns the number of files selected, or 0 if the dialog was cancelled.

    al_get_native_file_dialog_path

    const char *al_get_native_file_dialog_path(
       const ALLEGRO_FILECHOOSER *dialog, size_t i)

    Returns one of the selected paths.

    al_destroy_native_file_dialog

    void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog)

    Frees up all resources used by the file dialog.

    al_show_native_message_box

    int al_show_native_message_box(ALLEGRO_DISPLAY *display,
       char const *title, char const *heading, char const *text,
       char const *buttons, int flags)

    Show a native GUI message box. This can be used for example to display an error message if creation of an initial display fails. The display may be NULL, otherwise the given display is treated as the parent if possible.

    The message box will have a single "OK" button and use the style informative dialog boxes usually have on the native system. If the buttons parameter is not NULL, you can instead specify the button text in a string, with buttons separated by a vertical bar (|).

    ALLEGRO_MESSAGEBOX_WARN
    The message is a warning. This may cause a different icon (or other effects).
    ALLEGRO_MESSAGEBOX_ERROR
    The message is an error.
    ALLEGRO_MESSAGEBOX_QUESTION
    The message is a question.
    ALLEGRO_MESSAGEBOX_OK_CANCEL
    Instead of the "OK" button also display a cancel button. Ignored if buttons is not NULL.
    ALLEGRO_MESSAGEBOX_YES_NO
    Instead of the "OK" button display Yes/No buttons. Ignored if buttons is not NULL.

    al_show_native_message_box may be called without Allegro being installed. This is useful to report an error to initialise Allegro itself.

    Returns:

    • 0 if the dialog window was closed without activating a button.
    • 1 if the OK or Yes button was pressed.
    • 2 if the Cancel or No button was pressed.

    If buttons is not NULL, the number of the pressed button is returned, starting with 1.

    If a message box could not be created then this returns 0, as if the window was dismissed without activating a button.

    Example:

      button = al_show_native_message_box(
         display,
         "Warning",
         "Are you sure?",
         "If you click yes then you are confirming that \"Yes\""
         "is your response to the query which you have"
         "generated by the action you took to open this"
         "message box.",
         NULL,
         ALLEGRO_MESSAGEBOX_YES_NO
      );

    al_open_native_text_log

    ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags)

    Opens a window to which you can append log messages with al_append_native_text_log. This can be useful for debugging if you don't want to depend on a console being available.

    Use al_close_native_text_log to close the window again.

    The flags available are:

    ALLEGRO_TEXTLOG_NO_CLOSE

    Prevent the window from having a close button. Otherwise if the close button is pressed an event is generated; see al_get_native_text_log_event_source.

    ALLEGRO_TEXTLOG_MONOSPACE

    Use a monospace font to display the text.

    Returns NULL if there was an error opening the window, or if text log windows are not implemented on the platform.

    See also: al_append_native_text_log, al_close_native_text_log

    al_close_native_text_log

    void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog)

    Closes a message log window opened with al_open_native_text_log earlier.

    Does nothing if passed NULL.

    See also: al_open_native_text_log

    al_append_native_text_log

    void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog,
       char const *format, ...)

    Appends a line of text to the message log window and scrolls to the bottom (if the line would not be visible otherwise). This works like printf. A line is continued until you add a newline character.

    If the window is NULL then this function will fall back to calling printf. This makes it convenient to support logging to a window or a terminal.

    al_get_native_text_log_event_source

    ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source(
       ALLEGRO_TEXTLOG *textlog)

    Get an event source for a text log window. The possible events are:

    ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE
    The window was requested to be closed, either by pressing the close button or pressing Escape on the keyboard. The user.data1 field will hold a pointer to the ALLEGRO_TEXTLOG which generated the event. The user.data2 field will be 1 if the event was generated as a result of a key press; otherwise it will be zero.

    al_get_allegro_native_dialog_version

    uint32_t al_get_allegro_native_dialog_version(void)

    Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:14 UTC

    allegro-5.0.10/docs/html/refman/keyboard.html0000644000175000001440000002435112157230672020252 0ustar tjadenusers Keyboard routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_KEYBOARD_STATE

    typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE;

    This is a structure that is used to hold a "snapshot" of a keyboard's state at a particular instant. It contains the following publically readable fields:

    • display - points to the display that had keyboard focus at the time the state was saved. If no display was focused, this points to NULL.

    You cannot read the state of keys directly. Use the function al_key_down.

    Key codes

    The constant ALLEGRO_KEY_MAX is always one higher than the highest key code. So if you want to use the key code as array index you can do something like this:

    bool pressed_keys[ALLEGRO_KEY_MAX];
    ...
    pressed_keys[key_code] = true;

    These are the list of key codes used by Allegro, which are returned in the event.keyboard.keycode field of the ALLEGRO_KEY_DOWN and ALLEGRO_KEY_UP events and which you can pass to al_key_down:

    ALLEGRO_KEY_A ... ALLEGRO_KEY_Z
    ALLEGRO_KEY_0 ... ALLEGRO_KEY_9
    ALLEGRO_KEY_PAD_0 ... ALLEGRO_KEY_PAD_9
    ALLEGRO_KEY_F1 ... ALLEGRO_KEY_F12
    ALLEGRO_KEY_ESCAPE
    ALLEGRO_KEY_TILDE
    ALLEGRO_KEY_MINUS
    ALLEGRO_KEY_EQUALS
    ALLEGRO_KEY_BACKSPACE
    ALLEGRO_KEY_TAB
    ALLEGRO_KEY_OPENBRACE
    ALLEGRO_KEY_CLOSEBRACE
    ALLEGRO_KEY_ENTER
    ALLEGRO_KEY_SEMICOLON
    ALLEGRO_KEY_QUOTE
    ALLEGRO_KEY_BACKSLASH
    ALLEGRO_KEY_BACKSLASH2
    ALLEGRO_KEY_COMMA
    ALLEGRO_KEY_FULLSTOP
    ALLEGRO_KEY_SLASH
    ALLEGRO_KEY_SPACE
    ALLEGRO_KEY_INSERT
    ALLEGRO_KEY_DELETE
    ALLEGRO_KEY_HOME
    ALLEGRO_KEY_END
    ALLEGRO_KEY_PGUP
    ALLEGRO_KEY_PGDN
    ALLEGRO_KEY_LEFT
    ALLEGRO_KEY_RIGHT
    ALLEGRO_KEY_UP
    ALLEGRO_KEY_DOWN
    ALLEGRO_KEY_PAD_SLASH
    ALLEGRO_KEY_PAD_ASTERISK
    ALLEGRO_KEY_PAD_MINUS
    ALLEGRO_KEY_PAD_PLUS
    ALLEGRO_KEY_PAD_DELETE
    ALLEGRO_KEY_PAD_ENTER
    ALLEGRO_KEY_PRINTSCREEN
    ALLEGRO_KEY_PAUSE
    ALLEGRO_KEY_ABNT_C1
    ALLEGRO_KEY_YEN
    ALLEGRO_KEY_KANA
    ALLEGRO_KEY_CONVERT
    ALLEGRO_KEY_NOCONVERT
    ALLEGRO_KEY_AT
    ALLEGRO_KEY_CIRCUMFLEX
    ALLEGRO_KEY_COLON2
    ALLEGRO_KEY_KANJI
    ALLEGRO_KEY_LSHIFT
    ALLEGRO_KEY_RSHIFT
    ALLEGRO_KEY_LCTRL
    ALLEGRO_KEY_RCTRL
    ALLEGRO_KEY_ALT
    ALLEGRO_KEY_ALTGR
    ALLEGRO_KEY_LWIN
    ALLEGRO_KEY_RWIN
    ALLEGRO_KEY_MENU
    ALLEGRO_KEY_SCROLLLOCK
    ALLEGRO_KEY_NUMLOCK
    ALLEGRO_KEY_CAPSLOCK
    ALLEGRO_KEY_PAD_EQUALS
    ALLEGRO_KEY_BACKQUOTE
    ALLEGRO_KEY_SEMICOLON2
    ALLEGRO_KEY_COMMAND

    Keyboard modifier flags

    ALLEGRO_KEYMOD_SHIFT
    ALLEGRO_KEYMOD_CTRL
    ALLEGRO_KEYMOD_ALT
    ALLEGRO_KEYMOD_LWIN
    ALLEGRO_KEYMOD_RWIN
    ALLEGRO_KEYMOD_MENU
    ALLEGRO_KEYMOD_ALTGR
    ALLEGRO_KEYMOD_COMMAND
    ALLEGRO_KEYMOD_SCROLLLOCK
    ALLEGRO_KEYMOD_NUMLOCK
    ALLEGRO_KEYMOD_CAPSLOCK
    ALLEGRO_KEYMOD_INALTSEQ
    ALLEGRO_KEYMOD_ACCENT1
    ALLEGRO_KEYMOD_ACCENT2
    ALLEGRO_KEYMOD_ACCENT3
    ALLEGRO_KEYMOD_ACCENT4

    The event field 'keyboard.modifiers' is a bitfield composed of these constants. These indicate the modifier keys which were pressed at the time a character was typed.

    al_install_keyboard

    bool al_install_keyboard(void)

    Install a keyboard driver. Returns true if successful. If a driver was already installed, nothing happens and true is returned.

    See also: al_uninstall_keyboard, al_is_keyboard_installed

    al_is_keyboard_installed

    bool al_is_keyboard_installed(void)

    Returns true if al_install_keyboard was called successfully.

    al_uninstall_keyboard

    void al_uninstall_keyboard(void)

    Uninstalls the active keyboard driver, if any. This will automatically unregister the keyboard event source with any event queues.

    This function is automatically called when Allegro is shut down.

    See also: al_install_keyboard

    al_get_keyboard_state

    void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state)

    Save the state of the keyboard specified at the time the function is called into the structure pointed to by ret_state.

    See also: al_key_down, ALLEGRO_KEYBOARD_STATE

    al_key_down

    bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode)

    Return true if the key specified was held down in the state specified.

    See also: ALLEGRO_KEYBOARD_STATE

    al_keycode_to_name

    const char *al_keycode_to_name(int keycode)

    Converts the given keycode to a description of the key.

    al_set_keyboard_leds

    bool al_set_keyboard_leds(int leds)

    Overrides the state of the keyboard LED indicators. Set to -1 to return to default behavior. False is returned if the current keyboard driver cannot set LED indicators.

    al_get_keyboard_event_source

    ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void)

    Retrieve the keyboard event source.

    Returns NULL if the keyboard subsystem was not installed.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:10 UTC

    allegro-5.0.10/docs/html/refman/misc.html0000644000175000001440000001137412157230672017406 0ustar tjadenusers Miscellaneous routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_PI

    #define ALLEGRO_PI        3.14159265358979323846

    C99 compilers have no predefined value like M_PI for the constant π, but you can use this one instead.

    al_run_main

    int al_run_main(int argc, char **argv, int (*user_main)(int, char **))

    This function is useful in cases where you don't have a main() function but want to run Allegro (mostly useful in a wrapper library). Under Windows and Linux this is no problem because you simply can call al_install_system. But some other system (like OSX) don't allow calling al_install_system in the main thread. al_run_main will know what to do in that case.

    The passed argc and argv will simply be passed on to user_main and the return value of user_main will be returned.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:10 UTC

    allegro-5.0.10/docs/html/refman/joystick.html0000644000175000001440000004024512157230672020311 0ustar tjadenusers Joystick routines

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_JOYSTICK

    typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK;

    This is an abstract data type representing a physical joystick.

    See also: al_get_joystick

    ALLEGRO_JOYSTICK_STATE

    typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE;

    This is a structure that is used to hold a "snapshot" of a joystick's axes and buttons at a particular instant. All fields public and read-only.

    struct {
          float axis[num_axes];             // -1.0 to 1.0 
    } stick[num_sticks];
    int button[num_buttons];                // 0 to 32767

    See also: al_get_joystick_state

    ALLEGRO_JOYFLAGS

    enum ALLEGRO_JOYFLAGS
    • ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input
    • ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input

    (this enum is a holdover from the old API and may be removed)

    See also: al_get_joystick_stick_flags

    al_install_joystick

    bool al_install_joystick(void)

    Install a joystick driver, returning true if successful. If a joystick driver was already installed, returns true immediately.

    See also: al_uninstall_joystick

    al_uninstall_joystick

    void al_uninstall_joystick(void)

    Uninstalls the active joystick driver. All outstanding ALLEGRO_JOYSTICK structures are invalidated. If no joystick driver was active, this function does nothing.

    This function is automatically called when Allegro is shut down.

    See also: al_install_joystick

    al_is_joystick_installed

    bool al_is_joystick_installed(void)

    Returns true if al_install_joystick was called successfully.

    al_reconfigure_joysticks

    bool al_reconfigure_joysticks(void)

    Allegro is able to cope with users connecting and disconnected joystick devices on-the-fly. On existing platforms, the joystick event source will generate an event of type ALLEGRO_EVENT_JOYSTICK_CONFIGURATION when a device is plugged in or unplugged. In response, you should call al_reconfigure_joysticks.

    Afterwards, the number returned by al_get_num_joysticks may be different, and the handles returned by al_get_joystick may be different or be ordered differently.

    All ALLEGRO_JOYSTICK handles remain valid, but handles for disconnected devices become inactive: their states will no longer update, and al_get_joystick will not return the handle. Handles for devices which remain connected will continue to represent the same devices. Previously inactive handles may become active again, being reused to represent newly connected devices.

    Returns true if the joystick configuration changed, otherwise returns false.

    It is possible that on some systems, Allegro won't be able to generate ALLEGRO_EVENT_JOYSTICK_CONFIGURATION events. If your game has an input configuration screen or similar, you may wish to call al_reconfigure_joysticks when entering that screen.

    See also: al_get_joystick_event_source, ALLEGRO_EVENT

    al_get_num_joysticks

    int al_get_num_joysticks(void)

    Return the number of joysticks currently on the system (or potentially on the system). This number can change after al_reconfigure_joysticks is called, in order to support hotplugging.

    Returns 0 if there is no joystick driver installed.

    See also: al_get_joystick, al_get_joystick_active

    al_get_joystick

    ALLEGRO_JOYSTICK * al_get_joystick(int num)

    Get a handle for a joystick on the system. The number may be from 0 to al_get_num_joysticks-1. If successful a pointer to a joystick object is returned, which represents a physical device. Otherwise NULL is returned.

    The handle and the index are only incidentally linked. After al_reconfigure_joysticks is called, al_get_joystick may return handles in a different order, and handles which represent disconnected devices will not be returned.

    See also: al_get_num_joysticks, al_reconfigure_joysticks, al_get_joystick_active

    al_release_joystick

    void al_release_joystick(ALLEGRO_JOYSTICK *joy)

    This function currently does nothing.

    See also: al_get_joystick

    al_get_joystick_active

    bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy)

    Return if the joystick handle is "active", i.e. in the current configuration, the handle represents some physical device plugged into the system. al_get_joystick returns active handles. After reconfiguration, active handles may become inactive, and vice versa.

    See also: al_reconfigure_joysticks

    al_get_joystick_name

    const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy)

    Return the name of the given joystick.

    See also: al_get_joystick_stick_name, al_get_joystick_axis_name, al_get_joystick_button_name

    al_get_joystick_stick_name

    const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick)

    Return the name of the given "stick". If the stick doesn't exist, NULL is returned.

    See also: al_get_joystick_axis_name, al_get_joystick_num_sticks

    al_get_joystick_axis_name

    const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis)

    Return the name of the given axis. If the axis doesn't exist, NULL is returned. Indices begin from 0.

    See also: al_get_joystick_stick_name, al_get_joystick_num_axes

    al_get_joystick_button_name

    const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button)

    Return the name of the given button. If the button doesn't exist, NULL is returned. Indices begin from 0.

    See also: al_get_joystick_stick_name, al_get_joystick_axis_name, al_get_joystick_num_buttons

    al_get_joystick_stick_flags

    int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick)

    Return the flags of the given "stick". If the stick doesn't exist, NULL is returned. Indices begin from 0.

    See also: ALLEGRO_JOYFLAGS

    al_get_joystick_num_sticks

    int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy)

    Return the number of "sticks" on the given joystick. A stick has one or more axes.

    See also: al_get_joystick_num_axes, al_get_joystick_num_buttons

    al_get_joystick_num_axes

    int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick)

    Return the number of axes on the given "stick". If the stick doesn't exist, 0 is returned.

    See also: al_get_joystick_num_sticks

    al_get_joystick_num_buttons

    int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy)

    Return the number of buttons on the joystick.

    See also: al_get_joystick_num_sticks

    al_get_joystick_state

    void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state)

    Get the current joystick state.

    See also: ALLEGRO_JOYSTICK_STATE, al_get_joystick_num_buttons, al_get_joystick_num_axes

    al_get_joystick_event_source

    ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void)

    Returns the global joystick event source. All joystick events are generated by this event source.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:10 UTC

    allegro-5.0.10/docs/html/refman/search_index.js0000644000175000001440000012512112157230670020551 0ustar tjadenusersvar search_index = [ 'ALLEGRO_CONFIG','al_create_config','al_destroy_config','al_load_config_file','al_load_config_file_f','al_save_config_file','al_save_config_file_f','al_add_config_section','al_add_config_comment','al_get_config_value','al_set_config_value','al_get_first_config_section','al_get_next_config_section','al_get_first_config_entry','al_get_next_config_entry','al_merge_config','al_merge_config_into','ALLEGRO_DISPLAY','al_create_display','al_destroy_display','al_get_new_display_flags','al_set_new_display_flags','al_get_new_display_option','al_set_new_display_option','al_reset_new_display_options','al_get_new_window_position','al_set_new_window_position','al_get_new_display_refresh_rate','al_set_new_display_refresh_rate','al_get_display_event_source','al_get_backbuffer','al_flip_display','al_update_display_region','al_wait_for_vsync','al_get_display_width','al_get_display_height','al_resize_display','al_acknowledge_resize','al_get_window_position','al_set_window_position','al_get_display_flags','al_set_display_flag','al_toggle_display_flag','al_get_display_option','al_get_display_format','al_get_display_refresh_rate','al_set_window_title','al_set_display_icon','al_set_display_icons','al_inhibit_screensaver','ALLEGRO_EVENT','ALLEGRO_EVENT_JOYSTICK_AXIS','ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN','ALLEGRO_EVENT_JOYSTICK_BUTTON_UP','ALLEGRO_EVENT_JOYSTICK_CONFIGURATION','ALLEGRO_EVENT_KEY_DOWN','ALLEGRO_EVENT_KEY_UP','ALLEGRO_EVENT_KEY_CHAR','ALLEGRO_EVENT_MOUSE_AXES','ALLEGRO_EVENT_MOUSE_BUTTON_DOWN','ALLEGRO_EVENT_MOUSE_BUTTON_UP','ALLEGRO_EVENT_MOUSE_WARPED','ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY','ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY','ALLEGRO_EVENT_TIMER','ALLEGRO_EVENT_DISPLAY_EXPOSE','ALLEGRO_EVENT_DISPLAY_RESIZE','ALLEGRO_EVENT_DISPLAY_CLOSE','ALLEGRO_EVENT_DISPLAY_LOST','ALLEGRO_EVENT_DISPLAY_FOUND','ALLEGRO_EVENT_DISPLAY_SWITCH_OUT','ALLEGRO_EVENT_DISPLAY_SWITCH_IN','ALLEGRO_EVENT_DISPLAY_ORIENTATION','ALLEGRO_USER_EVENT','ALLEGRO_EVENT_QUEUE','ALLEGRO_EVENT_SOURCE','ALLEGRO_EVENT_TYPE','ALLEGRO_GET_EVENT_TYPE','ALLEGRO_EVENT_TYPE_IS_USER','al_create_event_queue','al_destroy_event_queue','al_register_event_source','al_unregister_event_source','al_is_event_queue_empty','al_get_next_event','al_peek_next_event','al_drop_next_event','al_flush_event_queue','al_wait_for_event','al_wait_for_event_timed','al_wait_for_event_until','al_init_user_event_source','al_destroy_user_event_source','al_emit_user_event','al_unref_user_event','al_get_event_source_data','al_set_event_source_data','ALLEGRO_FILE','ALLEGRO_FILE_INTERFACE','ALLEGRO_SEEK','al_fopen','al_fopen_interface','al_fopen_slice','al_fclose','al_fread','al_fwrite','al_fflush','al_ftell','al_fseek','al_feof','al_ferror','al_fclearerr','al_fungetc','al_fsize','al_fgetc','al_fputc','al_fread16le','al_fread16be','al_fwrite16le','al_fwrite16be','al_fread32le','al_fread32be','al_fwrite32le','al_fwrite32be','al_fgets','al_fget_ustr','al_fputs','al_fopen_fd','al_make_temp_file','al_set_new_file_interface','al_set_standard_file_interface','al_get_new_file_interface','al_create_file_handle','al_get_file_userdata','al_fixed','al_itofix','al_fixtoi','al_fixfloor','al_fixceil','al_ftofix','al_fixtof','al_fixmul','al_fixdiv','al_fixadd','al_fixsub','al_fixtorad_r','al_radtofix_r','al_fixsin','al_fixcos','al_fixtan','al_fixasin','al_fixacos','al_fixatan','al_fixatan2','al_fixsqrt','al_fixhypot','ALLEGRO_FS_ENTRY','ALLEGRO_FILE_MODE','al_create_fs_entry','al_destroy_fs_entry','al_get_fs_entry_name','al_update_fs_entry','al_get_fs_entry_mode','al_get_fs_entry_atime','al_get_fs_entry_ctime','al_get_fs_entry_mtime','al_get_fs_entry_size','al_fs_entry_exists','al_remove_fs_entry','al_filename_exists','al_remove_filename','al_open_directory','al_read_directory','al_close_directory','al_get_current_directory','al_change_directory','al_make_directory','al_open_fs_entry','ALLEGRO_FS_INTERFACE','al_set_fs_interface','al_set_standard_fs_interface','al_get_fs_interface','ALLEGRO_DISPLAY_MODE','al_get_display_mode','al_get_num_display_modes','ALLEGRO_COLOR','al_map_rgb','al_map_rgb_f','al_map_rgba','al_map_rgba_f','al_unmap_rgb','al_unmap_rgb_f','al_unmap_rgba','al_unmap_rgba_f','ALLEGRO_LOCKED_REGION','ALLEGRO_PIXEL_FORMAT','al_get_pixel_size','al_get_pixel_format_bits','al_lock_bitmap','al_lock_bitmap_region','al_unlock_bitmap','ALLEGRO_BITMAP','al_create_bitmap','al_create_sub_bitmap','al_clone_bitmap','al_destroy_bitmap','al_get_new_bitmap_flags','al_get_new_bitmap_format','al_set_new_bitmap_flags','al_add_new_bitmap_flag','al_set_new_bitmap_format','al_get_bitmap_flags','al_get_bitmap_format','al_get_bitmap_height','al_get_bitmap_width','al_get_pixel','al_is_bitmap_locked','al_is_compatible_bitmap','al_is_sub_bitmap','al_get_parent_bitmap','al_clear_to_color','al_draw_bitmap','al_draw_tinted_bitmap','al_draw_bitmap_region','al_draw_tinted_bitmap_region','al_draw_pixel','al_draw_rotated_bitmap','al_draw_tinted_rotated_bitmap','al_draw_scaled_rotated_bitmap','al_draw_tinted_scaled_rotated_bitmap','al_draw_tinted_scaled_rotated_bitmap_region','al_draw_scaled_bitmap','al_draw_tinted_scaled_bitmap','al_get_target_bitmap','al_put_pixel','al_put_blended_pixel','al_set_target_bitmap','al_set_target_backbuffer','al_get_current_display','al_get_blender','al_get_separate_blender','al_set_blender','al_set_separate_blender','al_get_clipping_rectangle','al_set_clipping_rectangle','al_reset_clipping_rectangle','al_convert_mask_to_alpha','al_hold_bitmap_drawing','al_is_bitmap_drawing_held','al_register_bitmap_loader','al_register_bitmap_saver','al_register_bitmap_loader_f','al_register_bitmap_saver_f','al_load_bitmap','al_load_bitmap_f','al_save_bitmap','al_save_bitmap_f','ALLEGRO_JOYSTICK','ALLEGRO_JOYSTICK_STATE','ALLEGRO_JOYFLAGS','al_install_joystick','al_uninstall_joystick','al_is_joystick_installed','al_reconfigure_joysticks','al_get_num_joysticks','al_get_joystick','al_release_joystick','al_get_joystick_active','al_get_joystick_name','al_get_joystick_stick_name','al_get_joystick_axis_name','al_get_joystick_button_name','al_get_joystick_stick_flags','al_get_joystick_num_sticks','al_get_joystick_num_axes','al_get_joystick_num_buttons','al_get_joystick_state','al_get_joystick_event_source','ALLEGRO_KEYBOARD_STATE','al_install_keyboard','al_is_keyboard_installed','al_uninstall_keyboard','al_get_keyboard_state','al_key_down','al_keycode_to_name','al_set_keyboard_leds','al_get_keyboard_event_source','al_malloc','al_free','al_realloc','al_calloc','al_malloc_with_context','al_free_with_context','al_realloc_with_context','al_calloc_with_context','ALLEGRO_MEMORY_INTERFACE','al_set_memory_interface','ALLEGRO_PI','al_run_main','ALLEGRO_MONITOR_INFO','al_get_new_display_adapter','al_set_new_display_adapter','al_get_monitor_info','al_get_num_video_adapters','ALLEGRO_MOUSE_STATE','al_install_mouse','al_is_mouse_installed','al_uninstall_mouse','al_get_mouse_num_axes','al_get_mouse_num_buttons','al_get_mouse_state','al_get_mouse_state_axis','al_mouse_button_down','al_set_mouse_xy','al_set_mouse_z','al_set_mouse_w','al_set_mouse_axis','al_get_mouse_event_source','al_create_mouse_cursor','al_destroy_mouse_cursor','al_set_mouse_cursor','al_set_system_mouse_cursor','al_get_mouse_cursor_position','al_hide_mouse_cursor','al_show_mouse_cursor','al_grab_mouse','al_ungrab_mouse','al_create_path','al_create_path_for_directory','al_destroy_path','al_clone_path','al_join_paths','al_rebase_path','al_get_path_drive','al_get_path_num_components','al_get_path_component','al_get_path_tail','al_get_path_filename','al_get_path_basename','al_get_path_extension','al_set_path_drive','al_append_path_component','al_insert_path_component','al_replace_path_component','al_remove_path_component','al_drop_path_tail','al_set_path_filename','al_set_path_extension','al_path_cstr','al_make_path_canonical','ALLEGRO_STATE','ALLEGRO_STATE_FLAGS','al_restore_state','al_store_state','al_get_errno','al_set_errno','al_install_system','al_init','al_uninstall_system','al_is_system_installed','al_get_allegro_version','al_get_standard_path','al_set_exe_name','al_set_app_name','al_set_org_name','al_get_app_name','al_get_org_name','al_get_system_config','al_register_assert_handler','ALLEGRO_THREAD','ALLEGRO_MUTEX','ALLEGRO_COND','al_create_thread','al_start_thread','al_join_thread','al_set_thread_should_stop','al_get_thread_should_stop','al_destroy_thread','al_run_detached_thread','al_create_mutex','al_create_mutex_recursive','al_lock_mutex','al_unlock_mutex','al_destroy_mutex','al_create_cond','al_destroy_cond','al_wait_cond','al_wait_cond_until','al_broadcast_cond','al_signal_cond','ALLEGRO_TIMEOUT','al_get_time','al_current_time','al_init_timeout','al_rest','ALLEGRO_TIMER','ALLEGRO_USECS_TO_SECS','ALLEGRO_MSECS_TO_SECS','ALLEGRO_BPS_TO_SECS','ALLEGRO_BPM_TO_SECS','al_create_timer','al_start_timer','al_stop_timer','al_get_timer_started','al_destroy_timer','al_get_timer_count','al_set_timer_count','al_add_timer_count','al_get_timer_speed','al_set_timer_speed','al_get_timer_event_source','ALLEGRO_TRANSFORM','al_copy_transform','al_use_transform','al_get_current_transform','al_invert_transform','al_check_inverse','al_identity_transform','al_build_transform','al_translate_transform','al_rotate_transform','al_scale_transform','al_transform_coordinates','al_compose_transform','ALLEGRO_USTR','ALLEGRO_USTR_INFO','al_ustr_new','al_ustr_new_from_buffer','al_ustr_newf','al_ustr_free','al_cstr','al_ustr_to_buffer','al_cstr_dup','al_ustr_dup','al_ustr_dup_substr','al_ustr_empty_string','al_ref_cstr','al_ref_buffer','al_ref_ustr','al_ustr_size','al_ustr_length','al_ustr_offset','al_ustr_next','al_ustr_prev','al_ustr_get','al_ustr_get_next','al_ustr_prev_get','al_ustr_insert','al_ustr_insert_cstr','al_ustr_insert_chr','al_ustr_append','al_ustr_append_cstr','al_ustr_append_chr','al_ustr_appendf','al_ustr_vappendf','al_ustr_remove_chr','al_ustr_remove_range','al_ustr_truncate','al_ustr_ltrim_ws','al_ustr_rtrim_ws','al_ustr_trim_ws','al_ustr_assign','al_ustr_assign_substr','al_ustr_assign_cstr','al_ustr_set_chr','al_ustr_replace_range','al_ustr_find_chr','al_ustr_rfind_chr','al_ustr_find_set','al_ustr_find_set_cstr','al_ustr_find_cset','al_ustr_find_cset_cstr','al_ustr_find_str','al_ustr_find_cstr','al_ustr_rfind_str','al_ustr_rfind_cstr','al_ustr_find_replace','al_ustr_find_replace_cstr','al_ustr_equal','al_ustr_compare','al_ustr_ncompare','al_ustr_has_prefix','al_ustr_has_prefix_cstr','al_ustr_has_suffix','al_ustr_has_suffix_cstr','al_ustr_new_from_utf16','al_ustr_size_utf16','al_ustr_encode_utf16','al_utf8_width','al_utf8_encode','al_utf16_width','al_utf16_encode','al_get_win_window_handle','al_osx_get_window','al_iphone_program_has_halted','al_iphone_override_screen_scale','al_get_d3d_device','al_get_d3d_system_texture','al_get_d3d_video_texture','al_have_d3d_non_pow2_texture_support','al_have_d3d_non_square_texture_support','al_get_d3d_texture_position','al_is_d3d_device_lost','al_get_opengl_extension_list','al_get_opengl_proc_address','al_get_opengl_texture','al_get_opengl_texture_size','al_get_opengl_texture_position','al_get_opengl_fbo','al_remove_opengl_fbo','al_have_opengl_extension','al_get_opengl_version','al_get_opengl_variant','al_set_current_opengl_context','ALLEGRO_AUDIO_DEPTH','ALLEGRO_AUDIO_PAN_NONE','ALLEGRO_CHANNEL_CONF','ALLEGRO_MIXER','ALLEGRO_MIXER_QUALITY','ALLEGRO_PLAYMODE','ALLEGRO_SAMPLE_ID','ALLEGRO_SAMPLE','ALLEGRO_SAMPLE_INSTANCE','ALLEGRO_AUDIO_STREAM','ALLEGRO_VOICE','al_install_audio','al_uninstall_audio','al_is_audio_installed','al_reserve_samples','al_get_allegro_audio_version','al_get_audio_depth_size','al_get_channel_count','al_create_voice','al_destroy_voice','al_detach_voice','al_attach_audio_stream_to_voice','al_attach_mixer_to_voice','al_attach_sample_instance_to_voice','al_get_voice_frequency','al_get_voice_channels','al_get_voice_depth','al_get_voice_playing','al_set_voice_playing','al_get_voice_position','al_set_voice_position','al_create_sample','al_destroy_sample','al_play_sample','al_stop_sample','al_stop_samples','al_get_sample_channels','al_get_sample_depth','al_get_sample_frequency','al_get_sample_length','al_get_sample_data','al_create_sample_instance','al_destroy_sample_instance','al_play_sample_instance','al_stop_sample_instance','al_get_sample_instance_channels','al_get_sample_instance_depth','al_get_sample_instance_frequency','al_get_sample_instance_length','al_set_sample_instance_length','al_get_sample_instance_position','al_set_sample_instance_position','al_get_sample_instance_speed','al_set_sample_instance_speed','al_get_sample_instance_gain','al_set_sample_instance_gain','al_get_sample_instance_pan','al_set_sample_instance_pan','al_get_sample_instance_time','al_get_sample_instance_playmode','al_set_sample_instance_playmode','al_get_sample_instance_playing','al_set_sample_instance_playing','al_get_sample_instance_attached','al_detach_sample_instance','al_get_sample','al_set_sample','al_create_mixer','al_destroy_mixer','al_get_default_mixer','al_set_default_mixer','al_restore_default_mixer','al_attach_mixer_to_mixer','al_attach_sample_instance_to_mixer','al_attach_audio_stream_to_mixer','al_get_mixer_frequency','al_set_mixer_frequency','al_get_mixer_channels','al_get_mixer_depth','al_get_mixer_gain','al_set_mixer_gain','al_get_mixer_quality','al_set_mixer_quality','al_get_mixer_playing','al_set_mixer_playing','al_get_mixer_attached','al_detach_mixer','al_set_mixer_postprocess_callback','al_create_audio_stream','al_destroy_audio_stream','al_get_audio_stream_event_source','al_drain_audio_stream','al_rewind_audio_stream','al_get_audio_stream_frequency','al_get_audio_stream_channels','al_get_audio_stream_depth','al_get_audio_stream_length','al_get_audio_stream_speed','al_set_audio_stream_speed','al_get_audio_stream_gain','al_set_audio_stream_gain','al_get_audio_stream_pan','al_set_audio_stream_pan','al_get_audio_stream_playing','al_set_audio_stream_playing','al_get_audio_stream_playmode','al_set_audio_stream_playmode','al_get_audio_stream_attached','al_detach_audio_stream','al_get_audio_stream_fragment','al_set_audio_stream_fragment','al_get_audio_stream_fragments','al_get_available_audio_stream_fragments','al_seek_audio_stream_secs','al_get_audio_stream_position_secs','al_get_audio_stream_length_secs','al_set_audio_stream_loop_secs','al_register_sample_loader','al_register_sample_loader_f','al_register_sample_saver','al_register_sample_saver_f','al_register_audio_stream_loader','al_register_audio_stream_loader_f','al_load_sample','al_load_sample_f','al_load_audio_stream','al_load_audio_stream_f','al_save_sample','al_save_sample_f','al_init_acodec_addon','al_get_allegro_acodec_version','al_color_cmyk','al_color_cmyk_to_rgb','al_color_hsl','al_color_hsl_to_rgb','al_color_hsv','al_color_hsv_to_rgb','al_color_html','al_color_html_to_rgb','al_color_rgb_to_html','al_color_name','al_color_name_to_rgb','al_color_rgb_to_cmyk','al_color_rgb_to_hsl','al_color_rgb_to_hsv','al_color_rgb_to_name','al_color_rgb_to_yuv','al_color_yuv','al_color_yuv_to_rgb','al_get_allegro_color_version','ALLEGRO_FONT','al_init_font_addon','al_shutdown_font_addon','al_load_font','al_destroy_font','al_register_font_loader','al_get_font_line_height','al_get_font_ascent','al_get_font_descent','al_get_text_width','al_get_ustr_width','al_draw_text','al_draw_ustr','al_draw_justified_text','al_draw_justified_ustr','al_draw_textf','al_draw_justified_textf','al_get_text_dimensions','al_get_ustr_dimensions','al_get_allegro_font_version','al_grab_font_from_bitmap','al_load_bitmap_font','al_create_builtin_font','al_init_ttf_addon','al_shutdown_ttf_addon','al_load_ttf_font','al_load_ttf_font_f','al_load_ttf_font_stretch','al_load_ttf_font_stretch_f','al_get_allegro_ttf_version','al_init_image_addon','al_shutdown_image_addon','al_get_allegro_image_version','al_open_memfile','al_get_allegro_memfile_version','ALLEGRO_FILECHOOSER','ALLEGRO_TEXTLOG','al_init_native_dialog_addon','al_shutdown_native_dialog_addon','al_create_native_file_dialog','al_show_native_file_dialog','al_get_native_file_dialog_count','al_get_native_file_dialog_path','al_destroy_native_file_dialog','al_show_native_message_box','al_open_native_text_log','al_close_native_text_log','al_append_native_text_log','al_get_native_text_log_event_source','al_get_allegro_native_dialog_version','al_set_physfs_file_interface','al_get_allegro_physfs_version','al_get_allegro_primitives_version','al_init_primitives_addon','al_shutdown_primitives_addon','al_draw_line','al_draw_triangle','al_draw_filled_triangle','al_draw_rectangle','al_draw_filled_rectangle','al_draw_rounded_rectangle','al_draw_filled_rounded_rectangle','al_calculate_arc','al_draw_pieslice','al_draw_filled_pieslice','al_draw_ellipse','al_draw_filled_ellipse','al_draw_circle','al_draw_filled_circle','al_draw_arc','al_draw_elliptical_arc','al_calculate_spline','al_draw_spline','al_calculate_ribbon','al_draw_ribbon','al_draw_prim','al_draw_indexed_prim','al_create_vertex_decl','al_destroy_vertex_decl','al_draw_soft_triangle','al_draw_soft_line','ALLEGRO_VERTEX','ALLEGRO_VERTEX_DECL','ALLEGRO_VERTEX_ELEMENT','ALLEGRO_PRIM_TYPE','ALLEGRO_PRIM_ATTR','ALLEGRO_PRIM_STORAGE','ALLEGRO_VERTEX_CACHE_SIZE','ALLEGRO_PRIM_QUALITY',] var search_urls = [ 'config.html#allegro_config','config.html#al_create_config','config.html#al_destroy_config','config.html#al_load_config_file','config.html#al_load_config_file_f','config.html#al_save_config_file','config.html#al_save_config_file_f','config.html#al_add_config_section','config.html#al_add_config_comment','config.html#al_get_config_value','config.html#al_set_config_value','config.html#al_get_first_config_section','config.html#al_get_next_config_section','config.html#al_get_first_config_entry','config.html#al_get_next_config_entry','config.html#al_merge_config','config.html#al_merge_config_into','display.html#allegro_display','display.html#al_create_display','display.html#al_destroy_display','display.html#al_get_new_display_flags','display.html#al_set_new_display_flags','display.html#al_get_new_display_option','display.html#al_set_new_display_option','display.html#al_reset_new_display_options','display.html#al_get_new_window_position','display.html#al_set_new_window_position','display.html#al_get_new_display_refresh_rate','display.html#al_set_new_display_refresh_rate','display.html#al_get_display_event_source','display.html#al_get_backbuffer','display.html#al_flip_display','display.html#al_update_display_region','display.html#al_wait_for_vsync','display.html#al_get_display_width','display.html#al_get_display_height','display.html#al_resize_display','display.html#al_acknowledge_resize','display.html#al_get_window_position','display.html#al_set_window_position','display.html#al_get_display_flags','display.html#al_set_display_flag','display.html#al_toggle_display_flag','display.html#al_get_display_option','display.html#al_get_display_format','display.html#al_get_display_refresh_rate','display.html#al_set_window_title','display.html#al_set_display_icon','display.html#al_set_display_icons','display.html#al_inhibit_screensaver','events.html#allegro_event','events.html#allegro_event_joystick_axis','events.html#allegro_event_joystick_button_down','events.html#allegro_event_joystick_button_up','events.html#allegro_event_joystick_configuration','events.html#allegro_event_key_down','events.html#allegro_event_key_up','events.html#allegro_event_key_char','events.html#allegro_event_mouse_axes','events.html#allegro_event_mouse_button_down','events.html#allegro_event_mouse_button_up','events.html#allegro_event_mouse_warped','events.html#allegro_event_mouse_enter_display','events.html#allegro_event_mouse_leave_display','events.html#allegro_event_timer','events.html#allegro_event_display_expose','events.html#allegro_event_display_resize','events.html#allegro_event_display_close','events.html#allegro_event_display_lost','events.html#allegro_event_display_found','events.html#allegro_event_display_switch_out','events.html#allegro_event_display_switch_in','events.html#allegro_event_display_orientation','events.html#allegro_user_event','events.html#allegro_event_queue','events.html#allegro_event_source','events.html#allegro_event_type','events.html#allegro_get_event_type','events.html#allegro_event_type_is_user','events.html#al_create_event_queue','events.html#al_destroy_event_queue','events.html#al_register_event_source','events.html#al_unregister_event_source','events.html#al_is_event_queue_empty','events.html#al_get_next_event','events.html#al_peek_next_event','events.html#al_drop_next_event','events.html#al_flush_event_queue','events.html#al_wait_for_event','events.html#al_wait_for_event_timed','events.html#al_wait_for_event_until','events.html#al_init_user_event_source','events.html#al_destroy_user_event_source','events.html#al_emit_user_event','events.html#al_unref_user_event','events.html#al_get_event_source_data','events.html#al_set_event_source_data','file.html#allegro_file','file.html#allegro_file_interface','file.html#allegro_seek','file.html#al_fopen','file.html#al_fopen_interface','file.html#al_fopen_slice','file.html#al_fclose','file.html#al_fread','file.html#al_fwrite','file.html#al_fflush','file.html#al_ftell','file.html#al_fseek','file.html#al_feof','file.html#al_ferror','file.html#al_fclearerr','file.html#al_fungetc','file.html#al_fsize','file.html#al_fgetc','file.html#al_fputc','file.html#al_fread16le','file.html#al_fread16be','file.html#al_fwrite16le','file.html#al_fwrite16be','file.html#al_fread32le','file.html#al_fread32be','file.html#al_fwrite32le','file.html#al_fwrite32be','file.html#al_fgets','file.html#al_fget_ustr','file.html#al_fputs','file.html#al_fopen_fd','file.html#al_make_temp_file','file.html#al_set_new_file_interface','file.html#al_set_standard_file_interface','file.html#al_get_new_file_interface','file.html#al_create_file_handle','file.html#al_get_file_userdata','fixed.html#al_fixed','fixed.html#al_itofix','fixed.html#al_fixtoi','fixed.html#al_fixfloor','fixed.html#al_fixceil','fixed.html#al_ftofix','fixed.html#al_fixtof','fixed.html#al_fixmul','fixed.html#al_fixdiv','fixed.html#al_fixadd','fixed.html#al_fixsub','fixed.html#al_fixtorad_r','fixed.html#al_radtofix_r','fixed.html#al_fixsin','fixed.html#al_fixcos','fixed.html#al_fixtan','fixed.html#al_fixasin','fixed.html#al_fixacos','fixed.html#al_fixatan','fixed.html#al_fixatan2','fixed.html#al_fixsqrt','fixed.html#al_fixhypot','fshook.html#allegro_fs_entry','fshook.html#allegro_file_mode','fshook.html#al_create_fs_entry','fshook.html#al_destroy_fs_entry','fshook.html#al_get_fs_entry_name','fshook.html#al_update_fs_entry','fshook.html#al_get_fs_entry_mode','fshook.html#al_get_fs_entry_atime','fshook.html#al_get_fs_entry_ctime','fshook.html#al_get_fs_entry_mtime','fshook.html#al_get_fs_entry_size','fshook.html#al_fs_entry_exists','fshook.html#al_remove_fs_entry','fshook.html#al_filename_exists','fshook.html#al_remove_filename','fshook.html#al_open_directory','fshook.html#al_read_directory','fshook.html#al_close_directory','fshook.html#al_get_current_directory','fshook.html#al_change_directory','fshook.html#al_make_directory','fshook.html#al_open_fs_entry','fshook.html#allegro_fs_interface','fshook.html#al_set_fs_interface','fshook.html#al_set_standard_fs_interface','fshook.html#al_get_fs_interface','fullscreen_mode.html#allegro_display_mode','fullscreen_mode.html#al_get_display_mode','fullscreen_mode.html#al_get_num_display_modes','graphics.html#allegro_color','graphics.html#al_map_rgb','graphics.html#al_map_rgb_f','graphics.html#al_map_rgba','graphics.html#al_map_rgba_f','graphics.html#al_unmap_rgb','graphics.html#al_unmap_rgb_f','graphics.html#al_unmap_rgba','graphics.html#al_unmap_rgba_f','graphics.html#allegro_locked_region','graphics.html#allegro_pixel_format','graphics.html#al_get_pixel_size','graphics.html#al_get_pixel_format_bits','graphics.html#al_lock_bitmap','graphics.html#al_lock_bitmap_region','graphics.html#al_unlock_bitmap','graphics.html#allegro_bitmap','graphics.html#al_create_bitmap','graphics.html#al_create_sub_bitmap','graphics.html#al_clone_bitmap','graphics.html#al_destroy_bitmap','graphics.html#al_get_new_bitmap_flags','graphics.html#al_get_new_bitmap_format','graphics.html#al_set_new_bitmap_flags','graphics.html#al_add_new_bitmap_flag','graphics.html#al_set_new_bitmap_format','graphics.html#al_get_bitmap_flags','graphics.html#al_get_bitmap_format','graphics.html#al_get_bitmap_height','graphics.html#al_get_bitmap_width','graphics.html#al_get_pixel','graphics.html#al_is_bitmap_locked','graphics.html#al_is_compatible_bitmap','graphics.html#al_is_sub_bitmap','graphics.html#al_get_parent_bitmap','graphics.html#al_clear_to_color','graphics.html#al_draw_bitmap','graphics.html#al_draw_tinted_bitmap','graphics.html#al_draw_bitmap_region','graphics.html#al_draw_tinted_bitmap_region','graphics.html#al_draw_pixel','graphics.html#al_draw_rotated_bitmap','graphics.html#al_draw_tinted_rotated_bitmap','graphics.html#al_draw_scaled_rotated_bitmap','graphics.html#al_draw_tinted_scaled_rotated_bitmap','graphics.html#al_draw_tinted_scaled_rotated_bitmap_region','graphics.html#al_draw_scaled_bitmap','graphics.html#al_draw_tinted_scaled_bitmap','graphics.html#al_get_target_bitmap','graphics.html#al_put_pixel','graphics.html#al_put_blended_pixel','graphics.html#al_set_target_bitmap','graphics.html#al_set_target_backbuffer','graphics.html#al_get_current_display','graphics.html#al_get_blender','graphics.html#al_get_separate_blender','graphics.html#al_set_blender','graphics.html#al_set_separate_blender','graphics.html#al_get_clipping_rectangle','graphics.html#al_set_clipping_rectangle','graphics.html#al_reset_clipping_rectangle','graphics.html#al_convert_mask_to_alpha','graphics.html#al_hold_bitmap_drawing','graphics.html#al_is_bitmap_drawing_held','graphics.html#al_register_bitmap_loader','graphics.html#al_register_bitmap_saver','graphics.html#al_register_bitmap_loader_f','graphics.html#al_register_bitmap_saver_f','graphics.html#al_load_bitmap','graphics.html#al_load_bitmap_f','graphics.html#al_save_bitmap','graphics.html#al_save_bitmap_f','joystick.html#allegro_joystick','joystick.html#allegro_joystick_state','joystick.html#allegro_joyflags','joystick.html#al_install_joystick','joystick.html#al_uninstall_joystick','joystick.html#al_is_joystick_installed','joystick.html#al_reconfigure_joysticks','joystick.html#al_get_num_joysticks','joystick.html#al_get_joystick','joystick.html#al_release_joystick','joystick.html#al_get_joystick_active','joystick.html#al_get_joystick_name','joystick.html#al_get_joystick_stick_name','joystick.html#al_get_joystick_axis_name','joystick.html#al_get_joystick_button_name','joystick.html#al_get_joystick_stick_flags','joystick.html#al_get_joystick_num_sticks','joystick.html#al_get_joystick_num_axes','joystick.html#al_get_joystick_num_buttons','joystick.html#al_get_joystick_state','joystick.html#al_get_joystick_event_source','keyboard.html#allegro_keyboard_state','keyboard.html#al_install_keyboard','keyboard.html#al_is_keyboard_installed','keyboard.html#al_uninstall_keyboard','keyboard.html#al_get_keyboard_state','keyboard.html#al_key_down','keyboard.html#al_keycode_to_name','keyboard.html#al_set_keyboard_leds','keyboard.html#al_get_keyboard_event_source','memory.html#al_malloc','memory.html#al_free','memory.html#al_realloc','memory.html#al_calloc','memory.html#al_malloc_with_context','memory.html#al_free_with_context','memory.html#al_realloc_with_context','memory.html#al_calloc_with_context','memory.html#allegro_memory_interface','memory.html#al_set_memory_interface','misc.html#allegro_pi','misc.html#al_run_main','monitor.html#allegro_monitor_info','monitor.html#al_get_new_display_adapter','monitor.html#al_set_new_display_adapter','monitor.html#al_get_monitor_info','monitor.html#al_get_num_video_adapters','mouse.html#allegro_mouse_state','mouse.html#al_install_mouse','mouse.html#al_is_mouse_installed','mouse.html#al_uninstall_mouse','mouse.html#al_get_mouse_num_axes','mouse.html#al_get_mouse_num_buttons','mouse.html#al_get_mouse_state','mouse.html#al_get_mouse_state_axis','mouse.html#al_mouse_button_down','mouse.html#al_set_mouse_xy','mouse.html#al_set_mouse_z','mouse.html#al_set_mouse_w','mouse.html#al_set_mouse_axis','mouse.html#al_get_mouse_event_source','mouse.html#al_create_mouse_cursor','mouse.html#al_destroy_mouse_cursor','mouse.html#al_set_mouse_cursor','mouse.html#al_set_system_mouse_cursor','mouse.html#al_get_mouse_cursor_position','mouse.html#al_hide_mouse_cursor','mouse.html#al_show_mouse_cursor','mouse.html#al_grab_mouse','mouse.html#al_ungrab_mouse','path.html#al_create_path','path.html#al_create_path_for_directory','path.html#al_destroy_path','path.html#al_clone_path','path.html#al_join_paths','path.html#al_rebase_path','path.html#al_get_path_drive','path.html#al_get_path_num_components','path.html#al_get_path_component','path.html#al_get_path_tail','path.html#al_get_path_filename','path.html#al_get_path_basename','path.html#al_get_path_extension','path.html#al_set_path_drive','path.html#al_append_path_component','path.html#al_insert_path_component','path.html#al_replace_path_component','path.html#al_remove_path_component','path.html#al_drop_path_tail','path.html#al_set_path_filename','path.html#al_set_path_extension','path.html#al_path_cstr','path.html#al_make_path_canonical','state.html#allegro_state','state.html#allegro_state_flags','state.html#al_restore_state','state.html#al_store_state','state.html#al_get_errno','state.html#al_set_errno','system.html#al_install_system','system.html#al_init','system.html#al_uninstall_system','system.html#al_is_system_installed','system.html#al_get_allegro_version','system.html#al_get_standard_path','system.html#al_set_exe_name','system.html#al_set_app_name','system.html#al_set_org_name','system.html#al_get_app_name','system.html#al_get_org_name','system.html#al_get_system_config','system.html#al_register_assert_handler','threads.html#allegro_thread','threads.html#allegro_mutex','threads.html#allegro_cond','threads.html#al_create_thread','threads.html#al_start_thread','threads.html#al_join_thread','threads.html#al_set_thread_should_stop','threads.html#al_get_thread_should_stop','threads.html#al_destroy_thread','threads.html#al_run_detached_thread','threads.html#al_create_mutex','threads.html#al_create_mutex_recursive','threads.html#al_lock_mutex','threads.html#al_unlock_mutex','threads.html#al_destroy_mutex','threads.html#al_create_cond','threads.html#al_destroy_cond','threads.html#al_wait_cond','threads.html#al_wait_cond_until','threads.html#al_broadcast_cond','threads.html#al_signal_cond','time.html#allegro_timeout','time.html#al_get_time','time.html#al_current_time','time.html#al_init_timeout','time.html#al_rest','timer.html#allegro_timer','timer.html#allegro_usecs_to_secs','timer.html#allegro_msecs_to_secs','timer.html#allegro_bps_to_secs','timer.html#allegro_bpm_to_secs','timer.html#al_create_timer','timer.html#al_start_timer','timer.html#al_stop_timer','timer.html#al_get_timer_started','timer.html#al_destroy_timer','timer.html#al_get_timer_count','timer.html#al_set_timer_count','timer.html#al_add_timer_count','timer.html#al_get_timer_speed','timer.html#al_set_timer_speed','timer.html#al_get_timer_event_source','transformations.html#allegro_transform','transformations.html#al_copy_transform','transformations.html#al_use_transform','transformations.html#al_get_current_transform','transformations.html#al_invert_transform','transformations.html#al_check_inverse','transformations.html#al_identity_transform','transformations.html#al_build_transform','transformations.html#al_translate_transform','transformations.html#al_rotate_transform','transformations.html#al_scale_transform','transformations.html#al_transform_coordinates','transformations.html#al_compose_transform','utf8.html#allegro_ustr','utf8.html#allegro_ustr_info','utf8.html#al_ustr_new','utf8.html#al_ustr_new_from_buffer','utf8.html#al_ustr_newf','utf8.html#al_ustr_free','utf8.html#al_cstr','utf8.html#al_ustr_to_buffer','utf8.html#al_cstr_dup','utf8.html#al_ustr_dup','utf8.html#al_ustr_dup_substr','utf8.html#al_ustr_empty_string','utf8.html#al_ref_cstr','utf8.html#al_ref_buffer','utf8.html#al_ref_ustr','utf8.html#al_ustr_size','utf8.html#al_ustr_length','utf8.html#al_ustr_offset','utf8.html#al_ustr_next','utf8.html#al_ustr_prev','utf8.html#al_ustr_get','utf8.html#al_ustr_get_next','utf8.html#al_ustr_prev_get','utf8.html#al_ustr_insert','utf8.html#al_ustr_insert_cstr','utf8.html#al_ustr_insert_chr','utf8.html#al_ustr_append','utf8.html#al_ustr_append_cstr','utf8.html#al_ustr_append_chr','utf8.html#al_ustr_appendf','utf8.html#al_ustr_vappendf','utf8.html#al_ustr_remove_chr','utf8.html#al_ustr_remove_range','utf8.html#al_ustr_truncate','utf8.html#al_ustr_ltrim_ws','utf8.html#al_ustr_rtrim_ws','utf8.html#al_ustr_trim_ws','utf8.html#al_ustr_assign','utf8.html#al_ustr_assign_substr','utf8.html#al_ustr_assign_cstr','utf8.html#al_ustr_set_chr','utf8.html#al_ustr_replace_range','utf8.html#al_ustr_find_chr','utf8.html#al_ustr_rfind_chr','utf8.html#al_ustr_find_set','utf8.html#al_ustr_find_set_cstr','utf8.html#al_ustr_find_cset','utf8.html#al_ustr_find_cset_cstr','utf8.html#al_ustr_find_str','utf8.html#al_ustr_find_cstr','utf8.html#al_ustr_rfind_str','utf8.html#al_ustr_rfind_cstr','utf8.html#al_ustr_find_replace','utf8.html#al_ustr_find_replace_cstr','utf8.html#al_ustr_equal','utf8.html#al_ustr_compare','utf8.html#al_ustr_ncompare','utf8.html#al_ustr_has_prefix','utf8.html#al_ustr_has_prefix_cstr','utf8.html#al_ustr_has_suffix','utf8.html#al_ustr_has_suffix_cstr','utf8.html#al_ustr_new_from_utf16','utf8.html#al_ustr_size_utf16','utf8.html#al_ustr_encode_utf16','utf8.html#al_utf8_width','utf8.html#al_utf8_encode','utf8.html#al_utf16_width','utf8.html#al_utf16_encode','platform.html#al_get_win_window_handle','platform.html#al_osx_get_window','platform.html#al_iphone_program_has_halted','platform.html#al_iphone_override_screen_scale','direct3d.html#al_get_d3d_device','direct3d.html#al_get_d3d_system_texture','direct3d.html#al_get_d3d_video_texture','direct3d.html#al_have_d3d_non_pow2_texture_support','direct3d.html#al_have_d3d_non_square_texture_support','direct3d.html#al_get_d3d_texture_position','direct3d.html#al_is_d3d_device_lost','opengl.html#al_get_opengl_extension_list','opengl.html#al_get_opengl_proc_address','opengl.html#al_get_opengl_texture','opengl.html#al_get_opengl_texture_size','opengl.html#al_get_opengl_texture_position','opengl.html#al_get_opengl_fbo','opengl.html#al_remove_opengl_fbo','opengl.html#al_have_opengl_extension','opengl.html#al_get_opengl_version','opengl.html#al_get_opengl_variant','opengl.html#al_set_current_opengl_context','audio.html#allegro_audio_depth','audio.html#allegro_audio_pan_none','audio.html#allegro_channel_conf','audio.html#allegro_mixer','audio.html#allegro_mixer_quality','audio.html#allegro_playmode','audio.html#allegro_sample_id','audio.html#allegro_sample','audio.html#allegro_sample_instance','audio.html#allegro_audio_stream','audio.html#allegro_voice','audio.html#al_install_audio','audio.html#al_uninstall_audio','audio.html#al_is_audio_installed','audio.html#al_reserve_samples','audio.html#al_get_allegro_audio_version','audio.html#al_get_audio_depth_size','audio.html#al_get_channel_count','audio.html#al_create_voice','audio.html#al_destroy_voice','audio.html#al_detach_voice','audio.html#al_attach_audio_stream_to_voice','audio.html#al_attach_mixer_to_voice','audio.html#al_attach_sample_instance_to_voice','audio.html#al_get_voice_frequency','audio.html#al_get_voice_channels','audio.html#al_get_voice_depth','audio.html#al_get_voice_playing','audio.html#al_set_voice_playing','audio.html#al_get_voice_position','audio.html#al_set_voice_position','audio.html#al_create_sample','audio.html#al_destroy_sample','audio.html#al_play_sample','audio.html#al_stop_sample','audio.html#al_stop_samples','audio.html#al_get_sample_channels','audio.html#al_get_sample_depth','audio.html#al_get_sample_frequency','audio.html#al_get_sample_length','audio.html#al_get_sample_data','audio.html#al_create_sample_instance','audio.html#al_destroy_sample_instance','audio.html#al_play_sample_instance','audio.html#al_stop_sample_instance','audio.html#al_get_sample_instance_channels','audio.html#al_get_sample_instance_depth','audio.html#al_get_sample_instance_frequency','audio.html#al_get_sample_instance_length','audio.html#al_set_sample_instance_length','audio.html#al_get_sample_instance_position','audio.html#al_set_sample_instance_position','audio.html#al_get_sample_instance_speed','audio.html#al_set_sample_instance_speed','audio.html#al_get_sample_instance_gain','audio.html#al_set_sample_instance_gain','audio.html#al_get_sample_instance_pan','audio.html#al_set_sample_instance_pan','audio.html#al_get_sample_instance_time','audio.html#al_get_sample_instance_playmode','audio.html#al_set_sample_instance_playmode','audio.html#al_get_sample_instance_playing','audio.html#al_set_sample_instance_playing','audio.html#al_get_sample_instance_attached','audio.html#al_detach_sample_instance','audio.html#al_get_sample','audio.html#al_set_sample','audio.html#al_create_mixer','audio.html#al_destroy_mixer','audio.html#al_get_default_mixer','audio.html#al_set_default_mixer','audio.html#al_restore_default_mixer','audio.html#al_attach_mixer_to_mixer','audio.html#al_attach_sample_instance_to_mixer','audio.html#al_attach_audio_stream_to_mixer','audio.html#al_get_mixer_frequency','audio.html#al_set_mixer_frequency','audio.html#al_get_mixer_channels','audio.html#al_get_mixer_depth','audio.html#al_get_mixer_gain','audio.html#al_set_mixer_gain','audio.html#al_get_mixer_quality','audio.html#al_set_mixer_quality','audio.html#al_get_mixer_playing','audio.html#al_set_mixer_playing','audio.html#al_get_mixer_attached','audio.html#al_detach_mixer','audio.html#al_set_mixer_postprocess_callback','audio.html#al_create_audio_stream','audio.html#al_destroy_audio_stream','audio.html#al_get_audio_stream_event_source','audio.html#al_drain_audio_stream','audio.html#al_rewind_audio_stream','audio.html#al_get_audio_stream_frequency','audio.html#al_get_audio_stream_channels','audio.html#al_get_audio_stream_depth','audio.html#al_get_audio_stream_length','audio.html#al_get_audio_stream_speed','audio.html#al_set_audio_stream_speed','audio.html#al_get_audio_stream_gain','audio.html#al_set_audio_stream_gain','audio.html#al_get_audio_stream_pan','audio.html#al_set_audio_stream_pan','audio.html#al_get_audio_stream_playing','audio.html#al_set_audio_stream_playing','audio.html#al_get_audio_stream_playmode','audio.html#al_set_audio_stream_playmode','audio.html#al_get_audio_stream_attached','audio.html#al_detach_audio_stream','audio.html#al_get_audio_stream_fragment','audio.html#al_set_audio_stream_fragment','audio.html#al_get_audio_stream_fragments','audio.html#al_get_available_audio_stream_fragments','audio.html#al_seek_audio_stream_secs','audio.html#al_get_audio_stream_position_secs','audio.html#al_get_audio_stream_length_secs','audio.html#al_set_audio_stream_loop_secs','audio.html#al_register_sample_loader','audio.html#al_register_sample_loader_f','audio.html#al_register_sample_saver','audio.html#al_register_sample_saver_f','audio.html#al_register_audio_stream_loader','audio.html#al_register_audio_stream_loader_f','audio.html#al_load_sample','audio.html#al_load_sample_f','audio.html#al_load_audio_stream','audio.html#al_load_audio_stream_f','audio.html#al_save_sample','audio.html#al_save_sample_f','acodec.html#al_init_acodec_addon','acodec.html#al_get_allegro_acodec_version','color.html#al_color_cmyk','color.html#al_color_cmyk_to_rgb','color.html#al_color_hsl','color.html#al_color_hsl_to_rgb','color.html#al_color_hsv','color.html#al_color_hsv_to_rgb','color.html#al_color_html','color.html#al_color_html_to_rgb','color.html#al_color_rgb_to_html','color.html#al_color_name','color.html#al_color_name_to_rgb','color.html#al_color_rgb_to_cmyk','color.html#al_color_rgb_to_hsl','color.html#al_color_rgb_to_hsv','color.html#al_color_rgb_to_name','color.html#al_color_rgb_to_yuv','color.html#al_color_yuv','color.html#al_color_yuv_to_rgb','color.html#al_get_allegro_color_version','font.html#allegro_font','font.html#al_init_font_addon','font.html#al_shutdown_font_addon','font.html#al_load_font','font.html#al_destroy_font','font.html#al_register_font_loader','font.html#al_get_font_line_height','font.html#al_get_font_ascent','font.html#al_get_font_descent','font.html#al_get_text_width','font.html#al_get_ustr_width','font.html#al_draw_text','font.html#al_draw_ustr','font.html#al_draw_justified_text','font.html#al_draw_justified_ustr','font.html#al_draw_textf','font.html#al_draw_justified_textf','font.html#al_get_text_dimensions','font.html#al_get_ustr_dimensions','font.html#al_get_allegro_font_version','font.html#al_grab_font_from_bitmap','font.html#al_load_bitmap_font','font.html#al_create_builtin_font','font.html#al_init_ttf_addon','font.html#al_shutdown_ttf_addon','font.html#al_load_ttf_font','font.html#al_load_ttf_font_f','font.html#al_load_ttf_font_stretch','font.html#al_load_ttf_font_stretch_f','font.html#al_get_allegro_ttf_version','image.html#al_init_image_addon','image.html#al_shutdown_image_addon','image.html#al_get_allegro_image_version','memfile.html#al_open_memfile','memfile.html#al_get_allegro_memfile_version','native_dialog.html#allegro_filechooser','native_dialog.html#allegro_textlog','native_dialog.html#al_init_native_dialog_addon','native_dialog.html#al_shutdown_native_dialog_addon','native_dialog.html#al_create_native_file_dialog','native_dialog.html#al_show_native_file_dialog','native_dialog.html#al_get_native_file_dialog_count','native_dialog.html#al_get_native_file_dialog_path','native_dialog.html#al_destroy_native_file_dialog','native_dialog.html#al_show_native_message_box','native_dialog.html#al_open_native_text_log','native_dialog.html#al_close_native_text_log','native_dialog.html#al_append_native_text_log','native_dialog.html#al_get_native_text_log_event_source','native_dialog.html#al_get_allegro_native_dialog_version','physfs.html#al_set_physfs_file_interface','physfs.html#al_get_allegro_physfs_version','primitives.html#al_get_allegro_primitives_version','primitives.html#al_init_primitives_addon','primitives.html#al_shutdown_primitives_addon','primitives.html#al_draw_line','primitives.html#al_draw_triangle','primitives.html#al_draw_filled_triangle','primitives.html#al_draw_rectangle','primitives.html#al_draw_filled_rectangle','primitives.html#al_draw_rounded_rectangle','primitives.html#al_draw_filled_rounded_rectangle','primitives.html#al_calculate_arc','primitives.html#al_draw_pieslice','primitives.html#al_draw_filled_pieslice','primitives.html#al_draw_ellipse','primitives.html#al_draw_filled_ellipse','primitives.html#al_draw_circle','primitives.html#al_draw_filled_circle','primitives.html#al_draw_arc','primitives.html#al_draw_elliptical_arc','primitives.html#al_calculate_spline','primitives.html#al_draw_spline','primitives.html#al_calculate_ribbon','primitives.html#al_draw_ribbon','primitives.html#al_draw_prim','primitives.html#al_draw_indexed_prim','primitives.html#al_create_vertex_decl','primitives.html#al_destroy_vertex_decl','primitives.html#al_draw_soft_triangle','primitives.html#al_draw_soft_line','primitives.html#allegro_vertex','primitives.html#allegro_vertex_decl','primitives.html#allegro_vertex_element','primitives.html#allegro_prim_type','primitives.html#allegro_prim_attr','primitives.html#allegro_prim_storage','primitives.html#allegro_vertex_cache_size','primitives.html#allegro_prim_quality',] allegro-5.0.10/docs/html/refman/index_all.html0000644000175000001440000020521412157230700020400 0ustar tjadenusers Index

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:15 UTC

    allegro-5.0.10/docs/html/refman/state.html0000644000175000001440000001704212157230673017572 0ustar tjadenusers State

    These functions are declared in the main Allegro header file:

    #include <allegro5/allegro.h>

    ALLEGRO_STATE

    typedef struct ALLEGRO_STATE ALLEGRO_STATE;

    Opaque type which is passed to al_store_state/al_restore_state.

    The various state kept internally by Allegro can be displayed like this:

      global
          active system driver
              current config
      per thread
          new bitmap params
          new display params
          active file interface
          errno
          current blending mode
          current display
              deferred drawing
          current target bitmap
              current transformation
              current clipping rectangle
              bitmap locking

    In general, the only real global state is the active system driver. All other global state is per-thread, so if your application has multiple separate threads they never will interfere with each other. (Except if there are objects accessed by multiple threads of course. Usually you want to minimize that though and for the remaining cases use synchronization primitives described in the threads section or events described in the events section to control inter-thread communication.)

    ALLEGRO_STATE_FLAGS

    typedef enum ALLEGRO_STATE_FLAGS

    Flags which can be passed to al_store_state/al_restore_state as bit combinations. See al_store_state for the list of flags.

    al_restore_state

    void al_restore_state(ALLEGRO_STATE const *state)

    Restores part of the state of the current thread from the given ALLEGRO_STATE object.

    See also: al_store_state, ALLEGRO_STATE_FLAGS

    al_store_state

    void al_store_state(ALLEGRO_STATE *state, int flags)

    Stores part of the state of the current thread in the given ALLEGRO_STATE objects. The flags parameter can take any bit-combination of these flags:

    • ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format, new_display_refresh_rate, new_display_flags
    • ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format, new_bitmap_flags
    • ALLEGRO_STATE_DISPLAY - current_display
    • ALLEGRO_STATE_TARGET_BITMAP - target_bitmap
    • ALLEGRO_STATE_BLENDER - blender
    • ALLEGRO_STATE_TRANSFORM - current_transformation
    • ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface
    • ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and ALLEGRO_STATE_TARGET_BITMAP
    • ALLEGRO_STATE_ALL - all of the above

    See also: al_restore_state, ALLEGRO_STATE

    al_get_errno

    int al_get_errno(void)

    Some Allegro functions will set an error number as well as returning an error code. Call this function to retrieve the last error number set for the calling thread.

    al_set_errno

    void al_set_errno(int errnum)

    Set the error number for for the calling thread.

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:11 UTC

    allegro-5.0.10/docs/html/refman/getting_started.html0000644000175000001440000003651212157230670021641 0ustar tjadenusers Getting started guide

    Introduction

    Welcome to Allegro 5.0!

    This short guide should point you at the parts of the API that you'll want to know about first. It's not a tutorial, as there isn't much discussion, only links into the manual. The rest you'll have to discover for yourself. Read the examples, and ask questions at Allegro.cc.

    There is an unofficial tutorial at the wiki. Be aware that, being on the wiki, it may be a little out of date, but the changes should be minor. Hopefully more will sprout when things stabilise, as they did for earlier versions of Allegro.

    Structure of the library and its addons

    Allegro 5.0 is divided into a core library and multiple addons. The addons are bundled together and built at the same time as the core, but they are distinct and kept in separate libraries. The core doesn't depend on anything in the addons, but addons may depend on the core and other addons and additional third party libraries.

    Here are the addons and their dependencies:

    allegro_main -> allegro
    
    allegro_image -> allegro
    allegro_primitives -> allegro
    allegro_color -> allegro
    
    allegro_font -> allegro
    allegro_ttf -> allegro_font -> allegro
    
    allegro_audio -> allegro
    allegro_acodec -> allegro_audio -> allegro
    
    allegro_memfile -> allegro
    allegro_physfs -> allegro
    
    allegro_native_dialog -> allegro

    The header file for the core library is allegro5/allegro.h. The header files for the addons are named allegro5/allegro_image.h, allegro5/allegro_font.h, etc. The allegro_main addon does not have a header file.

    The main function

    For the purposes of cross-platform compatibility Allegro puts some requirements on your main function. First, you must include the core header (allegro5/allegro.h) in the same file as your main function. Second, if your main function is inside a C++ file, then it must have this signature: int main(int argc, char **argv). Third, if you're using C/C++ then you need to link with the allegro_main addon when building your program.

    Initialisation

    Before using Allegro you must call al_init. Some addons have their own initialisation, e.g. al_init_image_addon, al_init_font_addon, al_init_ttf_addon.

    To receive input, you need to initialise some subsystems like al_install_keyboard, al_install_mouse, al_install_joystick.

    Opening a window

    al_create_display will open a window and return an ALLEGRO_DISPLAY.

    To clear the display, call al_clear_to_color. Use al_map_rgba or al_map_rgba_f to obtain an ALLEGRO_COLOR parameter.

    Drawing operations are performed on a backbuffer. To make the operations visible, call al_flip_display.

    Display an image

    To load an image from disk, you need to have initialised the image I/O addon with al_init_image_addon. Then use al_load_bitmap, which returns an ALLEGRO_BITMAP.

    Use al_draw_bitmap, al_draw_scaled_bitmap or al_draw_scaled_rotated_bitmap to draw the image to the backbuffer. Remember to call al_flip_display.

    Changing the drawing target

    Notice that al_clear_to_color and al_draw_bitmap didn't take destination parameters: the destination is implicit. Allegro remembers the current "target bitmap" for the current thread. To change the target bitmap, call al_set_target_bitmap.

    The backbuffer of the display is also a bitmap. You can get it with al_get_backbuffer and then restore it as the target bitmap.

    Other bitmaps can be created with al_create_bitmap, with options which can be adjusted with al_set_new_bitmap_flags and al_set_new_bitmap_format.

    Event queues and input

    Input comes from multiple sources: keyboard, mouse, joystick, timers, etc. Event queues aggregate events from all these sources, then you can query the queue for events.

    Create an event queue with al_create_event_queue, then tell input sources to place new events into that queue using al_register_event_source. The usual input event sources can be retrieved with al_get_keyboard_event_source, al_get_mouse_event_source and al_get_joystick_event_source.

    Events can be retrieved with al_wait_for_event or al_get_next_event. Check the event type and other fields of ALLEGRO_EVENT to react to the input.

    Displays are also event sources, which emit events when they are resized. You'll need to set the ALLEGRO_RESIZABLE flag with al_set_new_display_flags before creating the display, then register the display with an event queue. When you get a resize event, call al_acknowledge_resize.

    Timers are event sources which "tick" periodically, causing an event to be inserted into the queues that the timer is registered with. Create some with al_create_timer.

    al_get_time and al_rest are more direct ways to deal with time.

    Displaying some text

    To display some text, initialise the image and font addons with al_init_image_addon and al_init_font_addon, then load a bitmap font with al_load_font. Use al_draw_text or al_draw_textf.

    For TrueType fonts, you'll need to initialise the TTF font addon with al_init_ttf_addon and load a TTF font with al_load_ttf_font.

    Drawing primitives

    The primitives addon provides some handy routines to draw lines (al_draw_line), rectangles (al_draw_rectangle), circles (al_draw_circle), etc.

    Blending

    To draw translucent or tinted images or primitives, change the blender state with al_set_blender.

    As with al_set_target_bitmap, this changes Allegro's internal state (for the current thread). Often you'll want to save some part of the state and restore it later. The functions al_store_state and al_restore_state provide a convenient way to do that.

    Sound

    Use al_install_audio to initialize sound. To load any sample formats, you will need to initialise the acodec addon with al_init_acodec_addon.

    After that, you can simply use al_reserve_samples and pass the number of sound effects typically playing at the same time. Then load your sound effects with al_load_sample and play them with al_play_sample. To stream large pieces of music from disk, you can use al_load_audio_stream so the whole piece will not have to be pre-loaded into memory.

    If the above sounds too simple and you can't help but think about clipping and latency issues, don't worry. Allegro gives you full control over how much or little you want its sound system to do. The al_reserve_samples function mentioned above only sets up a default mixer and a number of sample instances but you don't need to use it.

    Instead, to get a "direct connection" to the sound system you would use an ALLEGRO_VOICE (but depending on the platform only one such voice is guaranteed to be available and it might require a specific format of audio data). Therefore all sound can be first routed through an ALLEGRO_MIXER which is connected to such a voice (or another mixer) and will mix together all sample data fed to it.

    You can then directly stream real-time sample data to a mixer or a voice using an ALLEGRO_AUDIO_STREAM or play complete sounds using an ALLEGRO_SAMPLE_INSTANCE. The latter simply points to an ALLEGRO_SAMPLE and will stream it for you.

    Not the end

    There's a heap of stuff we haven't even mentioned yet.

    Enjoy!

    Allegro version 5.0.10 - Last updated: 2013-06-16 03:32:08 UTC

    allegro-5.0.10/docs/html/refman/autosuggest.js0000644000175000001440000007715212157230664020504 0ustar tjadenusers/* Auto-suggest control, version 2.4, October 10th 2009. * * (c) 2007-2009 Dmitriy Khudorozhkov (dmitrykhudorozhkov@yahoo.com) * * Latest version download and documentation: * http://www.codeproject.com/KB/scripting/AutoSuggestControl.aspx * * Based on "Auto-complete Control" by zichun: * http://www.codeproject.com/KB/scripting/jsactb.aspx * * This software is provided "as-is", without any express or implied warranty. * In no event will the author be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ var autosuggest_url = ""; // Global link to the server-side script, that gives you the suggestion list. // Used for controls that do not define their own server script urls. function autosuggest(id, array, url, onSelect) { var field = document.getElementById(id); var exists = field.autosuggest; if(exists) return exists; // "Public" variables: this.time_out = 0; // autocomplete timeout, in milliseconds (0: autocomplete never times out) this.response_time = 250; // time, in milliseconds, between the last char typed and the actual query this.entry_limit = 10; // number of entries autocomplete will show at a time this.limit_start = false; // should the auto complete be limited to the beginning of keyword? this.match_first = true; // if previous is false, should the exact matches be displayed first? this.restrict_typing = true; // restrict to existing members of array this.full_refresh = false; // should the script re-send the AJAX request after each typed character? this.use_iframe = true; // should the control use an IFrame element to fix suggestion list positioning (MS IE only)? this.use_scroll = true; // should the control use a scroll bar (true) or a up/down arrow-buttons (false)? this.use_mouse = true; // enable mouse support this.no_default = false; // should the control omit selecting the 1st item in a suggestion list? this.start_check = 0; // show widget only after this number of characters is typed in (effective if >1) this.text_delimiter = [";", ","]; // delimiter for multiple autocomplete entries. Set it to empty array ( [] ) for single autocomplete. this.ajax_delimiter = "|"; // character that delimits entries in the string returned by AJAX call this.item_delimiter = ","; // character that delimits key and value for the suggestion item in the string returned by AJAX call this.selectedIndex = -1; // index (zero-based) of the entry last selected // "Private" variables: this.suggest_url = url || (array ? "" : autosuggest_url); // URL the server-side script that gives you the suggestion list this.msie = (document.all && !window.opera); this.displayed = false; this.delim_words = []; this.current_word = 0; this.delim_char = []; this.current = 0; this.total = 0; this.range_up = 0; this.range_down = 0; this.previous = 0; this.timer = 0; this.rebuild = false; this.evsetup = false; this.bool = []; this.rows = []; this.onSelect = onSelect || null; this.cur_x = 0; this.cur_y = 0; this.cur_w = 0; this.cur_h = 0; this.mouse_x = 0; this.mouse_y = 0; this.mouse_on_list = 0; this.caret_moved = false; this.field_id = id; this.field = field; this.lastterm = field.value; this.keywords = [], this.keywords_init = []; this.values = [], this.values_init = []; return this.construct(array || []); }; autosuggest.prototype = { construct: function(array) { function callLater(func, obj, param1, param2) { return function() { func.call(obj, param1 || null, param2 || null) }; } this.field.autosuggest = this; // Initialize the control from JS array, if any: this.bindArray(array); // Create event handlers: this.funcClick = this.mouseClick; this.funcCheck = this.checkKey; this.funcPress = this.keyPress; this.funcHighlight = this.highlightTable; this.funcClear = callLater(this.clearEvents, this); this.funcUp = callLater(this.scroll, this, true, 1); this.funcDown = callLater(this.scroll, this, false, 1); this.funcFocus = callLater(this.focusTable, this); this.funcUnfocus = callLater(this.unfocusTable, this); this.addEvent(this.field, "focus", callLater(this.setupEvents, this)); this.addEvent(window, "resize", callLater(this.reposition, this)); return this; }, bindArray: function(array) { if(!array || !array.length) return; this.suggest_url = ""; this.keywords = [], this.keywords_init = []; this.values = [], this.values_init = []; for(var i = 0, cl = array.length; i < cl; i++) { var item = array[i]; if(item.constructor == Array) { this.keywords[i] = this.keywords_init[i] = item[0]; this.values[i] = this.values_init[i] = item[1]; } else { this.keywords[i] = this.keywords_init[i] = item; this.values[i] = this.values_init[i] = ""; } } }, bindURL: function(url) { if(!url) url = autosuggest_url; this.suggest_url = url; }, setupEvents: function() { if(!this.evsetup) { this.evsetup = true; this.addEvent(document, "keydown", this.funcCheck); this.addEvent(this.field, "blur", this.funcClear); this.addEvent(document, "keypress", this.funcPress); } }, clearEvents: function() { // Removes an event handler: function removeEvent(obj, event_name, func_ref) { if(obj.removeEventListener && !window.opera) { obj.removeEventListener(event_name, func_ref, true); } else if(obj.detachEvent) { obj.detachEvent("on" + event_name, func_ref); } else { obj["on" + event_name] = null; } } var event = window.event; if(event && this.cur_h) { var elem = event.srcElement || event.target; var x = this.mouse_x + (document.documentElement.scrollLeft || document.body.scrollLeft || 0); var y = this.mouse_y + (document.documentElement.scrollTop || document.body.scrollTop || 0); if((elem.id == this.field_id) && (x > this.cur_x && x < (this.cur_x + this.cur_w)) && (y > this.cur_y && y < (this.cur_y + this.cur_h))) { this.field.focus(); return; } } removeEvent(document, "keydown", this.funcCheck); removeEvent(this.field, "blur", this.funcClear); removeEvent(document, "keypress", this.funcPress); this.hide(); this.evsetup = false; }, parse: function(n, plen, re) { if(!n || !n.length) return ""; if(!plen) return n; var tobuild = [], c = 0, p = n.search(re); tobuild[c++] = n.substr(0, p); tobuild[c++] = ""; tobuild[c++] = n.substring(p, plen + p); tobuild[c++] = ""; tobuild[c++] = n.substring(plen + p, n.length); return tobuild.join(""); }, build: function() { if(this.total == 0) { this.displayed = false; return; } this.rows = []; this.current = this.no_default ? -1 : 0; var that = this; this.addEvent(document, "mousemove", function(event) { event = event || window.event; that.mouse_x = event.x; that.mouse_y = event.y; }); var body = document.getElementById("suggest_table_" + this.field_id); if(body) { this.displayed = false; document.body.removeChild(body); var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) document.body.removeChild(helper); } var bb = document.createElement("div"); bb.id = "suggest_table_" + this.field_id; bb.className = "autosuggest-body"; this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; bb.style.top = this.cur_y + "px"; this.cur_x = this.curPos(this.field, "Left"); bb.style.left = this.cur_x + "px"; this.cur_w = this.field.offsetWidth - (this.msie ? 2 : 6); bb.style.width = this.cur_w + "px"; this.cur_h = 1; bb.style.height = "1px"; var cc = null; if(this.msie && this.use_iframe) { var cc = document.createElement("iframe"); cc.id = "suggest_helper_" + this.field_id; cc.src = "javascript:\"\";"; cc.scrolling = "no"; cc.frameBorder = "no"; } var that = this; var showFull = (this.total > this.entry_limit); if(cc) { document.body.appendChild(cc); cc.style.top = this.cur_y + "px"; cc.style.left = this.cur_x + "px"; cc.style.width = bb.offsetWidth + 2; } document.body.appendChild(bb); var first = true, dispCount = showFull ? this.entry_limit : this.total; var str = [], cn = 0; // cellspacing and cellpadding were not moved to css - IE doesn't understand border-spacing. str[cn++] = "
    "; bb.innerHTML = str.join(""); var table = bb.firstChild; if(this.use_mouse) { table.onmouseout = this.funcUnfocus; table.onmouseover = this.funcFocus; } var real_height = 0, real_width = 0; function createArrowRow(dir) { var row = table.insertRow(-1); row.className = dir ? "up" : "down"; var cell = row.insertCell(0); real_height += cell.offsetHeight + 1; return cell; } if(!this.use_scroll && showFull) createArrowRow(true).parentNode.className = "up-disabled"; var kl = this.keywords.length, counter = 0, j = 0; // For "parse" call: var t, plen; if(this.text_delimiter.length > 0) { var word = this.delim_words[this.current_word]; t = this.trim(this.addSlashes(word)); plen = this.trim(word).length; } else { var word = this.field.value; t = this.addSlashes(word); plen = word.length; } var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); function addSuggestion(index, _first) { var row = that.rows[j] = table.insertRow(-1); row.className = (_first || (that.previous == index)) ? "selected" : ""; var cell = row.insertCell(0); cell.innerHTML = that.parse(that.keywords[index], plen, re); cell.setAttribute("pos", j++); cell.autosuggest = that; if(that.use_mouse) { that.addEvent(cell, "click", that.funcClick); cell.onmouseover = that.funcHighlight; } return [row.offsetWidth, row.offsetHeight]; } for(var i = 0; i < kl; i++) { if(this.bool[i]) { var dim = addSuggestion(i, (first && !this.no_default && !this.rebuild)); first = false; if(counter <= this.entry_limit) real_height += dim[1] + 1; if(real_width < dim[0]) real_width = dim[0]; if(++counter == this.entry_limit) { ++i; break; } } } var last = i; if(showFull) { if(!this.use_scroll) { var cell = createArrowRow(false); if(this.use_mouse) this.addEvent(cell, "click", this.funcDown); } else { bb.style.height = real_height + "px"; bb.style.overflow = "auto"; bb.style.overflowX = "hidden"; } } this.cur_h = real_height + 1; bb.style.height = this.cur_h + "px"; this.cur_w = ((real_width > bb.offsetWidth) ? real_width : bb.offsetWidth) + (this.msie ? -2 : 2) + 100; bb.style.width = this.cur_w + "px"; if(cc) { cc.style.height = this.cur_h + "px"; cc.style.width = this.cur_w + "px"; } this.range_up = 0; this.range_down = j - 1; this.displayed = true; if(this.use_scroll) { setTimeout(function() { counter = 0; for(var i = last; i < kl; i++) { if(!that.displayed) return; if(that.bool[i]) { addSuggestion(i); if(++counter == that.entry_limit) { ++i; break; } } } last = i; if(j < that.total) setTimeout(arguments.callee, 25); }, 25); } }, remake: function() { this.rows = []; var a = document.getElementById("suggest_table2_" + this.field_id); var k = 0, first = true; function adjustArrow(obj, which, cond, handler) { var r = a.rows[k++]; r.className = which ? (cond ? "up" : "up-disabled") : (cond ? "down" : "down-disabled"); var c = r.firstChild; if(cond && handler && obj.use_mouse) obj.addEvent(c, "click", handler); } if(this.total > this.entry_limit) { var b = (this.range_up > 0); adjustArrow(this, true, b, this.funcUp); } // For "parse" call: var t, plen; if(this.text_delimiter.length > 0) { var word = this.delim_words[this.current_word]; t = this.trim(this.addSlashes(word)); plen = this.trim(word).length; } else { var word = this.field.value; t = this.addSlashes(word); plen = word.length; } var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); var kl = this.keywords.length, j = 0; for(var i = 0; i < kl; i++) { if(this.bool[i]) { if((j >= this.range_up) && (j <= this.range_down)) { var r = this.rows[j] = a.rows[k++]; r.className = ""; var c = r.firstChild; c.innerHTML = this.parse(this.keywords[i], plen, re); c.setAttribute("pos", j); } if(++j > this.range_down) break; } } if(kl > this.entry_limit) { var b = (j < this.total); adjustArrow(this, false, b, this.funcDown); } if(this.msie) { var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) helper.style.width = a.parentNode.offsetWidth + 2; } }, reposition: function() { if(this.displayed) { this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; this.cur_x = this.curPos(this.field, "Left"); var control = document.getElementById("suggest_table_" + this.field_id); control.style.top = this.cur_y + "px"; control.style.left = this.cur_x + "px"; } }, startTimer: function(on_list) { if(this.time_out > 0) this.timer = setTimeout(function() { this.mouse_on_list = on_list; this.hide(); }, this.time_out); }, stopTimer: function() { if(this.timer) { clearTimeout(this.timer); this.timer = 0; } }, getRow: function(index) { if(typeof(index) == "undefined") index = this.current; return (this.rows[index] || null); }, fixArrows: function(base) { if(this.total <= this.entry_limit) return; var table = base.firstChild, at_start = (this.current == 0), at_end = (this.current == (this.total - 1)); var row = table.rows[0]; row.className = at_start ? "up-disabled" : "up"; row = table.rows[this.entry_limit + 1]; row.className = at_end ? "down-disabled" : "down"; }, scroll: function(direction, times) { if(!this.displayed) return; this.field.focus(); if(this.current == (direction ? 0 : (this.total - 1))) return; if(!direction && (this.current < 0)) { this.current = -1; } else { var t = this.getRow(); if(t && t.style) t.className = ""; } this.current += times * (direction ? -1 : 1); if(direction) { if(this.current < 0) this.current = 0; } else { if(this.current >= this.total) this.current = this.total - 1; if(this.use_scroll && (this.current >= this.rows.length)) this.current = this.rows.length - 1; } var t = this.getRow(), base = document.getElementById("suggest_table_" + this.field_id); if(this.use_scroll) { if(direction) { if(t.offsetTop < base.scrollTop) base.scrollTop = t.offsetTop; } else { if((t.offsetTop + t.offsetHeight) > (base.scrollTop + base.offsetHeight)) { var ndx = this.current - this.entry_limit + 1; if(ndx > 0) base.scrollTop = this.getRow(ndx).offsetTop; } } } else { if(direction) { if(this.current < this.range_up) { this.range_up -= times; if(this.range_up < 0) this.range_up = 0; this.range_down = this.range_up + this.entry_limit - 1; this.remake(); } else this.fixArrows(base); } else { if(this.current > this.range_down) { this.range_down += times; if(this.range_down > (this.total - 1)) this.range_down = this.total - 1; this.range_up = this.range_down - this.entry_limit + 1; this.remake(); } else this.fixArrows(base); } t = this.getRow(); } if(t && t.style) t.className = "selected"; this.stopTimer(); this.startTimer(1); this.field.focus(); }, mouseClick: function(event) { event = event || window.event; var elem = event.srcElement || event.target; if(!elem.id) elem = elem.parentNode; var obj = elem.autosuggest; if(!obj) { var tag = elem.tagName.toLowerCase(); elem = (tag == "tr") ? elem.firstChild : elem.parentNode; obj = elem.autosuggest; } if(!obj || !obj.displayed) return; obj.mouse_on_list = 0; obj.current = parseInt(elem.getAttribute("pos"), 10); obj.choose(); }, focusTable: function() { this.mouse_on_list = 1; }, unfocusTable: function() { this.mouse_on_list = 0; this.stopTimer(); this.startTimer(0) }, highlightTable: function(event) { event = event || window.event; var elem = event.srcElement || event.target; var obj = elem.autosuggest; if(!obj) return; obj.mouse_on_list = 1; var row = obj.getRow(); if(row && row.style) row.className = ""; obj.current = parseInt(elem.getAttribute("pos"), 10); row = obj.getRow(); if(row && row.style) row.className = "selected"; obj.stopTimer(); obj.startTimer(0); }, choose: function() { if(!this.displayed) return; if(this.current < 0) return; this.displayed = false; var kl = this.keywords.length; for(var i = 0, c = 0; i < kl; i++) if(this.bool[i] && (c++ == this.current)) break; this.selectedIndex = i; this.insertWord(this.keywords[i]); if(this.onSelect) this.onSelect(i, this); }, insertWord: function(a) { // Sets the caret position to l in the object function setCaretPos(obj, l) { obj.focus(); if(obj.setSelectionRange) { obj.setSelectionRange(l, l); } else if(obj.createTextRange) { var m = obj.createTextRange(); m.moveStart("character", l); m.collapse(); m.select(); } } if(this.text_delimiter.length > 0) { var str = "", word = this.delim_words[this.current_word], wl = word.length, l = 0; for(var i = 0; i < this.delim_words.length; i++) { if(this.current_word == i) { var prespace = "", postspace = "", gotbreak = false; for(var j = 0; j < wl; ++j) { if(word.charAt(j) != " ") { gotbreak = true; break; } prespace += " "; } for(j = wl - 1; j >= 0; --j) { if(word.charAt(j) != " ") break; postspace += " "; } str += prespace; str += a; l = str.length; if(gotbreak) str += postspace; } else { str += this.delim_words[i]; } if(i != this.delim_words.length - 1) str += this.delim_char[i]; } this.field.value = str; setCaretPos(this.field, l); } else { this.field.value = a; } this.mouse_on_list = 0; this.hide(); }, hide: function() { if(this.mouse_on_list == 0) { this.displayed = false; var base = document.getElementById("suggest_table_" + this.field_id); if(base) { var helper = document.getElementById("suggest_helper_" + this.field_id); if(helper) document.body.removeChild(helper); document.body.removeChild(base); } this.stopTimer(); this.cur_x = 0; this.cur_y = 0; this.cur_w = 0; this.cur_h = 0; this.rows = []; } }, keyPress: function(event) { // On firefox there is no way to distingish pressing shift-8 (asterix) // from pressing 8 during the keyDown event, so we do restrict_typing // whilest handling the keyPress event event = event || window.event; var code = window.event ? event.keyCode : event.charCode; var obj = event.srcElement || event.target; obj = obj.autosuggest; if(obj.restrict_typing && !obj.suggest_url.length && (code >= 32)) { var caret_pos = obj.getCaretEnd(obj.field); var new_term = obj.field.value.substr(0, caret_pos).toLowerCase(); var isDelimiter = false; if(obj.text_delimiter.length > 0) { // check whether the pressed key is a delimiter key var delim_split = ""; for(var j = 0; j < obj.text_delimiter.length; j++) { delim_split += obj.text_delimiter[j]; if(obj.text_delimiter[j] == String.fromCharCode(code)) isDelimiter = true; } // only consider part of term after last delimiter delim_split = obj.addSlashes(delim_split); var lastterm_rx = new RegExp(".*([" + delim_split + "])"); new_term = new_term.replace(lastterm_rx, ''); } var keyw_len = obj.keywords.length; var i = 0; if(isDelimiter) { // pressed key is a delimiter: allow if current term is complete for(i = 0; i < keyw_len; i++) if(obj.keywords[i].toLowerCase() == new_term) break; } else { new_term += String.fromCharCode(code).toLowerCase(); for(i = 0; i < keyw_len; i++) if(obj.keywords[i].toLowerCase().indexOf(new_term) != -1) break; } if(i == keyw_len) { obj.stopEvent(event); return false; } } if(obj.caret_moved) obj.stopEvent(event); return !obj.caret_moved; }, checkKey: function(event) { event = event || window.event; var code = event.keyCode; var obj = event.srcElement || event.target; obj = obj.autosuggest; obj.caret_moved = 0; var term = ""; obj.stopTimer(); switch(code) { // Up arrow: case 38: if(obj.current <= 0) { obj.stopEvent(event); obj.hide(); } else { obj.scroll(true, 1); obj.caret_moved = 1; obj.stopEvent(event); } return false; // Down arrow: case 40: if(!obj.displayed) { obj.timer = setTimeout(function() { obj.preSuggest(-1); }, 25); } else { obj.scroll(false, 1); obj.caret_moved = 1; } return false; // Page up: case 33: if(obj.current == 0) { obj.caret_moved = 0; return false; } obj.scroll(true, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_up])) ? obj.entry_limit : (obj.current - obj.range_up)); obj.caret_moved = 1; break; // Page down: case 34: if(obj.current == (obj.total - 1)) { obj.caret_moved = 0; return false; } obj.scroll(false, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_down])) ? obj.entry_limit : (obj.range_down - obj.current)); obj.caret_moved = 1; break; // Home case 36: if(obj.current == 0) { obj.caret_moved = 0; return false; } obj.scroll(true, obj.total); obj.caret_moved = 1; break; // End case 35: if(obj.current == (obj.total - 1)) { obj.caret_moved = 0; return false; } obj.scroll(false, obj.total); obj.caret_moved = 1; break; // Esc: case 27: term = obj.field.value; obj.mouse_on_list = 0; obj.hide(); break; // Enter: case 13: if(obj.displayed) { obj.caret_moved = 1; obj.choose(); return false; } break; // Tab: case 9: if((obj.displayed && (obj.current >= 0)) || obj.timer) { obj.caret_moved = 1; obj.choose(); setTimeout(function() { obj.field.focus(); }, 25); return false; } break; case 16: //shift break; default: obj.caret_moved = 0; obj.timer = setTimeout(function() { obj.preSuggest(code); }, (obj.response_time < 10 ? 10 : obj.response_time)); } if(term.length) setTimeout(function() { obj.field.value = term; }, 25); return true; }, preSuggest: function(kc) { if(!this.timer) return; this.stopTimer(); if(this.displayed && (this.lastterm == this.field.value)) return; this.lastterm = this.field.value; if(kc == 38 || kc == 40 || kc == 13) return; var c = 0; if(this.displayed && (this.current >= 0)) { for(var i = 0; i < this.keywords.length; i++) { if(this.bool[i]) ++c; if(c == this.current) { this.previous = i; break; } } } else { this.previous = -1; } if(!this.field.value.length && (kc != -1)) { this.mouse_on_list = 0; this.hide(); } var ot, t; if(this.text_delimiter.length > 0) { var caret_pos = this.getCaretEnd(this.field); var delim_split = ""; for(var i = 0; i < this.text_delimiter.length; i++) delim_split += this.text_delimiter[i]; delim_split = this.addSlashes(delim_split); var delim_split_rx = new RegExp("([" + delim_split + "])"); c = 0; this.delim_words = []; this.delim_words[0] = ""; for(var i = 0, j = this.field.value.length; i < this.field.value.length; i++, j--) { if(this.field.value.substr(i, j).search(delim_split_rx) == 0) { var ma = this.field.value.substr(i, j).match(delim_split_rx); this.delim_char[c++] = ma[1]; this.delim_words[c] = ""; } else { this.delim_words[c] += this.field.value.charAt(i); } } var l = 0; this.current_word = -1; for(i = 0; i < this.delim_words.length; i++) { if((caret_pos >= l) && (caret_pos <= (l + this.delim_words[i].length))) this.current_word = i; l += this.delim_words[i].length + 1; } ot = this.trim(this.delim_words[this.current_word]); t = this.trim(this.addSlashes(this.delim_words[this.current_word])); } else { ot = this.field.value; t = this.addSlashes(ot); } if(ot.length == 0 && (kc != -1)) { this.mouse_on_list = 0; this.hide(); } else if((ot.length == 1) || this.full_refresh || ((ot.length > 1) && !this.keywords.length) || ((ot.length > 1) && (this.keywords[0].charAt(0).toLowerCase() != ot.charAt(0).toLowerCase()))) { var ot_ = ((ot.length > 1) && !this.full_refresh) ? ot.charAt(0) : ot; if(this.suggest_url.length) { // create xmlhttprequest object: var http = null; if(typeof(XMLHttpRequest) != "undefined") { try { http = new XMLHttpRequest(); } catch (e) { http = null; } } else { try { http = new ActiveXObject("Msxml2.XMLHTTP") ; } catch (e) { try { http = new ActiveXObject("Microsoft.XMLHTTP") ; } catch (e) { http = null; } } } if(http) { // Uncomment for local debugging in Mozilla/Firefox: // try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { } if(http.overrideMimeType) http.overrideMimeType("text/xml"); http.open("GET", this.suggest_url + ot_, true); var that = this; http.onreadystatechange = function(n) { if(http.readyState == 4) { if((http.status == 200) || (http.status == 0)) { var text = http.responseText; var index1 = text.indexOf(""); var index2 = (index1 == -1) ? text.length : text.indexOf(" obj.value.length) return -1; return rb; } return -1; }, // Get offset position from the top/left of the screen: curPos: function(obj, what) { var coord = 0; while(obj) { coord += obj["offset" + what]; obj = obj.offsetParent; } return coord; }, // String functions: addSlashes: function(str) { return str.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, "\\$1"); }, trim: function(str) { return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"); } }; allegro-5.0.10/docs/Refman.cmake0000644000175000001440000003570212120727071015556 0ustar tjadenusersset(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(SRC_REFMAN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/refman) # Put these in the order that they should appear in the Info or PDF manual. set(PAGES getting_started config display events file fixed fshook fullscreen_mode graphics joystick keyboard memory misc monitor mouse path state system threads time timer transformations utf8 platform direct3d opengl audio acodec color font image main memfile native_dialog physfs primitives ) set(PAGES_TXT) foreach(page ${PAGES}) list(APPEND PAGES_TXT ${SRC_REFMAN_DIR}/${page}.txt) endforeach(page) set(IMAGES primitives1 primitives2 ) #-----------------------------------------------------------------------------# # # Paths # #-----------------------------------------------------------------------------# set(HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/html/refman) set(MAN_DIR ${CMAKE_CURRENT_BINARY_DIR}/man) set(INFO_DIR ${CMAKE_CURRENT_BINARY_DIR}/info) set(TEXI_DIR ${CMAKE_CURRENT_BINARY_DIR}/texi) set(LATEX_DIR ${CMAKE_CURRENT_BINARY_DIR}/latex) set(PDF_DIR ${CMAKE_CURRENT_BINARY_DIR}/pdf) set(PROTOS ${CMAKE_CURRENT_BINARY_DIR}/protos) set(PROTOS_TIMESTAMP ${PROTOS}.timestamp) set(HTML_REFS ${CMAKE_CURRENT_BINARY_DIR}/html_refs) set(HTML_REFS_TIMESTAMP ${HTML_REFS}.timestamp) set(DUMMY_REFS ${CMAKE_CURRENT_BINARY_DIR}/dummy_refs) set(DUMMY_REFS_TIMESTAMP ${DUMMY_REFS}.timestamp) set(INDEX_ALL ${CMAKE_CURRENT_BINARY_DIR}/index_all.txt) set(SEARCH_INDEX_JS ${HTML_DIR}/search_index.js) set(SCRIPT_DIR ${CMAKE_SOURCE_DIR}/docs/scripts) set(MAKE_PROTOS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_protos) set(MAKE_HTML_REFS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_html_refs) set(MAKE_INDEX ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_index) set(MAKE_DUMMY_REFS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_dummy_refs) set(MAKE_DOC ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_doc --protos ${PROTOS}) set(INSERT_TIMESTAMP ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/insert_timestamp) set(MAKE_SEARCH_INDEX ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_search_index) set(DAWK_SOURCES scripts/aatree.c scripts/dawk.c scripts/trex.c) add_executable(make_protos scripts/make_protos.c ${DAWK_SOURCES}) add_executable(make_html_refs scripts/make_html_refs.c ${DAWK_SOURCES}) add_executable(make_dummy_refs scripts/make_dummy_refs.c ${DAWK_SOURCES}) add_executable(make_index scripts/make_index.c ${DAWK_SOURCES}) add_executable(make_doc scripts/make_doc.c scripts/make_man.c scripts/make_single.c ${DAWK_SOURCES}) add_executable(insert_timestamp scripts/insert_timestamp.c ${DAWK_SOURCES}) add_executable(make_search_index scripts/make_search_index.c ${DAWK_SOURCES}) #-----------------------------------------------------------------------------# # # Protos # #-----------------------------------------------------------------------------# # The protos file is a list of function prototypes and type declarations # which can then be embedded into the documentation. # Rebuilding the documentation whenever a source file changes is irritating, # especially as public prototypes rarely change. Thus we keep a second file # called protos.timestamp which reflects the last time that the protos file # changed. We declare _that_ file as the dependency of other targets. # We can get into a situation where the protos file is newer than the source # files (up-to-date) but the protos.timestamp is older than the source files. # If the protos and protos.timestamp files are identical then each time # you run make, it will compare them and find them equal, so protos.timestamp # won't be updated. However that check is instantaneous. # ALL_SRCS is split into multiple lists, otherwise the make_protos command # line is too long for Windows >:-( We use relative paths for the same reason. file(GLOB_RECURSE ALL_SRCS1 ${CMAKE_SOURCE_DIR}/src/*.[chm] ${CMAKE_SOURCE_DIR}/src/*.[ch]pp ) file(GLOB_RECURSE ALL_SRCS2 ${CMAKE_SOURCE_DIR}/include/*.h ${CMAKE_SOURCE_DIR}/include/*.inl ) file(GLOB_RECURSE ALL_SRCS3 ${CMAKE_SOURCE_DIR}/addons/*.[chm] ${CMAKE_SOURCE_DIR}/addons/*.[ch]pp ) foreach(x ${ALL_SRCS1}) file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) list(APPEND ALL_SRCS1_REL ${xrel}) endforeach() foreach(x ${ALL_SRCS2}) file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) list(APPEND ALL_SRCS2_REL ${xrel}) endforeach() foreach(x ${ALL_SRCS3}) file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) list(APPEND ALL_SRCS3_REL ${xrel}) endforeach() add_custom_command( OUTPUT ${PROTOS} DEPENDS ${ALL_SRCS1} ${ALL_SRCS2} ${ALL_SRCS3} make_protos WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${MAKE_PROTOS} ${ALL_SRCS1_REL} > ${PROTOS} COMMAND ${MAKE_PROTOS} ${ALL_SRCS2_REL} >> ${PROTOS} COMMAND ${MAKE_PROTOS} ${ALL_SRCS3_REL} >> ${PROTOS} ) add_custom_command( OUTPUT ${PROTOS_TIMESTAMP} DEPENDS ${PROTOS} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROTOS} ${PROTOS_TIMESTAMP} ) # For testing (command line too long for Windows) if(NOT WIN32) add_custom_target(gen_protos DEPENDS ${PROTOS}) endif() #-----------------------------------------------------------------------------# # # HTML # #-----------------------------------------------------------------------------# # The html_refs file contains link definitions for each API entry. # It's used to resolve references across HTML pages. # The search_index.js file contains definitions for the autosuggest widget. if(PANDOC_STRIP_UNDERSCORES) set(STRIP_UNDERSCORES "--strip-underscores") else() set(STRIP_UNDERSCORES "") endif() add_custom_command( OUTPUT ${HTML_REFS} DEPENDS ${PAGES_TXT} make_html_refs COMMAND ${MAKE_HTML_REFS} ${STRIP_UNDERSCORES} ${PAGES_TXT} > ${HTML_REFS} ) add_custom_command( OUTPUT ${HTML_REFS_TIMESTAMP} DEPENDS ${HTML_REFS} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${HTML_REFS} ${HTML_REFS_TIMESTAMP} ) add_custom_command( OUTPUT ${INDEX_ALL} DEPENDS ${HTML_REFS_TIMESTAMP} make_index COMMAND ${MAKE_INDEX} ${HTML_REFS} > ${INDEX_ALL} ) add_custom_command( OUTPUT ${SEARCH_INDEX_JS} DEPENDS ${HTML_REFS_TIMESTAMP} make_search_index COMMAND ${MAKE_SEARCH_INDEX} ${HTML_REFS} > ${SEARCH_INDEX_JS} ) if(WANT_DOCS_HTML) foreach(inc inc.a inc.z) # Use native Windows syntax to avoid "c:/foo.txt" being treated as a # remote URI by Pandoc 1.5 and 1.6. file(TO_NATIVE_PATH ${SRC_REFMAN_DIR}/${inc}.txt pandoc_src) add_custom_command( OUTPUT ${inc}.html DEPENDS ${SRC_REFMAN_DIR}/${inc}.txt COMMAND ${PANDOC} ${pandoc_src} -o ${inc}.html ) endforeach(inc) set(HTML_PAGES) foreach(page ${PAGES} index index_all) if(page STREQUAL "index_all") set(page_src ${INDEX_ALL}) else() set(page_src ${SRC_REFMAN_DIR}/${page}.txt) endif() add_custom_command( OUTPUT ${HTML_DIR}/${page}.html DEPENDS ${PROTOS_TIMESTAMP} ${HTML_REFS_TIMESTAMP} ${page_src} ${CMAKE_CURRENT_BINARY_DIR}/inc.a.html ${CMAKE_CURRENT_BINARY_DIR}/inc.z.html ${SEARCH_INDEX_JS} make_doc insert_timestamp COMMAND ${INSERT_TIMESTAMP} ${CMAKE_SOURCE_DIR}/include/allegro5/base.h > inc.timestamp.html COMMAND ${MAKE_DOC} --to html --raise-sections --include-before-body inc.a.html --include-after-body inc.timestamp.html --include-after-body inc.z.html --css pandoc.css --include-in-header ${SRC_DIR}/custom_header.html --standalone --toc -- ${page_src} ${HTML_REFS} > ${HTML_DIR}/${page}.html ) list(APPEND HTML_PAGES ${HTML_DIR}/${page}.html) endforeach(page) set(HTML_IMAGES) foreach(image ${IMAGES}) add_custom_command( OUTPUT ${HTML_DIR}/images/${image}.png DEPENDS ${SRC_REFMAN_DIR}/images/${image}.png COMMAND "${CMAKE_COMMAND}" -E copy "${SRC_REFMAN_DIR}/images/${image}.png" "${HTML_DIR}/images/${image}.png" ) list(APPEND HTML_IMAGES ${HTML_DIR}/images/${image}.png) endforeach(image) add_custom_target(html ALL DEPENDS ${HTML_PAGES} ${HTML_IMAGES}) foreach(file pandoc.css autosuggest.js) configure_file( ${SRC_DIR}/${file} ${HTML_DIR}/${file} COPY_ONLY) endforeach(file) endif(WANT_DOCS_HTML) #-----------------------------------------------------------------------------# # # Man pages # #-----------------------------------------------------------------------------# set(MANDIR "man" CACHE STRING "Install man pages into this directory") if(WANT_DOCS_MAN) make_directory(${MAN_DIR}) set(MAN_PAGES) foreach(page ${PAGES_TXT}) # Figure out the man pages that would be generated from this file. file(STRINGS ${page} lines REGEX "# API: ") if(lines) string(REGEX REPLACE "[#]* API: " ";" entries ${lines}) set(outputs) foreach(entry ${entries}) list(APPEND outputs ${MAN_DIR}/${entry}.3) endforeach(entry) add_custom_command( OUTPUT ${outputs} DEPENDS ${PROTOS_TIMESTAMP} ${page} make_doc COMMAND ${MAKE_DOC} --to man -- ${page} WORKING_DIRECTORY ${MAN_DIR} ) list(APPEND MAN_PAGES ${outputs}) endif(lines) endforeach(page) add_custom_target(man ALL DEPENDS ${MAN_PAGES}) install(FILES ${MAN_PAGES} DESTINATION ${MANDIR}/man3 ) endif(WANT_DOCS_MAN) #-----------------------------------------------------------------------------# # # Info # #-----------------------------------------------------------------------------# add_custom_command( OUTPUT ${DUMMY_REFS} DEPENDS ${PAGES_TXT} make_dummy_refs COMMAND ${MAKE_DUMMY_REFS} ${PAGES_TXT} > ${DUMMY_REFS} ) add_custom_command( OUTPUT ${DUMMY_REFS_TIMESTAMP} DEPENDS ${DUMMY_REFS} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DUMMY_REFS} ${DUMMY_REFS_TIMESTAMP} ) add_custom_target(gen_dummy_refs DEPENDS ${DUMMY_REFS}) if(WANT_DOCS_INFO AND PANDOC_WITH_TEXINFO AND MAKEINFO) make_directory(${INFO_DIR}) make_directory(${TEXI_DIR}) add_custom_target(info ALL DEPENDS ${INFO_DIR}/refman.info) add_custom_command( OUTPUT ${INFO_DIR}/refman.info DEPENDS ${TEXI_DIR}/refman.texi COMMAND ${MAKEINFO} --paragraph-indent 0 --no-split ${TEXI_DIR}/refman.texi -o ${INFO_DIR}/refman.info ) add_custom_command( OUTPUT ${TEXI_DIR}/refman.texi DEPENDS ${PROTOS_TIMESTAMP} ${DUMMY_REFS_TIMESTAMP} ${PAGES_TXT} make_doc COMMAND ${MAKE_DOC} --to texinfo --standalone -- ${DUMMY_REFS} ${PAGES_TXT} > ${TEXI_DIR}/refman.texi ) else() if(WANT_DOCS_INFO) message("Info documentation requires Pandoc 1.1+ and makeinfo") endif(WANT_DOCS_INFO) endif(WANT_DOCS_INFO AND PANDOC_WITH_TEXINFO AND MAKEINFO) #-----------------------------------------------------------------------------# # # LaTeX (PDF) # #-----------------------------------------------------------------------------# set(MAKE_PDF ${WANT_DOCS_PDF}) if(WANT_DOCS_PDF AND NOT PANDOC_FOR_LATEX) set(MAKE_PDF 0) message("PDF generation requires pandoc 1.5+") endif() if(WANT_DOCS_PDF AND NOT PDFLATEX_COMPILER) set(MAKE_PDF 0) message("PDF generation requires pdflatex") endif() if(MAKE_PDF) if(WANT_DOCS_PDF_PAPER) set(paperref 1) else() set(paperref) endif() make_directory(${LATEX_DIR}) add_custom_target(latex ALL DEPENDS ${LATEX_DIR}/refman.tex) add_custom_command( OUTPUT ${LATEX_DIR}/refman.tex DEPENDS ${PROTOS_TIMESTAMP} ${DUMMY_REFS_TIMESTAMP} ${PAGES_TXT} ${SRC_REFMAN_DIR}/latex.template make_doc COMMAND ${MAKE_DOC} --to latex --template ${SRC_REFMAN_DIR}/latex.template -V paperref=${paperref} --standalone --toc --number-sections -- ${DUMMY_REFS} ${PAGES_TXT} > ${LATEX_DIR}/refman.tex ) set(PDF_IMAGES) foreach(image ${IMAGES}) add_custom_command( OUTPUT ${LATEX_DIR}/images/${image}.png DEPENDS ${SRC_REFMAN_DIR}/images/${image}.png COMMAND "${CMAKE_COMMAND}" -E copy "${SRC_REFMAN_DIR}/images/${image}.png" "${LATEX_DIR}/images/${image}.png" ) list(APPEND PDF_IMAGES ${LATEX_DIR}/images/${image}.png) endforeach(image) make_directory(${PDF_DIR}) add_custom_target(pdf ALL DEPENDS ${PDF_DIR}/refman.pdf) add_custom_command( OUTPUT ${PDF_DIR}/refman.pdf DEPENDS ${LATEX_DIR}/refman.tex DEPENDS ${PDF_IMAGES} # Repeat three times to get cross references correct. COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction batchmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction batchmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction batchmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex ) endif(MAKE_PDF) #-----------------------------------------------------------------------------# # # Tags file # #-----------------------------------------------------------------------------# if(CTAGS) add_custom_target(gen_tags DEPENDS tags) add_custom_command( OUTPUT tags DEPENDS ${PAGES_TXT} COMMAND ${CTAGS} --langdef=allegrodoc --langmap=allegrodoc:.txt "--regex-allegrodoc=/^#+ API: (.+)/\\1/" ${PAGES_TXT} VERBATIM ) endif(CTAGS) #-----------------------------------------------------------------------------# # # Consistency check # #-----------------------------------------------------------------------------# add_custom_target(check_consistency DEPENDS ${PROTOS} COMMAND ${SH} ${SCRIPT_DIR}/check_consistency --protos ${PROTOS} ${PAGES_TXT} ) #-----------------------------------------------------------------------------# # vim: set sts=4 sw=4 et: allegro-5.0.10/docs/man/0000755000175000001440000000000012157230720014110 5ustar tjadenusersallegro-5.0.10/docs/man/al_fopen_interface.30000644000175000001440000000067712157230671020016 0ustar tjadenusers.TH al_fopen_interface 3 "" "Allegro reference manual" .SH NAME .PP al_fopen_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_fopen_interface(const\ ALLEGRO_FILE_INTERFACE\ *drv, \ \ \ const\ char\ *path,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Opens a file using the specified interface, instead of the interface set with al_set_new_file_interface(3). .SH SEE ALSO .PP al_fopen(3) allegro-5.0.10/docs/man/al_ustr_empty_string.30000644000175000001440000000051712157230675020465 0ustar tjadenusers.TH al_ustr_empty_string 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_empty_string \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_USTR\ *al_ustr_empty_string(void) \f[] .fi .SH DESCRIPTION .PP Return a pointer to a static empty string. The string is read only and must not be freed. allegro-5.0.10/docs/man/al_detach_voice.30000644000175000001440000000063412157230677017303 0ustar tjadenusers.TH al_detach_voice 3 "" "Allegro reference manual" .SH NAME .PP al_detach_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_detach_voice(ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Detaches the mixer or sample or stream from the voice. .SH SEE ALSO .PP al_attach_mixer_to_voice(3), al_attach_sample_instance_to_voice(3), al_attach_audio_stream_to_voice(3) allegro-5.0.10/docs/man/al_get_new_display_refresh_rate.30000644000175000001440000000062512157230670022565 0ustar tjadenusers.TH al_get_new_display_refresh_rate 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_display_refresh_rate \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_display_refresh_rate(void) \f[] .fi .SH DESCRIPTION .PP Get the requested refresh rate to be used when creating new displays on the calling thread. .SH SEE ALSO .PP al_set_new_display_refresh_rate(3) allegro-5.0.10/docs/man/al_init_primitives_addon.30000644000175000001440000000061012157230700021226 0ustar tjadenusers.TH al_init_primitives_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_primitives_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_init_primitives_addon(void) \f[] .fi .SH DESCRIPTION .PP Initializes the primitives addon. .PP \f[I]Returns:\f[] True on success, false on failure. .SH SEE ALSO .PP al_shutdown_primitives_addon(3) allegro-5.0.10/docs/man/al_set_new_file_interface.30000644000175000001440000000076712157230672021353 0ustar tjadenusers.TH al_set_new_file_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_file_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_file_interface(const\ ALLEGRO_FILE_INTERFACE\ *file_interface) \f[] .fi .SH DESCRIPTION .PP Set the ALLEGRO_FILE_INTERFACE(3) table for the calling thread. This will change the handler for later calls to al_fopen(3). .SH SEE ALSO .PP al_set_standard_file_interface(3), al_store_state(3), al_restore_state(3). allegro-5.0.10/docs/man/al_ustr_find_replace_cstr.30000644000175000001440000000064412157230677021412 0ustar tjadenusers.TH al_ustr_find_replace_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_replace_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_find_replace_cstr(ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ char\ *find,\ const\ char\ *replace) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_find_replace(3) but takes C\-style strings for \f[C]find\f[] and \f[C]replace\f[]. allegro-5.0.10/docs/man/al_get_path_component.30000644000175000001440000000106212157230674020534 0ustar tjadenusers.TH al_get_path_component 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_component \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_component(const\ ALLEGRO_PATH\ *path,\ int\ i) \f[] .fi .SH DESCRIPTION .PP Return the i\[aq]th directory component of a path, counting from zero. If the index is negative then count from the right, i.e. \-1 refers to the last path component. It is an error to pass an index which is out of bounds. .SH SEE ALSO .PP al_get_path_num_components(3), al_get_path_tail(3) allegro-5.0.10/docs/man/al_get_audio_stream_speed.30000644000175000001440000000055612157230701021350 0ustar tjadenusers.TH al_get_audio_stream_speed 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_audio_stream_speed(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the relative playback speed. .SH SEE ALSO .PP al_set_audio_stream_speed(3). allegro-5.0.10/docs/man/al_merge_config.30000644000175000001440000000111612157230670017277 0ustar tjadenusers.TH al_merge_config 3 "" "Allegro reference manual" .SH NAME .PP al_merge_config \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CONFIG\ *al_merge_config(const\ ALLEGRO_CONFIG\ *cfg1, \ \ \ \ const\ ALLEGRO_CONFIG\ *cfg2) \f[] .fi .SH DESCRIPTION .PP Merge two configuration structures, and return the result as a new configuration. Values in configuration \[aq]cfg2\[aq] override those in \[aq]cfg1\[aq]. Neither of the input configuration structures are modified. Comments from \[aq]cfg2\[aq] are not retained. .SH SEE ALSO .PP al_merge_config_into(3) allegro-5.0.10/docs/man/al_wait_cond_until.30000644000175000001440000000101112157230675020034 0ustar tjadenusers.TH al_wait_cond_until 3 "" "Allegro reference manual" .SH NAME .PP al_wait_cond_until \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_wait_cond_until(ALLEGRO_COND\ *cond,\ ALLEGRO_MUTEX\ *mutex, \ \ \ const\ ALLEGRO_TIMEOUT\ *timeout) \f[] .fi .SH DESCRIPTION .PP Like al_wait_cond(3) but the call can return if the absolute time passes \f[C]timeout\f[] before the condition is signalled. .PP Returns zero on success, non\-zero if the call timed out. .SH SEE ALSO .PP al_wait_cond(3) allegro-5.0.10/docs/man/al_get_file_userdata.30000644000175000001440000000062012157230672020322 0ustar tjadenusers.TH al_get_file_userdata 3 "" "Allegro reference manual" .SH NAME .PP al_get_file_userdata \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_get_file_userdata(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Returns a pointer to the custom userdata that is attached to the file handle. This is intended to be used by functions that extend ALLEGRO_FILE_INTERFACE(3). allegro-5.0.10/docs/man/al_fs_entry_exists.30000644000175000001440000000071512157230672020111 0ustar tjadenusers.TH al_fs_entry_exists 3 "" "Allegro reference manual" .SH NAME .PP al_fs_entry_exists \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_fs_entry_exists(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Check if the given entry exists on in the filesystem. Returns true if it does exist or false if it doesn\[aq]t exist, or an error occurred. Error is indicated in Allegro\[aq]s errno. .SH SEE ALSO .PP al_filename_exists(3) allegro-5.0.10/docs/man/al_set_system_mouse_cursor.30000644000175000001440000000324412157230674021667 0ustar tjadenusers.TH al_set_system_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_set_system_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_system_mouse_cursor(ALLEGRO_DISPLAY\ *display, \ \ \ ALLEGRO_SYSTEM_MOUSE_CURSOR\ cursor_id) \f[] .fi .SH DESCRIPTION .PP Set the given system mouse cursor to be the current mouse cursor for the given display. If the cursor is currently \[aq]shown\[aq] (as opposed to \[aq]hidden\[aq]) the change is immediately visible. .PP If the cursor doesn\[aq]t exist on the current platform another cursor will be silently be substituted. .PP The cursors are: .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT .IP \[bu] 2 ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_mouse_cursor(3), al_show_mouse_cursor(3), al_hide_mouse_cursor(3) allegro-5.0.10/docs/man/al_get_font_ascent.30000644000175000001440000000054412157230677020030 0ustar tjadenusers.TH al_get_font_ascent 3 "" "Allegro reference manual" .SH NAME .PP al_get_font_ascent \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_font_ascent(const\ ALLEGRO_FONT\ *f) \f[] .fi .SH DESCRIPTION .PP Returns the ascent of the specified font. .SH SEE ALSO .PP al_get_font_descent(3), al_get_font_line_height(3) allegro-5.0.10/docs/man/al_is_sub_bitmap.30000644000175000001440000000056612157230673017506 0ustar tjadenusers.TH al_is_sub_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_is_sub_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_sub_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns true if the specified bitmap is a sub\-bitmap, false otherwise. .SH SEE ALSO .PP al_create_sub_bitmap(3), al_get_parent_bitmap(3) allegro-5.0.10/docs/man/al_color_rgb_to_cmyk.30000644000175000001440000000125212157230677020360 0ustar tjadenusers.TH al_color_rgb_to_cmyk 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_cmyk \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_rgb_to_cmyk(float\ red,\ float\ green,\ float\ blue, \ \ \ float\ *cyan,\ float\ *magenta,\ float\ *yellow,\ float\ *key) \f[] .fi .SH DESCRIPTION .PP Each RGB color can be represented in CMYK with a K component of 0 with the following formula: .IP .nf \f[C] C\ =\ 1\ \-\ R M\ =\ 1\ \-\ G Y\ =\ 1\ \-\ B K\ =\ 0 \f[] .fi .PP This function will instead find the representation with the maximal value for K and minimal color components. .SH SEE ALSO .PP al_color_cmyk(3), al_color_cmyk_to_rgb(3) allegro-5.0.10/docs/man/al_set_org_name.30000644000175000001440000000100112157230674017312 0ustar tjadenusers.TH al_set_org_name 3 "" "Allegro reference manual" .SH NAME .PP al_set_org_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_org_name(const\ char\ *org_name) \f[] .fi .SH DESCRIPTION .PP Sets the global organization name. .PP The organization name is used by al_get_standard_path(3) to build the full path to an application\[aq]s files. .PP This function may be called before al_init(3) or al_install_system(3). .SH SEE ALSO .PP al_get_org_name(3), al_set_app_name(3) allegro-5.0.10/docs/man/al_add_new_bitmap_flag.30000644000175000001440000000072212157230673020606 0ustar tjadenusers.TH al_add_new_bitmap_flag 3 "" "Allegro reference manual" .SH NAME .PP al_add_new_bitmap_flag \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_add_new_bitmap_flag(int\ flag) \f[] .fi .SH DESCRIPTION .PP A convenience function which does the same as .IP .nf \f[C] al_set_new_bitmap_flags(al_get_new_bitmap_flags()\ |\ flag); \f[] .fi .SH SEE ALSO .PP al_set_new_bitmap_flags(3), al_get_new_bitmap_flags(3), al_get_bitmap_flags(3) allegro-5.0.10/docs/man/al_utf8_width.30000644000175000001440000000070112157230677016746 0ustar tjadenusers.TH al_utf8_width 3 "" "Allegro reference manual" .SH NAME .PP al_utf8_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_utf8_width(int\ c) \f[] .fi .SH DESCRIPTION .PP Returns the number of bytes that would be occupied by the specified code point when encoded in UTF\-8. This is between 1 and 4 bytes for legal code point values. Otherwise returns 0. .SH SEE ALSO .PP al_utf8_encode(3), al_utf16_width(3) allegro-5.0.10/docs/man/al_create_config.30000644000175000001440000000051312157230670017443 0ustar tjadenusers.TH al_create_config 3 "" "Allegro reference manual" .SH NAME .PP al_create_config \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CONFIG\ *al_create_config(void) \f[] .fi .SH DESCRIPTION .PP Create an empty configuration structure. .SH SEE ALSO .PP al_load_config_file(3), al_destroy_config(3) allegro-5.0.10/docs/man/al_get_mixer_playing.30000644000175000001440000000052212157230700020353 0ustar tjadenusers.TH al_get_mixer_playing 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_mixer_playing(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return true if the mixer is playing. .SH SEE ALSO .PP al_set_mixer_playing(3). allegro-5.0.10/docs/man/ALLEGRO_AUDIO_STREAM.30000644000175000001440000000352312157230676017272 0ustar tjadenusers.TH ALLEGRO_AUDIO_STREAM 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_AUDIO_STREAM \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_AUDIO_STREAM\ ALLEGRO_AUDIO_STREAM; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the sound device, in real\-time. This is done by reading from a buffer, which is split into a number of fragments. Whenever a fragment has finished playing, the user can refill it with new data. .PP As with ALLEGRO_SAMPLE_INSTANCE(3) objects, streams store information necessary for playback, so you may not play the same stream multiple times simultaneously. Streams also need to be attached to an ALLEGRO_VOICE(3) object, or to an ALLEGRO_MIXER(3) object which, eventually, reaches an ALLEGRO_VOICE object. .PP While playing, you must periodically fill fragments with new audio data. To know when a new fragment is ready to be filled, you can either directly check with al_get_available_audio_stream_fragments(3), or listen to events from the stream. .PP You can register an audio stream event source to an event queue; see al_get_audio_stream_event_source(3). An ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event is generated whenever a new fragment is ready. When you receive an event, use al_get_audio_stream_fragment(3) to obtain a pointer to the fragment to be filled. The size and format are determined by the parameters passed to al_create_audio_stream(3). .PP If you\[aq]re late with supplying new data, the stream will be silent until new data is provided. You must call al_drain_audio_stream(3) when you\[aq]re finished with supplying data to the stream. .PP If the stream is created by al_load_audio_stream(3) then it can also generate an ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event if it reaches the end of the file and is not set to loop. allegro-5.0.10/docs/man/ALLEGRO_MEMORY_INTERFACE.30000644000175000001440000000147512157230673017747 0ustar tjadenusers.TH ALLEGRO_MEMORY_INTERFACE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MEMORY_INTERFACE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_MEMORY_INTERFACE\ ALLEGRO_MEMORY_INTERFACE; \f[] .fi .SH DESCRIPTION .PP This structure has the following fields. .IP .nf \f[C] void\ *(*mi_malloc)(size_t\ n,\ int\ line,\ const\ char\ *file,\ const\ char\ *func); void\ (*mi_free)(void\ *ptr,\ int\ line,\ const\ char\ *file,\ const\ char\ *func); void\ *(*mi_realloc)(void\ *ptr,\ size_t\ n,\ int\ line,\ const\ char\ *file, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ char\ *func); void\ *(*mi_calloc)(size_t\ count,\ size_t\ n,\ int\ line,\ const\ char\ *file, \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ const\ char\ *func); \f[] .fi .SH SEE ALSO .PP al_set_memory_interface(3) allegro-5.0.10/docs/man/al_create_cond.30000644000175000001440000000047712157230675017137 0ustar tjadenusers.TH al_create_cond 3 "" "Allegro reference manual" .SH NAME .PP al_create_cond \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COND\ *al_create_cond(void) \f[] .fi .SH DESCRIPTION .PP Create a condition variable. .PP Returns the condition value on success or \f[C]NULL\f[] on error. allegro-5.0.10/docs/man/al_create_timer.30000644000175000001440000000120012157230675017315 0ustar tjadenusers.TH al_create_timer 3 "" "Allegro reference manual" .SH NAME .PP al_create_timer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_TIMER\ *al_create_timer(double\ speed_secs) \f[] .fi .SH DESCRIPTION .PP Allocates and initializes a timer. If successful, a pointer to a new timer object is returned, otherwise NULL is returned. \f[I]speed_secs\f[] is in seconds per "tick", and must be positive. The new timer is initially stopped. .PP Usage note: typical granularity is on the order of microseconds, but with some drivers might only be milliseconds. .SH SEE ALSO .PP al_start_timer(3), al_destroy_timer(3) allegro-5.0.10/docs/man/al_get_sample_instance_attached.30000644000175000001440000000074512157230700022515 0ustar tjadenusers.TH al_get_sample_instance_attached 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_attached \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_sample_instance_attached(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return whether the sample instance is attached to something. .SH SEE ALSO .PP al_attach_sample_instance_to_mixer(3), al_attach_sample_instance_to_voice(3), al_detach_sample_instance(3) allegro-5.0.10/docs/man/al_ustr_rfind_str.30000644000175000001440000000105412157230677017732 0ustar tjadenusers.TH al_ustr_rfind_str 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_rfind_str \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_rfind_str(const\ ALLEGRO_USTR\ *haystack,\ int\ end_pos, \ \ \ const\ ALLEGRO_USTR\ *needle) \f[] .fi .SH DESCRIPTION .PP Find the last occurrence of string \f[C]needle\f[] in \f[C]haystack\f[] before byte offset \f[C]end_pos\f[] (exclusive). Return the byte offset of the occurrence if it is found, otherwise return \-1. .SH SEE ALSO .PP al_ustr_rfind_cstr(3), al_ustr_find_str(3) allegro-5.0.10/docs/man/al_broadcast_cond.30000644000175000001440000000110512157230675017623 0ustar tjadenusers.TH al_broadcast_cond 3 "" "Allegro reference manual" .SH NAME .PP al_broadcast_cond \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_broadcast_cond(ALLEGRO_COND\ *cond) \f[] .fi .SH DESCRIPTION .PP Unblock all threads currently waiting on a condition variable. That is, broadcast that some condition which those threads were waiting for has become true. .SH SEE ALSO .PP al_signal_cond(3). .RS .PP \f[I]Note:\f[] The pthreads spec says to lock the mutex associated with \f[C]cond\f[] before signalling for predictable scheduling behaviour. .RE allegro-5.0.10/docs/man/al_show_native_file_dialog.30000644000175000001440000000117612157230700021517 0ustar tjadenusers.TH al_show_native_file_dialog 3 "" "Allegro reference manual" .SH NAME .PP al_show_native_file_dialog \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_show_native_file_dialog(ALLEGRO_DISPLAY\ *display, \ \ \ ALLEGRO_FILECHOOSER\ *dialog) \f[] .fi .SH DESCRIPTION .PP Show the dialog window. The display may be NULL, otherwise the given display is treated as the parent if possible. .PP This function blocks the calling thread until it returns, so you may want to spawn a thread with al_create_thread(3) and call it from inside that thread. .PP Returns true on success, false on failure. allegro-5.0.10/docs/man/al_fopen_fd.30000644000175000001440000000126312157230672016440 0ustar tjadenusers.TH al_fopen_fd 3 "" "Allegro reference manual" .SH NAME .PP al_fopen_fd \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_fopen_fd(int\ fd,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Create an ALLEGRO_FILE(3) object that operates on an open file descriptor using stdio routines. See the documentation of fdopen() for a description of the \[aq]mode\[aq] argument. .PP Returns an ALLEGRO_FILE object on success or NULL on an error. On an error, the Allegro errno will be set and the file descriptor will not be closed. .PP The file descriptor will be closed by al_fclose(3) so you should not call close() on it. .SH SEE ALSO .PP al_fopen(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_JOYSTICK_AXIS.30000644000175000001440000002700512157230670020375 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_fgets.30000644000175000001440000000152512157230671015770 0ustar tjadenusers.TH al_fgets 3 "" "Allegro reference manual" .SH NAME .PP al_fgets \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ *al_fgets(ALLEGRO_FILE\ *f,\ char\ *\ const\ buf,\ size_t\ max) \f[] .fi .SH DESCRIPTION .PP Read a string of bytes terminated with a newline or end\-of\-file into the buffer given. The line terminator(s), if any, are included in the returned string. A maximum of max\-1 bytes are read, with one byte being reserved for a NUL terminator. .PP Parameters: .IP \[bu] 2 f \- file to read from .IP \[bu] 2 buf \- buffer to fill .IP \[bu] 2 max \- maximum size of buffer .PP Returns the pointer to buf on success. Returns NULL if an error occurred or if the end of file was reached without reading any bytes. .PP See al_fopen(3) about translations of end\-of\-line characters. .SH SEE ALSO .PP al_fget_ustr(3) allegro-5.0.10/docs/man/al_fwrite16be.30000644000175000001440000000062612157230671016637 0ustar tjadenusers.TH al_fwrite16be 3 "" "Allegro reference manual" .SH NAME .PP al_fwrite16be \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fwrite16be(ALLEGRO_FILE\ *f,\ int16_t\ w) \f[] .fi .SH DESCRIPTION .PP Writes a 16\-bit word in big\-endian format (MSB first). .PP Returns the number of bytes written: 2 on success, less than 2 on an error. .SH SEE ALSO .PP al_fwrite16le(3) allegro-5.0.10/docs/man/al_get_sample_instance_playmode.30000644000175000001440000000063312157230700022546 0ustar tjadenusers.TH al_get_sample_instance_playmode 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_playmode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PLAYMODE\ al_get_sample_instance_playmode(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the playback mode. .SH SEE ALSO .PP ALLEGRO_PLAYMODE(3), al_set_sample_instance_playmode(3) allegro-5.0.10/docs/man/ALLEGRO_SAMPLE_ID.30000644000175000001440000000061012157230676016705 0ustar tjadenusers.TH ALLEGRO_SAMPLE_ID 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_SAMPLE_ID \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_SAMPLE_ID\ ALLEGRO_SAMPLE_ID; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_SAMPLE_ID represents a sample being played via al_play_sample(3). It can be used to later stop the sample with al_stop_sample(3). allegro-5.0.10/docs/man/al_restore_state.30000644000175000001440000000060512157230674017544 0ustar tjadenusers.TH al_restore_state 3 "" "Allegro reference manual" .SH NAME .PP al_restore_state \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_restore_state(ALLEGRO_STATE\ const\ *state) \f[] .fi .SH DESCRIPTION .PP Restores part of the state of the current thread from the given ALLEGRO_STATE(3) object. .SH SEE ALSO .PP al_store_state(3), ALLEGRO_STATE_FLAGS(3) allegro-5.0.10/docs/man/al_unlock_mutex.30000644000175000001440000000071212157230674017375 0ustar tjadenusers.TH al_unlock_mutex 3 "" "Allegro reference manual" .SH NAME .PP al_unlock_mutex \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unlock_mutex(ALLEGRO_MUTEX\ *mutex) \f[] .fi .SH DESCRIPTION .PP Release the lock on \f[C]mutex\f[] if the calling thread holds the lock on it. .PP If the calling thread doesn\[aq]t hold the lock, or if the mutex is not locked, undefined behaviour results. .SH SEE ALSO .PP al_lock_mutex(3). allegro-5.0.10/docs/man/al_ustr_free.30000644000175000001440000000056112157230675016661 0ustar tjadenusers.TH al_ustr_free 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_free \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_ustr_free(ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Free a previously allocated string. Does nothing if the argument is NULL. .SH SEE ALSO .PP al_ustr_new(3), al_ustr_new_from_buffer(3), al_ustr_newf(3) allegro-5.0.10/docs/man/al_get_win_window_handle.30000644000175000001440000000052112157230675021215 0ustar tjadenusers.TH al_get_win_window_handle 3 "" "Allegro reference manual" .SH NAME .PP al_get_win_window_handle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ HWND\ al_get_win_window_handle(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Returns the handle to the window that the passed display is using. allegro-5.0.10/docs/man/al_unref_user_event.30000644000175000001440000000111312157230672020230 0ustar tjadenusers.TH al_unref_user_event 3 "" "Allegro reference manual" .SH NAME .PP al_unref_user_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unref_user_event(ALLEGRO_USER_EVENT\ *event) \f[] .fi .SH DESCRIPTION .PP Decrease the reference count of a user\-defined event. This must be called on any user event that you get from al_get_next_event(3), al_peek_next_event(3), al_wait_for_event(3), etc. which is reference counted. This function does nothing if the event is not reference counted. .SH SEE ALSO .PP al_emit_user_event(3), ALLEGRO_USER_EVENT(3) allegro-5.0.10/docs/man/ALLEGRO_SEEK.30000644000175000001440000000066012157230671016077 0ustar tjadenusers.TH ALLEGRO_SEEK 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_SEEK \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_SEEK \f[] .fi .SH DESCRIPTION .IP \[bu] 2 ALLEGRO_SEEK_SET \- seek relative to beginning of file .IP \[bu] 2 ALLEGRO_SEEK_CUR \- seek relative to current file position .IP \[bu] 2 ALLEGRO_SEEK_END \- seek relative to end of file .SH SEE ALSO .PP al_fseek(3) allegro-5.0.10/docs/man/al_get_keyboard_event_source.30000644000175000001440000000056012157230673022100 0ustar tjadenusers.TH al_get_keyboard_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_keyboard_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_keyboard_event_source(void) \f[] .fi .SH DESCRIPTION .PP Retrieve the keyboard event source. .PP Returns NULL if the keyboard subsystem was not installed. allegro-5.0.10/docs/man/al_ustr_equal.30000644000175000001440000000066712157230677017060 0ustar tjadenusers.TH al_ustr_equal 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_equal \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_equal(const\ ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Return true iff the two strings are equal. This function is more efficient than al_ustr_compare(3) so is preferable if ordering is not important. .SH SEE ALSO .PP al_ustr_compare(3) allegro-5.0.10/docs/man/al_get_available_audio_stream_fragments.30000644000175000001440000000105212157230701024226 0ustar tjadenusers.TH al_get_available_audio_stream_fragments 3 "" "Allegro reference manual" .SH NAME .PP al_get_available_audio_stream_fragments \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_available_audio_stream_fragments( \ \ \ const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Returns the number of available fragments in the stream, that is, fragments which are not currently filled with data for playback. .SH SEE ALSO .PP al_get_audio_stream_fragment(3), al_get_audio_stream_fragments(3) allegro-5.0.10/docs/man/al_ustr_find_cset_cstr.30000644000175000001440000000066612157230677020741 0ustar tjadenusers.TH al_ustr_find_cset_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_cset_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_cset_cstr(const\ ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ char\ *reject) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_find_cset(3) but takes a C\-style string for \f[C]reject\f[]. .SH SEE ALSO .PP al_ustr_find_cset(3), al_ustr_find_set_cstr(3) allegro-5.0.10/docs/man/al_wait_cond.30000644000175000001440000000225212157230675016631 0ustar tjadenusers.TH al_wait_cond 3 "" "Allegro reference manual" .SH NAME .PP al_wait_cond \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_wait_cond(ALLEGRO_COND\ *cond,\ ALLEGRO_MUTEX\ *mutex) \f[] .fi .SH DESCRIPTION .PP On entering this function, \f[C]mutex\f[] must be locked by the calling thread. The function will atomically release \f[C]mutex\f[] and block on \f[C]cond\f[]. The function will return when \f[C]cond\f[] is "signalled", acquiring the lock on the mutex in the process. .PP Example of proper use: .IP .nf \f[C] al_lock_mutex(mutex); while\ (something_not_true)\ { \ \ \ \ al_wait_cond(cond,\ mutex); } do_something(); al_unlock_mutex(mutex); \f[] .fi .PP The mutex should be locked before checking the condition, and should be rechecked al_wait_cond(3) returns. al_wait_cond(3) can return for other reasons than the condition becoming true (e.g. the process was signalled). If multiple threads are blocked on the condition variable, the condition may no longer be true by the time the second and later threads are unblocked. Remember not to unlock the mutex prematurely. .SH SEE ALSO .PP al_wait_cond_until(3), al_broadcast_cond(3), al_signal_cond(3). allegro-5.0.10/docs/man/al_destroy_audio_stream.30000644000175000001440000000105412157230700021073 0ustar tjadenusers.TH al_destroy_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Destroy an audio stream which was created with al_create_audio_stream(3) or al_load_audio_stream(3). .RS .PP \f[I]Note:\f[] If the stream is still attached to a mixer or voice, al_detach_audio_stream(3) is automatically called on it first. .RE .SH SEE ALSO .PP al_drain_audio_stream(3). allegro-5.0.10/docs/man/al_calculate_arc.30000644000175000001440000000257012157230700017434 0ustar tjadenusers.TH al_calculate_arc 3 "" "Allegro reference manual" .SH NAME .PP al_calculate_arc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_calculate_arc(float*\ dest,\ int\ stride,\ float\ cx,\ float\ cy, \ \ \ float\ rx,\ float\ ry,\ float\ start_theta,\ float\ delta_theta,\ float\ thickness, \ \ \ int\ num_segments) \f[] .fi .SH DESCRIPTION .PP Calculates an elliptical arc, and sets the vertices in the destination buffer to the calculated positions. If \f[C]thickness\ <=\ 0\f[], then \f[C]num_points\f[] of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of \f[C]stride\f[] bytes) doublets of floats, corresponding to x and y coordinates of the vertices. .PP \f[I]Parameters:\f[] .IP \[bu] 2 dest \- The destination buffer .IP \[bu] 2 stride \- Distance (in bytes) between starts of successive pairs of coordinates .IP \[bu] 2 cx, cy \- Center of the arc .IP \[bu] 2 rx, ry \- Radii of the arc .IP \[bu] 2 start_theta \- The initial angle from which the arc is calculated .IP \[bu] 2 delta_theta \- Angular span of the arc (pass a negative number to switch direction) .IP \[bu] 2 thickness \- Thickness of the arc .IP \[bu] 2 num_points \- The number of points to calculate .SH SEE ALSO .PP al_draw_arc(3), al_calculate_spline(3), al_calculate_ribbon(3) allegro-5.0.10/docs/man/al_get_num_video_adapters.30000644000175000001440000000076112157230673021372 0ustar tjadenusers.TH al_get_num_video_adapters 3 "" "Allegro reference manual" .SH NAME .PP al_get_num_video_adapters \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_num_video_adapters(void) \f[] .fi .SH DESCRIPTION .PP Get the number of video "adapters" attached to the computer. Each video card attached to the computer counts as one or more adapters. An adapter is thus really a video port that can have a monitor connected to it. .SH SEE ALSO .PP al_get_monitor_info(3) allegro-5.0.10/docs/man/al_put_blended_pixel.30000644000175000001440000000063612157230673020352 0ustar tjadenusers.TH al_put_blended_pixel 3 "" "Allegro reference manual" .SH NAME .PP al_put_blended_pixel \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_put_blended_pixel(int\ x,\ int\ y,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Like al_put_pixel(3), but the pixel color is blended using the current blenders before being drawn. .SH SEE ALSO .PP ALLEGRO_COLOR(3), al_put_pixel(3) allegro-5.0.10/docs/man/al_stop_sample_instance.30000644000175000001440000000053212157230677021075 0ustar tjadenusers.TH al_stop_sample_instance 3 "" "Allegro reference manual" .SH NAME .PP al_stop_sample_instance \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Stop an sample instance playing. .SH SEE ALSO .PP al_play_sample_instance(3) allegro-5.0.10/docs/man/al_color_cmyk_to_rgb.30000644000175000001440000000066212157230677020364 0ustar tjadenusers.TH al_color_cmyk_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_cmyk_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_cmyk_to_rgb(float\ cyan,\ float\ magenta,\ float\ yellow, \ \ \ \ float\ key,\ float\ *red,\ float\ *green,\ float\ *blue) \f[] .fi .SH DESCRIPTION .PP Convert CMYK values to RGB values. .SH SEE ALSO .PP al_color_cmyk(3), al_color_rgb_to_cmyk(3) allegro-5.0.10/docs/man/al_get_new_bitmap_flags.30000644000175000001440000000051312157230673021016 0ustar tjadenusers.TH al_get_new_bitmap_flags 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_bitmap_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_bitmap_flags(void) \f[] .fi .SH DESCRIPTION .PP Returns the flags used for newly created bitmaps. .SH SEE ALSO .PP al_set_new_bitmap_flags(3) allegro-5.0.10/docs/man/al_set_config_value.30000644000175000001440000000153512157230670020174 0ustar tjadenusers.TH al_set_config_value 3 "" "Allegro reference manual" .SH NAME .PP al_set_config_value \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_config_value(ALLEGRO_CONFIG\ *config, \ \ \ const\ char\ *section,\ const\ char\ *key,\ const\ char\ *value) \f[] .fi .SH DESCRIPTION .PP Set a value in a section of a configuration. If the section doesn\[aq]t yet exist, it will be created. If a value already existed for the given key, it will be overwritten. The section can be NULL or "" for the global section. .PP For consistency with the on\-disk format of config files, any leading and trailing whitespace will be stripped from the value. If you have significant whitespace you wish to preserve, you should add your own quote characters and remove them when reading the values back in. .SH SEE ALSO .PP al_get_config_value(3) allegro-5.0.10/docs/man/al_ustr_length.30000644000175000001440000000051512157230676017221 0ustar tjadenusers.TH al_ustr_length 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_length \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_length(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Return the number of code points in the string. .SH SEE ALSO .PP al_ustr_size(3), al_ustr_offset(3) allegro-5.0.10/docs/man/al_color_hsl.30000644000175000001440000000060212157230677016645 0ustar tjadenusers.TH al_color_hsl 3 "" "Allegro reference manual" .SH NAME .PP al_color_hsl \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_hsl(float\ h,\ float\ s,\ float\ l) \f[] .fi .SH DESCRIPTION .PP Return an ALLEGRO_COLOR(3) structure from HSL (hue, saturation, lightness) values. .SH SEE ALSO .PP al_color_hsl_to_rgb(3), al_color_hsv(3) allegro-5.0.10/docs/man/al_get_mixer_gain.30000644000175000001440000000057712157230700017640 0ustar tjadenusers.TH al_get_mixer_gain 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_mixer_gain(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return the mixer gain (amplification factor). The default is 1.0. .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_set_mixer_gain(3). allegro-5.0.10/docs/man/al_register_audio_stream_loader_f.30000644000175000001440000000160212157230701023061 0ustar tjadenusers.TH al_register_audio_stream_loader_f 3 "" "Allegro reference manual" .SH NAME .PP al_register_audio_stream_loader_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_audio_stream_loader_f(const\ char\ *ext, \ \ \ ALLEGRO_AUDIO_STREAM\ *(*stream_loader)(ALLEGRO_FILE*\ fp, \ \ \ \ \ \ size_t\ buffer_count,\ unsigned\ int\ samples)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_audio_stream_f(3). The given function will be used to open streams from files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]stream_loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_audio_stream_loader(3) allegro-5.0.10/docs/man/al_ustr_get_next.30000644000175000001440000000125112157230676017553 0ustar tjadenusers.TH al_ustr_get_next 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_get_next \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int32_t\ al_ustr_get_next(const\ ALLEGRO_USTR\ *us,\ int\ *pos) \f[] .fi .SH DESCRIPTION .PP Find the code point in \f[C]us\f[] beginning at byte offset \f[C]*pos\f[], then advance to the next code point. .PP On success return the code point value. If \f[C]pos\f[] was out of bounds (e.g. past the end of the string), return \-1. On an error, such as an invalid byte sequence, return \-2. As with al_ustr_next(3), invalid byte sequences may be skipped while advancing. .SH SEE ALSO .PP al_ustr_get(3), al_ustr_prev_get(3) allegro-5.0.10/docs/man/al_iphone_override_screen_scale.30000644000175000001440000000236312157230675022554 0ustar tjadenusers.TH al_iphone_override_screen_scale 3 "" "Allegro reference manual" .SH NAME .PP al_iphone_override_screen_scale \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_iphone_override_screen_scale(float\ scale) \f[] .fi .SH DESCRIPTION .PP Original iPhones and iPod Touches had a screen resolution of 320x480 (in Portrait mode). When the iPhone 4 and iPod Touch 4th generation devices came out, they were backwards compatible with all old iPhone apps. This means that they assume a 320x480 screen resolution by default, while they actually have a 640x960 pixel screen (exactly 2x on each dimension). An API was added to allow access to the full (or in fact any fraction of the) resolution of the new devices. This function is normally not needed, as in the case when you want a scale of 2.0 for "retina display" resolution (640x960). In that case you would just call al_create_display with the larger width and height parameters. It is not limited to 2.0 scaling factors however. You can use 1.5 or 0.5 or other values in between, however if it\[aq]s not an exact multiple of the original iPhone resolution, linear filtering will be applied to the final image. .PP This function should be called BEFORE calling al_create_display. allegro-5.0.10/docs/man/ALLEGRO_VERTEX.30000644000175000001440000000166512157230701016365 0ustar tjadenusers.TH ALLEGRO_VERTEX 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_VERTEX \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_VERTEX\ ALLEGRO_VERTEX; \f[] .fi .SH DESCRIPTION .PP Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set z to 0. Note that when you must initialize all members of this struct when you\[aq]re using it. One exception to this rule are the u and v variables which can be left uninitialized when you are not using textures. .PP \f[I]Fields:\f[] .IP \[bu] 2 x, y, z \- Position of the vertex (float) .IP \[bu] 2 color \- ALLEGRO_COLOR(3) structure, storing the color of the vertex .IP \[bu] 2 u, v \- Texture coordinates measured in pixels (float) .SH SEE ALSO .PP ALLEGRO_PRIM_ATTR(3) allegro-5.0.10/docs/man/ALLEGRO_STATE_FLAGS.30000644000175000001440000000055212157230674017147 0ustar tjadenusers.TH ALLEGRO_STATE_FLAGS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_STATE_FLAGS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_STATE_FLAGS \f[] .fi .SH DESCRIPTION .PP Flags which can be passed to al_store_state(3)/al_restore_state(3) as bit combinations. See al_store_state(3) for the list of flags. allegro-5.0.10/docs/man/al_get_sample_instance_playing.30000644000175000001440000000061312157230700022375 0ustar tjadenusers.TH al_get_sample_instance_playing 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_sample_instance_playing(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return true if the sample instance is playing. .SH SEE ALSO .PP al_set_sample_instance_playing(3) allegro-5.0.10/docs/man/al_save_config_file_f.30000644000175000001440000000070712157230670020447 0ustar tjadenusers.TH al_save_config_file_f 3 "" "Allegro reference manual" .SH NAME .PP al_save_config_file_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_config_file_f(ALLEGRO_FILE\ *file,\ const\ ALLEGRO_CONFIG\ *config) \f[] .fi .SH DESCRIPTION .PP Write out a configuration file to an already open file. .PP Returns true on success, false on error. The file remains open afterwards. .SH SEE ALSO .PP al_save_config_file(3) allegro-5.0.10/docs/man/al_color_html_to_rgb.30000644000175000001440000000072412157230677020364 0ustar tjadenusers.TH al_color_html_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_html_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_html_to_rgb(char\ const\ *string, \ \ \ float\ *red,\ float\ *green,\ float\ *blue) \f[] .fi .SH DESCRIPTION .PP Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0. .SH SEE ALSO .PP al_color_html(3), al_color_rgb_to_html(3) allegro-5.0.10/docs/man/al_rotate_transform.30000644000175000001440000000077212157230675020260 0ustar tjadenusers.TH al_rotate_transform 3 "" "Allegro reference manual" .SH NAME .PP al_rotate_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_rotate_transform(ALLEGRO_TRANSFORM\ *trans,\ float\ theta) \f[] .fi .SH DESCRIPTION .PP Apply a rotation to a transformation. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .IP \[bu] 2 theta \- Rotation angle in radians .SH SEE ALSO .PP al_translate_transform(3), al_scale_transform(3), al_build_transform(3) allegro-5.0.10/docs/man/al_ustr_remove_range.30000644000175000001440000000111112157230676020402 0ustar tjadenusers.TH al_ustr_remove_range 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_remove_range \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_remove_range(ALLEGRO_USTR\ *us,\ int\ start_pos,\ int\ end_pos) \f[] .fi .SH DESCRIPTION .PP Remove the interval [start_pos, end_pos) from a string. \f[C]start_pos\f[] and \f[C]end_pos\f[] are byte offsets. Both may be past the end of the string but cannot be less than 0 (the start of the string). .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_remove_chr(3), al_ustr_truncate(3) allegro-5.0.10/docs/man/al_set_mixer_postprocess_callback.30000644000175000001440000000117012157230700023124 0ustar tjadenusers.TH al_set_mixer_postprocess_callback 3 "" "Allegro reference manual" .SH NAME .PP al_set_mixer_postprocess_callback \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mixer_postprocess_callback(ALLEGRO_MIXER\ *mixer, \ \ \ void\ (*pp_callback)(void\ *buf,\ unsigned\ int\ samples,\ void\ *data), \ \ \ void\ *pp_callback_userdata) \f[] .fi .SH DESCRIPTION .PP Sets a post\-processing filter function that\[aq]s called after the attached streams have been mixed. The buffer\[aq]s format will be whatever the mixer was created with. The sample count and user\-data pointer is also passed. allegro-5.0.10/docs/man/al_realloc_with_context.30000644000175000001440000000075612157230673021107 0ustar tjadenusers.TH al_realloc_with_context 3 "" "Allegro reference manual" .SH NAME .PP al_realloc_with_context \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_realloc_with_context(void\ *ptr,\ size_t\ n, \ \ \ int\ line,\ const\ char\ *file,\ const\ char\ *func) \f[] .fi .SH DESCRIPTION .PP This calls realloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface(3), .PP Generally you should use the al_realloc(3) macro. allegro-5.0.10/docs/man/al_get_opengl_texture_position.30000644000175000001440000000070612157230676022514 0ustar tjadenusers.TH al_get_opengl_texture_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_texture_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_opengl_texture_position(ALLEGRO_BITMAP\ *bitmap,\ int\ *u,\ int\ *v) \f[] .fi .SH DESCRIPTION .PP Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels. .SH SEE ALSO .PP al_get_opengl_texture_size(3) allegro-5.0.10/docs/man/al_get_text_width.30000644000175000001440000000064712157230677017714 0ustar tjadenusers.TH al_get_text_width 3 "" "Allegro reference manual" .SH NAME .PP al_get_text_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_text_width(const\ ALLEGRO_FONT\ *f,\ const\ char\ *str) \f[] .fi .SH DESCRIPTION .PP Calculates the length of a string in a particular font, in pixels. .SH SEE ALSO .PP al_get_ustr_width(3), al_get_font_line_height(3), al_get_text_dimensions(3) allegro-5.0.10/docs/man/al_set_path_extension.30000644000175000001440000000133412157230674020564 0ustar tjadenusers.TH al_set_path_extension 3 "" "Allegro reference manual" .SH NAME .PP al_set_path_extension \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_path_extension(ALLEGRO_PATH\ *path,\ char\ const\ *extension) \f[] .fi .SH DESCRIPTION .PP Replaces the extension of the path with the given one, i.e. replaces everything from the final dot (\[aq].\[aq]) character onwards, including the dot. If the filename of the path has no extension, the given one is appended. Usually the new extension you supply should include a leading dot. .PP Returns false if the path contains no filename part, i.e. the filename part is the empty string. .SH SEE ALSO .PP al_set_path_filename(3), al_get_path_extension(3) allegro-5.0.10/docs/man/al_set_mixer_quality.30000644000175000001440000000076412157230700020424 0ustar tjadenusers.TH al_set_mixer_quality 3 "" "Allegro reference manual" .SH NAME .PP al_set_mixer_quality \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mixer_quality(ALLEGRO_MIXER\ *mixer,\ ALLEGRO_MIXER_QUALITY\ new_quality) \f[] .fi .SH DESCRIPTION .PP Set the mixer quality. This can only succeed if the mixer does not have anything attached to it. .PP Returns true on success, false on failure. .SH SEE ALSO .PP ALLEGRO_MIXER_QUALITY(3), al_get_mixer_quality(3) allegro-5.0.10/docs/man/al_get_pixel_size.30000644000175000001440000000055612157230672017676 0ustar tjadenusers.TH al_get_pixel_size 3 "" "Allegro reference manual" .SH NAME .PP al_get_pixel_size \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_pixel_size(int\ format) \f[] .fi .SH DESCRIPTION .PP Return the number of bytes that a pixel of the given format occupies. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_format_bits(3) allegro-5.0.10/docs/man/ALLEGRO_FS_ENTRY.30000644000175000001440000000060712157230672016643 0ustar tjadenusers.TH ALLEGRO_FS_ENTRY 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FS_ENTRY \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FS_ENTRY\ ALLEGRO_FS_ENTRY; \f[] .fi .SH DESCRIPTION .PP Opaque filesystem entry object. Represents a file or a directory (check with al_get_fs_entry_mode(3)). There are no user accessible member variables. allegro-5.0.10/docs/man/al_replace_path_component.30000644000175000001440000000107412157230674021373 0ustar tjadenusers.TH al_replace_path_component 3 "" "Allegro reference manual" .SH NAME .PP al_replace_path_component \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_replace_path_component(ALLEGRO_PATH\ *path,\ int\ i,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Replace the i\[aq]th directory component by another string. If the index is negative then count from the right, i.e. \-1 refers to the last path component. It is an error to pass an index which is out of bounds. .SH SEE ALSO .PP al_insert_path_component(3), al_remove_path_component(3) allegro-5.0.10/docs/man/al_transform_coordinates.30000644000175000001440000000073712157230675021275 0ustar tjadenusers.TH al_transform_coordinates 3 "" "Allegro reference manual" .SH NAME .PP al_transform_coordinates \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_transform_coordinates(const\ ALLEGRO_TRANSFORM\ *trans,\ float\ *x,\ float\ *y) \f[] .fi .SH DESCRIPTION .PP Transform a pair of coordinates. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to use .IP \[bu] 2 x, y \- Pointers to the coordinates .SH SEE ALSO .PP al_use_transform(3) allegro-5.0.10/docs/man/al_uninstall_audio.30000644000175000001440000000045212157230676020055 0ustar tjadenusers.TH al_uninstall_audio 3 "" "Allegro reference manual" .SH NAME .PP al_uninstall_audio \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_uninstall_audio(void) \f[] .fi .SH DESCRIPTION .PP Uninstalls the audio subsystem. .SH SEE ALSO .PP al_install_audio(3) allegro-5.0.10/docs/man/ALLEGRO_PIXEL_FORMAT.30000644000175000001440000000675112157230672017311 0ustar tjadenusers.TH ALLEGRO_PIXEL_FORMAT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PIXEL_FORMAT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_PIXEL_FORMAT \f[] .fi .SH DESCRIPTION .PP Pixel formats. Each pixel format specifies the exact size and bit layout of a pixel in memory. Components are specified from high bits to low bits, so for example a fully opaque red pixel in ARGB_8888 format is 0xFFFF0000. .RS .PP \f[I]Note:\f[] .PP The pixel format is independent of endianness. That is, in the above example you can always get the red component with .IP .nf \f[C] (pixel\ &\ 0x00ff0000)\ >>\ 16 \f[] .fi .PP But you can \f[I]not\f[] rely on this code: .IP .nf \f[C] *(pixel\ +\ 2) \f[] .fi .PP It will return the red component on little endian systems, but the green component on big endian systems. .RE .PP Also note that Allegro\[aq]s naming is different from OpenGL naming here, where a format of GL_RGBA8 merely defines the component order and the exact layout including endianness treatment is specified separately. Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on little endian systems, so care must be taken (note the reversal of RGBA <\-> ABGR). .PP The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will always have the components as 4 bytes corresponding to red, green, blue and alpha, in this order, independent of the endianness. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY \- Let the driver choose a format. This is the default format at program start. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA \- Let the driver choose a format without alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA \- Let the driver choose a format with alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA \- Let the driver choose a 15 bit format without alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA \- Let the driver choose a 16 bit format without alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA \- Let the driver choose a 16 bit format with alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA \- Let the driver choose a 24 bit format without alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA \- Let the driver choose a 32 bit format without alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA \- Let the driver choose a 32 bit format with alpha. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ARGB_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGBA_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ARGB_4444 \- 16 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGB_888 \- 24 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGB_565 \- 16 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGB_555 \- 15 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGBA_5551 \- 16 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ARGB_1555 \- 16 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ABGR_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_XBGR_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_BGR_888 \- 24 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_BGR_565 \- 16 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_BGR_555 \- 15 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGBX_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_XRGB_8888 \- 32 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ABGR_F32 \- 128 bit .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE \- Like the version without _LE, but the component order is guaranteed to be red, green, blue, alpha. This only makes a difference on big endian systems, on little endian it is just an alias. .IP \[bu] 2 ALLEGRO_PIXEL_FORMAT_RGBA_4444 \- 16bit .SH SEE ALSO .PP al_set_new_bitmap_format(3), al_get_bitmap_format(3) allegro-5.0.10/docs/man/al_draw_tinted_bitmap.30000644000175000001440000000153512157230673020523 0ustar tjadenusers.TH al_draw_tinted_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_bitmap(ALLEGRO_BITMAP\ *bitmap,\ ALLEGRO_COLOR\ tint, \ \ \ float\ dx,\ float\ dy,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_bitmap(3) but multiplies all colors in the bitmap with the given color. For example: .IP .nf \f[C] al_draw_tinted_bitmap(bitmap,\ al_map_rgba_f(0.5,\ 0.5,\ 0.5,\ 0.5),\ x,\ y,\ 0); \f[] .fi .PP The above will draw the bitmap 50% transparently (r/g/b values need to be pre\-multiplied with the alpha component with the default blend mode). .IP .nf \f[C] al_draw_tinted_bitmap(bitmap,\ al_map_rgba_f(1,\ 0,\ 0,\ 1),\ x,\ y,\ 0); \f[] .fi .PP The above will only draw the red component of the bitmap. .SH SEE ALSO .PP al_draw_bitmap(3) allegro-5.0.10/docs/man/al_set_timer_speed.30000644000175000001440000000122412157230675020033 0ustar tjadenusers.TH al_set_timer_speed 3 "" "Allegro reference manual" .SH NAME .PP al_set_timer_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_timer_speed(ALLEGRO_TIMER\ *timer,\ double\ new_speed_secs) \f[] .fi .SH DESCRIPTION .PP Set the timer\[aq]s speed, i.e. the rate at which its counter will be incremented when it is started. This can be done when the timer is started or stopped. If the timer is currently running, it is made to look as though the speed change occurred precisely at the last tick. .PP \f[I]speed_secs\f[] has exactly the same meaning as with al_create_timer(3). .SH SEE ALSO .PP al_get_timer_speed(3) allegro-5.0.10/docs/man/ALLEGRO_KEYBOARD_STATE.30000644000175000001440000000121712157230673017511 0ustar tjadenusers.TH ALLEGRO_KEYBOARD_STATE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_KEYBOARD_STATE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_KEYBOARD_STATE\ ALLEGRO_KEYBOARD_STATE; \f[] .fi .SH DESCRIPTION .PP This is a structure that is used to hold a "snapshot" of a keyboard\[aq]s state at a particular instant. It contains the following publically readable fields: .IP \[bu] 2 display \- points to the display that had keyboard focus at the time the state was saved. If no display was focused, this points to NULL. .PP You cannot read the state of keys directly. Use the function al_key_down(3). allegro-5.0.10/docs/man/al_make_path_canonical.30000644000175000001440000000116212157230674020620 0ustar tjadenusers.TH al_make_path_canonical 3 "" "Allegro reference manual" .SH NAME .PP al_make_path_canonical \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_make_path_canonical(ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Removes any leading \[aq]..\[aq] directory components in absolute paths. Removes all \[aq].\[aq] directory components. .PP Note that this does \f[I]not\f[] collapse "x/../y" sections into "y". This is by design. If "/foo" on your system is a symlink to "/bar/baz", then "/foo/../quux" is actually "/bar/quux", not "/quux" as a naive removal of ".." components would give you. allegro-5.0.10/docs/man/al_append_path_component.30000644000175000001440000000053512157230674021230 0ustar tjadenusers.TH al_append_path_component 3 "" "Allegro reference manual" .SH NAME .PP al_append_path_component \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_append_path_component(ALLEGRO_PATH\ *path,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Append a directory component. .SH SEE ALSO .PP al_insert_path_component(3) allegro-5.0.10/docs/man/al_draw_ustr.30000644000175000001440000000076312157230700016666 0ustar tjadenusers.TH al_draw_ustr 3 "" "Allegro reference manual" .SH NAME .PP al_draw_ustr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_ustr(const\ ALLEGRO_FONT\ *font, \ \ \ ALLEGRO_COLOR\ color,\ float\ x,\ float\ y,\ int\ flags, \ \ \ const\ ALLEGRO_USTR\ *ustr)\ \f[] .fi .SH DESCRIPTION .PP Like al_draw_text(3), except the text is passed as an ALLEGRO_USTR instead of a NUL\-terminated char array. .SH SEE ALSO .PP al_draw_text(3), al_draw_justified_ustr(3) allegro-5.0.10/docs/man/al_calculate_spline.30000644000175000001440000000212712157230700020157 0ustar tjadenusers.TH al_calculate_spline 3 "" "Allegro reference manual" .SH NAME .PP al_calculate_spline \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_calculate_spline(float*\ dest,\ int\ stride,\ float\ points[8], \ \ \ float\ thickness,\ int\ num_segments) \f[] .fi .SH DESCRIPTION .PP Calculates a Bézier spline given 4 control points. If \f[C]thickness\ <=\ 0\f[], then \f[C]num_segments\f[] of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of stride bytes) doublets of floats, corresponding to x and y coordinates of the vertices. .PP \f[I]Parameters:\f[] .IP \[bu] 2 dest \- The destination buffer .IP \[bu] 2 stride \- Distance (in bytes) between starts of successive pairs of coordinates .IP \[bu] 2 points \- An array of 4 pairs of coordinates of the 4 control points .IP \[bu] 2 thickness \- Thickness of the spline ribbon .IP \[bu] 2 num_segments \- The number of points to calculate .SH SEE ALSO .PP al_draw_spline(3), al_calculate_arc(3), al_calculate_ribbon(3) allegro-5.0.10/docs/man/al_current_time.30000644000175000001440000000033712157230674017363 0ustar tjadenusers.TH al_current_time 3 "" "Allegro reference manual" .SH NAME .PP al_current_time \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ \f[] .fi .SH DESCRIPTION .PP Alternate spelling of al_get_time(3). allegro-5.0.10/docs/man/al_fixceil.30000644000175000001440000000114612157230671016302 0ustar tjadenusers.TH al_fixceil 3 "" "Allegro reference manual" .SH NAME .PP al_fixceil \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fixceil(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP Returns the smallest integer not less than x. That is, it rounds towards positive infinity. .PP Example: .IP .nf \f[C] \ \ \ \ int\ result; \ \ \ \ /*\ This\ will\ put\ 34\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixceil(al_itofix(100)\ /\ 3); \ \ \ \ /*\ This\ will\ round\ up\ to\ 17.\ */ \ \ \ \ result\ =\ al_fixceil(al_itofix(100)\ /\ 6); \f[] .fi .SH SEE ALSO .PP al_fixtoi(3), al_fixfloor(3). allegro-5.0.10/docs/man/al_set_app_name.30000644000175000001440000000077712157230674017326 0ustar tjadenusers.TH al_set_app_name 3 "" "Allegro reference manual" .SH NAME .PP al_set_app_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_app_name(const\ char\ *app_name) \f[] .fi .SH DESCRIPTION .PP Sets the global application name. .PP The application name is used by al_get_standard_path(3) to build the full path to an application\[aq]s files. .PP This function may be called before al_init(3) or al_install_system(3). .SH SEE ALSO .PP al_get_app_name(3), al_set_org_name(3) allegro-5.0.10/docs/man/al_shutdown_native_dialog_addon.30000644000175000001440000000060212157230700022551 0ustar tjadenusers.TH al_shutdown_native_dialog_addon 3 "" "Allegro reference manual" .SH NAME .PP al_shutdown_native_dialog_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_shutdown_native_dialog_addon(void) \f[] .fi .SH DESCRIPTION .PP Shut down the native dialog addon. .SH SINCE .PP 5.0.9, 5.1.5 .SH SEE ALSO .PP al_init_native_dialog_addon(3) allegro-5.0.10/docs/man/al_ustr_insert_cstr.30000644000175000001440000000063012157230676020275 0ustar tjadenusers.TH al_ustr_insert_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_insert_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_insert_cstr(ALLEGRO_USTR\ *us,\ int\ pos,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_insert(3) but inserts a C\-style string at byte offset \f[C]pos\f[]. .SH SEE ALSO .PP al_ustr_insert(3), al_ustr_insert_chr(3) allegro-5.0.10/docs/man/al_draw_filled_triangle.30000644000175000001440000000103312157230700021004 0ustar tjadenusers.TH al_draw_filled_triangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_triangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_triangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ float\ x3,\ float\ y3,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a filled triangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2, x3, y3 \- Three points of the triangle .IP \[bu] 2 color \- Color of the triangle .SH SEE ALSO .PP al_draw_triangle(3) allegro-5.0.10/docs/man/al_color_yuv.30000644000175000001440000000055412157230677016710 0ustar tjadenusers.TH al_color_yuv 3 "" "Allegro reference manual" .SH NAME .PP al_color_yuv \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_yuv(float\ y,\ float\ u,\ float\ v) \f[] .fi .SH DESCRIPTION .PP Return an ALLEGRO_COLOR(3) structure from YUV values. .SH SEE ALSO .PP al_color_yuv_to_rgb(3), al_color_rgb_to_yuv(3) allegro-5.0.10/docs/man/al_set_new_bitmap_format.30000644000175000001440000000073212157230673021231 0ustar tjadenusers.TH al_set_new_bitmap_format 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_bitmap_format \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_bitmap_format(int\ format) \f[] .fi .SH DESCRIPTION .PP Sets the pixel format for newly created bitmaps. The default format is 0 and means the display driver will choose the best format. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3), al_get_new_bitmap_format(3), al_get_bitmap_format(3) allegro-5.0.10/docs/man/al_create_sample.30000644000175000001440000000201612157230677017466 0ustar tjadenusers.TH al_create_sample 3 "" "Allegro reference manual" .SH NAME .PP al_create_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_SAMPLE\ *al_create_sample(void\ *buf,\ unsigned\ int\ samples, \ \ \ unsigned\ int\ freq,\ ALLEGRO_AUDIO_DEPTH\ depth, \ \ \ ALLEGRO_CHANNEL_CONF\ chan_conf,\ bool\ free_buf) \f[] .fi .SH DESCRIPTION .PP Create a sample data structure from the supplied buffer. If \f[C]free_buf\f[] is true then the buffer will be freed with al_free(3) when the sample data structure is destroyed. For portability (especially Windows), the buffer should have been allocated with al_malloc(3). Otherwise you should free the sample data yourself. .PP To allocate a buffer of the correct size, you can use something like this: .IP .nf \f[C] sample_size\ =\ al_get_channel_count(chan_conf)\ *\ al_get_audio_depth_size(depth); bytes\ =\ samples\ *\ sample_size; buffer\ =\ al_malloc(bytes); \f[] .fi .SH SEE ALSO .PP al_destroy_sample(3), ALLEGRO_AUDIO_DEPTH(3), ALLEGRO_CHANNEL_CONF(3) allegro-5.0.10/docs/man/ALLEGRO_USTR.30000644000175000001440000000060112157230675016144 0ustar tjadenusers.TH ALLEGRO_USTR 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_USTR \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ _al_tagbstring\ ALLEGRO_USTR; \f[] .fi .SH DESCRIPTION .PP An opaque type representing a string. ALLEGRO_USTRs normally contain UTF\-8 encoded strings, but they may be used to hold any byte sequences, including NULs. allegro-5.0.10/docs/man/al_get_timer_event_source.30000644000175000001440000000047412157230675021426 0ustar tjadenusers.TH al_get_timer_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_timer_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_timer_event_source(ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Retrieve the associated event source. allegro-5.0.10/docs/man/al_set_target_bitmap.30000644000175000001440000000474412157230673020365 0ustar tjadenusers.TH al_set_target_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_set_target_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_target_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using al_get_backbuffer(3). As a convenience, you may also use al_set_target_backbuffer(3). .PP Each video bitmap is tied to a display. When a video bitmap is set to as the target bitmap, the display that the bitmap belongs to is automatically made "current" for the calling thread (if it is not current already). Then drawing other bitmaps which are tied to the same display can be hardware accelerated. .PP A single display cannot be current for multiple threads simultaneously. If you need to release a display, so it is not current for the calling thread, call \f[C]al_set_target_bitmap(NULL);\f[] .PP Setting a memory bitmap as the target bitmap will not change which display is current for the calling thread. .PP OpenGL note: .PP Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is very fast. When using an OpenGL display, if all of the following conditions are met an FBO will be created for use with the bitmap: .IP \[bu] 2 The GL_EXT_framebuffer_object OpenGL extension is available. .IP \[bu] 2 The bitmap is not a memory bitmap. .IP \[bu] 2 The bitmap is not currently locked. .PP In Allegro 5.0.0, you had to be careful as an FBO would be kept around until the bitmap is destroyed or you explicitly called al_remove_opengl_fbo(3) on the bitmap, wasting resources. In newer versions, FBOs will be freed automatically when the bitmap is no longer the target bitmap, \f[I]unless\f[] you have called al_get_opengl_fbo(3) to retrieve the FBO id. .PP In the following example, no FBO will be created: .IP .nf \f[C] lock\ =\ al_lock_bitmap(bitmap); al_set_target_bitmap(bitmap); al_put_pixel(x,\ y,\ color); al_unlock_bitmap(bitmap); \f[] .fi .PP The above allows using al_put_pixel(3) on a locked bitmap without creating an FBO. .PP In this example an FBO is created however: .IP .nf \f[C] al_set_target_bitmap(bitmap); al_draw_line(x1,\ y1,\ x2,\ y2,\ color,\ 0); \f[] .fi .PP An OpenGL command will be used to directly draw the line into the bitmap\[aq]s associated texture. .SH SEE ALSO .PP al_get_target_bitmap(3), al_set_target_backbuffer(3) allegro-5.0.10/docs/man/al_ustr_size_utf16.30000644000175000001440000000073112157230677017740 0ustar tjadenusers.TH al_ustr_size_utf16 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_size_utf16 \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_size_utf16(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Returns the number of bytes required to encode the string in UTF\-16 (including the terminating 0). Usually called before al_ustr_encode_utf16(3) to determine the size of the buffer to allocate. .SH SEE ALSO .PP al_ustr_size(3) allegro-5.0.10/docs/man/al_color_rgb_to_html.30000644000175000001440000000142112157230677020357 0ustar tjadenusers.TH al_color_rgb_to_html 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_html \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_rgb_to_html(float\ red,\ float\ green,\ float\ blue, \ \ \ \ char\ *string) \f[] .fi .SH DESCRIPTION .PP Create an HTML\-style string representation of an ALLEGRO_COLOR(3), e.g. #00faff. .PP Parameters: .IP \[bu] 2 red, green, blue \- The color components in the range 0..1. .IP \[bu] 2 string \- A pointer to a buffer of at least 8 bytes, into which the result will be written (including the NUL terminator). .PP Example: .IP .nf \f[C] char\ html[8]; al_color_rgb_to_html(1,\ 0,\ 0,\ html); \f[] .fi .PP Now html will contain "#ff0000". .SH SEE ALSO .PP al_color_html(3), al_color_html_to_rgb(3) allegro-5.0.10/docs/man/al_ferror.30000644000175000001440000000054712157230671016162 0ustar tjadenusers.TH al_ferror 3 "" "Allegro reference manual" .SH NAME .PP al_ferror \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ferror(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Returns true if the error indicator is set on the given file, i.e. there was some sort of previous error. .SH SEE ALSO .PP al_feof(3), al_fclearerr(3) allegro-5.0.10/docs/man/al_free_with_context.30000644000175000001440000000072212157230673020400 0ustar tjadenusers.TH al_free_with_context 3 "" "Allegro reference manual" .SH NAME .PP al_free_with_context \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_free_with_context(void\ *ptr, \ \ \ int\ line,\ const\ char\ *file,\ const\ char\ *func) \f[] .fi .SH DESCRIPTION .PP This calls free() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface(3). .PP Generally you should use the al_free(3) macro. allegro-5.0.10/docs/man/al_get_opengl_proc_address.30000644000175000001440000000247212157230676021542 0ustar tjadenusers.TH al_get_opengl_proc_address 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_proc_address \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_get_opengl_proc_address(const\ char\ *name) \f[] .fi .SH DESCRIPTION .PP Helper to get the address of an OpenGL symbol .PP Example: .PP How to get the function \f[I]glMultiTexCoord3fARB\f[] that comes with ARB\[aq]s Multitexture extension: .IP .nf \f[C] //\ define\ the\ type\ of\ the\ function \ \ \ ALLEGRO_DEFINE_PROC_TYPE(void,\ MULTI_TEX_FUNC, \ \ \ \ \ \ (GLenum,\ GLfloat,\ GLfloat,\ GLfloat)); //\ declare\ the\ function\ pointer \ \ \ MULTI_TEX_FUNC\ glMultiTexCoord3fARB; //\ get\ the\ address\ of\ the\ function \ \ \ glMultiTexCoord3fARB\ =\ (MULTI_TEX_FUNC)\ al_get_opengl_proc_address( \ \ \ \ \ \ "glMultiTexCoord3fARB"); \f[] .fi .PP If \f[I]glMultiTexCoord3fARB\f[] is not NULL then it can be used as if it has been defined in the OpenGL core library. .RS .PP \f[I]Note:\f[] Under Windows, OpenGL functions may need a special calling convention, so it\[aq]s best to always use the ALLEGRO_DEFINE_PROC_TYPE macro when declaring function pointer types for OpenGL functions. .RE .PP Parameters: .PP name \- The name of the symbol you want to link to. .SH RETURN VALUE .PP A pointer to the symbol if available or NULL otherwise. allegro-5.0.10/docs/man/al_register_assert_handler.30000644000175000001440000000105012157230674021556 0ustar tjadenusers.TH al_register_assert_handler 3 "" "Allegro reference manual" .SH NAME .PP al_register_assert_handler \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_register_assert_handler(void\ (*handler)(char\ const\ *expr, \ \ \ char\ const\ *file,\ int\ line,\ char\ const\ *func)) \f[] .fi .SH DESCRIPTION .PP Register a function to be called when an internal Allegro assertion fails. Pass NULL to reset to the default behaviour, which is to do whatever the standard \f[C]assert()\f[] macro does. .SH SINCE .PP 5.0.6, 5.1.0 allegro-5.0.10/docs/man/al_start_timer.30000644000175000001440000000073412157230675017222 0ustar tjadenusers.TH al_start_timer 3 "" "Allegro reference manual" .SH NAME .PP al_start_timer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_start_timer(ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Start the timer specified. From then, the timer\[aq]s counter will increment at a constant rate, and it will begin generating events. Starting a timer that is already started does nothing. .SH SEE ALSO .PP al_stop_timer(3), al_get_timer_started(3) allegro-5.0.10/docs/man/al_set_mixer_frequency.30000644000175000001440000000071012157230700020724 0ustar tjadenusers.TH al_set_mixer_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_set_mixer_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mixer_frequency(ALLEGRO_MIXER\ *mixer,\ unsigned\ int\ val) \f[] .fi .SH DESCRIPTION .PP Set the mixer frequency. This will only work if the mixer is not attached to anything. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_mixer_frequency(3) allegro-5.0.10/docs/man/al_get_allegro_memfile_version.30000644000175000001440000000055512157230677022417 0ustar tjadenusers.TH al_get_allegro_memfile_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_memfile_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_memfile_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_set_voice_playing.30000644000175000001440000000105312157230677020365 0ustar tjadenusers.TH al_set_voice_playing 3 "" "Allegro reference manual" .SH NAME .PP al_set_voice_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_voice_playing(ALLEGRO_VOICE\ *voice,\ bool\ val) \f[] .fi .SH DESCRIPTION .PP Change whether a voice is playing or not. This can only work if the voice has a non\-streaming object attached to it, e.g. a sample instance. On success the voice\[aq]s current sample position is reset. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_voice_playing(3) allegro-5.0.10/docs/man/al_draw_circle.30000644000175000001440000000116412157230700017126 0ustar tjadenusers.TH al_draw_circle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_circle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_circle(float\ cx,\ float\ cy,\ float\ r,\ ALLEGRO_COLOR\ color, \ \ \ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an outlined circle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the circle .IP \[bu] 2 r \- Radius of the circle .IP \[bu] 2 color \- Color of the circle .IP \[bu] 2 thickness \- Thickness of the circle, pass \f[C]<=\ 0\f[] to draw a hairline circle .SH SEE ALSO .PP al_draw_filled_circle(3), al_draw_ellipse(3) allegro-5.0.10/docs/man/al_get_allegro_font_version.30000644000175000001440000000054112157230700021725 0ustar tjadenusers.TH al_get_allegro_font_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_font_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_font_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_seek_audio_stream_secs.30000644000175000001440000000116212157230701021347 0ustar tjadenusers.TH al_seek_audio_stream_secs 3 "" "Allegro reference manual" .SH NAME .PP al_seek_audio_stream_secs \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM\ *stream,\ double\ time) \f[] .fi .SH DESCRIPTION .PP Set the streaming file playing position to time. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream(3), al_load_audio_stream_f(3) and the format\-specific functions underlying those functions. .SH SEE ALSO .PP al_get_audio_stream_position_secs(3), al_get_audio_stream_length_secs(3) allegro-5.0.10/docs/man/al_lock_bitmap.30000644000175000001440000000343612157230672017150 0ustar tjadenusers.TH al_lock_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_lock_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_LOCKED_REGION\ *al_lock_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ int\ format,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Lock an entire bitmap for reading or writing. If the bitmap is a display bitmap it will be updated from system memory after the bitmap is unlocked (unless locked read only). Returns NULL if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked. .PP Flags are: .IP \[bu] 2 ALLEGRO_LOCK_READONLY \- The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card. .IP \[bu] 2 ALLEGRO_LOCK_WRITEONLY \- The locked region will not be read from. This can be faster if the bitmap is a video texture, as no data need to be read from the video card. You are required to fill in all pixels before unlocking the bitmap again, so be careful when using this flag. .IP \[bu] 2 ALLEGRO_LOCK_READWRITE \- The locked region can be written to and read from. Use this flag if a partial number of pixels need to be written to, even if reading is not needed. .PP \[aq]format\[aq] indicates the pixel format that the returned buffer will be in. To lock in the same format as the bitmap stores it\[aq]s data internally, call with \f[C]al_get_bitmap_format(bitmap)\f[] as the format or use ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster. .RS .PP \f[I]Note:\f[] While a bitmap is locked, you can not use any drawing operations on it (with the sole exception of al_put_pixel(3) and al_put_blended_pixel(3)). .RE .SH SEE ALSO .PP ALLEGRO_LOCKED_REGION(3), ALLEGRO_PIXEL_FORMAT(3), al_unlock_bitmap(3) allegro-5.0.10/docs/man/al_set_keyboard_leds.30000644000175000001440000000062412157230673020343 0ustar tjadenusers.TH al_set_keyboard_leds 3 "" "Allegro reference manual" .SH NAME .PP al_set_keyboard_leds \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_keyboard_leds(int\ leds) \f[] .fi .SH DESCRIPTION .PP Overrides the state of the keyboard LED indicators. Set to \-1 to return to default behavior. False is returned if the current keyboard driver cannot set LED indicators. allegro-5.0.10/docs/man/al_destroy_timer.30000644000175000001440000000076212157230675017557 0ustar tjadenusers.TH al_destroy_timer 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_timer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_timer(ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Uninstall the timer specified. If the timer is started, it will automatically be stopped before uninstallation. It will also automatically unregister the timer with any event queues. .PP Does nothing if passed the NULL pointer. .SH SEE ALSO .PP al_create_timer(3) allegro-5.0.10/docs/man/al_set_blender.30000644000175000001440000000634612157230673017156 0ustar tjadenusers.TH al_set_blender 3 "" "Allegro reference manual" .SH NAME .PP al_set_blender \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_blender(int\ op,\ int\ src,\ int\ dst) \f[] .fi .SH DESCRIPTION .PP Sets the function to use for blending for the current thread. .PP Blending means, the source and destination colors are combined in drawing operations. .PP Assume the source color (e.g. color of a rectangle to draw, or pixel of a bitmap to draw) is given as its red/green/blue/alpha components (if the bitmap has no alpha it always is assumed to be fully opaque, so 255 for 8\-bit or 1.0 for floating point): \f[I]sr, sg, sb, sa\f[]. And this color is drawn to a destination, which already has a color: \f[I]dr, dg, db, da\f[]. .PP The conceptional formula used by Allegro to draw any pixel then depends on the \f[C]op\f[] parameter: .IP \[bu] 2 ALLEGRO_ADD .RS 2 .IP .nf \f[C] \ r\ =\ dr\ *\ dst\ +\ sr\ *\ src \ g\ =\ dg\ *\ dst\ +\ sg\ *\ src \ b\ =\ db\ *\ dst\ +\ sb\ *\ src \ a\ =\ da\ *\ dst\ +\ sa\ *\ src \f[] .fi .RE .IP \[bu] 2 ALLEGRO_DEST_MINUS_SRC .RS 2 .IP .nf \f[C] \ r\ =\ dr\ *\ dst\ \-\ sr\ *\ src \ g\ =\ dg\ *\ dst\ \-\ sg\ *\ src \ b\ =\ db\ *\ dst\ \-\ sb\ *\ src \ a\ =\ da\ *\ dst\ \-\ sa\ *\ src \f[] .fi .RE .IP \[bu] 2 ALLEGRO_SRC_MINUS_DEST .RS 2 .IP .nf \f[C] \ r\ =\ sr\ *\ src\ \-\ dr\ *\ dst \ g\ =\ sg\ *\ src\ \-\ dg\ *\ dst \ b\ =\ sb\ *\ src\ \-\ db\ *\ dst \ a\ =\ sa\ *\ src\ \-\ da\ *\ dst \f[] .fi .RE .PP Valid values for \f[C]src\f[] and \f[C]dst\f[] passed to this function are .IP \[bu] 2 ALLEGRO_ZERO .RS 2 .IP .nf \f[C] \ src\ =\ 0 \ dst\ =\ 0 \f[] .fi .RE .IP \[bu] 2 ALLEGRO_ONE .RS 2 .IP .nf \f[C] \ src\ =\ 1 \ dst\ =\ 1 \f[] .fi .RE .IP \[bu] 2 ALLEGRO_ALPHA .RS 2 .IP .nf \f[C] \ src\ =\ sa \ dst\ =\ sa \f[] .fi .RE .IP \[bu] 2 ALLEGRO_INVERSE_ALPHA .RS 2 .IP .nf \f[C] \ src\ =\ 1\ \-\ sa \ dst\ =\ 1\ \-\ sa \f[] .fi .RE .IP \[bu] 2 ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0) .RS 2 .IP .nf \f[C] \ f\ =\ s.r,\ s.g,\ s.b,\ s.a \f[] .fi .RE .IP \[bu] 2 ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8) .RS 2 .IP .nf \f[C] \ f\ =\ d.r,\ d.g,\ d.b,\ d.a \f[] .fi .RE .IP \[bu] 2 ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0) .RS 2 .IP .nf \f[C] \ f\ =\ 1\ \-\ s.r,\ 1\ \-\ s.g,\ 1\ \-\ s.b,\ 1\ \-\ s.a \f[] .fi .RE .IP \[bu] 2 ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8) .RS 2 .IP .nf \f[C] \ f\ =\ 1\ \-\ d.r,\ 1\ \-\ d.g,\ 1\ \-\ d.b,\ 1\ \-\ d.a \f[] .fi .RE .PP Blending examples: .PP So for example, to restore the default of using premultiplied alpha blending, you would use (pseudo code) .IP .nf \f[C] al_set_blender(ALLEGRO_ADD,\ ALLEGRO_ONE,\ ALLEGRO_INVERSE_ALPHA) \f[] .fi .PP If you are using non\-pre\-multiplied alpha, you could use .IP .nf \f[C] al_set_blender(ALLEGRO_ADD,\ ALLEGRO_ALPHA,\ ALLEGRO_INVERSE_ALPHA) \f[] .fi .PP Additive blending would be achieved with .IP .nf \f[C] al_set_blender(ALLEGRO_ADD,\ ALLEGRO_ONE,\ ALLEGRO_ONE) \f[] .fi .PP Copying the source to the destination (including alpha) unmodified .IP .nf \f[C] al_set_blender(ALLEGRO_ADD,\ ALLEGRO_ONE,\ ALLEGRO_ZERO) \f[] .fi .PP Multiplying source and destination components .IP .nf \f[C] al_set_blender(ALLEGRO_ADD,\ ALLEGRO_DEST_COLOR,\ ALLEGRO_ZERO) \f[] .fi .SH SEE ALSO .PP al_set_separate_blender(3), al_get_blender(3) allegro-5.0.10/docs/man/al_put_pixel.30000644000175000001440000000113012157230673016663 0ustar tjadenusers.TH al_put_pixel 3 "" "Allegro reference manual" .SH NAME .PP al_put_pixel \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_put_pixel(int\ x,\ int\ y,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draw a single pixel on the target bitmap. This operation is slow on non\-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. This function is not affected by the transformations or the color blenders. .SH SEE ALSO .PP ALLEGRO_COLOR(3), al_get_pixel(3), al_put_blended_pixel(3), al_lock_bitmap(3) allegro-5.0.10/docs/man/al_show_native_message_box.30000644000175000001440000000456412157230700021561 0ustar tjadenusers.TH al_show_native_message_box 3 "" "Allegro reference manual" .SH NAME .PP al_show_native_message_box \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_show_native_message_box(ALLEGRO_DISPLAY\ *display, \ \ \ char\ const\ *title,\ char\ const\ *heading,\ char\ const\ *text, \ \ \ char\ const\ *buttons,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Show a native GUI message box. This can be used for example to display an error message if creation of an initial display fails. The display may be NULL, otherwise the given display is treated as the parent if possible. .PP The message box will have a single "OK" button and use the style informative dialog boxes usually have on the native system. If the \f[C]buttons\f[] parameter is not NULL, you can instead specify the button text in a string, with buttons separated by a vertical bar (|). .TP .B ALLEGRO_MESSAGEBOX_WARN The message is a warning. This may cause a different icon (or other effects). .RS .RE .TP .B ALLEGRO_MESSAGEBOX_ERROR The message is an error. .RS .RE .TP .B ALLEGRO_MESSAGEBOX_QUESTION The message is a question. .RS .RE .TP .B ALLEGRO_MESSAGEBOX_OK_CANCEL Instead of the "OK" button also display a cancel button. Ignored if \f[C]buttons\f[] is not NULL. .RS .RE .TP .B ALLEGRO_MESSAGEBOX_YES_NO Instead of the "OK" button display Yes/No buttons. Ignored if \f[C]buttons\f[] is not NULL. .RS .RE .PP al_show_native_message_box(3) may be called without Allegro being installed. This is useful to report an error to initialise Allegro itself. .PP Returns: .IP \[bu] 2 0 if the dialog window was closed without activating a button. .IP \[bu] 2 1 if the OK or Yes button was pressed. .IP \[bu] 2 2 if the Cancel or No button was pressed. .PP If \f[C]buttons\f[] is not NULL, the number of the pressed button is returned, starting with 1. .PP If a message box could not be created then this returns 0, as if the window was dismissed without activating a button. .PP Example: .IP .nf \f[C] \ \ button\ =\ al_show_native_message_box( \ \ \ \ \ display, \ \ \ \ \ "Warning", \ \ \ \ \ "Are\ you\ sure?", \ \ \ \ \ "If\ you\ click\ yes\ then\ you\ are\ confirming\ that\ \\"Yes\\"" \ \ \ \ \ "is\ your\ response\ to\ the\ query\ which\ you\ have" \ \ \ \ \ "generated\ by\ the\ action\ you\ took\ to\ open\ this" \ \ \ \ \ "message\ box.", \ \ \ \ \ NULL, \ \ \ \ \ ALLEGRO_MESSAGEBOX_YES_NO \ \ ); \f[] .fi allegro-5.0.10/docs/man/al_draw_arc.30000644000175000001440000000145012157230700016430 0ustar tjadenusers.TH al_draw_arc 3 "" "Allegro reference manual" .SH NAME .PP al_draw_arc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_arc(float\ cx,\ float\ cy,\ float\ r,\ float\ start_theta, \ \ \ float\ delta_theta,\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an arc. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the arc .IP \[bu] 2 r \- Radius of the arc .IP \[bu] 2 color \- Color of the arc .IP \[bu] 2 start_theta \- The initial angle from which the arc is calculated .IP \[bu] 2 delta_theta \- Angular span of the arc (pass a negative number to switch direction) .IP \[bu] 2 thickness \- Thickness of the arc, pass \f[C]<=\ 0\f[] to draw hairline arc .SH SEE ALSO .PP al_calculate_arc(3), al_draw_elliptical_arc(3) allegro-5.0.10/docs/man/al_draw_triangle.30000644000175000001440000000123112157230700017465 0ustar tjadenusers.TH al_draw_triangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_triangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_triangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ float\ x3,\ float\ y3,\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an outlined triangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2, x3, y3 \- Three points of the triangle .IP \[bu] 2 color \- Color of the triangle .IP \[bu] 2 thickness \- Thickness of the lines, pass \f[C]<=\ 0\f[] to draw hairline lines .SH SEE ALSO .PP al_draw_filled_triangle(3), al_draw_soft_triangle(3) allegro-5.0.10/docs/man/al_draw_justified_textf.30000644000175000001440000000113012157230700021056 0ustar tjadenusers.TH al_draw_justified_textf 3 "" "Allegro reference manual" .SH NAME .PP al_draw_justified_textf \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_justified_textf(const\ ALLEGRO_FONT\ *f, \ \ \ ALLEGRO_COLOR\ color,\ float\ x1,\ float\ x2,\ float\ y, \ \ \ float\ diff,\ int\ flags,\ const\ char\ *format,\ ...) \f[] .fi .SH DESCRIPTION .PP Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_justified_text(3) otherwise. .SH SEE ALSO .PP al_draw_justified_text(3), al_draw_justified_ustr(3). allegro-5.0.10/docs/man/al_open_native_text_log.30000644000175000001440000000201612157230700021061 0ustar tjadenusers.TH al_open_native_text_log 3 "" "Allegro reference manual" .SH NAME .PP al_open_native_text_log \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_TEXTLOG\ *al_open_native_text_log(char\ const\ *title,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Opens a window to which you can append log messages with al_append_native_text_log(3). This can be useful for debugging if you don\[aq]t want to depend on a console being available. .PP Use al_close_native_text_log(3) to close the window again. .PP The flags available are: .TP .B ALLEGRO_TEXTLOG_NO_CLOSE Prevent the window from having a close button. Otherwise if the close button is pressed an event is generated; see al_get_native_text_log_event_source(3). .RS .RE .TP .B ALLEGRO_TEXTLOG_MONOSPACE Use a monospace font to display the text. .RS .RE .PP Returns NULL if there was an error opening the window, or if text log windows are not implemented on the platform. .SH SEE ALSO .PP al_append_native_text_log(3), al_close_native_text_log(3) allegro-5.0.10/docs/man/al_fixmul.30000644000175000001440000000236512157230671016167 0ustar tjadenusers.TH al_fixmul 3 "" "Allegro reference manual" .SH NAME .PP al_fixmul \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixmul(al_fixed\ x,\ al_fixed\ y); \f[] .fi .SH DESCRIPTION .PP A fixed point value can be multiplied or divided by an integer with the normal \f[C]*\f[] and \f[C]/\f[] operators. To multiply two fixed point values, though, you must use this function. .PP If an overflow occurs, Allegro\[aq]s errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for overflow you should call \f[C]al_set_errno(0)\f[] before calling al_fixmul(3). .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ This\ will\ put\ 30000\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixmul(al_itofix(10),\ al_itofix(3000)); \ \ \ \ /*\ But\ this\ overflows,\ and\ sets\ errno.\ */ \ \ \ \ result\ =\ al_fixmul(al_itofix(100),\ al_itofix(3000)); \ \ \ \ assert(!al_get_errno()); \f[] .fi .SH RETURN VALUE .PP Returns the clamped result of multiplying \f[C]x\f[] by \f[C]y\f[], setting Allegro\[aq]s errno to ERANGE if there was an overflow. .SH SEE ALSO .PP al_fixadd(3), al_fixsub(3), al_fixdiv(3), al_get_errno(3). allegro-5.0.10/docs/man/ALLEGRO_EVENT_KEY_UP.30000644000175000001440000002700512157230670017346 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_ustr_appendf.30000644000175000001440000000101312157230676017347 0ustar tjadenusers.TH al_ustr_appendf 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_appendf \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_appendf(ALLEGRO_USTR\ *us,\ const\ char\ *fmt,\ ...) \f[] .fi .SH DESCRIPTION .PP This function appends formatted output to the string \f[C]us\f[]. \f[C]fmt\f[] is a printf\-style format string. See al_ustr_newf(3) about the "%s" and "%c" specifiers. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_vappendf(3), al_ustr_append(3) allegro-5.0.10/docs/man/al_update_fs_entry.30000644000175000001440000000120312157230672020045 0ustar tjadenusers.TH al_update_fs_entry 3 "" "Allegro reference manual" .SH NAME .PP al_update_fs_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_update_fs_entry(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Updates file status information for a filesystem entry. File status information is automatically updated when the entry is created, however you may update it again with this function, e.g. in case it changed. .PP Returns true on success, false on failure. Fills in errno to indicate the error. .SH SEE ALSO .PP al_get_errno(3), al_get_fs_entry_atime(3), al_get_fs_entry_ctime(3), al_get_fs_entry_mode(3) allegro-5.0.10/docs/man/al_get_mixer_depth.30000644000175000001440000000052312157230700020015 0ustar tjadenusers.TH al_get_mixer_depth 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_depth \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_DEPTH\ al_get_mixer_depth(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return the mixer audio depth. .SH SEE ALSO .PP ALLEGRO_AUDIO_DEPTH(3). allegro-5.0.10/docs/man/al_get_sample_instance_channels.30000644000175000001440000000061712157230677022546 0ustar tjadenusers.TH al_get_sample_instance_channels 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_channels \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CHANNEL_CONF\ al_get_sample_instance_channels( \ \ \ const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the channel configuration. .SH SEE ALSO .PP ALLEGRO_CHANNEL_CONF(3). allegro-5.0.10/docs/man/al_get_opengl_extension_list.30000644000175000001440000000233612157230676022140 0ustar tjadenusers.TH al_get_opengl_extension_list 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_extension_list \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_OGL_EXT_LIST\ *al_get_opengl_extension_list(void) \f[] .fi .SH DESCRIPTION .PP Returns the list of OpenGL extensions supported by Allegro, for the given display. .PP Allegro will keep information about all extensions it knows about in a structure returned by \f[C]al_get_opengl_extension_list\f[]. .PP For example: .IP .nf \f[C] if\ (al_get_opengl_extension_list()\->ALLEGRO_GL_ARB_multitexture)\ { \ \ \ \ use\ it } \f[] .fi .PP The extension will be set to true if available for the given display and false otherwise. This means to use the definitions and functions from an OpenGL extension, all you need to do is to check for it as above at run time, after acquiring the OpenGL display from Allegro. .PP Under Windows, this will also work with WGL extensions, and under Unix with GLX extensions. .PP In case you want to manually check for extensions and load function pointers yourself (say, in case the Allegro developers did not include it yet), you can use the al_have_opengl_extension(3) and al_get_opengl_proc_address(3) functions instead. allegro-5.0.10/docs/man/al_destroy_mutex.30000644000175000001440000000063512157230675017600 0ustar tjadenusers.TH al_destroy_mutex 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_mutex \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_mutex(ALLEGRO_MUTEX\ *mutex) \f[] .fi .SH DESCRIPTION .PP Free the resources used by the mutex. The mutex should be unlocked. Destroying a locked mutex results in undefined behaviour. .PP Does nothing if \f[C]mutex\f[] is \f[C]NULL\f[]. allegro-5.0.10/docs/man/al_set_standard_fs_interface.30000644000175000001440000000056712157230672022051 0ustar tjadenusers.TH al_set_standard_fs_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_standard_fs_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_standard_fs_interface(void) \f[] .fi .SH DESCRIPTION .PP Return the ALLEGRO_FS_INTERFACE(3) table to the default, for the calling thread. .SH SEE ALSO .PP al_set_fs_interface(3). allegro-5.0.10/docs/man/al_draw_justified_ustr.30000644000175000001440000000110012157230700020716 0ustar tjadenusers.TH al_draw_justified_ustr 3 "" "Allegro reference manual" .SH NAME .PP al_draw_justified_ustr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_justified_ustr(const\ ALLEGRO_FONT\ *font, \ \ \ ALLEGRO_COLOR\ color,\ float\ x1,\ float\ x2, \ \ \ float\ y,\ float\ diff,\ int\ flags,\ const\ ALLEGRO_USTR\ *ustr) \f[] .fi .SH DESCRIPTION .PP Like al_draw_justified_text(3), except the text is passed as an ALLEGRO_USTR instead of a NUL\-terminated char array. .SH SEE ALSO .PP al_draw_justified_text(3), al_draw_justified_textf(3). allegro-5.0.10/docs/man/al_get_opengl_texture_size.30000644000175000001440000000107612157230676021623 0ustar tjadenusers.TH al_get_opengl_texture_size 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_texture_size \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_opengl_texture_size(ALLEGRO_BITMAP\ *bitmap,\ int\ *w,\ int\ *h) \f[] .fi .SH DESCRIPTION .PP Retrieves the size of the texture used for the bitmap. This can be different from the bitmap size if OpenGL only supports power\-of\-two sizes or if it is a sub\-bitmap. 0\[aq]s are returned if the bitmap is not an OpenGL bitmap. .SH SEE ALSO .PP al_get_opengl_texture_position(3) allegro-5.0.10/docs/man/al_get_path_extension.30000644000175000001440000000117212157230674020550 0ustar tjadenusers.TH al_get_path_extension 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_extension \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_extension(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Return a pointer to the start of the extension of the filename, i.e. everything from the final dot (\[aq].\[aq]) character onwards. If no dot exists, returns an empty string. .PP The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. .SH SEE ALSO .PP al_get_path_filename(3), al_get_path_basename(3) allegro-5.0.10/docs/man/al_remove_path_component.30000644000175000001440000000105312157230674021252 0ustar tjadenusers.TH al_remove_path_component 3 "" "Allegro reference manual" .SH NAME .PP al_remove_path_component \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_remove_path_component(ALLEGRO_PATH\ *path,\ int\ i) \f[] .fi .SH DESCRIPTION .PP Delete the i\[aq]th directory component. If the index is negative then count from the right, i.e. \-1 refers to the last path component. It is an error to pass an index which is out of bounds. .SH SEE ALSO .PP al_insert_path_component(3), al_replace_path_component(3), al_drop_path_tail(3) allegro-5.0.10/docs/man/al_ustr_append_chr.30000644000175000001440000000060312157230676020041 0ustar tjadenusers.TH al_ustr_append_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_append_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_append_chr(ALLEGRO_USTR\ *us,\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Append a code point to the end of \f[C]us\f[]. .PP Returns the number of bytes added, or 0 on error. .SH SEE ALSO .PP al_ustr_append(3) allegro-5.0.10/docs/man/al_get_next_config_entry.30000644000175000001440000000066112157230670021242 0ustar tjadenusers.TH al_get_next_config_entry 3 "" "Allegro reference manual" .SH NAME .PP al_get_next_config_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ const\ *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY\ **iterator) \f[] .fi .SH DESCRIPTION .PP Returns the next key for the iterator obtained by al_get_first_config_entry(3). The \f[C]iterator\f[] works like the one for al_get_next_config_section(3). allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_AXES.30000644000175000001440000002700512157230670020022 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_ustr_truncate.30000644000175000001440000000106512157230676017566 0ustar tjadenusers.TH al_ustr_truncate 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_truncate \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_truncate(ALLEGRO_USTR\ *us,\ int\ start_pos) \f[] .fi .SH DESCRIPTION .PP Truncate a portion of a string at byte offset \f[C]start_pos\f[] onwards. \f[C]start_pos\f[] can be past the end of the string (has no effect) but cannot be less than 0. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_remove_range(3), al_ustr_ltrim_ws(3), al_ustr_rtrim_ws(3), al_ustr_trim_ws(3) allegro-5.0.10/docs/man/al_ustr_append.30000644000175000001440000000114712157230676017211 0ustar tjadenusers.TH al_ustr_append 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_append \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_append(ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Append \f[C]us2\f[] to the end of \f[C]us1\f[]. .PP Returns true on success, false on error. .PP This function can be used to append an arbitrary buffer: .IP .nf \f[C] ALLEGRO_USTR_INFO\ info; al_ustr_append(us,\ al_ref_buffer(&info,\ buf,\ size)); \f[] .fi .SH SEE ALSO .PP al_ustr_append_cstr(3), al_ustr_append_chr(3), al_ustr_appendf(3), al_ustr_vappendf(3) allegro-5.0.10/docs/man/al_create_bitmap.30000644000175000001440000000327412157230672017463 0ustar tjadenusers.TH al_create_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_create_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_create_bitmap(int\ w,\ int\ h) \f[] .fi .SH DESCRIPTION .PP Creates a new bitmap using the bitmap format and flags for the current thread. Blitting between bitmaps of differing formats, or blitting between memory bitmaps and display bitmaps may be slow. .PP Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created for the current display. Blitting to another display may be slow. .PP If a display bitmap is created, there may be limitations on the allowed dimensions. For example a DirectX or OpenGL backend usually has a maximum allowed texture size \- so if bitmap creation fails for very large dimensions, you may want to re\-try with a smaller bitmap. Some platforms also dictate a minimum texture size, which is relevant if you plan to use this bitmap with the primitives addon. If you try to create a bitmap smaller than this, this call will not fail but the returned bitmap will be a section of a larger bitmap with the minimum size. The minimum size that will work on all platforms is 32 by 32. .PP Some platforms do not directly support display bitmaps whose dimensions are not powers of two. Allegro handles this by creating a larger bitmap that has dimensions that are powers of two and then returning a section of that bitmap with the dimensions you requested. This can be relevant if you plan to use this bitmap with the primitives addon but shouldn\[aq]t be an issue otherwise. .SH SEE ALSO .PP al_set_new_bitmap_format(3), al_set_new_bitmap_flags(3), al_clone_bitmap(3), al_create_sub_bitmap(3), al_destroy_bitmap(3) allegro-5.0.10/docs/man/al_fget_ustr.30000644000175000001440000000125512157230671016662 0ustar tjadenusers.TH al_fget_ustr 3 "" "Allegro reference manual" .SH NAME .PP al_fget_ustr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_fget_ustr(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Read a string of bytes terminated with a newline or end\-of\-file. The line terminator(s), if any, are included in the returned string. .PP On success returns a pointer to a new ALLEGRO_USTR structure. This must be freed eventually with al_ustr_free(3). Returns NULL if an error occurred or if the end of file was reached without reading any bytes. .PP See al_fopen(3) about translations of end\-of\-line characters. .SH SEE ALSO .PP al_fgetc(3), al_fgets(3) allegro-5.0.10/docs/man/al_ustr_new_from_buffer.30000644000175000001440000000072412157230675021106 0ustar tjadenusers.TH al_ustr_new_from_buffer 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_new_from_buffer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_new_from_buffer(const\ char\ *s,\ size_t\ size) \f[] .fi .SH DESCRIPTION .PP Create a new string containing a copy of the buffer pointed to by \f[C]s\f[] of the given size in bytes. The string must eventually be freed with al_ustr_free(3). .SH SEE ALSO .PP al_ustr_new(3) allegro-5.0.10/docs/man/al_fixsin.30000644000175000001440000000134612157230671016161 0ustar tjadenusers.TH al_fixsin 3 "" "Allegro reference manual" .SH NAME .PP al_fixsin \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixsin(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP This function finds the sine of a value using a lookup table. The input value must be a fixed point binary angle. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ angle; \ \ \ \ int\ result; \ \ \ \ /*\ Set\ the\ binary\ angle\ to\ 90\ degrees.\ */ \ \ \ \ angle\ =\ al_itofix(64); \ \ \ \ /*\ The\ sine\ of\ 90\ degrees\ is\ one.\ */ \ \ \ \ result\ =\ al_fixtoi(al_fixsin(angle)); \ \ \ \ assert(result\ ==\ 1); \f[] .fi .SH RETURN VALUE .PP Returns the sine of a fixed point binary format angle. The return value will be in radians. allegro-5.0.10/docs/man/al_draw_elliptical_arc.30000644000175000001440000000156512157230700020641 0ustar tjadenusers.TH al_draw_elliptical_arc 3 "" "Allegro reference manual" .SH NAME .PP al_draw_elliptical_arc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_elliptical_arc(float\ cx,\ float\ cy,\ float\ rx,\ float\ ry,\ float\ start_theta, \ \ \ float\ delta_theta,\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an elliptical arc. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the arc .IP \[bu] 2 rx, ry \- Radii of the arc .IP \[bu] 2 color \- Color of the arc .IP \[bu] 2 start_theta \- The initial angle from which the arc is calculated .IP \[bu] 2 delta_theta \- Angular span of the arc (pass a negative number to switch direction) .IP \[bu] 2 thickness \- Thickness of the arc, pass \f[C]<=\ 0\f[] to draw hairline arc .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_calculate_arc(3), al_draw_arc(3) allegro-5.0.10/docs/man/al_path_cstr.30000644000175000001440000000115112157230674016645 0ustar tjadenusers.TH al_path_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_path_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_path_cstr(const\ ALLEGRO_PATH\ *path,\ char\ delim) \f[] .fi .SH DESCRIPTION .PP Convert a path to its string representation, i.e. optional drive, followed by directory components separated by \[aq]delim\[aq], followed by an optional filename. .PP To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP for \[aq]delim\[aq]. .PP The returned pointer is valid only until the path is modified in any way, or until the path is destroyed. allegro-5.0.10/docs/man/al_get_native_text_log_event_source.30000644000175000001440000000140012157230700023454 0ustar tjadenusers.TH al_get_native_text_log_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_native_text_log_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_native_text_log_event_source( \ \ \ ALLEGRO_TEXTLOG\ *textlog) \f[] .fi .SH DESCRIPTION .PP Get an event source for a text log window. The possible events are: .TP .B ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE The window was requested to be closed, either by pressing the close button or pressing Escape on the keyboard. The user.data1 field will hold a pointer to the ALLEGRO_TEXTLOG(3) which generated the event. The user.data2 field will be 1 if the event was generated as a result of a key press; otherwise it will be zero. .RS .RE allegro-5.0.10/docs/man/al_make_temp_file.30000644000175000001440000000150712157230672017622 0ustar tjadenusers.TH al_make_temp_file 3 "" "Allegro reference manual" .SH NAME .PP al_make_temp_file \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_make_temp_file(const\ char\ *template,\ ALLEGRO_PATH\ **ret_path) \f[] .fi .SH DESCRIPTION .PP Make a temporary randomly named file given a filename \[aq]template\[aq]. .PP \[aq]template\[aq] is a string giving the format of the generated filename and should include one or more capital Xs. The Xs are replaced with random alphanumeric characters, produced using a simple pseudo\-random number generator only. There should be no path separators. .PP If \[aq]ret_path\[aq] is not NULL, the address it points to will be set to point to a new path structure with the name of the temporary file. .PP Returns the opened ALLEGRO_FILE(3) on success, NULL on failure. allegro-5.0.10/docs/man/ALLEGRO_PRIM_TYPE.30000644000175000001440000000203612157230701016751 0ustar tjadenusers.TH ALLEGRO_PRIM_TYPE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PRIM_TYPE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_PRIM_TYPE \f[] .fi .SH DESCRIPTION .PP Enumerates the types of primitives this addon can draw. .IP \[bu] 2 ALLEGRO_PRIM_POINT_LIST \- A list of points, each vertex defines a point .IP \[bu] 2 ALLEGRO_PRIM_LINE_LIST \- A list of lines, sequential pairs of vertices define disjointed lines .IP \[bu] 2 ALLEGRO_PRIM_LINE_STRIP \- A strip of lines, sequential vertices define a strip of lines .IP \[bu] 2 ALLEGRO_PRIM_LINE_LOOP \- Like a line strip, except at the end the first and the last vertices are also connected by a line .IP \[bu] 2 ALLEGRO_PRIM_TRIANGLE_LIST \- A list of triangles, sequential triplets of vertices define disjointed triangles .IP \[bu] 2 ALLEGRO_PRIM_TRIANGLE_STRIP \- A strip of triangles, sequential vertices define a strip of triangles .IP \[bu] 2 ALLEGRO_PRIM_TRIANGLE_FAN \- A fan of triangles, all triangles share the first vertex allegro-5.0.10/docs/man/ALLEGRO_PRIM_STORAGE.30000644000175000001440000000102312157230701017267 0ustar tjadenusers.TH ALLEGRO_PRIM_STORAGE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PRIM_STORAGE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_PRIM_STORAGE \f[] .fi .SH DESCRIPTION .PP Enumerates the types of storage an attribute of a custom vertex may be stored in. .IP \[bu] 2 ALLEGRO_PRIM_FLOAT_2 \- A doublet of floats .IP \[bu] 2 ALLEGRO_PRIM_FLOAT_3 \- A triplet of floats .IP \[bu] 2 ALLEGRO_PRIM_SHORT_2 \- A doublet of shorts .SH SEE ALSO .PP ALLEGRO_PRIM_ATTR(3) allegro-5.0.10/docs/man/al_load_bitmap_f.30000644000175000001440000000143212157230674017440 0ustar tjadenusers.TH al_load_bitmap_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_bitmap_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_load_bitmap_f(ALLEGRO_FILE\ *fp,\ const\ char\ *ident) \f[] .fi .SH DESCRIPTION .PP Loads an image from an ALLEGRO_FILE(3) stream into an ALLEGRO_BITMAP(3). The file type is determined by the passed \[aq]ident\[aq] parameter, which is a file name extension including the leading dot. .PP Returns NULL on error. The file remains open afterwards. .RS .PP \f[I]Note:\f[] the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. .RE .SH SEE ALSO .PP al_load_bitmap(3), al_register_bitmap_loader_f(3), al_init_image_addon(3) allegro-5.0.10/docs/man/al_get_native_file_dialog_count.30000644000175000001440000000057212157230700022525 0ustar tjadenusers.TH al_get_native_file_dialog_count 3 "" "Allegro reference manual" .SH NAME .PP al_get_native_file_dialog_count \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_native_file_dialog_count(const\ ALLEGRO_FILECHOOSER\ *dialog) \f[] .fi .SH DESCRIPTION .PP Returns the number of files selected, or 0 if the dialog was cancelled. allegro-5.0.10/docs/man/ALLEGRO_USECS_TO_SECS.30000644000175000001440000000045012157230674017451 0ustar tjadenusers.TH ALLEGRO_USECS_TO_SECS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_USECS_TO_SECS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_USECS_TO_SECS(x)\ \ \ \ \ \ ((x)\ /\ 1000000.0) \f[] .fi .SH DESCRIPTION .PP Convert microseconds to seconds. allegro-5.0.10/docs/man/al_grab_font_from_bitmap.30000644000175000001440000000475012157230700021174 0ustar tjadenusers.TH al_grab_font_from_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_grab_font_from_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_grab_font_from_bitmap(ALLEGRO_BITMAP\ *bmp, \ \ \ int\ ranges_n,\ const\ int\ ranges[]) \f[] .fi .SH DESCRIPTION .PP Creates a new font from an Allegro bitmap. You can delete the bitmap after the function returns as the font will contain a copy for itself. .PP Parameters: .IP \[bu] 2 bmp: The bitmap with the glyphs drawn onto it .IP \[bu] 2 n: Number of unicode ranges in the bitmap. .IP \[bu] 2 ranges: \[aq]n\[aq] pairs of first and last unicode point to map glyphs to for each range. .PP The bitmap format is as in the following example, which contains three glyphs for 1, 2 and 3. .IP .nf \f[C] \&............. \&.\ 1\ .222.333. \&.\ 1\ .\ \ 2.\ \ 3. \&.\ 1\ .222.333. \&.\ 1\ .2\ \ .\ \ 3. \&.\ 1\ .222.333. \&............. \f[] .fi .PP In the above illustration, the dot is for pixels having the background color. It is determined by the color of the top left pixel in the bitmap. There should be a border of at least 1 pixel with this color to the bitmap edge and between all glyphs. .PP Each glyph is inside a rectangle of pixels not containing the background color. The height of all glyph rectangles should be the same, but the width can vary. .PP The placement of the rectangles does not matter, except that glyphs are scanned from left to right and top to bottom to match them to the specified unicode codepoints. .PP The glyphs will simply be drawn using al_draw_bitmap(3), so usually you will want the rectangles filled with full transparency and the glyphs drawn in opaque white. .PP Examples: .IP .nf \f[C] int\ ranges[]\ =\ {32,\ 126}; al_grab_font_from_bitmap(bitmap,\ 1,\ ranges) int\ ranges[]\ =\ { \ \ \ \ 0x0020,\ 0x007F,\ \ /*\ ASCII\ */ \ \ \ \ 0x00A1,\ 0x00FF,\ \ /*\ Latin\ 1\ */ \ \ \ \ 0x0100,\ 0x017F,\ \ /*\ Extended\-A\ */ \ \ \ \ 0x20AC,\ 0x20AC};\ /*\ Euro\ */ al_grab_font_from_bitmap(bitmap,\ 4,\ ranges) \f[] .fi .PP The first example will grab glyphs for the 95 standard printable ASCII characters, beginning with the space character (32) and ending with the tilde character (126). The second example will map the first 96 glyphs found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to Extended\-A, and the last glyph to the Euro character. (This is just the characters found in the Allegro 4 font.) .SH SEE ALSO .PP al_load_bitmap(3), al_grab_font_from_bitmap(3) allegro-5.0.10/docs/man/al_get_window_position.30000644000175000001440000000055712157230670020755 0ustar tjadenusers.TH al_get_window_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_window_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_window_position(ALLEGRO_DISPLAY\ *display,\ int\ *x,\ int\ *y) \f[] .fi .SH DESCRIPTION .PP Gets the position of a non\-fullscreen display. .SH SEE ALSO .PP al_set_window_position(3) allegro-5.0.10/docs/man/al_set_display_icon.30000644000175000001440000000066612157230670020214 0ustar tjadenusers.TH al_set_display_icon 3 "" "Allegro reference manual" .SH NAME .PP al_set_display_icon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_display_icon(ALLEGRO_DISPLAY\ *display,\ ALLEGRO_BITMAP\ *icon) \f[] .fi .SH DESCRIPTION .PP Changes the icon associated with the display (window). Same as al_set_display_icons(3) with one icon. .SH SEE ALSO .PP al_set_display_icons(3), al_set_window_title(3) allegro-5.0.10/docs/man/al_set_display_flag.30000644000175000001440000000140612157230670020166 0ustar tjadenusers.TH al_set_display_flag 3 "" "Allegro reference manual" .SH NAME .PP al_set_display_flag \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_display_flag(ALLEGRO_DISPLAY\ *display,\ int\ flag,\ bool\ onoff) \f[] .fi .SH DESCRIPTION .PP Enable or disable one of the display flags. The flags are the same as for al_set_new_display_flags(3). The only flags that can be changed after creation are: .IP \[bu] 2 ALLEGRO_FULLSCREEN_WINDOW .IP \[bu] 2 ALLEGRO_FRAMELESS .PP Returns true if the driver supports toggling the specified flag else false. You can use al_get_display_flags(3) to query whether the given display property actually changed. .SH SINCE .PP 5.0.7, 5.1.2 .SH SEE ALSO .PP al_set_new_display_flags(3), al_get_display_flags(3) allegro-5.0.10/docs/man/al_set_audio_stream_speed.30000644000175000001440000000076512157230701021366 0ustar tjadenusers.TH al_set_audio_stream_speed 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM\ *stream,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the relative playback speed. 1.0 is normal speed. .PP Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_audio_stream_speed(3). allegro-5.0.10/docs/man/ALLEGRO_AUDIO_PAN_NONE.30000644000175000001440000000156312157230676017536 0ustar tjadenusers.TH ALLEGRO_AUDIO_PAN_NONE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_AUDIO_PAN_NONE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_AUDIO_PAN_NONE\ \ \ \ \ \ (\-1000.0f) \f[] .fi .SH DESCRIPTION .PP A special value for the pan property of samples and audio streams. Use this value to disable panning on samples and audio streams, and play them without attentuation implied by panning support. .PP ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) because, when panning is enabled, we try to maintain a constant sound power level as a sample is panned from left to right. A sound coming out of one speaker should sound as loud as it does when split over two speakers. As a consequence, a sample with pan value 0.0 will be 3 dB softer than the original level. .PP (Please correct us if this is wrong.) allegro-5.0.10/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.30000644000175000001440000000115612157230701020075 0ustar tjadenusers.TH ALLEGRO_VERTEX_CACHE_SIZE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_VERTEX_CACHE_SIZE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_VERTEX_CACHE_SIZE\ 256 \f[] .fi .SH DESCRIPTION .PP Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high\-level primitives. This corresponds to the maximum number of line segments that will be used to form them. allegro-5.0.10/docs/man/al_inhibit_screensaver.30000644000175000001440000000077112157230671020710 0ustar tjadenusers.TH al_inhibit_screensaver 3 "" "Allegro reference manual" .SH NAME .PP al_inhibit_screensaver \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_inhibit_screensaver(bool\ inhibit) \f[] .fi .SH DESCRIPTION .PP This function allows the user to stop the system screensaver from starting up if true is passed, or resets the system back to the default state (the state at program start) if false is passed. It returns true if the state was set successfully, otherwise false. allegro-5.0.10/docs/man/al_itofix.30000644000175000001440000000171312157230671016161 0ustar tjadenusers.TH al_itofix 3 "" "Allegro reference manual" .SH NAME .PP al_itofix \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_itofix(int\ x); \f[] .fi .SH DESCRIPTION .PP Converts an integer to fixed point. This is the same thing as x<<16. Remember that overflows (trying to convert an integer greater than 32767) and underflows (trying to convert an integer lesser than \-32768) are not detected even in debug builds! The values simply "wrap around". .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ number; \ \ \ \ /*\ This\ conversion\ is\ OK.\ */ \ \ \ \ number\ =\ al_itofix(100); \ \ \ \ assert(al_fixtoi(number)\ ==\ 100); \ \ \ \ number\ =\ al_itofix(64000); \ \ \ \ /*\ This\ check\ will\ fail\ in\ debug\ builds.\ */ \ \ \ \ assert(al_fixtoi(number)\ ==\ 64000); \f[] .fi .SH RETURN VALUE .PP Returns the value of the integer converted to fixed point ignoring overflows. .SH SEE ALSO .PP al_fixtoi(3), al_ftofix(3), al_fixtof(3). allegro-5.0.10/docs/man/al_lock_mutex.30000644000175000001440000000147612157230674017042 0ustar tjadenusers.TH al_lock_mutex 3 "" "Allegro reference manual" .SH NAME .PP al_lock_mutex \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_lock_mutex(ALLEGRO_MUTEX\ *mutex) \f[] .fi .SH DESCRIPTION .PP Acquire the lock on \f[C]mutex\f[]. If the mutex is already locked by another thread, the call will block until the mutex becomes available and locked. .PP If the mutex is already locked by the calling thread, then the behaviour depends on whether the mutex was created with al_create_mutex(3) or al_create_mutex_recursive(3). In the former case, the behaviour is undefined; the most likely behaviour is deadlock. In the latter case, the count in the mutex will be incremented and the call will return immediately. .SH SEE ALSO .PP al_unlock_mutex(3). .PP \f[B]We don\[aq]t yet have al_mutex_trylock.\f[] allegro-5.0.10/docs/man/al_get_app_name.30000644000175000001440000000045612157230674017304 0ustar tjadenusers.TH al_get_app_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_app_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_app_name(void) \f[] .fi .SH DESCRIPTION .PP Returns the global application name string. .SH SEE ALSO .PP al_set_app_name(3) allegro-5.0.10/docs/man/al_set_audio_stream_playing.30000644000175000001440000000065212157230701021724 0ustar tjadenusers.TH al_set_audio_stream_playing 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM\ *stream,\ bool\ val) \f[] .fi .SH DESCRIPTION .PP Change whether the stream is playing. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_audio_stream_playing(3) allegro-5.0.10/docs/man/al_create_display.30000644000175000001440000000160512157230670017646 0ustar tjadenusers.TH al_create_display 3 "" "Allegro reference manual" .SH NAME .PP al_create_display \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_DISPLAY\ *al_create_display(int\ w,\ int\ h) \f[] .fi .SH DESCRIPTION .PP Create a display, or window, with the specified dimensions. The parameters of the display are determined by the last calls to al_set_new_display_*. Default parameters are used if none are set explicitly. Creating a new display will automatically make it the active one, with the backbuffer selected for drawing. .PP Returns NULL on error. .PP Each display has a distinct OpenGL rendering context associated with it. See al_set_target_bitmap(3) for the discussion about rendering contexts. .SH SEE ALSO .PP al_set_new_display_flags(3), al_set_new_display_option(3), al_set_new_display_refresh_rate(3), al_set_new_display_adapter(3), al_set_window_position(3) allegro-5.0.10/docs/man/al_clear_to_color.30000644000175000001440000000056612157230673017654 0ustar tjadenusers.TH al_clear_to_color 3 "" "Allegro reference manual" .SH NAME .PP al_clear_to_color \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_clear_to_color(ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Clear the complete target bitmap, but confined by the clipping rectangle. .SH SEE ALSO .PP ALLEGRO_COLOR(3), al_set_clipping_rectangle(3) allegro-5.0.10/docs/man/al_set_display_icons.30000644000175000001440000000144412157230670020372 0ustar tjadenusers.TH al_set_display_icons 3 "" "Allegro reference manual" .SH NAME .PP al_set_display_icons \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_display_icons(ALLEGRO_DISPLAY\ *display, \ \ \ int\ num_icons,\ ALLEGRO_BITMAP\ *icons[]) \f[] .fi .SH DESCRIPTION .PP Changes the icons associated with the display (window). Multiple icons can be provided for use in different contexts, e.g. window frame, taskbar, alt\-tab popup. The number of icons must be at least one. .RS .PP \f[I]Note:\f[] If the underlying OS requires an icon of a size not provided then one of the bitmaps will be scaled up or down to the required size. The choice of bitmap is implementation dependent. .RE .SH SINCE .PP 5.0.9, 5.1.5 .SH SEE ALSO .PP al_set_display_icon(3), al_set_window_title(3) allegro-5.0.10/docs/man/al_shutdown_image_addon.30000644000175000001440000000055712157230677021054 0ustar tjadenusers.TH al_shutdown_image_addon 3 "" "Allegro reference manual" .SH NAME .PP al_shutdown_image_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_shutdown_image_addon(void) \f[] .fi .SH DESCRIPTION .PP Shut down the image addon. This is done automatically at program exit, but can be called any time the user wishes as well. allegro-5.0.10/docs/man/al_get_bitmap_format.30000644000175000001440000000054212157230673020343 0ustar tjadenusers.TH al_get_bitmap_format 3 "" "Allegro reference manual" .SH NAME .PP al_get_bitmap_format \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_bitmap_format(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the pixel format of a bitmap. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3), al_set_new_bitmap_flags(3) allegro-5.0.10/docs/man/al_ustr_offset.30000644000175000001440000000125512157230676017230 0ustar tjadenusers.TH al_ustr_offset 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_offset \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_offset(const\ ALLEGRO_USTR\ *us,\ int\ index) \f[] .fi .SH DESCRIPTION .PP Return the byte offset (from the start of the string) of the code point at the specified index in the string. A zero index parameter will return the first character of the string. If index is negative, it counts backward from the end of the string, so an index of \-1 will return an offset to the last code point. .PP If the index is past the end of the string, returns the offset of the end of the string. .SH SEE ALSO .PP al_ustr_length(3) allegro-5.0.10/docs/man/al_get_timer_speed.30000644000175000001440000000062212157230675020020 0ustar tjadenusers.TH al_get_timer_speed 3 "" "Allegro reference manual" .SH NAME .PP al_get_timer_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ double\ al_get_timer_speed(const\ ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Return the timer\[aq]s speed, in seconds. (The same value passed to al_create_timer(3) or al_set_timer_speed(3).) .SH SEE ALSO .PP al_set_timer_speed(3) allegro-5.0.10/docs/man/al_flip_display.30000644000175000001440000000251212157230670017333 0ustar tjadenusers.TH al_flip_display 3 "" "Allegro reference manual" .SH NAME .PP al_flip_display \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_flip_display(void) \f[] .fi .SH DESCRIPTION .PP Copies or updates the front and back buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back buffer bitmap remain valid and retain their semantics as the back buffer, although the contents may have changed. .PP Several display options change how this function behaves: .IP \[bu] 2 With ALLEGRO_SINGLE_BUFFER, no flipping is done. You still have to call this function to display graphics, depending on how the used graphics system works. .IP \[bu] 2 The ALLEGRO_SWAP_METHOD option may have additional information about what kind of operation is used internally to flip the front and back buffers. .IP \[bu] 2 If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. If ALLEGRO_VSYNC is 2, this function will not wait for vsync. With many drivers the vsync behavior is controlled by the user and not the application, and ALLEGRO_VSYNC will not be set; in this case al_flip_display(3) will wait for vsync depending on the settings set in the system\[aq]s graphics preferences. .SH SEE ALSO .PP al_set_new_display_flags(3), al_set_new_display_option(3) allegro-5.0.10/docs/man/al_ungrab_mouse.30000644000175000001440000000057512157230674017355 0ustar tjadenusers.TH al_ungrab_mouse 3 "" "Allegro reference manual" .SH NAME .PP al_ungrab_mouse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ungrab_mouse(void) \f[] .fi .SH DESCRIPTION .PP Stop confining the mouse cursor to any display belonging to the program. .RS .PP \f[I]Note:\f[] not yet implemented on Mac OS X. .RE .SH SEE ALSO .PP al_grab_mouse(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.30000644000175000001440000000063212157230672020323 0ustar tjadenusers.TH ALLEGRO_EVENT_TYPE_IS_USER 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT_TYPE_IS_USER \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_EVENT_TYPE_IS_USER(t)\ \ \ \ \ \ \ \ ((t)\ >=\ 512) \f[] .fi .SH DESCRIPTION .PP A macro which evaluates to true if the event type is not a builtin event type, i.e. one of those described in ALLEGRO_EVENT_TYPE(3). allegro-5.0.10/docs/man/al_fflush.30000644000175000001440000000055712157230671016153 0ustar tjadenusers.TH al_fflush 3 "" "Allegro reference manual" .SH NAME .PP al_fflush \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_fflush(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Flush any pending writes to the given file. .PP Returns true on success, false otherwise. errno is set to indicate the error. .SH SEE ALSO .PP al_get_errno(3) allegro-5.0.10/docs/man/al_scale_transform.30000644000175000001440000000075312157230675020050 0ustar tjadenusers.TH al_scale_transform 3 "" "Allegro reference manual" .SH NAME .PP al_scale_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_scale_transform(ALLEGRO_TRANSFORM\ *trans,\ float\ sx,\ float\ sy) \f[] .fi .SH DESCRIPTION .PP Apply a scale to a transformation. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .IP \[bu] 2 sx, sy \- Scale .SH SEE ALSO .PP al_translate_transform(3), al_rotate_transform(3), al_build_transform(3) allegro-5.0.10/docs/man/al_get_sample_channels.30000644000175000001440000000070712157230677020662 0ustar tjadenusers.TH al_get_sample_channels 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_channels \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CHANNEL_CONF\ al_get_sample_channels(const\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the channel configuration. .SH SEE ALSO .PP ALLEGRO_CHANNEL_CONF(3), al_get_sample_depth(3), al_get_sample_frequency(3), al_get_sample_length(3), al_get_sample_data(3) allegro-5.0.10/docs/man/al_create_file_handle.30000644000175000001440000000115612157230672020436 0ustar tjadenusers.TH al_create_file_handle 3 "" "Allegro reference manual" .SH NAME .PP al_create_file_handle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_create_file_handle(const\ ALLEGRO_FILE_INTERFACE\ *drv, \ \ \ void\ *userdata) \f[] .fi .SH DESCRIPTION .PP Creates an empty, opened file handle with some abstract user data. This allows custom interfaces to extend the ALLEGRO_FILE(3) struct with their own data. You should close the handle with the standard al_fclose(3) function when you are finished with it. .SH SEE ALSO .PP al_fopen(3), al_fclose(3), al_set_new_file_interface(3) allegro-5.0.10/docs/man/al_fixfloor.30000644000175000001440000000116412157230671016507 0ustar tjadenusers.TH al_fixfloor 3 "" "Allegro reference manual" .SH NAME .PP al_fixfloor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fixfloor(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP Returns the greatest integer not greater than x. That is, it rounds towards negative infinity. .PP Example: .IP .nf \f[C] \ \ \ \ int\ result; \ \ \ \ /*\ This\ will\ put\ 33\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixfloor(al_itofix(100)\ /\ 3); \ \ \ \ /*\ And\ this\ will\ round\ down\ to\ 16.\ */ \ \ \ \ result\ =\ al_fixfloor(al_itofix(100)\ /\ 6); \f[] .fi .SH SEE ALSO .PP al_fixtoi(3), al_fixceil(3). allegro-5.0.10/docs/man/al_get_pixel.30000644000175000001440000000101612157230673016635 0ustar tjadenusers.TH al_get_pixel 3 "" "Allegro reference manual" .SH NAME .PP al_get_pixel \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_get_pixel(ALLEGRO_BITMAP\ *bitmap,\ int\ x,\ int\ y) \f[] .fi .SH DESCRIPTION .PP Get a pixel\[aq]s color value from the specified bitmap. This operation is slow on non\-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. .SH SEE ALSO .PP ALLEGRO_COLOR(3), al_put_pixel(3), al_lock_bitmap(3) allegro-5.0.10/docs/man/al_fixdiv.30000644000175000001440000000261612157230671016153 0ustar tjadenusers.TH al_fixdiv 3 "" "Allegro reference manual" .SH NAME .PP al_fixdiv \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixdiv(al_fixed\ x,\ al_fixed\ y); \f[] .fi .SH DESCRIPTION .PP A fixed point value can be divided by an integer with the normal \f[C]/\f[] operator. To divide two fixed point values, though, you must use this function. If a division by zero occurs, Allegro\[aq]s errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for division by zero you should call \f[C]al_set_errno(0)\f[] before calling al_fixdiv(3). .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ This\ will\ put\ 0.06060\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixdiv(al_itofix(2),\ al_itofix(33)); \ \ \ \ /*\ This\ will\ put\ 0\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixdiv(0,\ al_itofix(\-30)); \ \ \ \ /*\ Sets\ errno\ and\ puts\ \-32768\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixdiv(al_itofix(\-100),\ al_itofix(0)); \ \ \ \ assert(!al_get_errno());\ /*\ This\ will\ fail.\ */ \f[] .fi .SH RETURN VALUE .PP Returns the result of dividing \f[C]x\f[] by \f[C]y\f[]. If \f[C]y\f[] is zero, returns the maximum possible fixed point value and sets Allegro\[aq]s errno to ERANGE. .SH SEE ALSO .PP al_fixadd(3), al_fixsub(3), al_fixmul(3), al_get_errno(3). allegro-5.0.10/docs/man/al_register_font_loader.30000644000175000001440000000137612157230677021072 0ustar tjadenusers.TH al_register_font_loader 3 "" "Allegro reference manual" .SH NAME .PP al_register_font_loader \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_font_loader(char\ const\ *extension, \ \ \ ALLEGRO_FONT\ *(*load_font)(char\ const\ *filename,\ int\ size,\ int\ flags)) \f[] .fi .SH DESCRIPTION .PP Informs Allegro of a new font file type, telling it how to load files of this format. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]load_font\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_init_font_addon(3) allegro-5.0.10/docs/man/al_drain_audio_stream.30000644000175000001440000000076012157230701020503 0ustar tjadenusers.TH al_drain_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_drain_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_drain_audio_stream(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP You should call this to finalise an audio stream that you will no longer be feeding, to wait for all pending buffers to finish playing. The stream\[aq]s playing state will change to false. .SH SEE ALSO .PP al_destroy_audio_stream(3) allegro-5.0.10/docs/man/ALLEGRO_VERTEX_DECL.30000644000175000001440000000103712157230701017145 0ustar tjadenusers.TH ALLEGRO_VERTEX_DECL 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_VERTEX_DECL \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_VERTEX_DECL\ ALLEGRO_VERTEX_DECL; \f[] .fi .SH DESCRIPTION .PP A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions. .SH SEE ALSO .PP al_create_vertex_decl(3), al_destroy_vertex_decl(3), ALLEGRO_VERTEX_ELEMENT(3) allegro-5.0.10/docs/man/al_convert_mask_to_alpha.30000644000175000001440000000073312157230674021225 0ustar tjadenusers.TH al_convert_mask_to_alpha 3 "" "Allegro reference manual" .SH NAME .PP al_convert_mask_to_alpha \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_convert_mask_to_alpha(ALLEGRO_BITMAP\ *bitmap,\ ALLEGRO_COLOR\ mask_color) \f[] .fi .SH DESCRIPTION .PP Convert the given mask color to an alpha channel in the bitmap. Can be used to convert older 4.2\-style bitmaps with magic pink to alpha\-ready bitmaps. .SH SEE ALSO .PP ALLEGRO_COLOR(3) allegro-5.0.10/docs/man/al_change_directory.30000644000175000001440000000052612157230672020172 0ustar tjadenusers.TH al_change_directory 3 "" "Allegro reference manual" .SH NAME .PP al_change_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_change_directory(const\ char\ *path) \f[] .fi .SH DESCRIPTION .PP Changes the current working directory to \[aq]path\[aq]. .PP Returns true on success, false on error. allegro-5.0.10/docs/man/al_set_standard_file_interface.30000644000175000001440000000067612157230672022361 0ustar tjadenusers.TH al_set_standard_file_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_standard_file_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_standard_file_interface(void) \f[] .fi .SH DESCRIPTION .PP Set the ALLEGRO_FILE_INTERFACE(3) table to the default, for the calling thread. This will change the handler for later calls to al_fopen(3). .SH SEE ALSO .PP al_set_new_file_interface(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_KEY_DOWN.30000644000175000001440000002700512157230670017571 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_draw_line.30000644000175000001440000000113112157230700016606 0ustar tjadenusers.TH al_draw_line 3 "" "Allegro reference manual" .SH NAME .PP al_draw_line \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_line(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws a line segment between two points. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2 \- Start and end points of the line .IP \[bu] 2 color \- Color of the line .IP \[bu] 2 thickness \- Thickness of the line, pass \f[C]<=\ 0\f[] to draw hairline lines .SH SEE ALSO .PP al_draw_soft_line(3) allegro-5.0.10/docs/man/al_ustr_assign_cstr.30000644000175000001440000000070312157230677020257 0ustar tjadenusers.TH al_ustr_assign_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_assign_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_assign_cstr(ALLEGRO_USTR\ *us1,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Overwrite the string \f[C]us\f[] with the contents of the C\-style string \f[C]s\f[]. Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_assign_substr(3), al_ustr_assign_cstr(3) allegro-5.0.10/docs/man/al_get_joystick_axis_name.30000644000175000001440000000073512157230673021406 0ustar tjadenusers.TH al_get_joystick_axis_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_axis_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_joystick_axis_name(ALLEGRO_JOYSTICK\ *joy,\ int\ stick,\ int\ axis) \f[] .fi .SH DESCRIPTION .PP Return the name of the given axis. If the axis doesn\[aq]t exist, NULL is returned. Indices begin from 0. .SH SEE ALSO .PP al_get_joystick_stick_name(3), al_get_joystick_num_axes(3) allegro-5.0.10/docs/man/ALLEGRO_TIMER.30000644000175000001440000000044012157230674016227 0ustar tjadenusers.TH ALLEGRO_TIMER 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_TIMER \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_TIMER\ ALLEGRO_TIMER; \f[] .fi .SH DESCRIPTION .PP This is an abstract data type representing a timer object. allegro-5.0.10/docs/man/al_destroy_sample.30000644000175000001440000000112112157230677017710 0ustar tjadenusers.TH al_destroy_sample 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_sample(ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Free the sample data structure. If it was created with the \f[C]free_buf\f[] parameter set to true, then the buffer will be freed with al_free(3). .PP This function will stop any sample instances which may be playing the buffer referenced by the ALLEGRO_SAMPLE(3). .SH SEE ALSO .PP al_destroy_sample_instance(3), al_stop_sample(3), al_stop_samples(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_KEY_CHAR.30000644000175000001440000002700512157230670017537 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_voice_depth.30000644000175000001440000000053212157230677020013 0ustar tjadenusers.TH al_get_voice_depth 3 "" "Allegro reference manual" .SH NAME .PP al_get_voice_depth \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_DEPTH\ al_get_voice_depth(const\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Return the audio depth of the voice. .SH SEE ALSO .PP ALLEGRO_AUDIO_DEPTH(3). allegro-5.0.10/docs/man/al_drop_next_event.30000644000175000001440000000066612157230672020071 0ustar tjadenusers.TH al_drop_next_event 3 "" "Allegro reference manual" .SH NAME .PP al_drop_next_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_drop_next_event(ALLEGRO_EVENT_QUEUE\ *queue) \f[] .fi .SH DESCRIPTION .PP Drop (remove) the next event from the queue. If the queue is empty, nothing happens. Returns true if an event was dropped. .SH SEE ALSO .PP al_flush_event_queue(3), al_is_event_queue_empty(3) allegro-5.0.10/docs/man/al_translate_transform.30000644000175000001440000000077312157230675020760 0ustar tjadenusers.TH al_translate_transform 3 "" "Allegro reference manual" .SH NAME .PP al_translate_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_translate_transform(ALLEGRO_TRANSFORM\ *trans,\ float\ x,\ float\ y) \f[] .fi .SH DESCRIPTION .PP Apply a translation to a transformation. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .IP \[bu] 2 x, y \- Translation .SH SEE ALSO .PP al_rotate_transform(3), al_scale_transform(3), al_build_transform(3) allegro-5.0.10/docs/man/al_get_mouse_num_axes.30000644000175000001440000000053612157230673020551 0ustar tjadenusers.TH al_get_mouse_num_axes 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_num_axes \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_mouse_num_axes(void) \f[] .fi .SH DESCRIPTION .PP Return the number of buttons on the mouse. The first axis is 0. .SH SEE ALSO .PP al_get_mouse_num_buttons(3) allegro-5.0.10/docs/man/al_get_mixer_frequency.30000644000175000001440000000053112157230700020711 0ustar tjadenusers.TH al_get_mixer_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_mixer_frequency(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return the mixer frequency. .SH SEE ALSO .PP al_set_mixer_frequency(3) allegro-5.0.10/docs/man/al_get_parent_bitmap.30000644000175000001440000000070212157230673020342 0ustar tjadenusers.TH al_get_parent_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_get_parent_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_get_parent_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the bitmap this bitmap is a sub\-bitmap of. Returns NULL if this bitmap is not a sub\-bitmap. .SH SINCE .PP 5.0.6, 5.1.2 .SH SEE ALSO .PP al_create_sub_bitmap(3), al_is_sub_bitmap(3) allegro-5.0.10/docs/man/al_save_bitmap_f.30000644000175000001440000000145712157230674017466 0ustar tjadenusers.TH al_save_bitmap_f 3 "" "Allegro reference manual" .SH NAME .PP al_save_bitmap_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_bitmap_f(ALLEGRO_FILE\ *fp,\ const\ char\ *ident, \ \ \ ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Saves an ALLEGRO_BITMAP(3) to an ALLEGRO_FILE(3) stream. The file type is determined by the passed \[aq]ident\[aq] parameter, which is a file name extension including the leading dot. .PP Returns true on success, false on error. The file remains open afterwards. .RS .PP \f[I]Note:\f[] the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. .RE .SH SEE ALSO .PP al_save_bitmap(3), al_register_bitmap_saver_f(3), al_init_image_addon(3) allegro-5.0.10/docs/man/al_get_timer_started.30000644000175000001440000000046612157230675020374 0ustar tjadenusers.TH al_get_timer_started 3 "" "Allegro reference manual" .SH NAME .PP al_get_timer_started \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_timer_started(const\ ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Return true if the timer specified is currently started. allegro-5.0.10/docs/man/al_insert_path_component.30000644000175000001440000000120012157230674021253 0ustar tjadenusers.TH al_insert_path_component 3 "" "Allegro reference manual" .SH NAME .PP al_insert_path_component \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_insert_path_component(ALLEGRO_PATH\ *path,\ int\ i,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Insert a directory component at index i. If the index is negative then count from the right, i.e. \-1 refers to the last path component. .PP It is an error to pass an index i which is not within these bounds: 0 <= i <= al_get_path_num_components(path). .SH SEE ALSO .PP al_append_path_component(3), al_replace_path_component(3), al_remove_path_component(3) allegro-5.0.10/docs/man/al_fread16le.30000644000175000001440000000104012157230671016421 0ustar tjadenusers.TH al_fread16le 3 "" "Allegro reference manual" .SH NAME .PP al_fread16le \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int16_t\ al_fread16le(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Reads a 16\-bit word in little\-endian format (LSB first). .PP On success, returns the 16\-bit word. On failure, returns EOF (\-1). Since \-1 is also a valid return value, use al_feof(3) to check if the end of the file was reached prematurely, or al_ferror(3) to check if an error occurred. .SH SEE ALSO .PP al_fread16be(3) allegro-5.0.10/docs/man/al_ustr_find_chr.30000644000175000001440000000074712157230677017524 0ustar tjadenusers.TH al_ustr_find_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_chr(const\ ALLEGRO_USTR\ *us,\ int\ start_pos,\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Search for the encoding of code point \f[C]c\f[] in \f[C]us\f[] from byte offset \f[C]start_pos\f[] (inclusive). .PP Returns the position where it is found or \-1 if it is not found. .SH SEE ALSO .PP al_ustr_rfind_chr(3) allegro-5.0.10/docs/man/al_emit_user_event.30000644000175000001440000000310212157230672020047 0ustar tjadenusers.TH al_emit_user_event 3 "" "Allegro reference manual" .SH NAME .PP al_emit_user_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_emit_user_event(ALLEGRO_EVENT_SOURCE\ *src, \ \ \ ALLEGRO_EVENT\ *event,\ void\ (*dtor)(ALLEGRO_USER_EVENT\ *)) \f[] .fi .SH DESCRIPTION .PP Emit a user event. The event source must have been initialised with al_init_user_event_source(3). Returns \f[C]false\f[] if the event source isn\[aq]t registered with any queues, hence the event wouldn\[aq]t have been delivered into any queues. .PP Events are \f[I]copied\f[] in and out of event queues, so after this function returns the memory pointed to by \f[C]event\f[] may be freed or reused. Some fields of the event being passed in may be modified by the function. .PP Reference counting will be performed if \f[C]dtor\f[] is not NULL. Whenever a copy of the event is made, the reference count increases. You need to call al_unref_user_event(3) to decrease the reference count once you are done with a user event that you have received from al_get_next_event(3), al_peek_next_event(3), al_wait_for_event(3), etc. .PP Once the reference count drops to zero \f[C]dtor\f[] will be called with a copy of the event as an argument. It should free the resources associated with the event, but \f[I]not\f[] the event itself (since it is just a copy). .PP If \f[C]dtor\f[] is NULL then reference counting will not be performed. It is safe, but unnecessary, to call al_unref_user_event(3) on non\-reference counted user events. .SH SEE ALSO .PP ALLEGRO_USER_EVENT(3), al_unref_user_event(3) allegro-5.0.10/docs/man/al_ustr_new_from_utf16.30000644000175000001440000000071412157230677020603 0ustar tjadenusers.TH al_ustr_new_from_utf16 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_new_from_utf16 \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_new_from_utf16(uint16_t\ const\ *s) \f[] .fi .SH DESCRIPTION .PP Create a new string containing a copy of the 0\-terminated string \f[C]s\f[] which must be encoded as UTF\-16. The string must eventually be freed with al_ustr_free(3). .SH SEE ALSO .PP al_ustr_new(3) allegro-5.0.10/docs/man/al_get_audio_stream_playmode.30000644000175000001440000000062712157230701022061 0ustar tjadenusers.TH al_get_audio_stream_playmode 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_playmode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PLAYMODE\ al_get_audio_stream_playmode( \ \ \ const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the playback mode. .SH SEE ALSO .PP ALLEGRO_PLAYMODE(3), al_set_audio_stream_playmode(3). allegro-5.0.10/docs/man/al_ustr_assign_substr.30000644000175000001440000000123612157230677020630 0ustar tjadenusers.TH al_ustr_assign_substr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_assign_substr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_assign_substr(ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2, \ \ \ int\ start_pos,\ int\ end_pos) \f[] .fi .SH DESCRIPTION .PP Overwrite the string \f[C]us1\f[] with the contents of \f[C]us2\f[] in the byte interval [start_pos, end_pos). The end points will be clamed to the bounds of \f[C]us2\f[]. .PP Usually you will first have to use al_ustr_offset(3) to find the byte offsets. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_assign(3), al_ustr_assign_cstr(3) allegro-5.0.10/docs/man/al_get_sample_depth.30000644000175000001440000000066512157230677020176 0ustar tjadenusers.TH al_get_sample_depth 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_depth \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_DEPTH\ al_get_sample_depth(const\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the audio depth. .SH SEE ALSO .PP ALLEGRO_AUDIO_DEPTH(3), al_get_sample_channels(3), al_get_sample_frequency(3), al_get_sample_length(3), al_get_sample_data(3) allegro-5.0.10/docs/man/al_get_clipping_rectangle.30000644000175000001440000000056512157230674021356 0ustar tjadenusers.TH al_get_clipping_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_get_clipping_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_clipping_rectangle(int\ *x,\ int\ *y,\ int\ *w,\ int\ *h) \f[] .fi .SH DESCRIPTION .PP Gets the clipping rectangle of the target bitmap. .SH SEE ALSO .PP al_set_clipping_rectangle(3) allegro-5.0.10/docs/man/al_fopen_slice.30000644000175000001440000000317012157230671017144 0ustar tjadenusers.TH al_fopen_slice 3 "" "Allegro reference manual" .SH NAME .PP al_fopen_slice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_fopen_slice(ALLEGRO_FILE\ *fp,\ size_t\ initial_size,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Opens a slice (subset) of an already open random access file as if it were a stand alone file. While the slice is open, the parent file handle must not be used in any way. .PP The slice is opened at the current location of the parent file, up through \f[C]initial_size\f[] bytes. The \f[C]initial_size\f[] may be any non\-negative integer that will not exceed the bounds of the parent file. .PP Seeking with \f[C]ALLEGRO_SEEK_SET\f[] will be relative to this starting location. \f[C]ALLEGRO_SEEK_END\f[] will be relative to the starting location plus the size of the slice. .PP The mode can be any combination of: .IP \[bu] 2 r: read access .IP \[bu] 2 w: write access .IP \[bu] 2 e: expandable .PP For example, a mode of "rw" indicates the file can be read and written. (Note that this is slightly different from the stdio modes.) Keep in mind that the parent file must support random access and be open in normal write mode (not append) for the slice to work in a well defined way. .PP If the slice is marked as expandable, then reads and writes can happen after the initial end point, and the slice will grow accordingly. Otherwise, all activity is restricted to the initial size of the slice. .PP A slice must be closed with al_fclose(3). The parent file will then be positioned immediately after the end of the slice. .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_fopen(3) allegro-5.0.10/docs/man/al_get_display_option.30000644000175000001440000000055012157230670020550 0ustar tjadenusers.TH al_get_display_option 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_option \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_option(ALLEGRO_DISPLAY\ *display,\ int\ option) \f[] .fi .SH DESCRIPTION .PP Return an extra display setting of the display. .SH SEE ALSO .PP al_set_new_display_option(3) allegro-5.0.10/docs/man/ALLEGRO_TIMEOUT.30000644000175000001440000000061112157230674016475 0ustar tjadenusers.TH ALLEGRO_TIMEOUT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_TIMEOUT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_TIMEOUT\ ALLEGRO_TIMEOUT; \f[] .fi .SH DESCRIPTION .PP Represent a timeout value. The size of the structure is known so can be statically allocated. The contents are private. .SH SEE ALSO .PP al_init_timeout(3) allegro-5.0.10/docs/man/al_signal_cond.30000644000175000001440000000067612157230675017152 0ustar tjadenusers.TH al_signal_cond 3 "" "Allegro reference manual" .SH NAME .PP al_signal_cond \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_signal_cond(ALLEGRO_COND\ *cond) \f[] .fi .SH DESCRIPTION .PP Unblock at least one thread waiting on a condition variable. .PP Generally you should use al_broadcast_cond(3) but al_signal_cond(3) may be more efficient when it\[aq]s applicable. .SH SEE ALSO .PP al_broadcast_cond(3). allegro-5.0.10/docs/man/al_draw_justified_text.30000644000175000001440000000165312157230700020722 0ustar tjadenusers.TH al_draw_justified_text 3 "" "Allegro reference manual" .SH NAME .PP al_draw_justified_text \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_justified_text(const\ ALLEGRO_FONT\ *font, \ \ \ ALLEGRO_COLOR\ color,\ float\ x1,\ float\ x2, \ \ \ float\ y,\ float\ diff,\ int\ flags,\ const\ char\ *text) \f[] .fi .SH DESCRIPTION .PP Like al_draw_text(3), but justifies the string to the region x1\-x2. .PP The \f[I]diff\f[] parameter is the maximum amount of horizontal space to allow between words. If justisfying the text would exceed \f[I]diff\f[] pixels, or the string contains less than two words, then the string will be drawn left aligned. .PP The \f[C]flags\f[] parameter can be 0 or one of the following flags: .IP \[bu] 2 ALLEGRO_ALIGN_INTEGER \- Draw text aligned to integer pixel positions. Since: 5.0.8, 5.1.5 .SH SEE ALSO .PP al_draw_justified_textf(3), al_draw_justified_ustr(3) allegro-5.0.10/docs/man/al_ustr_rfind_chr.30000644000175000001440000000075312157230677017703 0ustar tjadenusers.TH al_ustr_rfind_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_rfind_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_rfind_chr(const\ ALLEGRO_USTR\ *us,\ int\ end_pos,\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Search for the encoding of code point \f[C]c\f[] in \f[C]us\f[] backwards from byte offset \f[C]end_pos\f[] (exclusive). Returns the position where it is found or \-1 if it is not found. .SH SEE ALSO .PP al_ustr_find_chr(3) allegro-5.0.10/docs/man/al_register_audio_stream_loader.30000644000175000001440000000160112157230701022553 0ustar tjadenusers.TH al_register_audio_stream_loader 3 "" "Allegro reference manual" .SH NAME .PP al_register_audio_stream_loader \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_audio_stream_loader(const\ char\ *ext, \ \ \ ALLEGRO_AUDIO_STREAM\ *(*stream_loader)(const\ char\ *filename, \ \ \ \ \ \ size_t\ buffer_count,\ unsigned\ int\ samples)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_audio_stream(3). The given function will be used to open streams from files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]stream_loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_audio_stream_loader_f(3) allegro-5.0.10/docs/man/al_fixsub.30000644000175000001440000000227012157230671016156 0ustar tjadenusers.TH al_fixsub 3 "" "Allegro reference manual" .SH NAME .PP al_fixsub \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixsub(al_fixed\ x,\ al_fixed\ y); \f[] .fi .SH DESCRIPTION .PP Although fixed point numbers can be subtracted with the normal \f[C]\-\f[] integer operator, that doesn\[aq]t provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro\[aq]s errno and clamp the result, rather than just letting it wrap. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ This\ will\ put\ 4965\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixsub(al_itofix(5000),\ al_itofix(35)); \ \ \ \ /*\ Sets\ errno\ and\ puts\ \-32768\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixsub(al_itofix(\-31000),\ al_itofix(3000)); \ \ \ \ assert(!al_get_errno());\ /*\ This\ will\ fail.\ */ \f[] .fi .SH RETURN VALUE .PP Returns the clamped result of subtracting \f[C]y\f[] from \f[C]x\f[], setting Allegro\[aq]s errno to ERANGE if there was an overflow. .SH SEE ALSO .PP al_fixadd(3), al_fixmul(3), al_fixdiv(3), al_get_errno(3). allegro-5.0.10/docs/man/al_ustr_has_prefix_cstr.30000644000175000001440000000062012157230677021121 0ustar tjadenusers.TH al_ustr_has_prefix_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_has_prefix_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_has_prefix_cstr(const\ ALLEGRO_USTR\ *us1,\ const\ char\ *s2) \f[] .fi .SH DESCRIPTION .PP Returns true iff \f[C]us1\f[] begins with \f[C]s2\f[]. .SH SEE ALSO .PP al_ustr_has_prefix(3), al_ustr_has_suffix_cstr(3) allegro-5.0.10/docs/man/al_get_allegro_image_version.30000644000175000001440000000054512157230677022062 0ustar tjadenusers.TH al_get_allegro_image_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_image_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_image_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_osx_get_window.30000644000175000001440000000053012157230675017716 0ustar tjadenusers.TH al_osx_get_window 3 "" "Allegro reference manual" .SH NAME .PP al_osx_get_window \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ NSWindow*\ al_osx_get_window(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Retrieves the NSWindow handle associated with the Allegro display. .SH SINCE .PP 5.0.8, 5.1.3 allegro-5.0.10/docs/man/ALLEGRO_EVENT_TIMER.30000644000175000001440000002700512157230671017173 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/ALLEGRO_FILECHOOSER.30000644000175000001440000000046212157230700017103 0ustar tjadenusers.TH ALLEGRO_FILECHOOSER 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FILECHOOSER \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FILECHOOSER\ ALLEGRO_FILECHOOSER; \f[] .fi .SH DESCRIPTION .PP Opaque handle to a native file dialog. allegro-5.0.10/docs/man/al_mouse_button_down.30000644000175000001440000000076612157230674020443 0ustar tjadenusers.TH al_mouse_button_down 3 "" "Allegro reference manual" .SH NAME .PP al_mouse_button_down \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_mouse_button_down(const\ ALLEGRO_MOUSE_STATE\ *state,\ int\ button) \f[] .fi .SH DESCRIPTION .PP Return true if the mouse button specified was held down in the state specified. Unlike most things, the first mouse button is numbered 1. .SH SEE ALSO .PP ALLEGRO_MOUSE_STATE(3), al_get_mouse_state(3), al_get_mouse_state_axis(3) allegro-5.0.10/docs/man/al_ftell.30000644000175000001440000000064412157230671015767 0ustar tjadenusers.TH al_ftell 3 "" "Allegro reference manual" .SH NAME .PP al_ftell \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int64_t\ al_ftell(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Returns the current position in the given file, or \-1 on error. errno is set to indicate the error. .PP On some platforms this function may not support large files. .SH SEE ALSO .PP al_fseek(3), al_get_errno(3) allegro-5.0.10/docs/man/al_get_sample_instance_time.30000644000175000001440000000065212157230700021673 0ustar tjadenusers.TH al_get_sample_instance_time 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_time \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_sample_instance_time(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the length of the sample instance in seconds, assuming a playback speed of 1.0. .SH SEE ALSO .PP al_get_sample_instance_length(3) allegro-5.0.10/docs/man/al_get_current_display.30000644000175000001440000000056712157230673020735 0ustar tjadenusers.TH al_get_current_display 3 "" "Allegro reference manual" .SH NAME .PP al_get_current_display \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_DISPLAY\ *al_get_current_display(void) \f[] .fi .SH DESCRIPTION .PP Return the display that is "current" for the calling thread, or NULL if there is none. .SH SEE ALSO .PP al_set_target_bitmap(3) allegro-5.0.10/docs/man/al_get_opengl_version.30000644000175000001440000000121012157230676020544 0ustar tjadenusers.TH al_get_opengl_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_opengl_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the OpenGL or OpenGL ES version number of the client (the computer the program is running on), for the current display. "1.0" is returned as 0x01000000, "1.2.1" is returned as 0x01020100, and "1.2.2" as 0x01020200, etc. .PP A valid OpenGL context must exist for this function to work, which means you may \f[I]not\f[] call it before al_create_display(3). .SH SEE ALSO .PP al_get_opengl_variant(3) allegro-5.0.10/docs/man/al_color_html.30000644000175000001440000000063512157230677017031 0ustar tjadenusers.TH al_color_html 3 "" "Allegro reference manual" .SH NAME .PP al_color_html \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_html(char\ const\ *string) \f[] .fi .SH DESCRIPTION .PP Interprets an HTML styled hex number (e.g. #00faff) as a color. Components that are malformed are set to 0. .SH SEE ALSO .PP al_color_html_to_rgb(3), al_color_rgb_to_html(3) allegro-5.0.10/docs/man/al_get_default_mixer.30000644000175000001440000000112712157230700020336 0ustar tjadenusers.TH al_get_default_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_get_default_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MIXER\ *al_get_default_mixer(void) \f[] .fi .SH DESCRIPTION .PP Return the default mixer, or NULL if one has not been set. Although different configurations of mixers and voices can be used, in most cases a single mixer attached to a voice is what you want. The default mixer is used by al_play_sample(3). .SH SEE ALSO .PP al_reserve_samples(3), al_play_sample(3), al_set_default_mixer(3), al_restore_default_mixer(3) allegro-5.0.10/docs/man/ALLEGRO_PRIM_ATTR.30000644000175000001440000000216212157230701016742 0ustar tjadenusers.TH ALLEGRO_PRIM_ATTR 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PRIM_ATTR \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_PRIM_ATTR \f[] .fi .SH DESCRIPTION .PP Enumerates the types of vertex attributes that a custom vertex may have. .IP \[bu] 2 ALLEGRO_PRIM_POSITION \- Position information, can be stored only in ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3. .IP \[bu] 2 ALLEGRO_PRIM_COLOR_ATTR \- Color information, stored in an ALLEGRO_COLOR(3). The storage field of ALLEGRO_VERTEX_ELEMENT is ignored .IP \[bu] 2 ALLEGRO_PRIM_TEX_COORD \- Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are normalized by the width and height of the texture, meaning that the bottom\-right corner has texture coordinates of (1, 1). .IP \[bu] 2 ALLEGRO_PRIM_TEX_COORD_PIXEL \- Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are measured in pixels. .SH SEE ALSO .PP ALLEGRO_VERTEX_DECL(3), ALLEGRO_PRIM_STORAGE(3) allegro-5.0.10/docs/man/al_drop_path_tail.30000644000175000001440000000050512157230674017651 0ustar tjadenusers.TH al_drop_path_tail 3 "" "Allegro reference manual" .SH NAME .PP al_drop_path_tail \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_drop_path_tail(ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Remove the last directory component, if any. .SH SEE ALSO .PP al_remove_path_component(3) allegro-5.0.10/docs/man/al_set_sample.30000644000175000001440000000202012157230700016774 0ustar tjadenusers.TH al_set_sample 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample(ALLEGRO_SAMPLE_INSTANCE\ *spl,\ ALLEGRO_SAMPLE\ *data) \f[] .fi .SH DESCRIPTION .PP Change the sample data that a sample instance plays. This can be quite an involved process. .PP First, the sample is stopped if it is not already. .PP Next, if data is NULL, the sample is detached from its parent (if any). .PP If data is not NULL, the sample may be detached and reattached to its parent (if any). This is not necessary if the old sample data and new sample data have the same frequency, depth and channel configuration. Reattaching may not always succeed. .PP On success, the sample remains stopped. The playback position and loop end points are reset to their default values. The loop mode remains unchanged. .PP Returns true on success, false on failure. On failure, the sample will be stopped and detached from its parent. .SH SEE ALSO .PP al_get_sample(3) allegro-5.0.10/docs/man/al_init_font_addon.30000644000175000001440000000076612157230677020032 0ustar tjadenusers.TH al_init_font_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_font_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_init_font_addon(void) \f[] .fi .SH DESCRIPTION .PP Initialise the font addon. .PP Note that if you intend to load bitmap fonts, you will need to initialise allegro_image separately (unless you are using another library to load images). .SH SEE ALSO .PP al_init_image_addon(3), al_init_ttf_addon(3), al_shutdown_font_addon(3) allegro-5.0.10/docs/man/al_clone_path.30000644000175000001440000000051612157230673016775 0ustar tjadenusers.TH al_clone_path 3 "" "Allegro reference manual" .SH NAME .PP al_clone_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PATH\ *al_clone_path(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Clones an ALLEGRO_PATH structure. Returns NULL on failure. .SH SEE ALSO .PP al_destroy_path(3) allegro-5.0.10/docs/man/al_load_sample_f.30000644000175000001440000000171112157230701017434 0ustar tjadenusers.TH al_load_sample_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_sample_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_SAMPLE\ *al_load_sample_f(ALLEGRO_FILE*\ fp,\ const\ char\ *ident) \f[] .fi .SH DESCRIPTION .PP Loads an audio file from an ALLEGRO_FILE(3) stream into an ALLEGRO_SAMPLE(3). The file type is determined by the passed \[aq]ident\[aq] parameter, which is a file name extension including the leading dot. .PP Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream_f(3). .PP Returns the sample on success, NULL on failure. The file remains open afterwards. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_register_sample_loader_f(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/ALLEGRO_BITMAP.30000644000175000001440000000043112157230672016321 0ustar tjadenusers.TH ALLEGRO_BITMAP 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_BITMAP \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_BITMAP\ ALLEGRO_BITMAP; \f[] .fi .SH DESCRIPTION .PP Abstract type representing a bitmap (2D image). allegro-5.0.10/docs/man/al_ustr_get.30000644000175000001440000000105312157230676016515 0ustar tjadenusers.TH al_ustr_get 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_get \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int32_t\ al_ustr_get(const\ ALLEGRO_USTR\ *ub,\ int\ pos) \f[] .fi .SH DESCRIPTION .PP Return the code point in \f[C]us\f[] beginning at byte offset \f[C]pos\f[]. .PP On success returns the code point value. If \f[C]pos\f[] was out of bounds (e.g. past the end of the string), return \-1. On an error, such as an invalid byte sequence, return \-2. .SH SEE ALSO .PP al_ustr_get_next(3), al_ustr_prev_get(3) allegro-5.0.10/docs/man/al_load_ttf_font_stretch_f.30000644000175000001440000000136512157230700021536 0ustar tjadenusers.TH al_load_ttf_font_stretch_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_ttf_font_stretch_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_ttf_font_stretch_f(ALLEGRO_FILE\ *file, \ \ \ \ char\ const\ *filename,\ int\ w,\ int\ h,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_load_ttf_font_stretch(3), but the font is read from the file handle. The filename is only used to find possible additional files next to a font file. .RS .PP \f[I]Note:\f[] The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time. .RE .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_load_ttf_font_stretch(3) allegro-5.0.10/docs/man/al_ustr_has_prefix.30000644000175000001440000000061312157230677020070 0ustar tjadenusers.TH al_ustr_has_prefix 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_has_prefix \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_has_prefix(const\ ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Returns true iff \f[C]us1\f[] begins with \f[C]us2\f[]. .SH SEE ALSO .PP al_ustr_has_prefix_cstr(3), al_ustr_has_suffix(3) allegro-5.0.10/docs/man/al_fixtoi.30000644000175000001440000000120312157230671016153 0ustar tjadenusers.TH al_fixtoi 3 "" "Allegro reference manual" .SH NAME .PP al_fixtoi \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fixtoi(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP Converts fixed point to integer, rounding as required to the nearest integer. .PP Example: .IP .nf \f[C] \ \ \ \ int\ result; \ \ \ \ /*\ This\ will\ put\ 33\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixtoi(al_itofix(100)\ /\ 3); \ \ \ \ /*\ But\ this\ will\ round\ up\ to\ 17.\ */ \ \ \ \ result\ =\ al_fixtoi(al_itofix(100)\ /\ 6); \f[] .fi .SH SEE ALSO .PP al_itofix(3), al_ftofix(3), al_fixtof(3), al_fixfloor(3), al_fixceil(3). allegro-5.0.10/docs/man/ALLEGRO_FONT.30000644000175000001440000000113012157230677016115 0ustar tjadenusers.TH ALLEGRO_FONT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FONT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FONT\ ALLEGRO_FONT; \f[] .fi .SH DESCRIPTION .PP A handle identifying any kind of font. Usually you will create it with al_load_font(3) which supports loading all kinds of TrueType fonts supported by the FreeType library. If you instead pass the filename of a bitmap file, it will be loaded with al_load_bitmap(3) and a font in Allegro\[aq]s bitmap font format will be created from it with al_grab_font_from_bitmap(3). allegro-5.0.10/docs/man/al_draw_tinted_scaled_rotated_bitmap.30000644000175000001440000000110712157230673023553 0ustar tjadenusers.TH al_draw_tinted_scaled_rotated_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_scaled_rotated_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ ALLEGRO_COLOR\ tint, \ \ \ float\ cx,\ float\ cy,\ float\ dx,\ float\ dy,\ float\ xscale,\ float\ yscale, \ \ \ float\ angle,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_scaled_rotated_bitmap(3) but multiplies all colors in the bitmap with the given color. .SH SEE ALSO .PP al_draw_tinted_bitmap(3) allegro-5.0.10/docs/man/al_ustr_size.30000644000175000001440000000065012157230676016712 0ustar tjadenusers.TH al_ustr_size 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_size \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_size(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Return the size of the string in bytes. This is equal to the number of code points in the string if the string is empty or contains only 7\-bit ASCII characters. .SH SEE ALSO .PP al_ustr_length(3) allegro-5.0.10/docs/man/al_is_system_installed.30000644000175000001440000000045412157230674020741 0ustar tjadenusers.TH al_is_system_installed 3 "" "Allegro reference manual" .SH NAME .PP al_is_system_installed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_system_installed(void) \f[] .fi .SH DESCRIPTION .PP Returns true if Allegro is initialized, otherwise returns false. allegro-5.0.10/docs/man/al_run_detached_thread.30000644000175000001440000000111612157230674020633 0ustar tjadenusers.TH al_run_detached_thread 3 "" "Allegro reference manual" .SH NAME .PP al_run_detached_thread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_run_detached_thread(void\ *(*proc)(void\ *arg),\ void\ *arg) \f[] .fi .SH DESCRIPTION .PP Runs the passed function in its own thread, with \f[C]arg\f[] passed to it as only parameter. This is similar to calling al_create_thread(3), al_start_thread(3) and (after the thread has finished) al_destroy_thread(3) \- but you don\[aq]t have the possibility of ever calling al_join_thread(3) on the thread any longer. allegro-5.0.10/docs/man/al_ustr_ltrim_ws.30000644000175000001440000000066412157230676017605 0ustar tjadenusers.TH al_ustr_ltrim_ws 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_ltrim_ws \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_ltrim_ws(ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Remove leading whitespace characters from a string, as defined by the C function \f[C]isspace()\f[]. .PP Returns true on success, or false on error. .SH SEE ALSO .PP al_ustr_rtrim_ws(3), al_ustr_trim_ws(3) allegro-5.0.10/docs/man/ALLEGRO_BPM_TO_SECS.30000644000175000001440000000044512157230674017211 0ustar tjadenusers.TH ALLEGRO_BPM_TO_SECS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_BPM_TO_SECS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_BPM_TO_SECS(x)\ \ \ \ \ \ \ \ (60.0\ /\ (x)) \f[] .fi .SH DESCRIPTION .PP Convert beats per minute to seconds. allegro-5.0.10/docs/man/al_load_config_file.30000644000175000001440000000071012157230670020115 0ustar tjadenusers.TH al_load_config_file 3 "" "Allegro reference manual" .SH NAME .PP al_load_config_file \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CONFIG\ *al_load_config_file(const\ char\ *filename) \f[] .fi .SH DESCRIPTION .PP Read a configuration file from disk. Returns NULL on error. The configuration structure should be destroyed with al_destroy_config(3). .SH SEE ALSO .PP al_load_config_file_f(3), al_save_config_file(3) allegro-5.0.10/docs/man/al_color_rgb_to_name.30000644000175000001440000000065712157230677020345 0ustar tjadenusers.TH al_color_rgb_to_name 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ const\ *al_color_rgb_to_name(float\ r,\ float\ g,\ float\ b) \f[] .fi .SH DESCRIPTION .PP Given an RGB triplet with components in the range 0..1, find a color name describing it approximately. .SH SEE ALSO .PP al_color_name_to_rgb(3), al_color_name(3) allegro-5.0.10/docs/man/al_remove_fs_entry.30000644000175000001440000000072712157230672020072 0ustar tjadenusers.TH al_remove_fs_entry 3 "" "Allegro reference manual" .SH NAME .PP al_remove_fs_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_remove_fs_entry(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Delete this filesystem entry from the filesystem. Only files and empty directories may be deleted. .PP Returns true on success, and false on failure, error is indicated in Allegro\[aq]s errno. .SH SEE ALSO .PP al_filename_exists(3) allegro-5.0.10/docs/man/al_unmap_rgb_f.30000644000175000001440000000066212157230672017141 0ustar tjadenusers.TH al_unmap_rgb_f 3 "" "Allegro reference manual" .SH NAME .PP al_unmap_rgb_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unmap_rgb_f(ALLEGRO_COLOR\ color,\ float\ *r,\ float\ *g,\ float\ *b) \f[] .fi .SH DESCRIPTION .PP Retrieves components of an ALLEGRO_COLOR(3), ignoring alpha. Components will range from 0.0f\-1.0f. .SH SEE ALSO .PP al_unmap_rgba(3), al_unmap_rgb(3), al_unmap_rgba_f(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_ORIENTATION.30000644000175000001440000002700512157230671021273 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_attach_audio_stream_to_voice.30000644000175000001440000000162412157230677022555 0ustar tjadenusers.TH al_attach_audio_stream_to_voice 3 "" "Allegro reference manual" .SH NAME .PP al_attach_audio_stream_to_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM\ *stream, \ \ \ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Attaches an audio stream to a voice. The same rules as al_attach_sample_instance_to_voice(3) apply. This may fail if the driver can\[aq]t create a voice with the buffer count and buffer size the stream uses. .PP An audio stream attached directly to a voice has a number of limitations. The audio stream plays immediately and cannot be stopped. The stream position, speed, gain, panning, cannot be changed. At this time, we don\[aq]t recommend attaching audio streams directly to voices. Use a mixer in between. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_detach_voice(3) allegro-5.0.10/docs/man/al_get_joystick_num_axes.30000644000175000001440000000063512157230673021260 0ustar tjadenusers.TH al_get_joystick_num_axes 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_num_axes \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_joystick_num_axes(ALLEGRO_JOYSTICK\ *joy,\ int\ stick) \f[] .fi .SH DESCRIPTION .PP Return the number of axes on the given "stick". If the stick doesn\[aq]t exist, 0 is returned. .SH SEE ALSO .PP al_get_joystick_num_sticks(3) allegro-5.0.10/docs/man/al_get_sample_instance_length.30000644000175000001440000000067412157230677022237 0ustar tjadenusers.TH al_get_sample_instance_length 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_length \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_sample_instance_length(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the length of the sample instance in sample values. .SH SEE ALSO .PP al_set_sample_instance_length(3), al_get_sample_instance_time(3) allegro-5.0.10/docs/man/al_fixatan2.30000644000175000001440000000221012157230671016364 0ustar tjadenusers.TH al_fixatan2 3 "" "Allegro reference manual" .SH NAME .PP al_fixatan2 \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixatan2(al_fixed\ y,\ al_fixed\ x) \f[] .fi .SH DESCRIPTION .PP This is a fixed point version of the libc atan2() routine. It computes the arc tangent of \f[C]y\ /\ x\f[], but the signs of both arguments are used to determine the quadrant of the result, and \f[C]x\f[] is permitted to be zero. This function is useful to convert Cartesian coordinates to polar coordinates. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ Sets\ `result\[aq]\ to\ binary\ angle\ 64.\ */ \ \ \ \ result\ =\ al_fixatan2(al_itofix(1),\ 0); \ \ \ \ /*\ Sets\ `result\[aq]\ to\ binary\ angle\ \-109.\ */ \ \ \ \ result\ =\ al_fixatan2(al_itofix(\-1),\ al_itofix(\-2)); \ \ \ \ /*\ Fails\ the\ assert.\ */ \ \ \ \ result\ =\ al_fixatan2(0,\ 0); \ \ \ \ assert(!al_get_errno()); \f[] .fi .SH RETURN VALUE .PP Returns the arc tangent of \f[C]y\ /\ x\f[] in fixed point binary format angle, from \-128 to 128. If both \f[C]x\f[] and \f[C]y\f[] are zero, returns zero and sets Allegro\[aq]s errno to EDOM. allegro-5.0.10/docs/man/al_get_display_width.30000644000175000001440000000055012157230670020357 0ustar tjadenusers.TH al_get_display_width 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_width(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Gets the width of the display. This is like SCREEN_W in Allegro 4.x. .SH SEE ALSO .PP al_get_display_height(3) allegro-5.0.10/docs/man/al_is_compatible_bitmap.30000644000175000001440000000202612157230673021025 0ustar tjadenusers.TH al_is_compatible_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_is_compatible_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_compatible_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each ALLEGRO_BITMAP(3) created with al_create_bitmap(3) however is usually tied to a single ALLEGRO_DISPLAY. This function can be used to know if the bitmap is compatible with the given display, even if it is a different display to the one it was created with. It returns true if the bitmap is compatible (things like a cached texture version can be used) and false otherwise (blitting in the current display will be slow). .PP The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both. .PP Returns true if the bitmap is compatible with the current display, false otherwise. If there is no current display, false is returned. allegro-5.0.10/docs/man/ALLEGRO_MSECS_TO_SECS.30000644000175000001440000000044512157230674017445 0ustar tjadenusers.TH ALLEGRO_MSECS_TO_SECS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MSECS_TO_SECS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_MSECS_TO_SECS(x)\ \ \ \ \ \ ((x)\ /\ 1000.0) \f[] .fi .SH DESCRIPTION .PP Convert milliseconds to seconds. allegro-5.0.10/docs/man/al_create_native_file_dialog.30000644000175000001440000000427712157230700022007 0ustar tjadenusers.TH al_create_native_file_dialog 3 "" "Allegro reference manual" .SH NAME .PP al_create_native_file_dialog \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILECHOOSER\ *al_create_native_file_dialog( \ \ \ char\ const\ *initial_path, \ \ \ char\ const\ *title, \ \ \ char\ const\ *patterns, \ \ \ int\ mode) \f[] .fi .SH DESCRIPTION .PP Creates a new native file dialog. You should only have one such dialog opened at a time. .PP Parameters: .IP \[bu] 2 initial_path: The initial search path and filename. Can be NULL. To start with a blank file name the string should end with a directory separator (this should be the common case). .IP \[bu] 2 title: Title of the dialog. .IP \[bu] 2 patterns: A list of semi\-colon separated patterns to match. You should always include the pattern "*.*" as usually the MIME type and not the file pattern is relevant. If no file patterns are supported by the native dialog, this parameter is ignored. .IP \[bu] 2 mode: 0, or a combination of the flags below. .PP Possible flags for the \[aq]flags\[aq] parameter are: .TP .B ALLEGRO_FILECHOOSER_FILE_MUST_EXIST If supported by the native dialog, it will not allow entering new names, but just allow existing files to be selected. Else it is ignored. .RS .RE .TP .B ALLEGRO_FILECHOOSER_SAVE If the native dialog system has a different dialog for saving (for example one which allows creating new directories), it is used. Else ignored. .RS .RE .TP .B ALLEGRO_FILECHOOSER_FOLDER If there is support for a separate dialog to select a folder instead of a file, it will be used. .RS .RE .TP .B ALLEGRO_FILECHOOSER_PICTURES If a different dialog is available for selecting pictures, it is used. Else ignored. .RS .RE .TP .B ALLEGRO_FILECHOOSER_SHOW_HIDDEN If the platform supports it, also hidden files will be shown. .RS .RE .TP .B ALLEGRO_FILECHOOSER_MULTIPLE If supported, allow selecting multiple files. .RS .RE .PP Returns: .PP A handle to the dialog which you can pass to al_show_native_file_dialog(3) to display it, and from which you then can query the results. When you are done, call al_destroy_native_file_dialog(3) on it. .PP If a dialog window could not be created then this function returns NULL. allegro-5.0.10/docs/man/al_get_opengl_fbo.30000644000175000001440000000155112157230676017635 0ustar tjadenusers.TH al_get_opengl_fbo 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_fbo \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ GLuint\ al_get_opengl_fbo(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the OpenGL FBO id internally used by the given bitmap if it uses one, otherwise returns zero. No attempt will be made to create an FBO if the bitmap is not owned by the current display. .PP The FBO returned by this function will only be freed when the bitmap is destroyed, or if you call al_remove_opengl_fbo(3) on the bitmap. .RS .PP \f[I]Note:\f[] In Allegro 5.0.0 this function only returned an FBO which had previously been created by calling al_set_target_bitmap(3). It would not attempt to create an FBO itself. This has since been changed. .RE .SH SEE ALSO .PP al_remove_opengl_fbo(3), al_set_target_bitmap(3) allegro-5.0.10/docs/man/al_get_display_flags.30000644000175000001440000000131512157230670020334 0ustar tjadenusers.TH al_get_display_flags 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_flags(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Gets the flags of the display. .PP In addition to the flags set for the display at creation time with al_set_new_display_flags(3) it can also have the ALLEGRO_MINIMIZED flag set, indicating that the window is currently minimized. This flag is very platform\-dependent as even a minimized application may still render a preview version so normally you should not care whether it is minimized or not. .SH SEE ALSO .PP al_set_new_display_flags(3), al_set_display_flag(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_TYPE.30000644000175000001440000000061212157230672017070 0ustar tjadenusers.TH ALLEGRO_EVENT_TYPE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT_TYPE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ unsigned\ int\ ALLEGRO_EVENT_TYPE; \f[] .fi .SH DESCRIPTION .PP An integer used to distinguish between different types of events. .SH SEE ALSO .PP ALLEGRO_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3), ALLEGRO_EVENT_TYPE_IS_USER(3) allegro-5.0.10/docs/man/al_create_path_for_directory.30000644000175000001440000000075112157230673022073 0ustar tjadenusers.TH al_create_path_for_directory 3 "" "Allegro reference manual" .SH NAME .PP al_create_path_for_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PATH\ *al_create_path_for_directory(const\ char\ *str) \f[] .fi .SH DESCRIPTION .PP This is the same as al_create_path(3), but interprets the passed string as a directory path. The filename component of the returned path will always be empty. .SH SEE ALSO .PP al_create_path(3), al_destroy_path(3) allegro-5.0.10/docs/man/al_start_thread.30000644000175000001440000000071612157230674017350 0ustar tjadenusers.TH al_start_thread 3 "" "Allegro reference manual" .SH NAME .PP al_start_thread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_start_thread(ALLEGRO_THREAD\ *thread) \f[] .fi .SH DESCRIPTION .PP When a thread is created, it is initially in a suspended state. Calling al_start_thread(3) will start its actual execution. .PP Starting a thread which has already been started does nothing. .SH SEE ALSO .PP al_create_thread(3). allegro-5.0.10/docs/man/al_get_display_format.30000644000175000001440000000051312157230670020527 0ustar tjadenusers.TH al_get_display_format 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_format \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_format(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Gets the pixel format of the display. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3) allegro-5.0.10/docs/man/al_is_event_queue_empty.30000644000175000001440000000057712157230672021125 0ustar tjadenusers.TH al_is_event_queue_empty 3 "" "Allegro reference manual" .SH NAME .PP al_is_event_queue_empty \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE\ *queue) \f[] .fi .SH DESCRIPTION .PP Return true if the event queue specified is currently empty. .SH SEE ALSO .PP al_get_next_event(3), al_peek_next_event(3) allegro-5.0.10/docs/man/al_draw_filled_rounded_rectangle.30000644000175000001440000000124212157230700022665 0ustar tjadenusers.TH al_draw_filled_rounded_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_rounded_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_rounded_rectangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ float\ rx,\ float\ ry,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws an filled rounded rectangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2 \- Upper left and lower right points of the rectangle .IP \[bu] 2 color \- Color of the rectangle .IP \[bu] 2 rx, ry \- The radii of the round .SH SEE ALSO .PP al_draw_rounded_rectangle(3), al_draw_filled_rectangle(3) allegro-5.0.10/docs/man/al_unregister_event_source.30000644000175000001440000000115112157230672021624 0ustar tjadenusers.TH al_unregister_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_unregister_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unregister_event_source(ALLEGRO_EVENT_QUEUE\ *queue, \ \ \ ALLEGRO_EVENT_SOURCE\ *source) \f[] .fi .SH DESCRIPTION .PP Unregister an event source with an event queue. If the event source is not actually registered with the event queue, nothing happens. .PP If the queue had any events in it which originated from the event source, they will no longer be in the queue after this call. .SH SEE ALSO .PP al_register_event_source(3) allegro-5.0.10/docs/man/al_peek_next_event.30000644000175000001440000000120512157230672020037 0ustar tjadenusers.TH al_peek_next_event 3 "" "Allegro reference manual" .SH NAME .PP al_peek_next_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_peek_next_event(ALLEGRO_EVENT_QUEUE\ *queue,\ ALLEGRO_EVENT\ *ret_event) \f[] .fi .SH DESCRIPTION .PP Copy the contents of the next event in the event queue specified into \f[C]ret_event\f[] and return true. The original event packet will remain at the head of the queue. If the event queue is actually empty, this function returns false and the contents of \f[C]ret_event\f[] are unspecified. .SH SEE ALSO .PP ALLEGRO_EVENT(3), al_get_next_event(3), al_drop_next_event(3) allegro-5.0.10/docs/man/al_destroy_mixer.30000644000175000001440000000045712157230700017551 0ustar tjadenusers.TH al_destroy_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_mixer(ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Destroys the mixer stream. .SH SEE ALSO .PP al_create_mixer(3) allegro-5.0.10/docs/man/al_get_joystick_button_name.30000644000175000001440000000077512157230673021761 0ustar tjadenusers.TH al_get_joystick_button_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_button_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_joystick_button_name(ALLEGRO_JOYSTICK\ *joy,\ int\ button) \f[] .fi .SH DESCRIPTION .PP Return the name of the given button. If the button doesn\[aq]t exist, NULL is returned. Indices begin from 0. .SH SEE ALSO .PP al_get_joystick_stick_name(3), al_get_joystick_axis_name(3), al_get_joystick_num_buttons(3) allegro-5.0.10/docs/man/al_set_mouse_axis.30000644000175000001440000000077212157230674017715 0ustar tjadenusers.TH al_set_mouse_axis 3 "" "Allegro reference manual" .SH NAME .PP al_set_mouse_axis \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mouse_axis(int\ which,\ int\ value) \f[] .fi .SH DESCRIPTION .PP Set the given mouse axis to the given value. .PP The axis number must not be 0 or 1, which are the X and Y axes. Use al_set_mouse_xy(3) for that. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_mouse_xy(3), al_set_mouse_z(3), al_set_mouse_w(3) allegro-5.0.10/docs/man/ALLEGRO_VOICE.30000644000175000001440000000101412157230676016214 0ustar tjadenusers.TH ALLEGRO_VOICE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_VOICE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_VOICE\ ALLEGRO_VOICE; \f[] .fi .SH DESCRIPTION .PP A voice represents an audio device on the system, which may be a real device, or an abstract device provided by the operating system. To play back audio, you would attach a mixer or sample or stream to a voice. .SH SEE ALSO .PP ALLEGRO_MIXER(3), ALLEGRO_SAMPLE(3), ALLEGRO_AUDIO_STREAM(3) allegro-5.0.10/docs/man/al_load_bitmap_font.30000644000175000001440000000104412157230700020146 0ustar tjadenusers.TH al_load_bitmap_font 3 "" "Allegro reference manual" .SH NAME .PP al_load_bitmap_font \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_bitmap_font(const\ char\ *fname) \f[] .fi .SH DESCRIPTION .PP Load a bitmap font from. It does this by first calling al_load_bitmap(3) and then al_grab_font_from_bitmap(3). If you want to for example load an old A4 font, you could load the bitmap yourself, then call al_convert_mask_to_alpha(3) on it and only then pass it to al_grab_font_from_bitmap(3). allegro-5.0.10/docs/man/al_draw_tinted_scaled_bitmap.30000644000175000001440000000105012157230673022026 0ustar tjadenusers.TH al_draw_tinted_scaled_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_scaled_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ ALLEGRO_COLOR\ tint, \ \ \ float\ sx,\ float\ sy,\ float\ sw,\ float\ sh, \ \ \ float\ dx,\ float\ dy,\ float\ dw,\ float\ dh,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_scaled_bitmap(3) but multiplies all colors in the bitmap with the given color. .SH SEE ALSO .PP al_draw_tinted_bitmap(3) allegro-5.0.10/docs/man/al_ustr_has_suffix.30000644000175000001440000000061112157230677020075 0ustar tjadenusers.TH al_ustr_has_suffix 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_has_suffix \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_has_suffix(const\ ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Returns true iff \f[C]us1\f[] ends with \f[C]us2\f[]. .SH SEE ALSO .PP al_ustr_has_suffix_cstr(3), al_ustr_has_prefix(3) allegro-5.0.10/docs/man/al_malloc_with_context.30000644000175000001440000000073412157230673020731 0ustar tjadenusers.TH al_malloc_with_context 3 "" "Allegro reference manual" .SH NAME .PP al_malloc_with_context \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_malloc_with_context(size_t\ n, \ \ \ int\ line,\ const\ char\ *file,\ const\ char\ *func) \f[] .fi .SH DESCRIPTION .PP This calls malloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface(3), .PP Generally you should use the al_malloc(3) macro. allegro-5.0.10/docs/man/al_fgetc.30000644000175000001440000000051412157230671015745 0ustar tjadenusers.TH al_fgetc 3 "" "Allegro reference manual" .SH NAME .PP al_fgetc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fgetc(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Read and return next byte in the given file. Returns EOF on end of file or if an error occurred. .SH SEE ALSO .PP al_fungetc(3) allegro-5.0.10/docs/man/al_get_new_display_option.30000644000175000001440000000055312157230670021424 0ustar tjadenusers.TH al_get_new_display_option 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_display_option \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_display_option(int\ option,\ int\ *importance) \f[] .fi .SH DESCRIPTION .PP Retrieve an extra display setting which was previously set with al_set_new_display_option(3). allegro-5.0.10/docs/man/al_detach_mixer.30000644000175000001440000000053212157230700017302 0ustar tjadenusers.TH al_detach_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_detach_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_detach_mixer(ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Detach the mixer from whatever it is attached to, if anything. .SH SEE ALSO .PP al_attach_mixer_to_mixer(3). allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_SWITCH_IN.30000644000175000001440000002700512157230671021067 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_set_audio_stream_loop_secs.30000644000175000001440000000103612157230701022244 0ustar tjadenusers.TH al_set_audio_stream_loop_secs 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_loop_secs \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM\ *stream, \ \ \ double\ start,\ double\ end) \f[] .fi .SH DESCRIPTION .PP Sets the loop points for the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream(3), al_load_audio_stream_f(3) and the format\-specific functions underlying those functions. allegro-5.0.10/docs/man/al_set_sample_instance_length.30000644000175000001440000000101012157230677022234 0ustar tjadenusers.TH al_set_sample_instance_length 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_length \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE\ *spl, \ \ \ unsigned\ int\ val) \f[] .fi .SH DESCRIPTION .PP Set the length of the sample instance in sample values. .PP Return true on success, false on failure. Will fail if the sample instance is currently playing. .SH SEE ALSO .PP al_get_sample_instance_length(3) allegro-5.0.10/docs/man/al_draw_filled_rectangle.30000644000175000001440000000107412157230700021150 0ustar tjadenusers.TH al_draw_filled_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_rectangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a filled rectangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2 \- Upper left and lower right points of the rectangle .IP \[bu] 2 color \- Color of the rectangle .SH SEE ALSO .PP al_draw_rectangle(3), al_draw_filled_rounded_rectangle(3) allegro-5.0.10/docs/man/al_get_new_display_adapter.30000644000175000001440000000075612157230673021544 0ustar tjadenusers.TH al_get_new_display_adapter 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_display_adapter \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_display_adapter(void) \f[] .fi .SH DESCRIPTION .PP Gets the video adapter index where new displays will be created by the calling thread, if previously set with al_set_new_display_adapter(3). Otherwise returns \f[C]ALLEGRO_DEFAULT_DISPLAY_ADAPTER\f[]. .SH SEE ALSO .PP al_set_new_display_adapter(3) allegro-5.0.10/docs/man/al_ustr_rtrim_ws.30000644000175000001440000000067712157230676017617 0ustar tjadenusers.TH al_ustr_rtrim_ws 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_rtrim_ws \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_rtrim_ws(ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Remove trailing ("right") whitespace characters from a string, as defined by the C function \f[C]isspace()\f[]. .PP Returns true on success, or false on error. .SH SEE ALSO .PP al_ustr_ltrim_ws(3), al_ustr_trim_ws(3) allegro-5.0.10/docs/man/al_save_sample.30000644000175000001440000000125312157230702017150 0ustar tjadenusers.TH al_save_sample 3 "" "Allegro reference manual" .SH NAME .PP al_save_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_sample(const\ char\ *filename,\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Writes a sample into a file. Currently, wav is the only supported format, and the extension must be ".wav". .PP Returns true on success, false on error. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_save_sample_f(3), al_register_sample_saver(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_create_sub_bitmap.30000644000175000001440000000200612157230673020325 0ustar tjadenusers.TH al_create_sub_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_create_sub_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_create_sub_bitmap(ALLEGRO_BITMAP\ *parent, \ \ \ int\ x,\ int\ y,\ int\ w,\ int\ h) \f[] .fi .SH DESCRIPTION .PP Creates a sub\-bitmap of the parent, at the specified coordinates and of the specified size. A sub\-bitmap is a bitmap that shares drawing memory with a pre\-existing (parent) bitmap, but possibly with a different size and clipping settings. .PP The sub\-bitmap may originate off or extend past the parent bitmap. .PP See the discussion in al_get_backbuffer(3) about using sub\-bitmaps of the backbuffer. .PP The parent bitmap\[aq]s clipping rectangles are ignored. .PP If a sub\-bitmap was not or cannot be created then NULL is returned. .PP Note that destroying parents of sub\-bitmaps will not destroy the sub\-bitmaps; instead the sub\-bitmaps become invalid and should no longer be used. .SH SEE ALSO .PP al_create_bitmap(3) allegro-5.0.10/docs/man/al_set_mouse_cursor.30000644000175000001440000000115312157230674020260 0ustar tjadenusers.TH al_set_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_set_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mouse_cursor(ALLEGRO_DISPLAY\ *display,\ ALLEGRO_MOUSE_CURSOR\ *cursor) \f[] .fi .SH DESCRIPTION .PP Set the given mouse cursor to be the current mouse cursor for the given display. .PP If the cursor is currently \[aq]shown\[aq] (as opposed to \[aq]hidden\[aq]) the change is immediately visible. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_system_mouse_cursor(3), al_show_mouse_cursor(3), al_hide_mouse_cursor(3) allegro-5.0.10/docs/man/al_get_path_tail.30000644000175000001440000000051312157230674017463 0ustar tjadenusers.TH al_get_path_tail 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_tail \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_tail(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Returns the last directory component, or NULL if there are no directory components. allegro-5.0.10/docs/man/ALLEGRO_PLAYMODE.30000644000175000001440000000054112157230676016565 0ustar tjadenusers.TH ALLEGRO_PLAYMODE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PLAYMODE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ ALLEGRO_PLAYMODE \f[] .fi .SH DESCRIPTION .PP Sample and stream playback mode. .IP \[bu] 2 ALLEGRO_PLAYMODE_ONCE .IP \[bu] 2 ALLEGRO_PLAYMODE_LOOP .IP \[bu] 2 ALLEGRO_PLAYMODE_BIDIR allegro-5.0.10/docs/man/al_map_rgba_f.30000644000175000001440000000060512157230672016734 0ustar tjadenusers.TH al_map_rgba_f 3 "" "Allegro reference manual" .SH NAME .PP al_map_rgba_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_map_rgba_f(float\ r,\ float\ g,\ float\ b,\ float\ a) \f[] .fi .SH DESCRIPTION .PP Convert r, g, b, a (ranging from 0.0f\-1.0f) into an ALLEGRO_COLOR(3). .SH SEE ALSO .PP al_map_rgba(3), al_map_rgb(3), al_map_rgb_f(3) allegro-5.0.10/docs/man/al_get_sample_frequency.30000644000175000001440000000065312157230677021070 0ustar tjadenusers.TH al_get_sample_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_sample_frequency(const\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the frequency of the sample. .SH SEE ALSO .PP al_get_sample_channels(3), al_get_sample_depth(3), al_get_sample_length(3), al_get_sample_data(3) allegro-5.0.10/docs/man/al_get_display_refresh_rate.30000644000175000001440000000055012157230670021711 0ustar tjadenusers.TH al_get_display_refresh_rate 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_refresh_rate \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_refresh_rate(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Gets the refresh rate of the display. .SH SEE ALSO .PP al_set_new_display_refresh_rate(3) allegro-5.0.10/docs/man/al_register_bitmap_loader_f.30000644000175000001440000000144612157230674021700 0ustar tjadenusers.TH al_register_bitmap_loader_f 3 "" "Allegro reference manual" .SH NAME .PP al_register_bitmap_loader_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_bitmap_loader_f(const\ char\ *extension, \ \ \ ALLEGRO_BITMAP\ *(*loader_f)(ALLEGRO_FILE\ *fp)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_bitmap_f(3). The given function will be used to handle the loading of bitmaps files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]fs_loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_bitmap_loader(3) allegro-5.0.10/docs/man/al_load_config_file_f.30000644000175000001440000000074712157230670020434 0ustar tjadenusers.TH al_load_config_file_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_config_file_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CONFIG\ *al_load_config_file_f(ALLEGRO_FILE\ *file) \f[] .fi .SH DESCRIPTION .PP Read a configuration file from an already open file. .PP Returns NULL on error. The configuration structure should be destroyed with al_destroy_config(3). The file remains open afterwards. .SH SEE ALSO .PP al_load_config_file(3) allegro-5.0.10/docs/man/ALLEGRO_FILE_MODE.30000644000175000001440000000103012157230672016664 0ustar tjadenusers.TH ALLEGRO_FILE_MODE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FILE_MODE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ enum\ ALLEGRO_FILE_MODE \f[] .fi .SH DESCRIPTION .PP Filesystem modes/types .IP \[bu] 2 ALLEGRO_FILEMODE_READ \- Readable .IP \[bu] 2 ALLEGRO_FILEMODE_WRITE \- Writable .IP \[bu] 2 ALLEGRO_FILEMODE_EXECUTE \- Executable .IP \[bu] 2 ALLEGRO_FILEMODE_HIDDEN \- Hidden .IP \[bu] 2 ALLEGRO_FILEMODE_ISFILE \- Regular file .IP \[bu] 2 ALLEGRO_FILEMODE_ISDIR \- Directory allegro-5.0.10/docs/man/al_init_acodec_addon.30000644000175000001440000000210612157230676020267 0ustar tjadenusers.TH al_init_acodec_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_acodec_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_init_acodec_addon(void) \f[] .fi .SH DESCRIPTION .PP This function registers all the known audio file type handlers for al_load_sample(3), al_save_sample(3), al_load_audio_stream(3), etc. .PP Depending on what libraries are available, the full set of recognised extensions is: .wav, .flac, .ogg, .it, .mod, .s3m, .xm. .PP \f[I]Limitations:\f[] .IP \[bu] 2 Saving is only supported for wav files. .IP \[bu] 2 Wav file loader currently only supports 8/16 bit little endian PCM files. 16 bits are used when saving wav files. Use flac files if more precision is required. .IP \[bu] 2 Module files (.it, .mod, .s3m, .xm) are often composed with streaming in mind, and sometimes cannot be easily rendered into a finite length sample. Therefore they cannot be loaded with al_load_sample(3)/al_load_sample_f(3) and must be streamed with al_load_audio_stream(3) or al_load_audio_stream_f(3). .PP Return true on success. allegro-5.0.10/docs/man/al_create_vertex_decl.30000644000175000001440000000125312157230700020476 0ustar tjadenusers.TH al_create_vertex_decl 3 "" "Allegro reference manual" .SH NAME .PP al_create_vertex_decl \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_VERTEX_DECL*\ al_create_vertex_decl(const\ ALLEGRO_VERTEX_ELEMENT*\ elements,\ int\ stride) \f[] .fi .SH DESCRIPTION .PP Creates a vertex declaration, which describes a custom vertex format. .PP \f[I]Parameters:\f[] .IP \[bu] 2 elements \- An array of ALLEGRO_VERTEX_ELEMENT structures. .IP \[bu] 2 stride \- Size of the custom vertex structure .PP \f[I]Returns:\f[] Newly created vertex declaration. .SH SEE ALSO .PP ALLEGRO_VERTEX_ELEMENT(3), ALLEGRO_VERTEX_DECL(3), al_destroy_vertex_decl(3) allegro-5.0.10/docs/man/al_fixtan.30000644000175000001440000000152112157230671016145 0ustar tjadenusers.TH al_fixtan 3 "" "Allegro reference manual" .SH NAME .PP al_fixtan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixtan(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP This function finds the tangent of a value using a lookup table. The input value must be a fixed point binary angle. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ angle,\ res_a,\ res_b; \ \ \ \ float\ dif; \ \ \ \ angle\ =\ al_itofix(37); \ \ \ \ /*\ Prove\ that\ tan(angle)\ ==\ sin(angle)\ /\ cos(angle).\ */ \ \ \ \ res_a\ =\ al_fixdiv(al_fixsin(angle),\ al_fixcos(angle)); \ \ \ \ res_b\ =\ al_fixtan(angle); \ \ \ \ dif\ =\ al_fixtof(al_fixsub(res_a,\ res_b)); \ \ \ \ printf("Precision\ error:\ %f\\n",\ dif); \f[] .fi .SH RETURN VALUE .PP Returns the tangent of a fixed point binary format angle. The return value will be in radians. allegro-5.0.10/docs/man/al_create_event_queue.30000644000175000001440000000067512157230672020536 0ustar tjadenusers.TH al_create_event_queue 3 "" "Allegro reference manual" .SH NAME .PP al_create_event_queue \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_QUEUE\ *al_create_event_queue(void) \f[] .fi .SH DESCRIPTION .PP Create a new, empty event queue, returning a pointer to object if successful. Returns NULL on error. .SH SEE ALSO .PP al_register_event_source(3), al_destroy_event_queue(3), ALLEGRO_EVENT_QUEUE(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_JOYSTICK_BUTTON_UP.30000644000175000001440000002700512157230670021250 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_append_native_text_log.30000644000175000001440000000122712157230700021372 0ustar tjadenusers.TH al_append_native_text_log 3 "" "Allegro reference manual" .SH NAME .PP al_append_native_text_log \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_append_native_text_log(ALLEGRO_TEXTLOG\ *textlog, \ \ \ char\ const\ *format,\ ...) \f[] .fi .SH DESCRIPTION .PP Appends a line of text to the message log window and scrolls to the bottom (if the line would not be visible otherwise). This works like printf. A line is continued until you add a newline character. .PP If the window is NULL then this function will fall back to calling printf. This makes it convenient to support logging to a window or a terminal. allegro-5.0.10/docs/man/al_get_d3d_video_texture.30000644000175000001440000000077512157230676021152 0ustar tjadenusers.TH al_get_d3d_video_texture 3 "" "Allegro reference manual" .SH NAME .PP al_get_d3d_video_texture \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ LPDIRECT3DTEXTURE9\ al_get_d3d_video_texture(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the video texture (stored with the D3DPOOL_DEFAULT or D3DPOOL_MANAGED flags depending on whether render\-to\-texture is enabled or disabled respectively). .PP \f[I]Returns:\f[] A pointer to the Direct3D video texture. allegro-5.0.10/docs/man/al_create_mutex_recursive.30000644000175000001440000000131712157230674021436 0ustar tjadenusers.TH al_create_mutex_recursive 3 "" "Allegro reference manual" .SH NAME .PP al_create_mutex_recursive \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MUTEX\ *al_create_mutex_recursive(void) \f[] .fi .SH DESCRIPTION .PP Create the mutex object (a mutual exclusion device), with support for "recursive" locking. That is, the mutex will count the number of times it has been locked by the same thread. If the caller tries to acquire a lock on the mutex when it already holds the lock then the count is incremented. The mutex is only unlocked when the thread releases the lock on the mutex an equal number of times, i.e. the count drops down to zero. .SH SEE ALSO .PP al_create_mutex(3). allegro-5.0.10/docs/man/al_destroy_voice.30000644000175000001440000000056612157230677017550 0ustar tjadenusers.TH al_destroy_voice 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_voice(ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Destroys the voice and deallocates it from the digital driver. Does nothing if the voice is NULL. .SH SEE ALSO .PP al_create_voice(3) allegro-5.0.10/docs/man/al_set_mouse_w.30000644000175000001440000000053712157230674017216 0ustar tjadenusers.TH al_set_mouse_w 3 "" "Allegro reference manual" .SH NAME .PP al_set_mouse_w \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mouse_w(int\ w) \f[] .fi .SH DESCRIPTION .PP Set the second mouse wheel position to the given value. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_mouse_z(3) allegro-5.0.10/docs/man/ALLEGRO_VERTEX_ELEMENT.30000644000175000001440000000355312157230701017534 0ustar tjadenusers.TH ALLEGRO_VERTEX_ELEMENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_VERTEX_ELEMENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_VERTEX_ELEMENT\ ALLEGRO_VERTEX_ELEMENT; \f[] .fi .SH DESCRIPTION .PP A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the al_create_vertex_decl function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the attribute field equal to 0, to signify that it is the end of the array. Here is an example code that would create a declaration describing the ALLEGRO_VERTEX structure (passing this as vertex declaration to al_draw_prim would be identical to passing NULL): .IP .nf \f[C] /*\ On\ compilers\ without\ the\ offsetof\ keyword\ you\ need\ to\ obtain\ the \ *\ offset\ with\ sizeof\ and\ make\ sure\ to\ account\ for\ packing. \ */ ALLEGRO_VERTEX_ELEMENT\ elems[]\ =\ { \ \ \ {ALLEGRO_PRIM_POSITION,\ ALLEGRO_PRIM_FLOAT_3,\ offsetof(ALLEGRO_VERTEX,\ x)}, \ \ \ {ALLEGRO_PRIM_TEX_COORD_PIXEL,\ ALLEGRO_PRIM_FLOAT_2,\ offsetof(ALLEGRO_VERTEX,\ u)}, \ \ \ {ALLEGRO_PRIM_COLOR_ATTR,\ 0,\ offsetof(ALLEGRO_VERTEX,\ color)}, \ \ \ {0,\ 0,\ 0} }; ALLEGRO_VERTEX_DECL*\ decl\ =\ al_create_vertex_decl(elems,\ sizeof(ALLEGRO_VERTEX)); \f[] .fi .PP \f[I]Fields:\f[] .IP \[bu] 2 attribute \- A member of the ALLEGRO_PRIM_ATTR(3) enumeration, specifying what this attribute signifies .IP \[bu] 2 storage \- A member of the ALLEGRO_PRIM_STORAGE(3) enumeration, specifying how this attribute is stored .IP \[bu] 2 offset \- Offset in bytes from the beginning of the custom vertex structure. C function offsetof is very useful here. .SH SEE ALSO .PP al_create_vertex_decl(3), ALLEGRO_VERTEX_DECL(3), ALLEGRO_PRIM_ATTR(3), ALLEGRO_PRIM_STORAGE(3) allegro-5.0.10/docs/man/al_open_directory.30000644000175000001440000000075312157230672017710 0ustar tjadenusers.TH al_open_directory 3 "" "Allegro reference manual" .SH NAME .PP al_open_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_open_directory(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Opens a directory entry object. You must call this before using al_read_directory(3) on an entry and you must call al_close_directory(3) when you no longer need it. .PP Returns true on success. .SH SEE ALSO .PP al_read_directory(3), al_close_directory(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_CLOSE.30000644000175000001440000002700512157230671020345 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_blender.30000644000175000001440000000063112157230673017131 0ustar tjadenusers.TH al_get_blender 3 "" "Allegro reference manual" .SH NAME .PP al_get_blender \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_blender(int\ *op,\ int\ *src,\ int\ *dst) \f[] .fi .SH DESCRIPTION .PP Returns the active blender for the current thread. You can pass NULL for values you are not interested in. .SH SEE ALSO .PP al_set_blender(3), al_get_separate_blender(3) allegro-5.0.10/docs/man/al_ustr_vappendf.30000644000175000001440000000102312157230676017536 0ustar tjadenusers.TH al_ustr_vappendf 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_vappendf \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_vappendf(ALLEGRO_USTR\ *us,\ const\ char\ *fmt,\ va_list\ ap) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_appendf(3) but you pass the variable argument list directly, instead of the arguments themselves. See al_ustr_newf(3) about the "%s" and "%c" specifiers. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_appendf(3), al_ustr_append(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_BUTTON_DOWN.30000644000175000001440000002700512157230670021124 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_ref_buffer.30000644000175000001440000000111512157230675016764 0ustar tjadenusers.TH al_ref_buffer 3 "" "Allegro reference manual" .SH NAME .PP al_ref_buffer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_USTR\ *al_ref_buffer(ALLEGRO_USTR_INFO\ *info,\ const\ char\ *s,\ size_t\ size) \f[] .fi .SH DESCRIPTION .PP Create a string that references the storage of an underlying buffer. The size of the buffer is given in bytes. You can use it to reference only part of a string or an arbitrary region of memory. .PP The string is valid while the underlying memory buffer is valid. .SH SEE ALSO .PP al_ref_cstr(3), al_ref_ustr(3) allegro-5.0.10/docs/man/al_fixtorad_r.30000644000175000001440000000130512157230671017015 0ustar tjadenusers.TH al_fixtorad_r 3 "" "Allegro reference manual" .SH NAME .PP al_fixtorad_r \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ al_fixed\ al_fixtorad_r\ =\ (al_fixed)1608; \f[] .fi .SH DESCRIPTION .PP This constant gives a ratio which can be used to convert a fixed point number in binary angle format to a fixed point number in radians. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ rad_angle,\ binary_angle; \ \ \ \ /*\ Set\ the\ binary\ angle\ to\ 90\ degrees.\ */ \ \ \ \ binary_angle\ =\ 64; \ \ \ \ /*\ Now\ convert\ to\ radians\ (about\ 1.57).\ */ \ \ \ \ rad_angle\ =\ al_fixmul(binary_angle,\ al_fixtorad_r); \f[] .fi .SH SEE ALSO .PP al_fixmul(3), al_radtofix_r(3). allegro-5.0.10/docs/man/al_fread.30000644000175000001440000000127512157230671015743 0ustar tjadenusers.TH al_fread 3 "" "Allegro reference manual" .SH NAME .PP al_fread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fread(ALLEGRO_FILE\ *f,\ void\ *ptr,\ size_t\ size) \f[] .fi .SH DESCRIPTION .PP Read \[aq]size\[aq] bytes into the buffer pointed to by \[aq]ptr\[aq], from the given file. .PP Returns the number of bytes actually read. If an error occurs, or the end\-of\-file is reached, the return value is a short byte count (or zero). .PP al_fread() does not distinguish between EOF and other errors. Use al_feof(3) and al_ferror(3) to determine which occurred. .SH SEE ALSO .PP al_fgetc(3), al_fread16be(3), al_fread16le(3), al_fread32be(3), al_fread32le(3) allegro-5.0.10/docs/man/al_fixhypot.30000644000175000001440000000062412157230672016532 0ustar tjadenusers.TH al_fixhypot 3 "" "Allegro reference manual" .SH NAME .PP al_fixhypot \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixhypot(al_fixed\ x,\ al_fixed\ y) \f[] .fi .SH DESCRIPTION .PP Fixed point hypotenuse (returns the square root of \f[C]x*x\ +\ y*y\f[]). This should be better than calculating the formula yourself manually, since the error is much smaller. allegro-5.0.10/docs/man/al_unmap_rgba_f.30000644000175000001440000000066512157230672017305 0ustar tjadenusers.TH al_unmap_rgba_f 3 "" "Allegro reference manual" .SH NAME .PP al_unmap_rgba_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unmap_rgba_f(ALLEGRO_COLOR\ color, \ \ \ float\ *r,\ float\ *g,\ float\ *b,\ float\ *a) \f[] .fi .SH DESCRIPTION .PP Retrieves components of an ALLEGRO_COLOR(3). Components will range from 0.0f\-1.0f. .SH SEE ALSO .PP al_unmap_rgba(3), al_unmap_rgb(3), al_unmap_rgb_f(3) allegro-5.0.10/docs/man/al_open_memfile.30000644000175000001440000000134412157230677017324 0ustar tjadenusers.TH al_open_memfile 3 "" "Allegro reference manual" .SH NAME .PP al_open_memfile \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_open_memfile(void\ *mem,\ int64_t\ size,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Returns a file handle to the block of memory. All read and write operations act upon the memory directly, so it must not be freed while the file remains open. .PP The mode can be any combination of "r" (readable) and "w" (writable). Regardless of the mode, the file always opens at position 0. The file size is fixed and cannot be expanded. .PP It should be closed with al_fclose(3). After the file is closed, you are responsible for freeing the memory (if needed). allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_EXPOSE.30000644000175000001440000002700512157230671020503 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_hide_mouse_cursor.30000644000175000001440000000077712157230674020411 0ustar tjadenusers.TH al_hide_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_hide_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_hide_mouse_cursor(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Hide the mouse cursor in the given display. This has no effect on what the current mouse cursor looks like; it just makes it disappear. .PP Returns true on success (or if the cursor already was hidden), false otherwise. .SH SEE ALSO .PP al_show_mouse_cursor(3) allegro-5.0.10/docs/man/al_ustr_replace_range.30000644000175000001440000000137412157230677020534 0ustar tjadenusers.TH al_ustr_replace_range 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_replace_range \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_replace_range(ALLEGRO_USTR\ *us1,\ int\ start_pos1,\ int\ end_pos1, \ \ \ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Replace the part of \f[C]us1\f[] in the byte interval [start_pos, end_pos) with the contents of \f[C]us2\f[]. \f[C]start_pos\f[] cannot be less than 0. If \f[C]start_pos\f[] is past the end of \f[C]us1\f[] then the space between the end of the string and \f[C]start_pos\f[] will be padded with NUL (\[aq]\[aq]) bytes. .PP Use al_ustr_offset(3) to find the byte offsets. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_set_chr(3) allegro-5.0.10/docs/man/al_get_fs_entry_size.30000644000175000001440000000060512157230672020401 0ustar tjadenusers.TH al_get_fs_entry_size 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_size \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ off_t\ al_get_fs_entry_size(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the size, in bytes, of the given entry. May not return anything sensible for a directory entry. .SH SEE ALSO .PP al_update_fs_entry(3) allegro-5.0.10/docs/man/al_make_directory.30000644000175000001440000000102212157230672017652 0ustar tjadenusers.TH al_make_directory 3 "" "Allegro reference manual" .SH NAME .PP al_make_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_make_directory(const\ char\ *path) \f[] .fi .SH DESCRIPTION .PP Creates a new directory on the filesystem. This function also creates any parent directories as needed. .PP Returns true on success (including if the directory already exists), otherwise returns false on error. Fills in Allegro\[aq]s errno to indicate the error. .SH SEE ALSO .PP al_get_errno(3) allegro-5.0.10/docs/man/al_register_sample_saver_f.30000644000175000001440000000144512157230701021545 0ustar tjadenusers.TH al_register_sample_saver_f 3 "" "Allegro reference manual" .SH NAME .PP al_register_sample_saver_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_sample_saver_f(const\ char\ *ext, \ \ \ bool\ (*saver)(ALLEGRO_FILE*\ fp,\ ALLEGRO_SAMPLE\ *spl)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_save_sample_f(3). The given function will be used to handle the saving of sample files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]saver\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_sample_saver(3) allegro-5.0.10/docs/man/al_set_audio_stream_gain.30000644000175000001440000000072312157230701021176 0ustar tjadenusers.TH al_set_audio_stream_gain 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM\ *stream,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the playback gain. .PP Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_audio_stream_gain(3). allegro-5.0.10/docs/man/al_color_rgb_to_hsl.30000644000175000001440000000101612157230677020201 0ustar tjadenusers.TH al_color_rgb_to_hsl 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_hsl \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_rgb_to_hsl(float\ red,\ float\ green,\ float\ blue, \ \ \ float\ *hue,\ float\ *saturation,\ float\ *lightness) \f[] .fi .SH DESCRIPTION .PP Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and lightness in the range 0..1. .SH SEE ALSO .PP al_color_hsl_to_rgb(3), al_color_hsl(3) allegro-5.0.10/docs/man/al_fclose.30000644000175000001440000000042112157230671016125 0ustar tjadenusers.TH al_fclose 3 "" "Allegro reference manual" .SH NAME .PP al_fclose \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_fclose(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Close the given file, writing any buffered output data (if any). allegro-5.0.10/docs/man/al_create_voice.30000644000175000001440000000177512157230677017325 0ustar tjadenusers.TH al_create_voice 3 "" "Allegro reference manual" .SH NAME .PP al_create_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_VOICE\ *al_create_voice(unsigned\ int\ freq, \ \ \ ALLEGRO_AUDIO_DEPTH\ depth,\ ALLEGRO_CHANNEL_CONF\ chan_conf) \f[] .fi .SH DESCRIPTION .PP Creates a voice structure and allocates a voice from the digital sound driver. The passed frequency, sample format and channel configuration are used as a hint to what kind of data will be sent to the voice. However, the underlying sound driver is free to use non\-matching values. For example it may be the native format of the sound hardware. If a mixer is attached to the voice, the mixer will convert from the mixer\[aq]s format to the voice format and care does not have to be taken for this. .PP However if you access the voice directly, make sure to not rely on the parameters passed to this function, but instead query the returned voice for the actual settings. .SH SEE ALSO .PP al_destroy_voice(3) allegro-5.0.10/docs/man/al_lock_bitmap_region.30000644000175000001440000000127112157230672020506 0ustar tjadenusers.TH al_lock_bitmap_region 3 "" "Allegro reference manual" .SH NAME .PP al_lock_bitmap_region \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_LOCKED_REGION\ *al_lock_bitmap_region(ALLEGRO_BITMAP\ *bitmap, \ \ \ int\ x,\ int\ y,\ int\ width,\ int\ height,\ int\ format,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_lock_bitmap(3), but only locks a specific area of the bitmap. If the bitmap is a display bitmap, only that area of the texture will be updated when it is unlocked. Locking only the region you indend to modify will be faster than locking the whole bitmap. .SH SEE ALSO .PP ALLEGRO_LOCKED_REGION(3), ALLEGRO_PIXEL_FORMAT(3), al_unlock_bitmap(3) allegro-5.0.10/docs/man/al_uninstall_keyboard.30000644000175000001440000000073012157230673020550 0ustar tjadenusers.TH al_uninstall_keyboard 3 "" "Allegro reference manual" .SH NAME .PP al_uninstall_keyboard \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_uninstall_keyboard(void) \f[] .fi .SH DESCRIPTION .PP Uninstalls the active keyboard driver, if any. This will automatically unregister the keyboard event source with any event queues. .PP This function is automatically called when Allegro is shut down. .SH SEE ALSO .PP al_install_keyboard(3) allegro-5.0.10/docs/man/al_attach_audio_stream_to_mixer.30000644000175000001440000000066412157230700022562 0ustar tjadenusers.TH al_attach_audio_stream_to_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_attach_audio_stream_to_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM\ *stream,\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Attach a stream to a mixer. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_detach_audio_stream(3). allegro-5.0.10/docs/man/al_check_inverse.30000644000175000001440000000311612157230675017472 0ustar tjadenusers.TH al_check_inverse 3 "" "Allegro reference manual" .SH NAME .PP al_check_inverse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_check_inverse(const\ ALLEGRO_TRANSFORM\ *trans,\ float\ tol) \f[] .fi .SH DESCRIPTION .PP Checks if the transformation has an inverse using the supplied tolerance. Tolerance should be a small value between 0 and 1, with 1e\-7 being sufficient for most applications. .PP In this function tolerance specifies how close the determinant can be to 0 (if the determinant is 0, the transformation has no inverse). Thus the smaller the tolerance you specify, the "worse" transformations will pass this test. Using a tolerance of 1e\-7 will catch errors greater than 1/1000\[aq]s of a pixel, but let smaller errors pass. That means that if you transformed a point by a transformation and then transformed it again by the inverse transformation that passed this check, the resultant point should less than 1/1000\[aq]s of a pixel away from the original point. .PP Note that this check is superfluous most of the time if you never touched the transformation matrix values yourself. The only thing that would cause the transformation to not have an inverse is if you applied a 0 (or very small) scale to the transformation or you have a really large translation. As long as the scale is comfortably above 0, the transformation will be invertible. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to check .IP \[bu] 2 tol \- Tolerance .PP \f[I]Returns:\f[] 1 if the transformation is invertible, 0 otherwise .SH SEE ALSO .PP al_invert_transform(3) allegro-5.0.10/docs/man/al_register_bitmap_saver.30000644000175000001440000000150412157230674021240 0ustar tjadenusers.TH al_register_bitmap_saver 3 "" "Allegro reference manual" .SH NAME .PP al_register_bitmap_saver \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_bitmap_saver(const\ char\ *extension, \ \ \ bool\ (*saver)(const\ char\ *filename,\ ALLEGRO_BITMAP\ *bmp)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_save_bitmap(3). The given function will be used to handle the loading of bitmaps files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]saver\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_bitmap_loader(3), al_register_bitmap_saver_f(3) allegro-5.0.10/docs/man/al_destroy_user_event_source.30000644000175000001440000000072012157230672022165 0ustar tjadenusers.TH al_destroy_user_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_user_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE\ *src) \f[] .fi .SH DESCRIPTION .PP Destroy an event source initialised with al_init_user_event_source(3). .PP This does not free the memory, as that was user allocated to begin with. .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3) allegro-5.0.10/docs/man/al_ustr_find_replace.30000644000175000001440000000110512157230677020350 0ustar tjadenusers.TH al_ustr_find_replace 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_replace \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_find_replace(ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ ALLEGRO_USTR\ *find,\ const\ ALLEGRO_USTR\ *replace) \f[] .fi .SH DESCRIPTION .PP Replace all occurrences of \f[C]find\f[] in \f[C]us\f[] with \f[C]replace\f[], beginning at byte offset \f[C]start_pos\f[]. The \f[C]find\f[] string must be non\-empty. Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_find_replace_cstr(3) allegro-5.0.10/docs/man/al_set_new_display_refresh_rate.30000644000175000001440000000117312157230670022600 0ustar tjadenusers.TH al_set_new_display_refresh_rate 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_display_refresh_rate \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_display_refresh_rate(int\ refresh_rate) \f[] .fi .SH DESCRIPTION .PP Sets the refresh rate to use when creating new displays on the calling thread. If the refresh rate is not available, al_create_display(3) will fail. A list of modes with refresh rates can be found with al_get_num_display_modes(3) and al_get_display_mode(3). .PP The default setting is zero (don\[aq]t care). .SH SEE ALSO .PP al_get_new_display_refresh_rate(3) allegro-5.0.10/docs/man/ALLEGRO_JOYSTICK.30000644000175000001440000000052512157230672016610 0ustar tjadenusers.TH ALLEGRO_JOYSTICK 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_JOYSTICK \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_JOYSTICK\ ALLEGRO_JOYSTICK; \f[] .fi .SH DESCRIPTION .PP This is an abstract data type representing a physical joystick. .SH SEE ALSO .PP al_get_joystick(3) allegro-5.0.10/docs/man/al_close_directory.30000644000175000001440000000070412157230672020050 0ustar tjadenusers.TH al_close_directory 3 "" "Allegro reference manual" .SH NAME .PP al_close_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_close_directory(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Closes a previously opened directory entry object. .PP Returns true on success, false on failure and fills in Allegro\[aq]s errno to indicate the error. .SH SEE ALSO .PP al_open_directory(3), al_read_directory(3) allegro-5.0.10/docs/man/al_get_bitmap_width.30000644000175000001440000000043512157230673020173 0ustar tjadenusers.TH al_get_bitmap_width 3 "" "Allegro reference manual" .SH NAME .PP al_get_bitmap_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_bitmap_width(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the width of a bitmap in pixels. allegro-5.0.10/docs/man/al_get_channel_count.30000644000175000001440000000060712157230677020345 0ustar tjadenusers.TH al_get_channel_count 3 "" "Allegro reference manual" .SH NAME .PP al_get_channel_count \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_get_channel_count(ALLEGRO_CHANNEL_CONF\ conf) \f[] .fi .SH DESCRIPTION .PP Return the number of channels for the given channel configuration, which is one of the values listed under ALLEGRO_CHANNEL_CONF(3). allegro-5.0.10/docs/man/al_get_audio_stream_length_secs.30000644000175000001440000000113312157230701022536 0ustar tjadenusers.TH al_get_audio_stream_length_secs 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_length_secs \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ double\ al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the length of the stream in seconds, if known. Otherwise returns zero. .PP Currently this can only be called on streams created with al_load_audio_stream(3), al_load_audio_stream_f(3) and the format\-specific functions underlying those functions. .SH SEE ALSO .PP al_get_audio_stream_position_secs(3) allegro-5.0.10/docs/man/al_get_d3d_texture_position.30000644000175000001440000000110312157230676021672 0ustar tjadenusers.TH al_get_d3d_texture_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_d3d_texture_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_d3d_texture_position(ALLEGRO_BITMAP\ *bitmap,\ int\ *u,\ int\ *v) \f[] .fi .SH DESCRIPTION .PP Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels. .PP \f[I]Parameters:\f[] .IP \[bu] 2 bitmap \- ALLEGRO_BITMAP to examine .IP \[bu] 2 u \- Will hold the returned u coordinate .IP \[bu] 2 v \- Will hold the returned v coordinate allegro-5.0.10/docs/man/al_get_voice_position.30000644000175000001440000000071612157230677020557 0ustar tjadenusers.TH al_get_voice_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_voice_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_voice_position(const\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP When the voice has a non\-streaming object attached to it, e.g. a sample, returns the voice\[aq]s current sample position. Otherwise, returns zero. .SH SEE ALSO .PP al_set_voice_position(3). allegro-5.0.10/docs/man/al_get_errno.30000644000175000001440000000056112157230674016646 0ustar tjadenusers.TH al_get_errno 3 "" "Allegro reference manual" .SH NAME .PP al_get_errno \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_errno(void) \f[] .fi .SH DESCRIPTION .PP Some Allegro functions will set an error number as well as returning an error code. Call this function to retrieve the last error number set for the calling thread. allegro-5.0.10/docs/man/al_fsize.30000644000175000001440000000043012157230671015772 0ustar tjadenusers.TH al_fsize 3 "" "Allegro reference manual" .SH NAME .PP al_fsize \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int64_t\ al_fsize(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Return the size of the file, if it can be determined, or \-1 otherwise. allegro-5.0.10/docs/man/al_get_audio_stream_depth.30000644000175000001440000000057012157230701021350 0ustar tjadenusers.TH al_get_audio_stream_depth 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_depth \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_DEPTH\ al_get_audio_stream_depth( \ \ \ const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the stream audio depth. .SH SEE ALSO .PP ALLEGRO_AUDIO_DEPTH(3). allegro-5.0.10/docs/man/al_realloc.30000644000175000001440000000067612157230673016311 0ustar tjadenusers.TH al_realloc 3 "" "Allegro reference manual" .SH NAME .PP al_realloc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ al_realloc(p,\ n)\ \\ \ \ \ (al_realloc_with_context((p),\ (n),\ __LINE__,\ __FILE__,\ __func__)) \f[] .fi .SH DESCRIPTION .PP Like realloc() in the C standard library, but the implementation may be overridden. .PP This is a macro. .SH SEE ALSO .PP al_malloc(3), al_realloc_with_context(3) allegro-5.0.10/docs/man/al_get_joystick.30000644000175000001440000000142212157230673017354 0ustar tjadenusers.TH al_get_joystick 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_JOYSTICK\ *\ al_get_joystick(int\ num) \f[] .fi .SH DESCRIPTION .PP Get a handle for a joystick on the system. The number may be from 0 to al_get_num_joysticks(3)\-1. If successful a pointer to a joystick object is returned, which represents a physical device. Otherwise NULL is returned. .PP The handle and the index are only incidentally linked. After al_reconfigure_joysticks(3) is called, al_get_joystick(3) may return handles in a different order, and handles which represent disconnected devices will not be returned. .SH SEE ALSO .PP al_get_num_joysticks(3), al_reconfigure_joysticks(3), al_get_joystick_active(3) allegro-5.0.10/docs/man/al_get_audio_stream_event_source.30000644000175000001440000000075212157230700022746 0ustar tjadenusers.TH al_get_audio_stream_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_audio_stream_event_source( \ \ \ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Retrieve the associated event source. .PP See al_get_audio_stream_fragment(3) for a description of the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event that audio streams emit. allegro-5.0.10/docs/man/al_show_mouse_cursor.30000644000175000001440000000071012157230674020443 0ustar tjadenusers.TH al_show_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_show_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_show_mouse_cursor(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Make a mouse cursor visible in the given display. .PP Returns true if a mouse cursor is shown as a result of the call (or one already was visible), false otherwise. .SH SEE ALSO .PP al_hide_mouse_cursor(3) allegro-5.0.10/docs/man/al_ustr_rfind_cstr.30000644000175000001440000000065212157230677020100 0ustar tjadenusers.TH al_ustr_rfind_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_rfind_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_rfind_cstr(const\ ALLEGRO_USTR\ *haystack,\ int\ end_pos, \ \ \ const\ char\ *needle) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_rfind_str(3) but takes a C\-style string for \f[C]needle\f[]. .SH SEE ALSO .PP al_ustr_rfind_str(3), al_ustr_find_cstr(3) allegro-5.0.10/docs/man/al_ustr_compare.30000644000175000001440000000117712157230677017374 0ustar tjadenusers.TH al_ustr_compare 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_compare \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_compare(const\ ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP This function compares \f[C]us1\f[] and \f[C]us2\f[] by code point values. Returns zero if the strings are equal, a positive number if \f[C]us1\f[] comes after \f[C]us2\f[], else a negative number. .PP This does \f[I]not\f[] take into account locale\-specific sorting rules. For that you will need to use another library. .SH SEE ALSO .PP al_ustr_ncompare(3), al_ustr_equal(3) allegro-5.0.10/docs/man/al_get_joystick_name.30000644000175000001440000000062312157230673020356 0ustar tjadenusers.TH al_get_joystick_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_joystick_name(ALLEGRO_JOYSTICK\ *joy) \f[] .fi .SH DESCRIPTION .PP Return the name of the given joystick. .SH SEE ALSO .PP al_get_joystick_stick_name(3), al_get_joystick_axis_name(3), al_get_joystick_button_name(3) allegro-5.0.10/docs/man/al_install_audio.30000644000175000001440000000077112157230676017516 0ustar tjadenusers.TH al_install_audio 3 "" "Allegro reference manual" .SH NAME .PP al_install_audio \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_install_audio(void) \f[] .fi .SH DESCRIPTION .PP Install the audio subsystem. .PP Returns true on success, false on failure. .PP Note: most users will call al_reserve_samples(3) and al_init_acodec_addon(3) after this. .SH SEE ALSO .PP al_reserve_samples(3), al_uninstall_audio(3), al_is_audio_installed(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_get_keyboard_state.30000644000175000001440000000070212157230673020515 0ustar tjadenusers.TH al_get_keyboard_state 3 "" "Allegro reference manual" .SH NAME .PP al_get_keyboard_state \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE\ *ret_state) \f[] .fi .SH DESCRIPTION .PP Save the state of the keyboard specified at the time the function is called into the structure pointed to by \f[I]ret_state\f[]. .SH SEE ALSO .PP al_key_down(3), ALLEGRO_KEYBOARD_STATE(3) allegro-5.0.10/docs/man/al_destroy_display.30000644000175000001440000000115412157230670020073 0ustar tjadenusers.TH al_destroy_display 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_display \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_display(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Destroy a display. .PP If the target bitmap of the calling thread is tied to the display, then it implies a call to "al_set_target_bitmap(NULL);" before the display is destroyed. .PP That special case notwithstanding, you should make sure no threads are currently targeting a bitmap which is tied to the display before you destroy it. .SH SEE ALSO .PP al_set_target_bitmap(3) allegro-5.0.10/docs/man/al_wait_for_event_until.30000644000175000001440000000147512157230672021113 0ustar tjadenusers.TH al_wait_for_event_until 3 "" "Allegro reference manual" .SH NAME .PP al_wait_for_event_until \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_wait_for_event_until(ALLEGRO_EVENT_QUEUE\ *queue, \ \ \ ALLEGRO_EVENT\ *ret_event,\ ALLEGRO_TIMEOUT\ *timeout) \f[] .fi .SH DESCRIPTION .PP Wait until the event queue specified is non\-empty. If \f[C]ret_event\f[] is not NULL, the first event in the queue will be copied into \f[C]ret_event\f[] and removed from the queue. If \f[C]ret_event\f[] is NULL the first event is left at the head of the queue. .PP \f[C]timeout\f[] determines how long to wait. If the call times out, false is returned. Otherwise true is returned. .SH SEE ALSO .PP ALLEGRO_EVENT(3), ALLEGRO_TIMEOUT(3), al_init_timeout(3), al_wait_for_event(3), al_wait_for_event_timed(3) allegro-5.0.10/docs/man/al_get_config_value.30000644000175000001440000000115412157230670020155 0ustar tjadenusers.TH al_get_config_value 3 "" "Allegro reference manual" .SH NAME .PP al_get_config_value \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_config_value(const\ ALLEGRO_CONFIG\ *config, \ \ \ const\ char\ *section,\ const\ char\ *key) \f[] .fi .SH DESCRIPTION .PP Gets a pointer to an internal character buffer that will only remain valid as long as the ALLEGRO_CONFIG structure is not destroyed. Copy the value if you need a copy. The section can be NULL or "" for the global section. Returns NULL if the section or key do not exist. .SH SEE ALSO .PP al_set_config_value(3) allegro-5.0.10/docs/man/al_destroy_bitmap.30000644000175000001440000000126112157230673017704 0ustar tjadenusers.TH al_destroy_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Destroys the given bitmap, freeing all resources used by it. This function does nothing if the bitmap argument is NULL. .PP As a convenience, if the calling thread is currently targets the bitmap then the bitmap will be untargeted first. The new target bitmap is unspecified. (since: 5.0.10, 5.1.6) .PP Otherwise, it is an error to destroy a bitmap while it (or a sub\-bitmap) is the target bitmap of any thread. .SH SEE ALSO .PP al_create_bitmap(3) allegro-5.0.10/docs/man/al_color_hsv.30000644000175000001440000000057612157230677016671 0ustar tjadenusers.TH al_color_hsv 3 "" "Allegro reference manual" .SH NAME .PP al_color_hsv \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_hsv(float\ h,\ float\ s,\ float\ v) \f[] .fi .SH DESCRIPTION .PP Return an ALLEGRO_COLOR(3) structure from HSV (hue, saturation, value) values. .SH SEE ALSO .PP al_color_hsv_to_rgb(3), al_color_hsl(3) allegro-5.0.10/docs/man/al_get_text_dimensions.30000644000175000001440000000154212157230700020723 0ustar tjadenusers.TH al_get_text_dimensions 3 "" "Allegro reference manual" .SH NAME .PP al_get_text_dimensions \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_text_dimensions(const\ ALLEGRO_FONT\ *f, \ \ \ char\ const\ *text, \ \ \ int\ *bbx,\ int\ *bby,\ int\ *bbw,\ int\ *bbh) \f[] .fi .SH DESCRIPTION .PP Sometimes, the al_get_text_width(3) and al_get_font_line_height(3) functions are not enough for exact text placement, so this function returns some additional information. .PP Returned variables (all in pixel): .IP \[bu] 2 x, y \- Offset to upper left corner of bounding box. .IP \[bu] 2 w, h \- Dimensions of bounding box. .PP Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values. .SH SEE ALSO .PP al_get_text_width(3), al_get_font_line_height(3), al_get_ustr_dimensions(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY.30000644000175000001440000002700512157230671021325 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_fs_entry_mode.30000644000175000001440000000063212157230672020353 0ustar tjadenusers.TH al_get_fs_entry_mode 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_mode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_fs_entry_mode(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the entry\[aq]s mode flags, i.e. permissions and whether the entry refers to a file or directory. .SH SEE ALSO .PP al_get_errno(3), ALLEGRO_FILE_MODE(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_RESIZE.30000644000175000001440000002700512157230671020501 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_new_bitmap_format.30000644000175000001440000000055112157230673021214 0ustar tjadenusers.TH al_get_new_bitmap_format 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_bitmap_format \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_bitmap_format(void) \f[] .fi .SH DESCRIPTION .PP Returns the format used for newly created bitmaps. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3), al_set_new_bitmap_format(3) allegro-5.0.10/docs/man/al_stop_timer.30000644000175000001440000000070112157230675017044 0ustar tjadenusers.TH al_stop_timer 3 "" "Allegro reference manual" .SH NAME .PP al_stop_timer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_stop_timer(ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Stop the timer specified. The timer\[aq]s counter will stop incrementing and it will stop generating events. Stopping a timer that is already stopped does nothing. .SH SEE ALSO .PP al_start_timer(3), al_get_timer_started(3) allegro-5.0.10/docs/man/al_stop_sample.30000644000175000001440000000050112157230677017205 0ustar tjadenusers.TH al_stop_sample 3 "" "Allegro reference manual" .SH NAME .PP al_stop_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_stop_sample(ALLEGRO_SAMPLE_ID\ *spl_id) \f[] .fi .SH DESCRIPTION .PP Stop the sample started by al_play_sample(3). .SH SEE ALSO .PP al_stop_samples(3) allegro-5.0.10/docs/man/al_set_clipping_rectangle.30000644000175000001440000000074712157230674021374 0ustar tjadenusers.TH al_set_clipping_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_set_clipping_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_clipping_rectangle(int\ x,\ int\ y,\ int\ width,\ int\ height) \f[] .fi .SH DESCRIPTION .PP Set the region of the target bitmap or display that pixels get clipped to. The default is to clip pixels to the entire bitmap. .SH SEE ALSO .PP al_get_clipping_rectangle(3), al_reset_clipping_rectangle(3) allegro-5.0.10/docs/man/ALLEGRO_USTR_INFO.30000644000175000001440000000064312157230675016765 0ustar tjadenusers.TH ALLEGRO_USTR_INFO 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_USTR_INFO \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ _al_tagbstring\ ALLEGRO_USTR_INFO; \f[] .fi .SH DESCRIPTION .PP A type that holds additional information for an ALLEGRO_USTR(3) that references an external memory buffer. .SH SEE ALSO .PP al_ref_cstr(3), al_ref_buffer(3) and al_ref_ustr(3). allegro-5.0.10/docs/man/al_draw_spline.30000644000175000001440000000113612157230700017156 0ustar tjadenusers.TH al_draw_spline 3 "" "Allegro reference manual" .SH NAME .PP al_draw_spline \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_spline(float\ points[8],\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws a Bézier spline given 4 control points. .PP \f[I]Parameters:\f[] .IP \[bu] 2 points \- An array of 4 pairs of coordinates of the 4 control points .IP \[bu] 2 color \- Color of the spline .IP \[bu] 2 thickness \- Thickness of the spline, pass \f[C]<=\ 0\f[] to draw a hairline spline .SH SEE ALSO .PP al_calculate_spline(3) allegro-5.0.10/docs/man/ALLEGRO_USER_EVENT.30000644000175000001440000000266212157230671017073 0ustar tjadenusers.TH ALLEGRO_USER_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_USER_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_USER_EVENT\ ALLEGRO_USER_EVENT; \f[] .fi .SH DESCRIPTION .PP An event structure that can be emitted by user event sources. These are the public fields: .IP \[bu] 2 ALLEGRO_EVENT_SOURCE *source; .IP \[bu] 2 intptr_t data1; .IP \[bu] 2 intptr_t data2; .IP \[bu] 2 intptr_t data3; .IP \[bu] 2 intptr_t data4; .PP Like all other event types this structure is a part of the ALLEGRO_EVENT union. To access the fields in an ALLEGRO_EVENT variable \f[C]ev\f[], you would use: .IP \[bu] 2 ev.user.source .IP \[bu] 2 ev.user.data1 .IP \[bu] 2 ev.user.data2 .IP \[bu] 2 ev.user.data3 .IP \[bu] 2 ev.user.data4 .PP To create a new user event you would do this: .IP .nf \f[C] ALLEGRO_EVENT_SOURCE\ my_event_source; ALLEGRO_EVENT\ my_event; float\ some_var; al_init_user_event_source(&my_event_source); my_event.user.type\ =\ ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]); my_event.user.data1\ =\ 1; my_event.user.data2\ =\ &some_var; al_emit_user_event(&my_event_source,\ &my_event,\ NULL); \f[] .fi .PP Event type identifiers for user events are assigned by the user. Please see the documentation for ALLEGRO_GET_EVENT_TYPE(3) for the rules you should follow when assigning identifiers. .SH SEE ALSO .PP al_emit_user_event(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_load_sample.30000644000175000001440000000140212157230701017124 0ustar tjadenusers.TH al_load_sample 3 "" "Allegro reference manual" .SH NAME .PP al_load_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_SAMPLE\ *al_load_sample(const\ char\ *filename) \f[] .fi .SH DESCRIPTION .PP Loads a few different audio file formats based on their extension. .PP Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream(3). .PP Returns the sample on success, NULL on failure. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_register_sample_loader(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_install_mouse.30000644000175000001440000000053212157230673017535 0ustar tjadenusers.TH al_install_mouse 3 "" "Allegro reference manual" .SH NAME .PP al_install_mouse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_install_mouse(void) \f[] .fi .SH DESCRIPTION .PP Install a mouse driver. .PP Returns true if successful. If a driver was already installed, nothing happens and true is returned. allegro-5.0.10/docs/man/al_fputs.30000644000175000001440000000135212157230671016017 0ustar tjadenusers.TH al_fputs 3 "" "Allegro reference manual" .SH NAME .PP al_fputs \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fputs(ALLEGRO_FILE\ *f,\ char\ const\ *p) \f[] .fi .SH DESCRIPTION .PP Writes a string to file. Apart from the return value, this is equivalent to: .IP .nf \f[C] al_fwrite(f,\ p,\ strlen(p)); \f[] .fi .PP Parameters: .IP \[bu] 2 f \- file handle to write to .IP \[bu] 2 p \- string to write .PP Returns a non\-negative integer on success, EOF on error. .PP Note: depending on the stream type and the mode passed to al_fopen(3), newline characters in the string may or may not be automatically translated to native end\-of\-line sequences, e.g. CR/LF instead of LF. .SH SEE ALSO .PP al_fwrite(3) allegro-5.0.10/docs/man/al_ustr_assign.30000644000175000001440000000065412157230676017230 0ustar tjadenusers.TH al_ustr_assign 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_assign \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_assign(ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Overwrite the string \f[C]us1\f[] with another string \f[C]us2\f[]. Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_assign_substr(3), al_ustr_assign_cstr(3) allegro-5.0.10/docs/man/al_filename_exists.30000644000175000001440000000057312157230672020042 0ustar tjadenusers.TH al_filename_exists 3 "" "Allegro reference manual" .SH NAME .PP al_filename_exists \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_filename_exists(const\ char\ *path) \f[] .fi .SH DESCRIPTION .PP Check if the path exists on the filesystem, without creating an ALLEGRO_FS_ENTRY(3) object explicitly. .SH SEE ALSO .PP al_fs_entry_exists(3) allegro-5.0.10/docs/man/al_get_sample_data.30000644000175000001440000000063612157230677020001 0ustar tjadenusers.TH al_get_sample_data 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_data \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_get_sample_data(const\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return a pointer to the raw sample data. .SH SEE ALSO .PP al_get_sample_channels(3), al_get_sample_depth(3), al_get_sample_frequency(3), al_get_sample_length(3) allegro-5.0.10/docs/man/al_set_sample_instance_playing.30000644000175000001440000000067712157230700022423 0ustar tjadenusers.TH al_set_sample_instance_playing 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE\ *spl,\ bool\ val) \f[] .fi .SH DESCRIPTION .PP Change whether the sample instance is playing. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_sample_instance_playing(3) allegro-5.0.10/docs/man/al_is_audio_installed.30000644000175000001440000000050312157230676020513 0ustar tjadenusers.TH al_is_audio_installed 3 "" "Allegro reference manual" .SH NAME .PP al_is_audio_installed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_audio_installed(void) \f[] .fi .SH DESCRIPTION .PP Returns true if al_install_audio(3) was called previously and returned successfully. allegro-5.0.10/docs/man/al_wait_for_event.30000644000175000001440000000120612157230672017670 0ustar tjadenusers.TH al_wait_for_event 3 "" "Allegro reference manual" .SH NAME .PP al_wait_for_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_wait_for_event(ALLEGRO_EVENT_QUEUE\ *queue,\ ALLEGRO_EVENT\ *ret_event) \f[] .fi .SH DESCRIPTION .PP Wait until the event queue specified is non\-empty. If \f[C]ret_event\f[] is not NULL, the first event in the queue will be copied into \f[C]ret_event\f[] and removed from the queue. If \f[C]ret_event\f[] is NULL the first event is left at the head of the queue. .SH SEE ALSO .PP ALLEGRO_EVENT(3), al_wait_for_event_timed(3), al_wait_for_event_until(3), al_get_next_event(3) allegro-5.0.10/docs/man/al_create_builtin_font.30000644000175000001440000000166412157230700020674 0ustar tjadenusers.TH al_create_builtin_font 3 "" "Allegro reference manual" .SH NAME .PP al_create_builtin_font \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_create_builtin_font(void) \f[] .fi .SH DESCRIPTION .PP Creates a monochrome bitmap font (8x8 pixels per character). .PP This font is primarily intended to be used for displaying information in environments or during early runtime states where no external font data is available or loaded (e.g. for debugging). .PP The builtin font contains the following unicode character ranges: .IP .nf \f[C] 0x0020\ to\ 0x007F\ (ASCII) 0x00A1\ to\ 0x00FF\ (Latin\ 1) 0x0100\ to\ 0x017F\ (Extended\ A) 0x20AC\ to\ 0x20AC\ (euro\ currency\ symbol) \f[] .fi .PP Returns NULL on an error. .PP The font memory must be freed the same way as for any other font, using al_destroy_font(3). .SH SINCE .PP 5.0.8, 5.1.3 .SH SEE ALSO .PP al_load_bitmap_font(3), al_destroy_font(3) allegro-5.0.10/docs/man/al_register_bitmap_saver_f.30000644000175000001440000000145312157230674021550 0ustar tjadenusers.TH al_register_bitmap_saver_f 3 "" "Allegro reference manual" .SH NAME .PP al_register_bitmap_saver_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_bitmap_saver_f(const\ char\ *extension, \ \ \ bool\ (*saver_f)(ALLEGRO_FILE\ *fp,\ ALLEGRO_BITMAP\ *bmp)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_save_bitmap_f(3). The given function will be used to handle the loading of bitmaps files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]saver_f\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_bitmap_saver(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_WARPED.30000644000175000001440000002700512157230671020245 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_create_thread.30000644000175000001440000000110312157230674017445 0ustar tjadenusers.TH al_create_thread 3 "" "Allegro reference manual" .SH NAME .PP al_create_thread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_THREAD\ *al_create_thread( \ \ \ void\ *(*proc)(ALLEGRO_THREAD\ *thread,\ void\ *arg),\ void\ *arg) \f[] .fi .SH DESCRIPTION .PP Spawn a new thread which begins executing \f[C]proc\f[]. The new thread is passed its own thread handle and the value \f[C]arg\f[]. .PP Returns a pointer to the thread on success. Otherwise, returns NULL if there was an error. .SH SEE ALSO .PP al_start_thread(3), al_join_thread(3). allegro-5.0.10/docs/man/al_draw_scaled_bitmap.30000644000175000001440000000153712157230673020471 0ustar tjadenusers.TH al_draw_scaled_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_scaled_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_scaled_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ float\ sx,\ float\ sy,\ float\ sw,\ float\ sh, \ \ \ float\ dx,\ float\ dy,\ float\ dw,\ float\ dh,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Draws a scaled version of the given bitmap to the target bitmap. .IP \[bu] 2 sx \- source x .IP \[bu] 2 sy \- source y .IP \[bu] 2 sw \- source width .IP \[bu] 2 sh \- source height .IP \[bu] 2 dx \- destination x .IP \[bu] 2 dy \- destination y .IP \[bu] 2 dw \- destination width .IP \[bu] 2 dh \- destination height .IP \[bu] 2 flags \- same as for al_draw_bitmap(3) .SH SEE ALSO .PP al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_rotated_bitmap(3), al_draw_scaled_rotated_bitmap(3), allegro-5.0.10/docs/man/al_color_hsv_to_rgb.30000644000175000001440000000131312157230677020213 0ustar tjadenusers.TH al_color_hsv_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_hsv_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_hsv_to_rgb(float\ hue,\ float\ saturation,\ float\ value, \ \ \ float\ *red,\ float\ *green,\ float\ *blue) \f[] .fi .SH DESCRIPTION .PP Convert values in HSV color model to RGB color model. .PP Parameters: .IP \[bu] 2 hue \- Color hue angle in the range 0..360. .IP \[bu] 2 saturation \- Color saturation in the range 0..1. .IP \[bu] 2 value \- Color value in the range 0..1. .IP \[bu] 2 red, green, blue \- returned RGB values in the range 0..1. .SH SEE ALSO .PP al_color_rgb_to_hsv(3), al_color_hsv(3), al_color_hsl_to_rgb(3) allegro-5.0.10/docs/man/al_shutdown_font_addon.30000644000175000001440000000062112157230677020730 0ustar tjadenusers.TH al_shutdown_font_addon 3 "" "Allegro reference manual" .SH NAME .PP al_shutdown_font_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_shutdown_font_addon(void) \f[] .fi .SH DESCRIPTION .PP Shut down the font addon. This is done automatically at program exit, but can be called any time the user wishes as well. .SH SEE ALSO .PP al_init_font_addon(3) allegro-5.0.10/docs/man/al_get_audio_stream_length.30000644000175000001440000000051312157230701021522 0ustar tjadenusers.TH al_get_audio_stream_length 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_length \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_audio_stream_length(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the stream length in samples. allegro-5.0.10/docs/man/al_get_timer_count.30000644000175000001440000000055412157230675020054 0ustar tjadenusers.TH al_get_timer_count 3 "" "Allegro reference manual" .SH NAME .PP al_get_timer_count \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int64_t\ al_get_timer_count(const\ ALLEGRO_TIMER\ *timer) \f[] .fi .SH DESCRIPTION .PP Return the timer\[aq]s counter value. The timer can be started or stopped. .SH SEE ALSO .PP al_set_timer_count(3) allegro-5.0.10/docs/man/al_get_new_window_position.30000644000175000001440000000062512157230670021622 0ustar tjadenusers.TH al_get_new_window_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_window_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_new_window_position(int\ *x,\ int\ *y) \f[] .fi .SH DESCRIPTION .PP Get the position where new non\-fullscreen displays created by the calling thread will be placed. .SH SEE ALSO .PP al_set_new_window_position(3) allegro-5.0.10/docs/man/al_malloc.30000644000175000001440000000074512157230673016134 0ustar tjadenusers.TH al_malloc 3 "" "Allegro reference manual" .SH NAME .PP al_malloc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ al_malloc(n)\ \\ \ \ \ (al_malloc_with_context((n),\ __LINE__,\ __FILE__,\ __func__)) \f[] .fi .SH DESCRIPTION .PP Like malloc() in the C standard library, but the implementation may be overridden. .PP This is a macro. .SH SEE ALSO .PP al_free(3), al_realloc(3), al_calloc(3), al_malloc_with_context(3), al_set_memory_interface(3) allegro-5.0.10/docs/man/al_set_sample_instance_speed.30000644000175000001440000000100012157230677022052 0ustar tjadenusers.TH al_set_sample_instance_speed 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE\ *spl,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the relative playback speed. 1.0 is normal speed. .PP Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_sample_instance_speed(3) allegro-5.0.10/docs/man/al_get_pixel_format_bits.30000644000175000001440000000057312157230672021234 0ustar tjadenusers.TH al_get_pixel_format_bits 3 "" "Allegro reference manual" .SH NAME .PP al_get_pixel_format_bits \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_pixel_format_bits(int\ format) \f[] .fi .SH DESCRIPTION .PP Return the number of bits that a pixel of the given format occupies. .SH SEE ALSO .PP ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_size(3) allegro-5.0.10/docs/man/al_is_keyboard_installed.30000644000175000001440000000046112157230673021212 0ustar tjadenusers.TH al_is_keyboard_installed 3 "" "Allegro reference manual" .SH NAME .PP al_is_keyboard_installed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_keyboard_installed(void) \f[] .fi .SH DESCRIPTION .PP Returns true if al_install_keyboard(3) was called successfully. allegro-5.0.10/docs/man/al_get_allegro_version.30000644000175000001440000000172412157230674020715 0ustar tjadenusers.TH al_get_allegro_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the Allegro library, packed into a single integer as groups of 8 bits in the form \f[C](major\ <<\ 24)\ |\ (minor\ <<\ 16)\ |\ (revision\ <<\ 8)\ |\ release\f[]. .PP You can use code like this to extract them: .IP .nf \f[C] uint32_t\ version\ =\ al_get_allegro_version(); int\ major\ =\ version\ >>\ 24; int\ minor\ =\ (version\ >>\ 16)\ &\ 255; int\ revision\ =\ (version\ >>\ 8)\ &\ 255; int\ release\ =\ version\ &\ 255; \f[] .fi .PP The \f[C]release\f[] number is 0 for an unofficial version and 1 or greater for an official release. For example "5.0.2[1]" would be the (first) official 5.0.2 release while "5.0.2[0]" would be a compile of a version from the "5.0.2" branch before the official release. allegro-5.0.10/docs/man/al_get_allegro_physfs_version.30000644000175000001440000000055112157230700022274 0ustar tjadenusers.TH al_get_allegro_physfs_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_physfs_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_physfs_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/ALLEGRO_EVENT.30000644000175000001440000002700512157230670016232 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_ustr_prev.30000644000175000001440000000153712157230676016721 0ustar tjadenusers.TH al_ustr_prev 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_prev \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_prev(const\ ALLEGRO_USTR\ *us,\ int\ *pos) \f[] .fi .SH DESCRIPTION .PP Find the byte offset of the previous code point in string, before \f[C]*pos\f[]. \f[C]*pos\f[] does not have to be at the beginning of a code point. Returns true on success, then value pointed to by \f[C]pos\f[] will be updated to the found offset. Otherwise returns false if \f[C]*pos\f[] was already at the end of the string, then \f[C]*pos\f[] is unmodified. .PP This function just looks for an appropriate byte; it doesn\[aq]t check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF\-8 strings then it could skip over some invalid bytes. .SH SEE ALSO .PP al_ustr_next(3) allegro-5.0.10/docs/man/al_acknowledge_resize.30000644000175000001440000000135212157230670020521 0ustar tjadenusers.TH al_acknowledge_resize 3 "" "Allegro reference manual" .SH NAME .PP al_acknowledge_resize \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_acknowledge_resize(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP When the user receives a resize event from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display. Returns true on success. .PP Adjusts the clipping rectangle to the full size of the backbuffer. .PP Note that a resize event may be outdated by the time you acknowledge it; there could be further resize events generated in the meantime. .SH SEE ALSO .PP al_resize_display(3), ALLEGRO_EVENT(3) allegro-5.0.10/docs/man/al_ustr_trim_ws.30000644000175000001440000000062312157230676017424 0ustar tjadenusers.TH al_ustr_trim_ws 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_trim_ws \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_trim_ws(ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Remove both leading and trailing whitespace characters from a string. .PP Returns true on success, or false on error. .SH SEE ALSO .PP al_ustr_ltrim_ws(3), al_ustr_rtrim_ws(3) allegro-5.0.10/docs/man/al_color_name_to_rgb.30000644000175000001440000000432212157230677020336 0ustar tjadenusers.TH al_color_name_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_name_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_color_name_to_rgb(char\ const\ *name,\ float\ *r,\ float\ *g,\ float\ *b) \f[] .fi .SH DESCRIPTION .PP Parameters: .IP \[bu] 2 name \- The (lowercase) name of the color. .IP \[bu] 2 r, g, b \- If one of the recognized color names below is passed, the corresponding RGB values in the range 0..1 are written. .PP The recognized names are: .RS .PP aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, purple, purwablue, red, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen .RE .PP They are taken from . .PP Returns: true if a name from the list above was passed, else false. .SH SEE ALSO .PP al_color_name(3) allegro-5.0.10/docs/man/al_uninstall_system.30000644000175000001440000000057712157230674020306 0ustar tjadenusers.TH al_uninstall_system 3 "" "Allegro reference manual" .SH NAME .PP al_uninstall_system \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_uninstall_system(void) \f[] .fi .SH DESCRIPTION .PP Closes down the Allegro system. .RS .PP Note: al_uninstall_system() can be called without a corresponding al_install_system(3) call, e.g. from atexit(). .RE allegro-5.0.10/docs/man/ALLEGRO_BPS_TO_SECS.30000644000175000001440000000044412157230674017216 0ustar tjadenusers.TH ALLEGRO_BPS_TO_SECS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_BPS_TO_SECS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_BPS_TO_SECS(x)\ \ \ \ \ \ \ \ (1.0\ /\ (x)) \f[] .fi .SH DESCRIPTION .PP Convert beats per second to seconds. allegro-5.0.10/docs/man/al_get_allegro_acodec_version.30000644000175000001440000000055112157230676022212 0ustar tjadenusers.TH al_get_allegro_acodec_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_acodec_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_acodec_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_load_bitmap.30000644000175000001440000000125712157230674017140 0ustar tjadenusers.TH al_load_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_load_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_load_bitmap(const\ char\ *filename) \f[] .fi .SH DESCRIPTION .PP Loads an image file into an ALLEGRO_BITMAP(3). The file type is determined by the extension. .PP Returns NULL on error. .RS .PP \f[I]Note:\f[] the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. .RE .SH SEE ALSO .PP al_load_bitmap_f(3), al_register_bitmap_loader(3), al_set_new_bitmap_format(3), al_set_new_bitmap_flags(3), al_init_image_addon(3) allegro-5.0.10/docs/man/al_set_window_title.30000644000175000001440000000055212157230670020241 0ustar tjadenusers.TH al_set_window_title 3 "" "Allegro reference manual" .SH NAME .PP al_set_window_title \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_window_title(ALLEGRO_DISPLAY\ *display,\ const\ char\ *title) \f[] .fi .SH DESCRIPTION .PP Set the title on a display. .SH SEE ALSO .PP al_set_display_icon(3), al_set_display_icons(3) allegro-5.0.10/docs/man/al_get_org_name.30000644000175000001440000000045712157230674017314 0ustar tjadenusers.TH al_get_org_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_org_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_org_name(void) \f[] .fi .SH DESCRIPTION .PP Returns the global organization name string. .SH SEE ALSO .PP al_set_org_name(3) allegro-5.0.10/docs/man/al_load_ttf_font_f.30000644000175000001440000000120712157230700017775 0ustar tjadenusers.TH al_load_ttf_font_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_ttf_font_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_ttf_font_f(ALLEGRO_FILE\ *file, \ \ \ \ char\ const\ *filename,\ int\ size,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_load_ttf_font(3), but the font is read from the file handle. The filename is only used to find possible additional files next to a font file. .RS .PP \f[I]Note:\f[] The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time. .RE allegro-5.0.10/docs/man/ALLEGRO_MIXER.30000644000175000001440000000050312157230676016235 0ustar tjadenusers.TH ALLEGRO_MIXER 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MIXER \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_MIXER\ ALLEGRO_MIXER; \f[] .fi .SH DESCRIPTION .PP A mixer is a type of stream which mixes together attached streams into a single buffer. allegro-5.0.10/docs/man/al_ustr_ncompare.30000644000175000001440000000105112157230677017541 0ustar tjadenusers.TH al_ustr_ncompare 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_ncompare \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_ncompare(const\ ALLEGRO_USTR\ *us1,\ const\ ALLEGRO_USTR\ *us2,\ int\ n) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_compare(3) but only compares up to the first \f[C]n\f[] code points of both strings. .PP Returns zero if the strings are equal, a positive number if \f[C]us1\f[] comes after \f[C]us2\f[], else a negative number. .SH SEE ALSO .PP al_ustr_compare(3), al_ustr_equal(3) allegro-5.0.10/docs/man/al_ref_cstr.30000644000175000001440000000151712157230675016474 0ustar tjadenusers.TH al_ref_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ref_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_USTR\ *al_ref_cstr(ALLEGRO_USTR_INFO\ *info,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Create a string that references the storage of a C\-style string. The information about the string (e.g. its size) is stored in the structure pointed to by the \f[C]info\f[] parameter. The string will not have any other storage allocated of its own, so if you allocate the \f[C]info\f[] structure on the stack then no explicit "free" operation is required. .PP The string is valid until the underlying C string disappears. .PP Example: .IP .nf \f[C] ALLEGRO_USTR_INFO\ info; ALLEGRO_USTR\ *us\ =\ al_ref_cstr(&info,\ "my\ string"); \f[] .fi .SH SEE ALSO .PP al_ref_buffer(3), al_ref_ustr(3) allegro-5.0.10/docs/man/al_get_audio_stream_playing.30000644000175000001440000000056712157230701021715 0ustar tjadenusers.TH al_get_audio_stream_playing 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_audio_stream_playing(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return true if the stream is playing. .SH SEE ALSO .PP al_set_audio_stream_playing(3). allegro-5.0.10/docs/man/al_ustr_to_buffer.30000644000175000001440000000076712157230675017723 0ustar tjadenusers.TH al_ustr_to_buffer 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_to_buffer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_ustr_to_buffer(const\ ALLEGRO_USTR\ *us,\ char\ *buffer,\ int\ size) \f[] .fi .SH DESCRIPTION .PP Write the contents of the string into a pre\-allocated buffer of the given size in bytes. The result will always be NUL terminated, so a maximum of \f[C]size\ \-\ 1\f[] bytes will be copied. .SH SEE ALSO .PP al_cstr(3), al_cstr_dup(3) allegro-5.0.10/docs/man/al_restore_default_mixer.30000644000175000001440000000073412157230700021245 0ustar tjadenusers.TH al_restore_default_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_restore_default_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_restore_default_mixer(void) \f[] .fi .SH DESCRIPTION .PP Restores Allegro\[aq]s default mixer. All samples started with al_play_sample(3) will be stopped. Returns true on success, false on error. .SH SEE ALSO .PP al_get_default_mixer(3), al_set_default_mixer(3), al_reserve_samples(3). allegro-5.0.10/docs/man/al_get_voice_frequency.30000644000175000001440000000050112157230677020704 0ustar tjadenusers.TH al_get_voice_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_get_voice_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_voice_frequency(const\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Return the frequency of the voice, e.g. 44100. allegro-5.0.10/docs/man/al_fixsqrt.30000644000175000001440000000055212157230672016360 0ustar tjadenusers.TH al_fixsqrt 3 "" "Allegro reference manual" .SH NAME .PP al_fixsqrt \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixsqrt(al_fixed\ x) \f[] .fi .SH DESCRIPTION .PP This finds out the non negative square root of \f[C]x\f[]. If \f[C]x\f[] is negative, Allegro\[aq]s errno is set to EDOM and the function returns zero. allegro-5.0.10/docs/man/al_get_opengl_variant.30000644000175000001440000000131512157230676020531 0ustar tjadenusers.TH al_get_opengl_variant 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_variant \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_opengl_variant(void) \f[] .fi .SH DESCRIPTION .PP Returns the variant or type of OpenGL used on the running platform. This function can be called before creating a display or setting properties for new displays. Possible values are: .TP .B ALLEGRO_DESKTOP_OPENGL Regular OpenGL as seen on desktop/laptop computers. .RS .RE .TP .B ALLEGRO_OPENGL_ES Trimmed down version of OpenGL used on many small consumer electronic devices such as handheld (and sometimes full size) consoles. .RS .RE .SH SEE ALSO .PP al_get_opengl_version(3) allegro-5.0.10/docs/man/al_get_fs_entry_ctime.30000644000175000001440000000065312157230672020533 0ustar tjadenusers.TH al_get_fs_entry_ctime 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_ctime \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ time_t\ al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the time in seconds since the epoch this entry was created on the filesystem. .SH SEE ALSO .PP al_get_fs_entry_atime(3), al_get_fs_entry_mtime(3), al_update_fs_entry(3) allegro-5.0.10/docs/man/al_draw_scaled_rotated_bitmap.30000644000175000001440000000203112157230673022201 0ustar tjadenusers.TH al_draw_scaled_rotated_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_scaled_rotated_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ float\ cx,\ float\ cy,\ float\ dx,\ float\ dy,\ float\ xscale,\ float\ yscale, \ \ \ float\ angle,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_rotated_bitmap(3), but can also scale the bitmap. .PP The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap is rotated and scaled around this point. .IP \[bu] 2 cx \- center x .IP \[bu] 2 cy \- center y .IP \[bu] 2 dx \- destination x .IP \[bu] 2 dy \- destination y .IP \[bu] 2 xscale \- how much to scale on the x\-axis (e.g. 2 for twice the size) .IP \[bu] 2 yscale \- how much to scale on the y\-axis .IP \[bu] 2 angle \- angle by which to rotate (radians) .IP \[bu] 2 flags \- same as for al_draw_bitmap(3) .SH SEE ALSO .PP al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), al_draw_rotated_bitmap(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY.30000644000175000001440000002700512157230671021304 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_create_sample_instance.30000644000175000001440000000103312157230677021350 0ustar tjadenusers.TH al_create_sample_instance 3 "" "Allegro reference manual" .SH NAME .PP al_create_sample_instance \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_SAMPLE_INSTANCE\ *al_create_sample_instance(ALLEGRO_SAMPLE\ *sample_data) \f[] .fi .SH DESCRIPTION .PP Creates a sample stream, using the supplied data. This must be attached to a voice or mixer before it can be played. The argument may be NULL. You can then set the data later with al_set_sample(3). .SH SEE ALSO .PP al_destroy_sample_instance(3) allegro-5.0.10/docs/man/ALLEGRO_MOUSE_STATE.30000644000175000001440000000126312157230673017202 0ustar tjadenusers.TH ALLEGRO_MOUSE_STATE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MOUSE_STATE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_MOUSE_STATE\ ALLEGRO_MOUSE_STATE; \f[] .fi .SH DESCRIPTION .PP Public fields (read only): .IP \[bu] 2 x \- mouse x position .IP \[bu] 2 y \- mouse y position .IP \[bu] 2 w, z \- mouse wheel position (2D \[aq]ball\[aq]) .IP \[bu] 2 buttons \- mouse buttons bitfield .PP The zeroth bit is set if the primary mouse button is held down, the first bit is set if the secondary mouse button is held down, and so on. .SH SEE ALSO .PP al_get_mouse_state(3), al_get_mouse_state_axis(3), al_mouse_button_down(3) allegro-5.0.10/docs/man/al_set_new_display_flags.30000644000175000001440000000665212157230670021232 0ustar tjadenusers.TH al_set_new_display_flags 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_display_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_display_flags(int\ flags) \f[] .fi .SH DESCRIPTION .PP Sets various flags to be used when creating new displays on the calling thread. flags is a bitfield containing any reasonable combination of the following: .TP .B ALLEGRO_WINDOWED Prefer a windowed mode. .RS .PP Under multi\-head X (not XRandR/TwinView), the use of more than one adapter is impossible due to bugs in X and GLX. al_create_display(3) will fail if more than one adapter is attempted to be used. .RE .TP .B ALLEGRO_FULLSCREEN Prefer a fullscreen mode. .RS .PP Under X the use of more than one FULLSCREEN display when using multi\-head X, or true Xinerama is not possible due to bugs in X and GLX, display creation will fail if more than one adapter is attempted to be used. .RE .TP .B ALLEGRO_FULLSCREEN_WINDOW Make the window span the entire screen. Unlike ALLEGRO_FULLSCREEN this will never attempt to modify the screen resolution. Instead the pixel dimensions of the created display will be the same as the desktop. .RS .PP The passed width and height are only used if the window is switched out of fullscreen mode later but will be ignored initially. .PP Under Windows and X11 a fullscreen display created with this flag will behave differently from one created with the ALLEGRO_FULLSCREEN flag \- even if the ALLEGRO_FULLSCREEN display is passed the desktop dimensions. The exact difference is platform dependent, but some things which may be different is how alt\-tab works, how fast you can toggle between fullscreen/windowed mode or how additional monitors behave while your display is in fullscreen mode. .PP Additionally under X, the use of more than one adapter in multi\-head mode or with true Xinerama enabled is impossible due to bugs in X/GLX, creation will fail if more than one adapter is attempted to be used. .RE .TP .B ALLEGRO_RESIZABLE The display is resizable (only applicable if combined with ALLEGRO_WINDOWED). .RS .RE .TP .B ALLEGRO_OPENGL Require the driver to provide an initialized OpenGL context after returning successfully. .RS .RE .TP .B ALLEGRO_OPENGL_3_0 Require the driver to provide an initialized OpenGL context compatible with OpenGL version 3.0. .RS .RE .TP .B ALLEGRO_OPENGL_FORWARD_COMPATIBLE If this flag is set, the OpenGL context created with ALLEGRO_OPENGL_3_0 will be forward compatible \f[I]only\f[], meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not be supported. Currently, a display created with this flag will \f[I]not\f[] be compatible with Allegro drawing routines; the display option ALLEGRO_COMPATIBLE_DISPLAY will be set to false. .RS .RE .TP .B ALLEGRO_DIRECT3D Require the driver to do rendering with Direct3D and provide a Direct3D device. .RS .RE .TP .B ALLEGRO_FRAMELESS Try to create a window without a frame (i.e. no border or titlebar). This usually does nothing for fullscreen modes, and even in windowed modes it depends on the underlying platform whether it is supported or not. Since: 5.0.7, 5.1.2 .RS .RE .TP .B ALLEGRO_NOFRAME Original name for ALLEGRO_FRAMELESS. This works with older versions of Allegro. .RS .RE .TP .B ALLEGRO_GENERATE_EXPOSE_EVENTS Let the display generate expose events. .RS .RE .PP 0 can be used for default values. .SH SEE ALSO .PP al_set_new_display_option(3), al_get_display_option(3), al_change_display_option(3) allegro-5.0.10/docs/man/al_attach_mixer_to_mixer.30000644000175000001440000000116312157230700021225 0ustar tjadenusers.TH al_attach_mixer_to_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_attach_mixer_to_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_mixer_to_mixer(ALLEGRO_MIXER\ *stream,\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Attaches a mixer onto another mixer. The same rules as with al_attach_sample_instance_to_mixer(3) apply, with the added caveat that both mixers must be the same frequency. Returns true on success, false on error. .PP Currently both mixers must have the same audio depth, otherwise the function fails. .SH SEE ALSO .PP al_detach_mixer(3). allegro-5.0.10/docs/man/al_ustr_find_set_cstr.30000644000175000001440000000066212157230677020572 0ustar tjadenusers.TH al_ustr_find_set_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_set_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_set_cstr(const\ ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ char\ *accept) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_find_set(3) but takes a C\-style string for \f[C]accept\f[]. .SH SEE ALSO .PP al_ustr_find_set(3), al_ustr_find_cset_cstr(3) allegro-5.0.10/docs/man/al_ustr_insert.30000644000175000001440000000140212157230676017240 0ustar tjadenusers.TH al_ustr_insert 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_insert \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_insert(ALLEGRO_USTR\ *us1,\ int\ pos,\ const\ ALLEGRO_USTR\ *us2) \f[] .fi .SH DESCRIPTION .PP Insert \f[C]us2\f[] into \f[C]us1\f[] beginning at byte offset \f[C]pos\f[]. \f[C]pos\f[] cannot be less than 0. If \f[C]pos\f[] is past the end of \f[C]us1\f[] then the space between the end of the string and \f[C]pos\f[] will be padded with NUL (\[aq]\[aq]) bytes. .PP If required, use al_ustr_offset(3) to find the byte offset for a given code point index. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_insert_cstr(3), al_ustr_insert_chr(3), al_ustr_append(3), al_ustr_offset(3) allegro-5.0.10/docs/man/al_destroy_vertex_decl.30000644000175000001440000000072312157230700020725 0ustar tjadenusers.TH al_destroy_vertex_decl 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_vertex_decl \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL*\ decl) \f[] .fi .SH DESCRIPTION .PP Destroys a vertex declaration. .PP \f[I]Parameters:\f[] .IP \[bu] 2 decl \- Vertex declaration to destroy .SH SEE ALSO .PP ALLEGRO_VERTEX_ELEMENT(3), ALLEGRO_VERTEX_DECL(3), al_create_vertex_decl(3) allegro-5.0.10/docs/man/ALLEGRO_GET_EVENT_TYPE.30000644000175000001440000000262412157230672017574 0ustar tjadenusers.TH ALLEGRO_GET_EVENT_TYPE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_GET_EVENT_TYPE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_GET_EVENT_TYPE(a,\ b,\ c,\ d)\ \ \ AL_ID(a,\ b,\ c,\ d) \f[] .fi .SH DESCRIPTION .PP Make an event type identifier, which is a 32\-bit integer. Usually, but not necessarily, this will be made from four 8\-bit character codes, for example: .IP .nf \f[C] #define\ MY_EVENT_TYPE\ \ \ ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]) \f[] .fi .PP IDs less than 1024 are reserved for Allegro or its addons. Don\[aq]t use anything lower than \f[C]ALLEGRO_GET_EVENT_TYPE(0,\ 0,\ 4,\ 0)\f[]. .PP You should try to make your IDs unique so they don\[aq]t clash with any 3rd party code you may be using. Be creative. Numbering from 1024 is not creative. .PP If you need multiple identifiers, you could define them like this: .IP .nf \f[C] #define\ BASE_EVENT\ \ \ ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]) #define\ BARK_EVENT\ \ \ (BASE_EVENT\ +\ 0) #define\ MEOW_EVENT\ \ \ (BASE_EVENT\ +\ 1) #define\ SQUAWK_EVENT\ (BASE_EVENT\ +\ 2) /*\ Alternatively\ */ enum\ { \ \ \ BARK_EVENT\ =\ ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]), \ \ \ MEOW_EVENT, \ \ \ SQUAWK_EVENT }; \f[] .fi .SH SEE ALSO .PP ALLEGRO_EVENT(3), ALLEGRO_USER_EVENT(3), ALLEGRO_EVENT_TYPE_IS_USER(3) allegro-5.0.10/docs/man/al_set_default_mixer.30000644000175000001440000000110212157230700020343 0ustar tjadenusers.TH al_set_default_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_set_default_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_default_mixer(ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Sets the default mixer. All samples started with al_play_sample(3) will be stopped. If you are using your own mixer, this should be called before al_reserve_samples(3). .PP Returns true on success, false on error. .SH SEE ALSO .PP al_reserve_samples(3), al_play_sample(3), al_get_default_mixer(3), al_restore_default_mixer(3) allegro-5.0.10/docs/man/al_get_path_basename.30000644000175000001440000000123312157230674020305 0ustar tjadenusers.TH al_get_path_basename 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_basename \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_basename(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Return the basename, i.e. filename with the extension removed. If the filename doesn\[aq]t have an extension, the whole filename is the basename. If there is no filename part then the empty string is returned. .PP The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. .SH SEE ALSO .PP al_get_path_filename(3), al_get_path_extension(3) allegro-5.0.10/docs/man/al_rewind_audio_stream.30000644000175000001440000000101112157230701020664 0ustar tjadenusers.TH al_rewind_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_rewind_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Set the streaming file playing position to the beginning. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream(3), al_load_audio_stream_f(3) and the format\-specific functions underlying those functions. allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_SWITCH_OUT.30000644000175000001440000002700512157230671021230 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_audio_stream_fragment.30000644000175000001440000000257312157230701022054 0ustar tjadenusers.TH al_get_audio_stream_fragment 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_fragment \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_get_audio_stream_fragment(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP When using Allegro\[aq]s audio streaming, you will use this function to continuously provide new sample data to a stream. .PP If the stream is ready for new data, the function will return the address of an internal buffer to be filled with audio data. The length and format of the buffer are specified with al_create_audio_stream(3) or can be queried with the various functions described here. Once the buffer is filled, you must signal this to Allegro by passing the buffer to al_set_audio_stream_fragment(3). .PP If the stream is not ready for new data, the function will return NULL. .RS .PP \f[I]Note:\f[] If you listen to events from the stream, an ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event will be generated whenever a new fragment is ready. However, getting an event is \f[I]not\f[] a guarantee that al_get_audio_stream_fragment(3) will not return NULL, so you still must check for it. .RE .SH SEE ALSO .PP al_set_audio_stream_fragment(3), al_get_audio_stream_event_source(3), al_get_audio_stream_frequency(3), al_get_audio_stream_channels(3), al_get_audio_stream_depth(3), al_get_audio_stream_length(3) allegro-5.0.10/docs/man/al_ref_ustr.30000644000175000001440000000174512157230676016522 0ustar tjadenusers.TH al_ref_ustr 3 "" "Allegro reference manual" .SH NAME .PP al_ref_ustr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_USTR\ *al_ref_ustr(ALLEGRO_USTR_INFO\ *info,\ const\ ALLEGRO_USTR\ *us, \ \ \ int\ start_pos,\ int\ end_pos) \f[] .fi .SH DESCRIPTION .PP Create a read\-only string that references the storage of another ALLEGRO_USTR(3) string. The information about the string (e.g. its size) is stored in the structure pointed to by the \f[C]info\f[] parameter. The new string will not have any other storage allocated of its own, so if you allocate the \f[C]info\f[] structure on the stack then no explicit "free" operation is required. .PP The referenced interval is [start_pos, end_pos). Both are byte offsets. .PP The string is valid until the underlying string is modified or destroyed. .PP If you need a range of code\-points instead of bytes, use al_ustr_offset(3) to find the byte offsets. .SH SEE ALSO .PP al_ref_cstr(3), al_ref_buffer(3) allegro-5.0.10/docs/man/al_add_timer_count.30000644000175000001440000000103612157230675020021 0ustar tjadenusers.TH al_add_timer_count 3 "" "Allegro reference manual" .SH NAME .PP al_add_timer_count \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_add_timer_count(ALLEGRO_TIMER\ *timer,\ int64_t\ diff) \f[] .fi .SH DESCRIPTION .PP Add \f[I]diff\f[] to the timer\[aq]s counter value. This is similar to writing: .IP .nf \f[C] al_set_timer_count(timer,\ al_get_timer_count(timer)\ +\ diff); \f[] .fi .PP except that the addition is performed atomically, so no ticks will be lost. .SH SEE ALSO .PP al_set_timer_count(3) allegro-5.0.10/docs/man/al_fseek.30000644000175000001440000000161512157230671015755 0ustar tjadenusers.TH al_fseek 3 "" "Allegro reference manual" .SH NAME .PP al_fseek \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_fseek(ALLEGRO_FILE\ *f,\ int64_t\ offset,\ int\ whence) \f[] .fi .SH DESCRIPTION .PP Set the current position of the given file to a position relative to that specified by \[aq]whence\[aq], plus \[aq]offset\[aq] number of bytes. .PP \[aq]whence\[aq] can be: .IP \[bu] 2 ALLEGRO_SEEK_SET \- seek relative to beginning of file .IP \[bu] 2 ALLEGRO_SEEK_CUR \- seek relative to current file position .IP \[bu] 2 ALLEGRO_SEEK_END \- seek relative to end of file .PP Returns true on success, false on failure. errno is set to indicate the error. .PP After a successful seek, the end\-of\-file indicator is cleared and all pushback bytes are forgotten. .PP On some platforms this function may not support large files. .SH SEE ALSO .PP al_ftell(3), al_get_errno(3) allegro-5.0.10/docs/man/al_get_audio_stream_attached.30000644000175000001440000000071312157230701022020 0ustar tjadenusers.TH al_get_audio_stream_attached 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_attached \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_audio_stream_attached(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return whether the stream is attached to something. .SH SEE ALSO .PP al_attach_audio_stream_to_mixer(3), al_attach_audio_stream_to_voice(3), al_detach_audio_stream(3). allegro-5.0.10/docs/man/al_fwrite32le.30000644000175000001440000000063112157230671016643 0ustar tjadenusers.TH al_fwrite32le 3 "" "Allegro reference manual" .SH NAME .PP al_fwrite32le \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fwrite32le(ALLEGRO_FILE\ *f,\ int32_t\ l) \f[] .fi .SH DESCRIPTION .PP Writes a 32\-bit word in little\-endian format (LSB first). .PP Returns the number of bytes written: 4 on success, less than 4 on an error. .SH SEE ALSO .PP al_fwrite32be(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN.30000644000175000001440000002700512157230670021473 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_new_file_interface.30000644000175000001440000000064112157230672021326 0ustar tjadenusers.TH al_get_new_file_interface 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_file_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_FILE_INTERFACE\ *al_get_new_file_interface(void) \f[] .fi .SH DESCRIPTION .PP Return a pointer to the ALLEGRO_FILE_INTERFACE(3) table in effect for the calling thread. .SH SEE ALSO .PP al_store_state(3), al_restore_state(3). allegro-5.0.10/docs/man/al_get_mixer_attached.30000644000175000001440000000070512157230700020470 0ustar tjadenusers.TH al_get_mixer_attached 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_attached \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_mixer_attached(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return true if the mixer is attached to something. .SH SEE ALSO .PP al_attach_sample_instance_to_mixer(3), al_attach_audio_stream_to_mixer(3), al_attach_mixer_to_mixer(3), al_detach_mixer(3) allegro-5.0.10/docs/man/al_reset_clipping_rectangle.30000644000175000001440000000102012157230674021704 0ustar tjadenusers.TH al_reset_clipping_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_reset_clipping_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_reset_clipping_rectangle(void) \f[] .fi .SH DESCRIPTION .PP Equivalent to calling `al_set_clipping_rectangle(0, 0, w, h)\[aq] where \f[I]w\f[] and \f[I]h\f[] are the width and height of the target bitmap respectively. .PP Does nothing if there is no target bitmap. .SH SEE ALSO .PP al_set_clipping_rectangle(3) .SH SINCE .PP 5.0.6, 5.1.0 allegro-5.0.10/docs/man/al_build_transform.30000644000175000001440000000147712157230675020064 0ustar tjadenusers.TH al_build_transform 3 "" "Allegro reference manual" .SH NAME .PP al_build_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_build_transform(ALLEGRO_TRANSFORM\ *trans,\ float\ x,\ float\ y, \ \ \ float\ sx,\ float\ sy,\ float\ theta) \f[] .fi .SH DESCRIPTION .PP Builds a transformation given some parameters. This call is equivalent to calling the transformations in this order: make identity, scale, rotate, translate. This method is faster, however, than actually calling those functions. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .IP \[bu] 2 x, y \- Translation .IP \[bu] 2 sx, sy \- Scale .IP \[bu] 2 theta \- Rotation angle in radians .SH SEE ALSO .PP al_translate_transform(3), al_rotate_transform(3), al_scale_transform(3), al_compose_transform(3) allegro-5.0.10/docs/man/al_color_hsl_to_rgb.30000644000175000001440000000132712157230677020206 0ustar tjadenusers.TH al_color_hsl_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_hsl_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_hsl_to_rgb(float\ hue,\ float\ saturation,\ float\ lightness, \ \ \ float\ *red,\ float\ *green,\ float\ *blue) \f[] .fi .SH DESCRIPTION .PP Convert values in HSL color model to RGB color model. .PP Parameters: .IP \[bu] 2 hue \- Color hue angle in the range 0..360. .IP \[bu] 2 saturation \- Color saturation in the range 0..1. .IP \[bu] 2 lightness \- Color lightness in the range 0..1. .IP \[bu] 2 red, green, blue \- returned RGB values in the range 0..1. .SH SEE ALSO .PP al_color_rgb_to_hsl(3), al_color_hsl(3), al_color_hsv_to_rgb(3) allegro-5.0.10/docs/man/al_calloc.30000644000175000001440000000067012157230673016117 0ustar tjadenusers.TH al_calloc 3 "" "Allegro reference manual" .SH NAME .PP al_calloc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ al_calloc(c,\ n)\ \\ \ \ \ (al_calloc_with_context((c),\ (n),\ __LINE__,\ __FILE__,\ __func__)) \f[] .fi .SH DESCRIPTION .PP Like calloc() in the C standard library, but the implementation may be overridden. .PP This is a macro. .SH SEE ALSO .PP al_malloc(3), al_calloc_with_context(3) allegro-5.0.10/docs/man/al_get_mixer_quality.30000644000175000001440000000056112157230700020403 0ustar tjadenusers.TH al_get_mixer_quality 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_quality \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MIXER_QUALITY\ al_get_mixer_quality(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return the mixer quality. .SH SEE ALSO .PP ALLEGRO_MIXER_QUALITY(3), al_set_mixer_quality(3) allegro-5.0.10/docs/man/al_calculate_ribbon.30000644000175000001440000000246112157230700020141 0ustar tjadenusers.TH al_calculate_ribbon 3 "" "Allegro reference manual" .SH NAME .PP al_calculate_ribbon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_calculate_ribbon(float*\ dest,\ int\ dest_stride,\ const\ float\ *points, \ \ \ int\ points_stride,\ float\ thickness,\ int\ num_segments) \f[] .fi .SH DESCRIPTION .PP Calculates a ribbon given an array of points. The ribbon will go through all of the passed points. If \f[C]thickness\ <=\ 0\f[], then \f[C]num_segments\f[] of points are required in the destination buffer, otherwise twice as many are needed. The destination and the points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices. .PP \f[I]Parameters:\f[] .IP \[bu] 2 dest \- Pointer to the destination buffer .IP \[bu] 2 dest_stride \- Distance (in bytes) between starts of successive pairs of coordinates in the destination buffer .IP \[bu] 2 points \- An array of pairs of coordinates for each point .IP \[bu] 2 points_stride \- Distance (in bytes) between starts successive pairs of coordinates in the points buffer .IP \[bu] 2 thickness \- Thickness of the spline ribbon .IP \[bu] 2 num_segments \- The number of points to calculate .SH SEE ALSO .PP al_draw_ribbon(3), al_calculate_arc(3), al_calculate_spline(3) allegro-5.0.10/docs/man/al_create_audio_stream.30000644000175000001440000000433112157230700020646 0ustar tjadenusers.TH al_create_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_create_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_STREAM\ *al_create_audio_stream(size_t\ fragment_count, \ \ \ unsigned\ int\ frag_samples,\ unsigned\ int\ freq,\ ALLEGRO_AUDIO_DEPTH\ depth, \ \ \ ALLEGRO_CHANNEL_CONF\ chan_conf) \f[] .fi .SH DESCRIPTION .PP Creates an ALLEGRO_AUDIO_STREAM(3). The stream will be set to play by default. It will feed audio data from a buffer, which is split into a number of fragments. .PP Parameters: .IP \[bu] 2 fragment_count \- How many fragments to use for the audio stream. Usually only two fragments are required \- splitting the audio buffer in two halves. But it means that the only time when new data can be supplied is whenever one half has finished playing. When using many fragments, you usually will use fewer samples for one, so there always will be (small) fragments available to be filled with new data. .IP \[bu] 2 frag_samples \- The size of a fragment in samples. See note below. .IP \[bu] 2 freq \- The frequency, in Hertz. .IP \[bu] 2 depth \- Must be one of the values listed for ALLEGRO_AUDIO_DEPTH(3). .IP \[bu] 2 chan_conf \- Must be one of the values listed for ALLEGRO_CHANNEL_CONF(3). .PP The choice of \f[I]fragment_count\f[], \f[I]frag_samples\f[] and \f[I]freq\f[] directly influences the audio delay. The delay in seconds can be expressed as: .IP .nf \f[C] delay\ =\ fragment_count\ *\ frag_samples\ /\ freq \f[] .fi .PP This is only the delay due to Allegro\[aq]s streaming, there may be additional delay caused by sound drivers and/or hardware. .RS .PP \f[I]Note:\f[] If you know the fragment size in bytes, you can get the size in samples like this: .IP .nf \f[C] sample_size\ =\ al_get_channel_count(chan_conf)\ *\ al_get_audio_depth_size(depth); samples\ =\ bytes_per_fragment\ /\ sample_size; \f[] .fi .PP The size of the complete buffer is: .IP .nf \f[C] buffer_size\ =\ bytes_per_fragment\ *\ fragment_count \f[] .fi .RE .RS .PP \f[I]Note:\f[] unlike many Allegro objects, audio streams are not implicitly destroyed when Allegro is shut down. You must destroy them manually with al_destroy_audio_stream(3) before the audio system is shut down. .RE allegro-5.0.10/docs/man/al_have_opengl_extension.30000644000175000001440000000123112157230676021242 0ustar tjadenusers.TH al_have_opengl_extension 3 "" "Allegro reference manual" .SH NAME .PP al_have_opengl_extension \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_have_opengl_extension(const\ char\ *extension) \f[] .fi .SH DESCRIPTION .PP This function is a helper to determine whether an OpenGL extension is available on the given display or not. .PP Example: .IP .nf \f[C] bool\ packedpixels\ =\ al_have_opengl_extension("GL_EXT_packed_pixels"); \f[] .fi .PP If \f[I]packedpixels\f[] is true then you can safely use the constants related to the packed pixels extension. .PP Returns true if the extension is available; false otherwise. allegro-5.0.10/docs/man/al_get_allegro_ttf_version.30000644000175000001440000000053512157230700021557 0ustar tjadenusers.TH al_get_allegro_ttf_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_ttf_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_ttf_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_run_main.30000644000175000001440000000136012157230673016467 0ustar tjadenusers.TH al_run_main 3 "" "Allegro reference manual" .SH NAME .PP al_run_main \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_run_main(int\ argc,\ char\ **argv,\ int\ (*user_main)(int,\ char\ **)) \f[] .fi .SH DESCRIPTION .PP This function is useful in cases where you don\[aq]t have a main() function but want to run Allegro (mostly useful in a wrapper library). Under Windows and Linux this is no problem because you simply can call al_install_system(3). But some other system (like OSX) don\[aq]t allow calling al_install_system(3) in the main thread. al_run_main will know what to do in that case. .PP The passed argc and argv will simply be passed on to user_main and the return value of user_main will be returned. allegro-5.0.10/docs/man/al_get_sample_instance_frequency.30000644000175000001440000000054512157230677022754 0ustar tjadenusers.TH al_get_sample_instance_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_sample_instance_frequency(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the frequency of the sample instance. allegro-5.0.10/docs/man/al_free.30000644000175000001440000000121312157230673015575 0ustar tjadenusers.TH al_free 3 "" "Allegro reference manual" .SH NAME .PP al_free \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ al_free(p)\ \\ \ \ \ (al_free_with_context((p),\ __LINE__,\ __FILE__,\ __func__)) \f[] .fi .SH DESCRIPTION .PP Like free() in the C standard library, but the implementation may be overridden. .PP Additionally, on Windows, a memory block allocated by one DLL must be freed from the same DLL. In the few places where an Allegro function returns a pointer that must be freed, you must use al_free(3) for portability to Windows. .PP This is a macro. .SH SEE ALSO .PP al_malloc(3), al_free_with_context(3) allegro-5.0.10/docs/man/al_set_path_filename.30000644000175000001440000000072712157230674020335 0ustar tjadenusers.TH al_set_path_filename 3 "" "Allegro reference manual" .SH NAME .PP al_set_path_filename \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_path_filename(ALLEGRO_PATH\ *path,\ const\ char\ *filename) \f[] .fi .SH DESCRIPTION .PP Set the optional filename part of the path. The filename may be NULL, which is equivalent to setting the filename to the empty string. .SH SEE ALSO .PP al_set_path_extension(3), al_get_path_filename(3) allegro-5.0.10/docs/man/al_ustr_find_set.30000644000175000001440000000110012157230677017523 0ustar tjadenusers.TH al_ustr_find_set 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_set \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_set(const\ ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ ALLEGRO_USTR\ *accept) \f[] .fi .SH DESCRIPTION .PP This function finds the first code point in \f[C]us\f[], beginning from byte offset \f[C]start_pos\f[], that matches any code point in \f[C]accept\f[]. Returns the position if a code point was found. Otherwise returns \-1. .SH SEE ALSO .PP al_ustr_find_set_cstr(3), al_ustr_find_cset(3) allegro-5.0.10/docs/man/al_get_event_source_data.30000644000175000001440000000066012157230672021211 0ustar tjadenusers.TH al_get_event_source_data 3 "" "Allegro reference manual" .SH NAME .PP al_get_event_source_data \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ intptr_t\ al_get_event_source_data(const\ ALLEGRO_EVENT_SOURCE\ *source) \f[] .fi .SH DESCRIPTION .PP Returns the abstract user data associated with the event source. If no data was previously set, returns NULL. .SH SEE ALSO .PP al_set_event_source_data(3) allegro-5.0.10/docs/man/al_reset_new_display_options.30000644000175000001440000000052212157230670022146 0ustar tjadenusers.TH al_reset_new_display_options 3 "" "Allegro reference manual" .SH NAME .PP al_reset_new_display_options \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_reset_new_display_options(void) \f[] .fi .SH DESCRIPTION .PP This undoes any previous call to al_set_new_display_option(3) on the calling thread. allegro-5.0.10/docs/man/ALLEGRO_PRIM_QUALITY.30000644000175000001440000000055112157230701017320 0ustar tjadenusers.TH ALLEGRO_PRIM_QUALITY 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PRIM_QUALITY \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_PRIM_QUALITY\ 10 \f[] .fi .SH DESCRIPTION .PP Defines the quality of the quadratic primitives. At 10, this roughly corresponds to error of less than half of a pixel. allegro-5.0.10/docs/man/al_reserve_samples.30000644000175000001440000000207312157230676020063 0ustar tjadenusers.TH al_reserve_samples 3 "" "Allegro reference manual" .SH NAME .PP al_reserve_samples \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_reserve_samples(int\ reserve_samples) \f[] .fi .SH DESCRIPTION .PP Reserves a number of sample instances, attaching them to the default mixer. If no default mixer is set when this function is called, then it will automatically create a voice with an attached mixer, which becomes the default mixer. This diagram illustrates the structures that are set up: .IP .nf \f[C] \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ sample\ instance\ 1 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ /\ sample\ instance\ 2 voice\ <\-\-\ default\ mixer\ <\-\-\-\ \ \ \ \ \ \ \ \ . \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\\ \ \ \ \ \ \ \ . \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ sample\ instance\ N \f[] .fi .PP Returns true on success, false on error. al_install_audio(3) must have been called first. .SH SEE ALSO .PP al_set_default_mixer(3), al_play_sample(3) allegro-5.0.10/docs/man/al_key_down.30000644000175000001440000000055412157230673016502 0ustar tjadenusers.TH al_key_down 3 "" "Allegro reference manual" .SH NAME .PP al_key_down \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_key_down(const\ ALLEGRO_KEYBOARD_STATE\ *state,\ int\ keycode) \f[] .fi .SH DESCRIPTION .PP Return true if the key specified was held down in the state specified. .SH SEE ALSO .PP ALLEGRO_KEYBOARD_STATE(3) allegro-5.0.10/docs/man/al_draw_prim.30000644000175000001440000000305612157230700016636 0ustar tjadenusers.TH al_draw_prim 3 "" "Allegro reference manual" .SH NAME .PP al_draw_prim \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_draw_prim(const\ void*\ vtxs,\ const\ ALLEGRO_VERTEX_DECL*\ decl, \ \ \ ALLEGRO_BITMAP*\ texture,\ int\ start,\ int\ end,\ int\ type) \f[] .fi .SH DESCRIPTION .PP Draws a subset of the passed vertex buffer. .PP \f[I]Parameters:\f[] .IP \[bu] 2 texture \- Texture to use, pass 0 to use only color shaded primitves .IP \[bu] 2 vtxs \- Pointer to an array of vertices .IP \[bu] 2 decl \- Pointer to a vertex declaration. If set to NULL, the vertices are assumed to be of the ALLEGRO_VERTEX type .IP \[bu] 2 start \- Start index of the subset of the vertex buffer to draw .IP \[bu] 2 end \- One past the last index of subset of the vertex buffer to draw .IP \[bu] 2 type \- A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what kind of primitive to draw .PP \f[I]Returns:\f[] Number of primitives drawn .PP For example to draw a textured triangle you could use: .IP .nf \f[C] ALLEGRO_COLOR\ white\ =\ al_map_rgb_f(1,\ 1,\ 1); ALLEGRO_VERTEX\ v[]\ =\ { \ \ \ \ {.x\ =\ 128,\ .y\ =\ 0,\ .z\ =\ 0,\ .color\ =\ white,\ .u\ =\ 128,\ .v\ =\ 0}, \ \ \ \ {.x\ =\ 0,\ .y\ =\ 256,\ .z\ =\ 0,\ .color\ =\ white,\ .u\ =\ 0,\ .v\ =\ 256}, \ \ \ \ {.x\ =\ 256,\ .y\ =\ 256,\ .z\ =\ 0,\ .color\ =\ white,\ .u\ =\ 256,\ .v\ =\ 256}}; al_draw_prim(v,\ NULL,\ texture,\ 0,\ 3,\ ALLEGRO_PRIM_TRIANGLE_LIST); \f[] .fi .SH SEE ALSO .PP ALLEGRO_VERTEX(3), ALLEGRO_PRIM_TYPE(3), ALLEGRO_VERTEX_DECL(3), al_draw_indexed_prim(3) allegro-5.0.10/docs/man/al_set_new_display_option.30000644000175000001440000001125412157230670021440 0ustar tjadenusers.TH al_set_new_display_option 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_display_option \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_display_option(int\ option,\ int\ value,\ int\ importance) \f[] .fi .SH DESCRIPTION .PP Set an extra display option, to be used when creating new displays on the calling thread. Display options differ from display flags, and specify some details of the context to be created within the window itself. These mainly have no effect on Allegro itself, but you may want to specify them, for example if you want to use multisampling. .PP The \[aq]importance\[aq] parameter can be either: .IP \[bu] 2 ALLEGRO_REQUIRE \- The display will not be created if the setting can not be met. .IP \[bu] 2 ALLEGRO_SUGGEST \- If the setting is not available, the display will be created anyway. FIXME: We need a way to query the settings back from a created display. .IP \[bu] 2 ALLEGRO_DONTCARE \- If you added a display option with one of the above two settings before, it will be removed again. Else this does nothing. .PP The supported options are: .TP .B ALLEGRO_COLOR_SIZE This can be used to ask for a specific bit depth. For example to force a 16\-bit framebuffer set this to 16. .RS .RE .TP .B ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE Individual color component size in bits. .RS .RE .TP .B ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT Together with the previous settings these can be used to specify the exact pixel layout the display should use. Normally there is no reason to use these. .RS .RE .TP .B ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE This can be used to define the required accumulation buffer size. .RS .RE .TP .B ALLEGRO_STEREO Whether the display is a stereo display. .RS .RE .TP .B ALLEGRO_AUX_BUFFERS Number of auxiliary buffers the display should have. .RS .RE .TP .B ALLEGRO_DEPTH_SIZE How many depth buffer (z\-buffer) bits to use. .RS .RE .TP .B ALLEGRO_STENCIL_SIZE How many bits to use for the stencil buffer. .RS .RE .TP .B ALLEGRO_SAMPLE_BUFFERS Whether to use multisampling (1) or not (0). .RS .RE .TP .B ALLEGRO_SAMPLES If the above is 1, the number of samples to use per pixel. Else 0. .RS .RE .TP .B ALLEGRO_RENDER_METHOD: 0 if hardware acceleration is not used with this display. .RS .RE .TP .B ALLEGRO_FLOAT_COLOR Whether to use floating point color components. .RS .RE .TP .B ALLEGRO_FLOAT_DEPTH Whether to use a floating point depth buffer. .RS .RE .TP .B ALLEGRO_SINGLE_BUFFER Whether the display uses a single buffer (1) or another update method (0). .RS .RE .TP .B ALLEGRO_SWAP_METHOD If the above is 0, this is set to 1 to indicate the display is using a copying method to make the next buffer in the flip chain available, or to 2 to indicate a flipping or other method. .RS .RE .TP .B ALLEGRO_COMPATIBLE_DISPLAY Indicates if Allegro\[aq]s graphics functions can use this display. If you request a display not useable by Allegro, you can still use for example OpenGL to draw graphics. .RS .RE .TP .B ALLEGRO_UPDATE_DISPLAY_REGION Set to 1 if the display is capable of updating just a region, and 0 if calling al_update_display_region(3) is equivalent to al_flip_display(3). .RS .RE .TP .B ALLEGRO_VSYNC Set to 1 to tell the driver to wait for vsync in al_flip_display(3), or to 2 to force vsync off. The default of 0 means that Allegro does not try to modify the vsync behavior so it may be on or off. Note that even in the case of 1 or 2 it is possible to override the vsync behavior in the graphics driver so you should not rely on it. .RS .RE .TP .B ALLEGRO_MAX_BITMAP_SIZE When queried this returns the maximum size (width as well as height) a bitmap can have for this display. Calls to al_create_bitmap(3) or al_load_bitmap(3) for bitmaps larger than this size will fail. It does not apply to memory bitmaps which always can have arbitrary size (but are slow for drawing). .RS .RE .TP .B ALLEGRO_SUPPORT_NPOT_BITMAP Set to 1 if textures used for bitmaps on this display can have a size which is not a power of two. This is mostly useful if you use Allegro to load textures as otherwise only power\-of\-two textures will be used internally as bitmap storage. .RS .RE .TP .B ALLEGRO_CAN_DRAW_INTO_BITMAP Set to 1 if you can use al_set_target_bitmap(3) on bitmaps of this display to draw into them. If this is not the case software emulation will be used when drawing into display bitmaps (which can be very slow). .RS .RE .TP .B ALLEGRO_SUPPORT_SEPARATE_ALPHA This is set to 1 if the al_set_separate_blender(3) function is supported. Otherwise the alpha parameters will be ignored. .RS .RE .SH SEE ALSO .PP al_set_new_display_flags(3) allegro-5.0.10/docs/man/al_get_ustr_width.30000644000175000001440000000061012157230677017713 0ustar tjadenusers.TH al_get_ustr_width 3 "" "Allegro reference manual" .SH NAME .PP al_get_ustr_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_ustr_width(const\ ALLEGRO_FONT\ *f,\ ALLEGRO_USTR\ const\ *ustr) \f[] .fi .SH DESCRIPTION .PP Like al_get_text_width(3) but expects an ALLEGRO_USTR. .SH SEE ALSO .PP al_get_text_width(3), al_get_ustr_dimensions(3) allegro-5.0.10/docs/man/ALLEGRO_MIXER_QUALITY.30000644000175000001440000000066412157230676017455 0ustar tjadenusers.TH ALLEGRO_MIXER_QUALITY 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MIXER_QUALITY \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ ALLEGRO_MIXER_QUALITY \f[] .fi .SH DESCRIPTION .IP \[bu] 2 ALLEGRO_MIXER_QUALITY_POINT \- point sampling .IP \[bu] 2 ALLEGRO_MIXER_QUALITY_LINEAR \- linear interpolation .IP \[bu] 2 ALLEGRO_MIXER_QUALITY_CUBIC \- cubic interpolation (since: 5.0.8, 5.1.4) allegro-5.0.10/docs/man/al_utf16_width.30000644000175000001440000000070312157230677017027 0ustar tjadenusers.TH al_utf16_width 3 "" "Allegro reference manual" .SH NAME .PP al_utf16_width \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_utf16_width(int\ c) \f[] .fi .SH DESCRIPTION .PP Returns the number of bytes that would be occupied by the specified code point when encoded in UTF\-16. This is either 2 or 4 bytes for legal code point values. Otherwise returns 0. .SH SEE ALSO .PP al_utf16_encode(3), al_utf8_width(3) allegro-5.0.10/docs/man/al_map_rgba.30000644000175000001440000000065012157230672016427 0ustar tjadenusers.TH al_map_rgba 3 "" "Allegro reference manual" .SH NAME .PP al_map_rgba \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_map_rgba( \ \ \ unsigned\ char\ r,\ unsigned\ char\ g,\ unsigned\ char\ b,\ unsigned\ char\ a) \f[] .fi .SH DESCRIPTION .PP Convert r, g, b, a (ranging from 0\-255) into an ALLEGRO_COLOR(3). .SH SEE ALSO .PP al_map_rgb(3), al_map_rgba_f(3), al_map_rgb_f(3) allegro-5.0.10/docs/man/al_feof.30000644000175000001440000000134212157230671015574 0ustar tjadenusers.TH al_feof 3 "" "Allegro reference manual" .SH NAME .PP al_feof \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_feof(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Returns true if the end\-of\-file indicator has been set on the file, i.e. we have attempted to read \f[I]past\f[] the end of the file. .PP This does \f[I]not\f[] return true if we simply are at the end of the file. The following code correctly reads two bytes, even when the file contains exactly two bytes: .IP .nf \f[C] int\ b1\ =\ al_fgetc(f); int\ b2\ =\ al_fgetc(f); if\ (al_feof(f))\ { \ \ \ /*\ At\ least\ one\ byte\ was\ unsuccessfully\ read.\ */ \ \ \ report_error(); } \f[] .fi .SH SEE ALSO .PP al_ferror(3), al_fclearerr(3) allegro-5.0.10/docs/man/al_flush_event_queue.30000644000175000001440000000055112157230672020405 0ustar tjadenusers.TH al_flush_event_queue 3 "" "Allegro reference manual" .SH NAME .PP al_flush_event_queue \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_flush_event_queue(ALLEGRO_EVENT_QUEUE\ *queue) \f[] .fi .SH DESCRIPTION .PP Drops all events, if any, from the queue. .SH SEE ALSO .PP al_drop_next_event(3), al_is_event_queue_empty(3) allegro-5.0.10/docs/man/al_get_mouse_cursor_position.30000644000175000001440000000111012157230674022161 0ustar tjadenusers.TH al_get_mouse_cursor_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_cursor_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_mouse_cursor_position(int\ *ret_x,\ int\ *ret_y) \f[] .fi .SH DESCRIPTION .PP On platforms where this information is available, this function returns the global location of the mouse cursor, relative to the desktop. You should not normally use this function, as the information is not useful except for special scenarios as moving a window. .PP Returns true on success, false on failure. allegro-5.0.10/docs/man/al_attach_sample_instance_to_voice.30000644000175000001440000000144012157230677023242 0ustar tjadenusers.TH al_attach_sample_instance_to_voice 3 "" "Allegro reference manual" .SH NAME .PP al_attach_sample_instance_to_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE\ *spl, \ \ \ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Attaches a sample to a voice, and allows it to play. The sample\[aq]s volume and loop mode will be ignored, and it must have the same frequency and depth (including signed\-ness) as the voice. This function may fail if the selected driver doesn\[aq]t support preloading sample data. .PP At this time, we don\[aq]t recommend attaching samples directly to voices. Use a mixer in between. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_detach_voice(3) allegro-5.0.10/docs/man/al_utf8_encode.30000644000175000001440000000111412157230677017063 0ustar tjadenusers.TH al_utf8_encode 3 "" "Allegro reference manual" .SH NAME .PP al_utf8_encode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_utf8_encode(char\ s[],\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Encode the specified code point to UTF\-8 into the buffer \f[C]s\f[]. The buffer must have enough space to hold the encoding, which takes between 1 and 4 bytes. This routine will refuse to encode code points above 0x10FFFF. .PP Returns the number of bytes written, which is the same as that returned by al_utf8_width(3). .SH SEE ALSO .PP al_utf16_encode(3) allegro-5.0.10/docs/man/al_use_transform.30000644000175000001440000000220012157230675017542 0ustar tjadenusers.TH al_use_transform 3 "" "Allegro reference manual" .SH NAME .PP al_use_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_use_transform(const\ ALLEGRO_TRANSFORM\ *trans) \f[] .fi .SH DESCRIPTION .PP Sets the transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own transformation). Every drawing operation after this call will be transformed using this transformation. Call this function with an identity transformation to return to the default behaviour. .PP This function does nothing if there is no target bitmap. .PP The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables. .IP .nf \f[C] void\ setup_my_transformation(void) { \ \ \ ALLEGRO_TRANSFORM\ transform; \ \ \ al_translate_transform(&transform,\ 5,\ 10); \ \ \ al_use_transform(&transform); } \f[] .fi .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to use .SH SEE ALSO .PP al_get_current_transform(3), al_transform_coordinates(3) allegro-5.0.10/docs/man/al_create_path.30000644000175000001440000000107112157230673017135 0ustar tjadenusers.TH al_create_path 3 "" "Allegro reference manual" .SH NAME .PP al_create_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PATH\ *al_create_path(const\ char\ *str) \f[] .fi .SH DESCRIPTION .PP Create a path structure from a string. The last component, if it is followed by a directory separator and is neither "." nor "..", is treated as the last directory name in the path. Otherwise the last component is treated as the filename. The string may be NULL for an empty path. .SH SEE ALSO .PP al_create_path(3), al_destroy_path(3) allegro-5.0.10/docs/man/ALLEGRO_THREAD.30000644000175000001440000000042412157230674016320 0ustar tjadenusers.TH ALLEGRO_THREAD 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_THREAD \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_THREAD\ ALLEGRO_THREAD; \f[] .fi .SH DESCRIPTION .PP An opaque structure representing a thread. allegro-5.0.10/docs/man/al_destroy_sample_instance.30000644000175000001440000000067212157230677021606 0ustar tjadenusers.TH al_destroy_sample_instance 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_sample_instance \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Detaches the sample stream from anything it may be attached to and frees it (the sample data is \f[I]not\f[] freed!). .SH SEE ALSO .PP al_create_sample_instance(3) allegro-5.0.10/docs/man/ALLEGRO_PI.30000644000175000001440000000052212157230673015657 0ustar tjadenusers.TH ALLEGRO_PI 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_PI \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ ALLEGRO_PI\ \ \ \ \ \ \ \ 3.14159265358979323846 \f[] .fi .SH DESCRIPTION .PP C99 compilers have no predefined value like M_PI for the constant π, but you can use this one instead. allegro-5.0.10/docs/man/al_ustr_dup.30000644000175000001440000000057712157230675016537 0ustar tjadenusers.TH al_ustr_dup 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_dup \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_dup(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Return a duplicate copy of a string. The new string will need to be freed with al_ustr_free(3). .SH SEE ALSO .PP al_ustr_dup_substr(3), al_ustr_free(3) allegro-5.0.10/docs/man/ALLEGRO_JOYFLAGS.30000644000175000001440000000072312157230672016567 0ustar tjadenusers.TH ALLEGRO_JOYFLAGS 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_JOYFLAGS \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ ALLEGRO_JOYFLAGS \f[] .fi .SH DESCRIPTION .IP \[bu] 2 ALLEGRO_JOYFLAG_DIGITAL \- the stick provides digital input .IP \[bu] 2 ALLEGRO_JOYFLAG_ANALOGUE \- the stick provides analogue input .PP (this enum is a holdover from the old API and may be removed) .SH SEE ALSO .PP al_get_joystick_stick_flags(3) allegro-5.0.10/docs/man/al_destroy_cond.30000644000175000001440000000063112157230675017355 0ustar tjadenusers.TH al_destroy_cond 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_cond \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_cond(ALLEGRO_COND\ *cond) \f[] .fi .SH DESCRIPTION .PP Destroy a condition variable. .PP Destroying a condition variable which has threads block on it results in undefined behaviour. .PP Does nothing if \f[C]cond\f[] is \f[C]NULL\f[]. allegro-5.0.10/docs/man/al_have_d3d_non_square_texture_support.30000644000175000001440000000072012157230676024144 0ustar tjadenusers.TH al_have_d3d_non_square_texture_support 3 "" "Allegro reference manual" .SH NAME .PP al_have_d3d_non_square_texture_support \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_have_d3d_non_square_texture_support(void) \f[] .fi .SH DESCRIPTION .PP Returns whether the Direct3D device supports textures that are not square. .PP \f[I]Returns:\f[] True if the Direct3D device suports non\-square textures, false otherwise. allegro-5.0.10/docs/man/ALLEGRO_EVENT_QUEUE.30000644000175000001440000000103312157230672017171 0ustar tjadenusers.TH ALLEGRO_EVENT_QUEUE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT_QUEUE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_EVENT_QUEUE\ ALLEGRO_EVENT_QUEUE; \f[] .fi .SH DESCRIPTION .PP An event queue holds events that have been generated by event sources that are registered with the queue. Events are stored in the order they are generated. Access is in a strictly FIFO (first\-in\-first\-out) order. .SH SEE ALSO .PP al_create_event_queue(3), al_destroy_event_queue(3) allegro-5.0.10/docs/man/al_rebase_path.30000644000175000001440000000125012157230674017133 0ustar tjadenusers.TH al_rebase_path 3 "" "Allegro reference manual" .SH NAME .PP al_rebase_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_rebase_path(const\ ALLEGRO_PATH\ *head,\ ALLEGRO_PATH\ *tail) \f[] .fi .SH DESCRIPTION .PP Concatenate two path structures, modifying the second path structure. If \f[I]tail\f[] is an absolute path, this function does nothing. Otherwise, the drive and path components in \f[I]head\f[] are inserted at the start of \f[I]tail\f[]. .PP For example, if \f[I]head\f[] is "/anchor/" and \f[I]tail\f[] is "data/file.ext", then after the call \f[I]tail\f[] becomes "/anchor/data/file.ext". .SH SEE ALSO .PP al_join_paths(3) allegro-5.0.10/docs/man/al_get_fs_interface.30000644000175000001440000000061312157230672020145 0ustar tjadenusers.TH al_get_fs_interface 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_FS_INTERFACE\ *al_get_fs_interface(void) \f[] .fi .SH DESCRIPTION .PP Return a pointer to the ALLEGRO_FS_INTERFACE(3) table in effect for the calling thread. .SH SEE ALSO .PP al_store_state(3), al_restore_state(3). allegro-5.0.10/docs/man/al_draw_pieslice.30000644000175000001440000000157112157230700017464 0ustar tjadenusers.TH al_draw_pieslice 3 "" "Allegro reference manual" .SH NAME .PP al_draw_pieslice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_pieslice(float\ cx,\ float\ cy,\ float\ r,\ float\ start_theta, \ \ \ float\ delta_theta,\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws a pieslice (outlined circular sector). .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the pieslice .IP \[bu] 2 r \- Radius of the pieslice .IP \[bu] 2 color \- Color of the pieslice .IP \[bu] 2 start_theta \- The initial angle from which the pieslice is drawn .IP \[bu] 2 delta_theta \- Angular span of the pieslice (pass a negative number to switch direction) .IP \[bu] 2 thickness \- Thickness of the circle, pass \f[C]<=\ 0\f[] to draw hairline pieslice .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_draw_filled_pieslice(3) allegro-5.0.10/docs/man/al_merge_config_into.30000644000175000001440000000100012157230670020320 0ustar tjadenusers.TH al_merge_config_into 3 "" "Allegro reference manual" .SH NAME .PP al_merge_config_into \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_merge_config_into(ALLEGRO_CONFIG\ *master,\ const\ ALLEGRO_CONFIG\ *add) \f[] .fi .SH DESCRIPTION .PP Merge one configuration structure into another. Values in configuration \[aq]add\[aq] override those in \[aq]master\[aq]. \[aq]master\[aq] is modified. Comments from \[aq]add\[aq] are not retained. .SH SEE ALSO .PP al_merge_config(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_MOUSE_BUTTON_UP.30000644000175000001440000002700512157230671020702 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_install_keyboard.30000644000175000001440000000065112157230673020207 0ustar tjadenusers.TH al_install_keyboard 3 "" "Allegro reference manual" .SH NAME .PP al_install_keyboard \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_install_keyboard(void) \f[] .fi .SH DESCRIPTION .PP Install a keyboard driver. Returns true if successful. If a driver was already installed, nothing happens and true is returned. .SH SEE ALSO .PP al_uninstall_keyboard(3), al_is_keyboard_installed(3) allegro-5.0.10/docs/man/al_get_ustr_dimensions.30000644000175000001440000000106112157230700020730 0ustar tjadenusers.TH al_get_ustr_dimensions 3 "" "Allegro reference manual" .SH NAME .PP al_get_ustr_dimensions \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_ustr_dimensions(const\ ALLEGRO_FONT\ *f, \ \ \ ALLEGRO_USTR\ const\ *ustr, \ \ \ int\ *bbx,\ int\ *bby,\ int\ *bbw,\ int\ *bbh) \f[] .fi .SH DESCRIPTION .PP Sometimes, the al_get_ustr_width(3) and al_get_font_line_height(3) functions are not enough for exact text placement, so this function returns some additional information. .SH SEE ALSO .PP al_get_text_dimensions(3) allegro-5.0.10/docs/man/al_wait_for_vsync.30000644000175000001440000000111412157230670017705 0ustar tjadenusers.TH al_wait_for_vsync 3 "" "Allegro reference manual" .SH NAME .PP al_wait_for_vsync \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_wait_for_vsync(void) \f[] .fi .SH DESCRIPTION .PP Wait for the beginning of a vertical retrace. Some driver/card/monitor combinations may not be capable of this. .PP Note how al_flip_display(3) usually already waits for the vertical retrace, so unless you are doing something special, there is no reason to call this function. .PP Returns false if not possible, true if successful. .SH SEE ALSO .PP al_flip_display(3) allegro-5.0.10/docs/man/al_keycode_to_name.30000644000175000001440000000044712157230673020011 0ustar tjadenusers.TH al_keycode_to_name 3 "" "Allegro reference manual" .SH NAME .PP al_keycode_to_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_keycode_to_name(int\ keycode) \f[] .fi .SH DESCRIPTION .PP Converts the given keycode to a description of the key. allegro-5.0.10/docs/man/al_set_mixer_gain.30000644000175000001440000000064012157230700017643 0ustar tjadenusers.TH al_set_mixer_gain 3 "" "Allegro reference manual" .SH NAME .PP al_set_mixer_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mixer_gain(ALLEGRO_MIXER\ *mixer,\ float\ new_gain) \f[] .fi .SH DESCRIPTION .PP Set the mixer gain (amplification factor). .PP Returns true on success, false on failure. .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_get_mixer_gain(3) allegro-5.0.10/docs/man/al_set_sample_instance_gain.30000644000175000001440000000073612157230700021672 0ustar tjadenusers.TH al_set_sample_instance_gain 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE\ *spl,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the playback gain. .PP Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_sample_instance_gain(3) allegro-5.0.10/docs/man/al_get_sample_length.30000644000175000001440000000066312157230677020351 0ustar tjadenusers.TH al_get_sample_length 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_length \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_sample_length(const\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the length of the sample in sample values. .SH SEE ALSO .PP al_get_sample_channels(3), al_get_sample_depth(3), al_get_sample_frequency(3), al_get_sample_data(3) allegro-5.0.10/docs/man/al_get_opengl_texture.30000644000175000001440000000103712157230676020566 0ustar tjadenusers.TH al_get_opengl_texture 3 "" "Allegro reference manual" .SH NAME .PP al_get_opengl_texture \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ GLuint\ al_get_opengl_texture(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the OpenGL texture id internally used by the given bitmap if it uses one, else 0. .PP Example: .IP .nf \f[C] bitmap\ =\ al_load_bitmap("my_texture.png"); texture\ =\ al_get_opengl_texture(bitmap); if\ (texture\ !=\ 0) \ \ \ \ glBindTexture(GL_TEXTURE_2D,\ texture); \f[] .fi allegro-5.0.10/docs/man/al_get_sample.30000644000175000001440000000113012157230700016761 0ustar tjadenusers.TH al_get_sample 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_SAMPLE\ *al_get_sample(ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the sample data that the sample instance plays. .PP Note this returns a pointer to an internal structure, \f[I]not\f[] the ALLEGRO_SAMPLE(3) that you may have passed to al_set_sample(3). You may, however, check which sample buffer is being played by the sample instance with al_get_sample_data(3), and so on. .SH SEE ALSO .PP al_set_sample(3) allegro-5.0.10/docs/man/ALLEGRO_SAMPLE.30000644000175000001440000000117012157230676016333 0ustar tjadenusers.TH ALLEGRO_SAMPLE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_SAMPLE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_SAMPLE\ ALLEGRO_SAMPLE; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_SAMPLE object stores the data necessary for playing pre\-defined digital audio. It holds information pertaining to data length, frequency, channel configuration, etc. You can have an ALLEGRO_SAMPLE object playing multiple times simultaneously. The object holds a user\-specified PCM data buffer, of the format the object is created with. .SH SEE ALSO .PP ALLEGRO_SAMPLE_INSTANCE(3) allegro-5.0.10/docs/man/al_reconfigure_joysticks.30000644000175000001440000000277412157230672021302 0ustar tjadenusers.TH al_reconfigure_joysticks 3 "" "Allegro reference manual" .SH NAME .PP al_reconfigure_joysticks \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_reconfigure_joysticks(void) \f[] .fi .SH DESCRIPTION .PP Allegro is able to cope with users connecting and disconnected joystick devices on\-the\-fly. On existing platforms, the joystick event source will generate an event of type \f[C]ALLEGRO_EVENT_JOYSTICK_CONFIGURATION\f[] when a device is plugged in or unplugged. In response, you should call al_reconfigure_joysticks(3). .PP Afterwards, the number returned by al_get_num_joysticks(3) may be different, and the handles returned by al_get_joystick(3) may be different or be ordered differently. .PP All ALLEGRO_JOYSTICK(3) handles remain valid, but handles for disconnected devices become inactive: their states will no longer update, and al_get_joystick(3) will not return the handle. Handles for devices which remain connected will continue to represent the same devices. Previously inactive handles may become active again, being reused to represent newly connected devices. .PP Returns true if the joystick configuration changed, otherwise returns false. .PP It is possible that on some systems, Allegro won\[aq]t be able to generate \f[C]ALLEGRO_EVENT_JOYSTICK_CONFIGURATION\f[] events. If your game has an input configuration screen or similar, you may wish to call al_reconfigure_joysticks(3) when entering that screen. .SH SEE ALSO .PP al_get_joystick_event_source(3), ALLEGRO_EVENT(3) allegro-5.0.10/docs/man/ALLEGRO_CONFIG.30000644000175000001440000000041612157230670016313 0ustar tjadenusers.TH ALLEGRO_CONFIG 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_CONFIG \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_CONFIG\ ALLEGRO_CONFIG; \f[] .fi .SH DESCRIPTION .PP An abstract configuration structure. allegro-5.0.10/docs/man/al_get_current_directory.30000644000175000001440000000111612157230672021262 0ustar tjadenusers.TH al_get_current_directory 3 "" "Allegro reference manual" .SH NAME .PP al_get_current_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ *al_get_current_directory(void) \f[] .fi .SH DESCRIPTION .PP Returns the path to the current working directory, or NULL on failure. The returned path is dynamically allocated and must be destroyed with al_free(3). .PP Allegro\[aq]s errno is filled in to indicate the error if there is a failure. This function may not be implemented on some (virtual) filesystems. .SH SEE ALSO .PP al_get_errno(3), al_free(3) allegro-5.0.10/docs/man/al_join_paths.30000644000175000001440000000142112157230674017014 0ustar tjadenusers.TH al_join_paths 3 "" "Allegro reference manual" .SH NAME .PP al_join_paths \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_join_paths(ALLEGRO_PATH\ *path,\ const\ ALLEGRO_PATH\ *tail) \f[] .fi .SH DESCRIPTION .PP Concatenate two path structures. The first path structure is modified. If \[aq]tail\[aq] is an absolute path, this function does nothing. .PP If \[aq]tail\[aq] is a relative path, all of its directory components will be appended to \[aq]path\[aq]. tail\[aq]s filename will also overwrite path\[aq]s filename, even if it is just the empty string. .PP Tail\[aq]s drive is ignored. .PP Returns true if \[aq]tail\[aq] was a relative path and so concatenated to \[aq]path\[aq], otherwise returns false. .SH SEE ALSO .PP al_rebase_path(3) allegro-5.0.10/docs/man/ALLEGRO_STATE.30000644000175000001440000000254012157230674016232 0ustar tjadenusers.TH ALLEGRO_STATE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_STATE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_STATE\ ALLEGRO_STATE; \f[] .fi .SH DESCRIPTION .PP Opaque type which is passed to al_store_state(3)/al_restore_state(3). .PP The various state kept internally by Allegro can be displayed like this: .IP .nf \f[C] \ \ global \ \ \ \ \ \ active\ system\ driver \ \ \ \ \ \ \ \ \ \ current\ config \ \ per\ thread \ \ \ \ \ \ new\ bitmap\ params \ \ \ \ \ \ new\ display\ params \ \ \ \ \ \ active\ file\ interface \ \ \ \ \ \ errno \ \ \ \ \ \ current\ blending\ mode \ \ \ \ \ \ current\ display \ \ \ \ \ \ \ \ \ \ deferred\ drawing \ \ \ \ \ \ current\ target\ bitmap \ \ \ \ \ \ \ \ \ \ current\ transformation \ \ \ \ \ \ \ \ \ \ current\ clipping\ rectangle \ \ \ \ \ \ \ \ \ \ bitmap\ locking \f[] .fi .PP In general, the only real global state is the active system driver. All other global state is per\-thread, so if your application has multiple separate threads they never will interfere with each other. (Except if there are objects accessed by multiple threads of course. Usually you want to minimize that though and for the remaining cases use synchronization primitives described in the threads section or events described in the events section to control inter\-thread communication.) allegro-5.0.10/docs/man/al_ustr_find_str.30000644000175000001440000000111212157230677017543 0ustar tjadenusers.TH al_ustr_find_str 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_str \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_str(const\ ALLEGRO_USTR\ *haystack,\ int\ start_pos, \ \ \ const\ ALLEGRO_USTR\ *needle) \f[] .fi .SH DESCRIPTION .PP Find the first occurrence of string \f[C]needle\f[] in \f[C]haystack\f[], beginning from byte offset \f[C]pos\f[] (inclusive). Return the byte offset of the occurrence if it is found, otherwise return \-1. .SH SEE ALSO .PP al_ustr_find_cstr(3), al_ustr_rfind_str(3), al_ustr_find_replace(3) allegro-5.0.10/docs/man/al_color_yuv_to_rgb.30000644000175000001440000000063412157230677020243 0ustar tjadenusers.TH al_color_yuv_to_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_color_yuv_to_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_yuv_to_rgb(float\ y,\ float\ u,\ float\ v, \ \ \ \ float\ *red,\ float\ *green,\ float\ *blue) \f[] .fi .SH DESCRIPTION .PP Convert YUV color values to RGB color space. .SH SEE ALSO .PP al_color_yuv(3), al_color_rgb_to_yuv(3) allegro-5.0.10/docs/man/al_ustr_new.30000644000175000001440000000071112157230675016526 0ustar tjadenusers.TH al_ustr_new 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_new \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_new(const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Create a new string containing a copy of the C\-style string \f[C]s\f[]. The string must eventually be freed with al_ustr_free(3). .SH SEE ALSO .PP al_ustr_new_from_buffer(3), al_ustr_newf(3), al_ustr_dup(3), al_ustr_new_from_utf16(3) allegro-5.0.10/docs/man/al_get_joystick_state.30000644000175000001440000000064712157230673020564 0ustar tjadenusers.TH al_get_joystick_state 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_state \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_joystick_state(ALLEGRO_JOYSTICK\ *joy,\ ALLEGRO_JOYSTICK_STATE\ *ret_state) \f[] .fi .SH DESCRIPTION .PP Get the current joystick state. .SH SEE ALSO .PP ALLEGRO_JOYSTICK_STATE(3), al_get_joystick_num_buttons(3), al_get_joystick_num_axes(3) allegro-5.0.10/docs/man/al_resize_display.30000644000175000001440000000103412157230670017700 0ustar tjadenusers.TH al_resize_display 3 "" "Allegro reference manual" .SH NAME .PP al_resize_display \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_resize_display(ALLEGRO_DISPLAY\ *display,\ int\ width,\ int\ height) \f[] .fi .SH DESCRIPTION .PP Resize the display. Returns true on success, or false on error. This works on both fullscreen and windowed displays, regardless of the ALLEGRO_RESIZABLE flag. .PP Adjusts the clipping rectangle to the full size of the backbuffer. .SH SEE ALSO .PP al_acknowledge_resize(3) allegro-5.0.10/docs/man/al_hold_bitmap_drawing.30000644000175000001440000000265212157230674020662 0ustar tjadenusers.TH al_hold_bitmap_drawing 3 "" "Allegro reference manual" .SH NAME .PP al_hold_bitmap_drawing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_hold_bitmap_drawing(bool\ hold) \f[] .fi .SH DESCRIPTION .PP Enables or disables deferred bitmap drawing. This allows for efficient drawing of many bitmaps that share a parent bitmap, such as sub\-bitmaps from a tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls such that the parent bitmap is the same for large number of those calls. While deferred bitmap drawing is enabled, the only functions that can be used are the bitmap drawing functions and font drawing functions. Changing the state such as the blending modes will result in undefined behaviour. One exception to this rule are the transformations. It is possible to set a new transformation while the drawing is held. .PP No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function\[aq]s usage is to enable the deferred bitmap drawing, draw as many bitmaps as possible, taking care to stagger bitmaps that share parent bitmaps, and then disable deferred drawing. As mentioned above, this function also works with bitmap and truetype fonts, so if multiple lines of text need to be drawn, this function can speed things up. .SH SEE ALSO .PP al_is_bitmap_drawing_held(3) allegro-5.0.10/docs/man/al_set_physfs_file_interface.30000644000175000001440000000140112157230700022050 0ustar tjadenusers.TH al_set_physfs_file_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_physfs_file_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_physfs_file_interface(void) \f[] .fi .SH DESCRIPTION .PP After calling this, subsequent calls to al_fopen(3) will be handled by PHYSFS_open(). Operations on the files returned by al_fopen(3) will then be performed through PhysicsFS. .PP At the same time, all filesystem functions like al_read_directory(3) or al_create_fs_entry(3) will use PhysicsFS. .PP This functions only affects the thread it was called from. .PP To remember and restore another file I/O backend, you can use al_store_state(3)/al_restore_state(3). .SH SEE ALSO .PP al_set_new_file_interface(3). allegro-5.0.10/docs/man/al_attach_sample_instance_to_mixer.30000644000175000001440000000100512157230700023241 0ustar tjadenusers.TH al_attach_sample_instance_to_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_attach_sample_instance_to_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE\ *spl, \ \ \ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Attach a sample instance to a mixer. The instance must not already be attached to anything. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_detach_sample_instance(3). allegro-5.0.10/docs/man/al_draw_rounded_rectangle.30000644000175000001440000000137612157230700021356 0ustar tjadenusers.TH al_draw_rounded_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_rounded_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_rounded_rectangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ float\ rx,\ float\ ry,\ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an outlined rounded rectangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2 \- Upper left and lower right points of the rectangle .IP \[bu] 2 color \- Color of the rectangle .IP \[bu] 2 rx, ry \- The radii of the round .IP \[bu] 2 thickness \- Thickness of the lines, pass \f[C]<=\ 0\f[] to draw hairline lines .SH SEE ALSO .PP al_draw_filled_rounded_rectangle(3), al_draw_rectangle(3) allegro-5.0.10/docs/man/al_get_mouse_state_axis.30000644000175000001440000000076312157230673021100 0ustar tjadenusers.TH al_get_mouse_state_axis 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_state_axis \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_mouse_state_axis(const\ ALLEGRO_MOUSE_STATE\ *state,\ int\ axis) \f[] .fi .SH DESCRIPTION .PP Extract the mouse axis value from the saved state. The axes are numbered from 0, in this order: x\-axis, y\-axis, z\-axis, w\-axis. .SH SEE ALSO .PP ALLEGRO_MOUSE_STATE(3), al_get_mouse_state(3), al_mouse_button_down(3) allegro-5.0.10/docs/man/al_play_sample_instance.30000644000175000001440000000060712157230677021060 0ustar tjadenusers.TH al_play_sample_instance 3 "" "Allegro reference manual" .SH NAME .PP al_play_sample_instance \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Play an instance of a sample data. Returns true on success, false on failure. .SH SEE ALSO .PP al_stop_sample_instance(3) allegro-5.0.10/docs/man/al_fixadd.30000644000175000001440000000223412157230671016115 0ustar tjadenusers.TH al_fixadd 3 "" "Allegro reference manual" .SH NAME .PP al_fixadd \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixadd(al_fixed\ x,\ al_fixed\ y); \f[] .fi .SH DESCRIPTION .PP Although fixed point numbers can be added with the normal \f[C]+\f[] integer operator, that doesn\[aq]t provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro\[aq]s errno and clamp the result, rather than just letting it wrap. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ This\ will\ put\ 5035\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixadd(al_itofix(5000),\ al_itofix(35)); \ \ \ \ /*\ Sets\ errno\ and\ puts\ \-32768\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixadd(al_itofix(\-31000),\ al_itofix(\-3000)); \ \ \ \ assert(!al_get_errno());\ /*\ This\ will\ fail.\ */ \f[] .fi .SH RETURN VALUE .PP Returns the clamped result of adding \f[C]x\f[] to \f[C]y\f[], setting Allegro\[aq]s errno to ERANGE if there was an overflow. .SH SEE ALSO .PP al_fixsub(3), al_fixmul(3), al_fixdiv(3). allegro-5.0.10/docs/man/al_draw_soft_line.30000644000175000001440000000303312157230701017645 0ustar tjadenusers.TH al_draw_soft_line 3 "" "Allegro reference manual" .SH NAME .PP al_draw_soft_line \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_soft_line(ALLEGRO_VERTEX*\ v1,\ ALLEGRO_VERTEX*\ v2,\ uintptr_t\ state, \ \ \ void\ (*first)(uintptr_t,\ int,\ int,\ ALLEGRO_VERTEX*,\ ALLEGRO_VERTEX*), \ \ \ void\ (*step)(uintptr_t,\ int), \ \ \ void\ (*draw)(uintptr_t,\ int,\ int)) \f[] .fi .SH DESCRIPTION .PP Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/line_soft.c. The line is drawn top to bottom. .PP \f[I]Parameters:\f[] .IP \[bu] 2 v1, v2 \- The two vertices of the line .IP \[bu] 2 state \- A pointer to a user supplied struct, this struct will be passed to all the pixel functions .IP \[bu] 2 first \- Called before drawing the first pixel of the line. It is passed the coordinates of this pixel, as well as the two vertices above. The passed vertices may have been altered by clipping. .IP \[bu] 2 step \- Called once per pixel. The second parameter is set to 1 if the step is a minor step, and 0 if this step is a major step. Minor steps are taken only either in x or y directions. Major steps are taken in both directions diagonally. In all cases, the the absolute value of the change in coordinate is at most 1 in either direction. .IP \[bu] 2 draw \- Called once per pixel. The function is expected to draw the pixel at the coordinates passed to it. allegro-5.0.10/docs/man/al_install_system.30000644000175000001440000000137212157230674017735 0ustar tjadenusers.TH al_install_system 3 "" "Allegro reference manual" .SH NAME .PP al_install_system \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_install_system(int\ version,\ int\ (*atexit_ptr)(void\ (*)(void))) \f[] .fi .SH DESCRIPTION .PP Initialize the Allegro system. No other Allegro functions can be called before this (with one or two exceptions). .PP The version field should always be set to ALLEGRO_VERSION_INT. .PP If atexit_ptr is non\-NULL, and if hasn\[aq]t been done already, al_uninstall_system(3) will be registered as an atexit function. .PP Returns true if Allegro was successfully initialized by this function call (or already was initialized previously), false if Allegro cannot be used. .SH SEE ALSO .PP al_init(3) allegro-5.0.10/docs/man/ALLEGRO_DISPLAY_MODE.30000644000175000001440000000137012157230672017261 0ustar tjadenusers.TH ALLEGRO_DISPLAY_MODE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_DISPLAY_MODE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_DISPLAY_MODE \f[] .fi .SH DESCRIPTION .PP Used for fullscreen mode queries. Contains information about a supported fullscreen modes. .IP .nf \f[C] typedef\ struct\ ALLEGRO_DISPLAY_MODE\ { \ \ \ int\ width;\ \ \ \ \ \ \ \ \ \ //\ Screen\ width \ \ \ int\ height;\ \ \ \ \ \ \ \ \ //\ Screen\ height \ \ \ int\ format;\ \ \ \ \ \ \ \ \ //\ The\ pixel\ format\ of\ the\ mode \ \ \ int\ refresh_rate;\ \ \ //\ The\ refresh\ rate\ of\ the\ mode }\ ALLEGRO_DISPLAY_MODE; \f[] .fi .PP The \f[C]refresh_rate\f[] may be zero if unknown. .SH SEE ALSO .PP al_get_display_mode(3) allegro-5.0.10/docs/man/al_get_next_event.30000644000175000001440000000115012157230672017671 0ustar tjadenusers.TH al_get_next_event 3 "" "Allegro reference manual" .SH NAME .PP al_get_next_event \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_next_event(ALLEGRO_EVENT_QUEUE\ *queue,\ ALLEGRO_EVENT\ *ret_event) \f[] .fi .SH DESCRIPTION .PP Take the next event out of the event queue specified, and copy the contents into \f[C]ret_event\f[], returning true. The original event will be removed from the queue. If the event queue is empty, return false and the contents of \f[C]ret_event\f[] are unspecified. .SH SEE ALSO .PP ALLEGRO_EVENT(3), al_peek_next_event(3), al_wait_for_event(3) allegro-5.0.10/docs/man/al_unmap_rgb.30000644000175000001440000000070612157230672016633 0ustar tjadenusers.TH al_unmap_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_unmap_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unmap_rgb(ALLEGRO_COLOR\ color, \ \ \ unsigned\ char\ *r,\ unsigned\ char\ *g,\ unsigned\ char\ *b) \f[] .fi .SH DESCRIPTION .PP Retrieves components of an ALLEGRO_COLOR, ignoring alpha Components will range from 0\-255. .SH SEE ALSO .PP al_unmap_rgba(3), al_unmap_rgba_f(3), al_unmap_rgb_f(3) allegro-5.0.10/docs/man/al_fixasin.30000644000175000001440000000221712157230671016320 0ustar tjadenusers.TH al_fixasin 3 "" "Allegro reference manual" .SH NAME .PP al_fixasin \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixasin(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP This function finds the inverse sine of a value using a lookup table. The input value must be a fixed point value. The inverse sine is defined only in the domain from \-1 to 1. Outside of this input range, the function will set Allegro\[aq]s errno to EDOM and return zero. .PP Example: .IP .nf \f[C] \ \ \ \ float\ angle; \ \ \ \ al_fixed\ val; \ \ \ \ /*\ Sets\ `val\[aq]\ to\ a\ right\ binary\ angle\ (64).\ */ \ \ \ \ val\ =\ al_fixasin(al_itofix(1)); \ \ \ \ /*\ Sets\ `angle\[aq]\ to\ 0.2405.\ */ \ \ \ \ angle\ =\ al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)),\ al_fixtorad_r)); \ \ \ \ /*\ This\ will\ trigger\ the\ assert.\ */ \ \ \ \ val\ =\ al_fixasin(al_ftofix(\-1.09)); \ \ \ \ assert(!al_get_errno()); \f[] .fi .SH RETURN VALUE .PP Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of the range. All return values of this function will be in the range \-64 to 64. allegro-5.0.10/docs/man/al_register_bitmap_loader.30000644000175000001440000000147512157230674021375 0ustar tjadenusers.TH al_register_bitmap_loader 3 "" "Allegro reference manual" .SH NAME .PP al_register_bitmap_loader \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_bitmap_loader(const\ char\ *extension, \ \ \ ALLEGRO_BITMAP\ *(*loader)(const\ char\ *filename)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_bitmap(3). The given function will be used to handle the loading of bitmaps files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_bitmap_saver(3), al_register_bitmap_loader_f(3) allegro-5.0.10/docs/man/al_get_audio_depth_size.30000644000175000001440000000061612157230677021044 0ustar tjadenusers.TH al_get_audio_depth_size 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_depth_size \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH\ depth) \f[] .fi .SH DESCRIPTION .PP Return the size of a sample, in bytes, for the given format. The format is one of the values listed under ALLEGRO_AUDIO_DEPTH(3). allegro-5.0.10/docs/man/al_get_mouse_event_source.30000644000175000001440000000054112157230674021430 0ustar tjadenusers.TH al_get_mouse_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_mouse_event_source(void) \f[] .fi .SH DESCRIPTION .PP Retrieve the mouse event source. .PP Returns NULL if the mouse subsystem was not installed. allegro-5.0.10/docs/man/al_get_first_config_entry.30000644000175000001440000000126212157230670021411 0ustar tjadenusers.TH al_get_first_config_entry 3 "" "Allegro reference manual" .SH NAME .PP al_get_first_config_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ const\ *al_get_first_config_entry(ALLEGRO_CONFIG\ const\ *config, \ \ \ char\ const\ *section,\ ALLEGRO_CONFIG_ENTRY\ **iterator) \f[] .fi .SH DESCRIPTION .PP Returns the name of the first key in the given section in the given config or NULL if the section is empty. The \f[C]iterator\f[] works like the one for al_get_first_config_section(3). .PP The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG(3). .SH SEE ALSO .PP al_get_next_config_entry(3) allegro-5.0.10/docs/man/al_draw_tinted_rotated_bitmap.30000644000175000001440000000100612157230673022236 0ustar tjadenusers.TH al_draw_tinted_rotated_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_rotated_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ ALLEGRO_COLOR\ tint, \ \ \ float\ cx,\ float\ cy,\ float\ dx,\ float\ dy,\ float\ angle,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_rotated_bitmap(3) but multiplies all colors in the bitmap with the given color. .SH SEE ALSO .PP al_draw_tinted_bitmap(3) allegro-5.0.10/docs/man/al_get_allegro_native_dialog_version.30000644000175000001440000000060512157230700023565 0ustar tjadenusers.TH al_get_allegro_native_dialog_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_native_dialog_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_native_dialog_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/ALLEGRO_EVENT_SOURCE.30000644000175000001440000000117612157230672017315 0ustar tjadenusers.TH ALLEGRO_EVENT_SOURCE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT_SOURCE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_EVENT_SOURCE\ ALLEGRO_EVENT_SOURCE; \f[] .fi .SH DESCRIPTION .PP An event source is any object which can generate events. For example, an ALLEGRO_DISPLAY can generate events, and you can get the ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with al_get_display_event_source(3). .PP You may create your own "user" event sources that emit custom events. .SH SEE ALSO .PP ALLEGRO_EVENT(3), al_init_user_event_source(3), al_emit_user_event(3) allegro-5.0.10/docs/man/al_load_ttf_font.30000644000175000001440000000253012157230700017470 0ustar tjadenusers.TH al_load_ttf_font 3 "" "Allegro reference manual" .SH NAME .PP al_load_ttf_font \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_ttf_font(char\ const\ *filename,\ int\ size,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Loads a TrueType font from a file using the FreeType library. Quoting from the FreeType FAQ this means support for many different font formats: .PP \f[I]TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and others\f[] .PP The \f[I]size\f[] parameter determines the size the font will be rendered at, specified in pixels. The standard font size is measured in \f[I]units per EM\f[], if you instead want to specify the size as the total height of glyphs in pixels, pass it as a negative value. .RS .PP \f[I]Note:\f[] If you want to display text at multiple sizes, load the font multiple times with different size parameters. .RE .PP The following flags are supported: .IP \[bu] 2 ALLEGRO_TTF_NO_KERNING \- Do not use any kerning even if the font file supports it. .IP \[bu] 2 ALLEGRO_TTF_MONOCHROME \- Load as a monochrome font (which means no anti\-aliasing of the font is done). .IP \[bu] 2 ALLEGRO_TTF_NO_AUTOHINT \- Disable the Auto Hinter which is enabled by default in newer versions of FreeType. Since: 5.0.6, 5.1.2 .SH SEE ALSO .PP al_init_ttf_addon(3), al_load_ttf_font_f(3) allegro-5.0.10/docs/man/al_get_bitmap_height.30000644000175000001440000000044112157230673020321 0ustar tjadenusers.TH al_get_bitmap_height 3 "" "Allegro reference manual" .SH NAME .PP al_get_bitmap_height \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_bitmap_height(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the height of a bitmap in pixels. allegro-5.0.10/docs/man/al_get_sample_instance_speed.30000644000175000001440000000057112157230677022052 0ustar tjadenusers.TH al_get_sample_instance_speed 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_speed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_sample_instance_speed(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the relative playback speed. .SH SEE ALSO .PP al_set_sample_instance_speed(3) allegro-5.0.10/docs/man/al_ustr_prev_get.30000644000175000001440000000125512157230676017555 0ustar tjadenusers.TH al_ustr_prev_get 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_prev_get \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int32_t\ al_ustr_prev_get(const\ ALLEGRO_USTR\ *us,\ int\ *pos) \f[] .fi .SH DESCRIPTION .PP Find the beginning of a code point before byte offset \f[C]*pos\f[], then return it. Note this performs a \f[I]pre\-increment\f[]. .PP On success returns the code point value. If \f[C]pos\f[] was out of bounds (e.g. past the end of the string), return \-1. On an error, such as an invalid byte sequence, return \-2. As with al_ustr_prev(3), invalid byte sequences may be skipped while advancing. .SH SEE ALSO .PP al_ustr_get_next(3) allegro-5.0.10/docs/man/al_get_display_height.30000644000175000001440000000055312157230670020513 0ustar tjadenusers.TH al_get_display_height 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_height \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_display_height(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Gets the height of the display. This is like SCREEN_H in Allegro 4.x. .SH SEE ALSO .PP al_get_display_width(3) allegro-5.0.10/docs/man/al_fixatan.30000644000175000001440000000124412157230671016310 0ustar tjadenusers.TH al_fixatan 3 "" "Allegro reference manual" .SH NAME .PP al_fixatan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixatan(al_fixed\ x) \f[] .fi .SH DESCRIPTION .PP This function finds the inverse tangent of a value using a lookup table. The input value must be a fixed point radian. The inverse tangent is the value whose tangent is \f[C]x\f[]. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ Sets\ result\ to\ binary\ angle\ 13.\ */ \ \ \ \ result\ =\ al_fixatan(al_ftofix(0.326)); \f[] .fi .SH RETURN VALUE .PP Returns the inverse tangent of a fixed point value, measured as a fixed point binary format angle. allegro-5.0.10/docs/man/al_get_d3d_system_texture.30000644000175000001440000000074212157230676021362 0ustar tjadenusers.TH al_get_d3d_system_texture 3 "" "Allegro reference manual" .SH NAME .PP al_get_d3d_system_texture \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ LPDIRECT3DTEXTURE9\ al_get_d3d_system_texture(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). This texture is used for the render\-to\-texture feature set. .PP \f[I]Returns:\f[] A pointer to the Direct3D system texture. allegro-5.0.10/docs/man/al_get_bitmap_flags.30000644000175000001440000000051412157230673020146 0ustar tjadenusers.TH al_get_bitmap_flags 3 "" "Allegro reference manual" .SH NAME .PP al_get_bitmap_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_bitmap_flags(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Return the flags used to create the bitmap. .SH SEE ALSO .PP al_set_new_bitmap_flags(3) allegro-5.0.10/docs/man/al_register_sample_loader.30000644000175000001440000000147412157230701021370 0ustar tjadenusers.TH al_register_sample_loader 3 "" "Allegro reference manual" .SH NAME .PP al_register_sample_loader \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_sample_loader(const\ char\ *ext, \ \ \ ALLEGRO_SAMPLE\ *(*loader)(const\ char\ *filename)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_sample(3). The given function will be used to handle the loading of sample files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_sample_loader_f(3), al_register_sample_saver(3) allegro-5.0.10/docs/man/al_get_audio_stream_frequency.30000644000175000001440000000051412157230701022243 0ustar tjadenusers.TH al_get_audio_stream_frequency 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_frequency \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_audio_stream_frequency(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the stream frequency. allegro-5.0.10/docs/man/al_is_joystick_installed.30000644000175000001440000000046112157230672021250 0ustar tjadenusers.TH al_is_joystick_installed 3 "" "Allegro reference manual" .SH NAME .PP al_is_joystick_installed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_joystick_installed(void) \f[] .fi .SH DESCRIPTION .PP Returns true if al_install_joystick(3) was called successfully. allegro-5.0.10/docs/man/al_identity_transform.30000644000175000001440000000125212157230675020605 0ustar tjadenusers.TH al_identity_transform 3 "" "Allegro reference manual" .SH NAME .PP al_identity_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_identity_transform(ALLEGRO_TRANSFORM\ *trans) \f[] .fi .SH DESCRIPTION .PP Sets the transformation to be the identity transformation. This is the default transformation. Use al_use_transform(3) on an identity transformation to return to the default. .IP .nf \f[C] ALLEGRO_TRANSFORM\ t; al_identity_transform(&t); al_use_transform(&t); \f[] .fi .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .SH SEE ALSO .PP al_translate_transform(3), al_rotate_transform(3), al_scale_transform(3) allegro-5.0.10/docs/man/al_color_rgb_to_yuv.30000644000175000001440000000062412157230677020242 0ustar tjadenusers.TH al_color_rgb_to_yuv 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_yuv \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_rgb_to_yuv(float\ red,\ float\ green,\ float\ blue, \ \ \ float\ *y,\ float\ *u,\ float\ *v) \f[] .fi .SH DESCRIPTION .PP Convert RGB values to YUV color space. .SH SEE ALSO .PP al_color_yuv(3), al_color_yuv_to_rgb(3) allegro-5.0.10/docs/man/al_compose_transform.30000644000175000001440000000136212157230675020423 0ustar tjadenusers.TH al_compose_transform 3 "" "Allegro reference manual" .SH NAME .PP al_compose_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_compose_transform(ALLEGRO_TRANSFORM\ *trans,\ const\ ALLEGRO_TRANSFORM\ *other) \f[] .fi .SH DESCRIPTION .PP Compose (combine) two transformations by a matrix multiplication. .IP .nf \f[C] trans\ :=\ trans\ other \f[] .fi .PP Note that the order of matrix multiplications is important. The effect of applying the combined transform will be as if first applying \f[C]trans\f[] and then applying \f[C]other\f[] and not the other way around. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to alter .IP \[bu] 2 other \- Transformation used to transform \f[C]trans\f[] allegro-5.0.10/docs/man/ALLEGRO_FS_INTERFACE.30000644000175000001440000000371312157230672017243 0ustar tjadenusers.TH ALLEGRO_FS_INTERFACE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FS_INTERFACE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FS_INTERFACE\ ALLEGRO_FS_INTERFACE; \f[] .fi .SH DESCRIPTION .PP The available functions you can provide for a filesystem. They are: .IP .nf \f[C] \ \ \ ALLEGRO_FS_ENTRY\ *\ \ fs_create_entry\ \ \ (const\ char\ *path); \ \ \ void\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_destroy_entry\ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ const\ char\ *\ \ \ \ \ \ \ \ fs_entry_name\ \ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_update_entry\ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ uint32_t\ \ \ \ \ \ \ \ \ \ \ \ fs_entry_mode\ \ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ time_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_entry_atime\ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ time_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_entry_mtime\ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ time_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_entry_ctime\ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ off_t\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_entry_size\ \ \ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_entry_exists\ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_remove_entry\ \ \ (ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_open_directory\ (ALLEGRO_FS_ENTRY\ *e); \ \ \ ALLEGRO_FS_ENTRY\ *\ \ fs_read_directory\ (ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_close_directory(ALLEGRO_FS_ENTRY\ *e); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_filename_exists(const\ char\ *path); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_remove_filename(const\ char\ *path); \ \ \ char\ *\ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_get_current_directory(void); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_change_directory(const\ char\ *path); \ \ \ bool\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fs_make_directory(const\ char\ *path); \ \ \ ALLEGRO_FILE\ *\ \ \ \ \ \ fs_open_file(ALLEGRO_FS_ENTRY\ *e); \f[] .fi allegro-5.0.10/docs/man/al_fixed.30000644000175000001440000000306412157230671015757 0ustar tjadenusers.TH al_fixed 3 "" "Allegro reference manual" .SH NAME .PP al_fixed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ int32_t\ al_fixed; \f[] .fi .SH DESCRIPTION .PP A fixed point number. .PP Allegro provides some routines for working with fixed point numbers, and defines the type \f[C]al_fixed\f[] to be a signed 32\-bit integer. The high word is used for the integer part and the low word for the fraction, giving a range of \-32768 to 32767 and an accuracy of about four or five decimal places. Fixed point numbers can be assigned, compared, added, subtracted, negated and shifted (for multiplying or dividing by powers of two) using the normal integer operators, but you should take care to use the appropriate conversion routines when mixing fixed point with integer or floating point values. Writing \f[C]fixed_point_1\ +\ fixed_point_2\f[] is OK, but \f[C]fixed_point\ +\ integer\f[] is not. .PP The only advantage of fixed point math routines is that you don\[aq]t require a floating point coprocessor to use them. This was great in the time period of i386 and i486 machines, but stopped being so useful with the coming of the Pentium class of processors. From Pentium onwards, CPUs have increased their strength in floating point operations, equaling or even surpassing integer math performance. .PP Depending on the type of operations your program may need, using floating point types may be faster than fixed types if you are targeting a specific machine class. Many embedded processors have no FPUs so fixed point maths can be useful there. allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_LOST.30000644000175000001440000002700512157230671020261 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_ustr_set_chr.30000644000175000001440000000143412157230677017371 0ustar tjadenusers.TH al_ustr_set_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_set_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_set_chr(ALLEGRO_USTR\ *us,\ int\ start_pos,\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Replace the code point beginning at byte offset \f[C]pos\f[] with \f[C]c\f[]. \f[C]pos\f[] cannot be less than 0. If \f[C]pos\f[] is past the end of \f[C]us1\f[] then the space between the end of the string and \f[C]pos\f[] will be padded with NUL (\[aq]\[aq]) bytes. If \f[C]pos\f[] is not the start of a valid code point, that is an error and the string will be unmodified. .PP On success, returns the number of bytes written, i.e. the offset to the following code point. On error, returns 0. .SH SEE ALSO .PP al_ustr_replace_range(3) allegro-5.0.10/docs/man/al_color_cmyk.30000644000175000001440000000063412157230676017026 0ustar tjadenusers.TH al_color_cmyk 3 "" "Allegro reference manual" .SH NAME .PP al_color_cmyk \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_cmyk(float\ c,\ float\ m,\ float\ y,\ float\ k) \f[] .fi .SH DESCRIPTION .PP Return an ALLEGRO_COLOR(3) structure from CMYK values (cyan, magenta, yellow, black). .SH SEE ALSO .PP al_color_cmyk_to_rgb(3), al_color_rgb_to_cmyk(3) allegro-5.0.10/docs/man/al_destroy_config.30000644000175000001440000000057712157230670017703 0ustar tjadenusers.TH al_destroy_config 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_config \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_config(ALLEGRO_CONFIG\ *config) \f[] .fi .SH DESCRIPTION .PP Free the resources used by a configuration structure. Does nothing if passed NULL. .SH SEE ALSO .PP al_create_config(3), al_load_config_file(3) allegro-5.0.10/docs/man/al_unlock_bitmap.30000644000175000001440000000073612157230672017513 0ustar tjadenusers.TH al_unlock_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_unlock_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unlock_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Unlock a previously locked bitmap or bitmap region. If the bitmap is a display bitmap, the texture will be updated to match the system memory copy (unless it was locked read only). .SH SEE ALSO .PP al_lock_bitmap(3), al_lock_bitmap_region(3) allegro-5.0.10/docs/man/al_remove_opengl_fbo.30000644000175000001440000000073312157230676020354 0ustar tjadenusers.TH al_remove_opengl_fbo 3 "" "Allegro reference manual" .SH NAME .PP al_remove_opengl_fbo \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_remove_opengl_fbo(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Explicitly free an OpenGL FBO created for a bitmap, if it has one. Usually you do not need to worry about freeing FBOs, unless you use al_get_opengl_fbo(3). .SH SEE ALSO .PP al_get_opengl_fbo(3), al_set_target_bitmap(3) allegro-5.0.10/docs/man/al_get_d3d_device.30000644000175000001440000000070012157230676017507 0ustar tjadenusers.TH al_get_d3d_device 3 "" "Allegro reference manual" .SH NAME .PP al_get_d3d_device \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ LPDIRECT3DDEVICE9\ al_get_d3d_device(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Returns the Direct3D device of the display. The return value is undefined if the display was not created with the Direct3D flag. .PP \f[I]Returns:\f[] A pointer to the Direct3D device. allegro-5.0.10/docs/man/al_load_audio_stream.30000644000175000001440000000213712157230702020326 0ustar tjadenusers.TH al_load_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_load_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_STREAM\ *al_load_audio_stream(const\ char\ *filename, \ \ \ size_t\ buffer_count,\ unsigned\ int\ samples) \f[] .fi .SH DESCRIPTION .PP Loads an audio file from disk as it is needed. .PP Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain \f[I]buffer_count\f[] buffers with \f[I]samples\f[] samples. .PP The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM(3) for more details. .PP Returns the stream on success, NULL on failure. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_load_audio_stream_f(3), al_register_audio_stream_loader(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_set_voice_position.30000644000175000001440000000075212157230677020573 0ustar tjadenusers.TH al_set_voice_position 3 "" "Allegro reference manual" .SH NAME .PP al_set_voice_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_voice_position(ALLEGRO_VOICE\ *voice,\ unsigned\ int\ val) \f[] .fi .SH DESCRIPTION .PP Set the voice position. This can only work if the voice has a non\-streaming object attached to it, e.g. a sample instance. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_voice_position(3). allegro-5.0.10/docs/man/al_get_path_num_components.30000644000175000001440000000070012157230674021574 0ustar tjadenusers.TH al_get_path_num_components 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_num_components \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_path_num_components(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Return the number of directory components in a path. .PP The directory components do not include the final part of a path (the filename). .SH SEE ALSO .PP al_get_path_component(3) allegro-5.0.10/docs/man/al_set_sample_instance_position.30000644000175000001440000000072212157230677022630 0ustar tjadenusers.TH al_set_sample_instance_position 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE\ *spl, \ \ \ unsigned\ int\ val) \f[] .fi .SH DESCRIPTION .PP Set the playback position of a sample instance. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_sample_instance_position(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_DISPLAY_FOUND.30000644000175000001440000002700512157230671020353 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_audio_stream_position_secs.30000644000175000001440000000074212157230701023126 0ustar tjadenusers.TH al_get_audio_stream_position_secs 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_position_secs \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ double\ al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the position of the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream(3). .SH SEE ALSO .PP al_get_audio_stream_length_secs(3) allegro-5.0.10/docs/man/al_draw_rotated_bitmap.30000644000175000001440000000250712157230673020676 0ustar tjadenusers.TH al_draw_rotated_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_rotated_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_rotated_bitmap(ALLEGRO_BITMAP\ *bitmap, \ \ \ float\ cx,\ float\ cy,\ float\ dx,\ float\ dy,\ float\ angle,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Draws a rotated version of the given bitmap to the target bitmap. The bitmap is rotated by \[aq]angle\[aq] radians clockwise. .PP The point at cx/cy relative to the upper left corner of the bitmap will be drawn at dx/dy and the bitmap is rotated around this point. If cx,cy is 0,0 the bitmap will rotate around its upper left corner. .IP \[bu] 2 cx \- center x (relative to the bitmap) .IP \[bu] 2 cy \- center y (relative to the bitmap) .IP \[bu] 2 dx \- destination x .IP \[bu] 2 dy \- destination y .IP \[bu] 2 angle \- angle by which to rotate (radians) .IP \[bu] 2 flags \- same as for al_draw_bitmap(3) .PP Example .IP .nf \f[C] float\ w\ =\ al_get_bitmap_width(bitmap); float\ h\ =\ al_get_bitmap_height(bitmap); al_draw_rotated_bitmap(bitmap,\ w\ /\ 2,\ h\ /\ 2,\ x,\ y,\ ALLEGRO_PI\ /\ 2,\ 0); \f[] .fi .PP The above code draws the bitmap centered on x/y and rotates it 90° clockwise. .SH SEE ALSO .PP al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), al_draw_scaled_rotated_bitmap(3) allegro-5.0.10/docs/man/al_get_audio_stream_fragments.30000644000175000001440000000077112157230701022235 0ustar tjadenusers.TH al_get_audio_stream_fragments 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_fragments \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_audio_stream_fragments(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Returns the number of fragments this stream uses. This is the same value as passed to al_create_audio_stream(3) when a new stream is created. .SH SEE ALSO .PP al_get_available_audio_stream_fragments(3) allegro-5.0.10/docs/man/al_fread32be.30000644000175000001440000000103412157230671016410 0ustar tjadenusers.TH al_fread32be 3 "" "Allegro reference manual" .SH NAME .PP al_fread32be \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int32_t\ al_fread32be(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Read a 32\-bit word in big\-endian format (MSB first). .PP On success, returns the 32\-bit word. On failure, returns EOF (\-1). Since \-1 is also a valid return value, use al_feof(3) to check if the end of the file was reached prematurely, or al_ferror(3) to check if an error occurred. .SH SEE ALSO .PP al_fread32le(3) allegro-5.0.10/docs/man/al_get_audio_stream_gain.30000644000175000001440000000054012157230701021157 0ustar tjadenusers.TH al_get_audio_stream_gain 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_audio_stream_gain(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the playback gain. .SH SEE ALSO .PP al_set_audio_stream_gain(3). allegro-5.0.10/docs/man/al_ustr_next.30000644000175000001440000000154712157230676016724 0ustar tjadenusers.TH al_ustr_next 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_next \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_next(const\ ALLEGRO_USTR\ *us,\ int\ *pos) \f[] .fi .SH DESCRIPTION .PP Find the byte offset of the next code point in string, beginning at \f[C]*pos\f[]. \f[C]*pos\f[] does not have to be at the beginning of a code point. .PP Returns true on success, and the value pointed to by \f[C]pos\f[] will be updated to the found offset. Otherwise returns false if \f[C]*pos\f[] was already at the end of the string, and \f[C]*pos\f[] is unmodified. .PP This function just looks for an appropriate byte; it doesn\[aq]t check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF\-8 strings then it could skip over some invalid bytes. .SH SEE ALSO .PP al_ustr_prev(3) allegro-5.0.10/docs/man/al_draw_filled_circle.30000644000175000001440000000101612157230700020441 0ustar tjadenusers.TH al_draw_filled_circle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_circle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_circle(float\ cx,\ float\ cy,\ float\ r,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a filled circle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the circle .IP \[bu] 2 r \- Radius of the circle .IP \[bu] 2 color \- Color of the circle .SH SEE ALSO .PP al_draw_circle(3), al_draw_filled_ellipse(3) allegro-5.0.10/docs/man/al_init_image_addon.30000644000175000001440000000133612157230677020140 0ustar tjadenusers.TH al_init_image_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_image_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_init_image_addon(void) \f[] .fi .SH DESCRIPTION .PP Initializes the image addon. This registers bitmap format handlers for al_load_bitmap(3), al_load_bitmap_f(3), al_save_bitmap(3), al_save_bitmap_f(3). .PP The following types are built into the Allegro image addon and guaranteed to be available: BMP, PCX, TGA. Every platform also supports JPEG and PNG via external dependencies. .PP Other formats may be available depending on the operating system and installed libraries, but are not guaranteed and should not be assumed to be universally available. allegro-5.0.10/docs/man/al_fputc.30000644000175000001440000000074012157230671015777 0ustar tjadenusers.TH al_fputc 3 "" "Allegro reference manual" .SH NAME .PP al_fputc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fputc(ALLEGRO_FILE\ *f,\ int\ c) \f[] .fi .SH DESCRIPTION .PP Write a single byte to the given file. The byte written is the value of c cast to an unsigned char. .PP Parameters: .IP \[bu] 2 c \- byte value to write .IP \[bu] 2 f \- file to write to .PP Returns the written byte (cast back to an int) on success, or EOF on error. allegro-5.0.10/docs/man/al_destroy_path.30000644000175000001440000000053512157230673017367 0ustar tjadenusers.TH al_destroy_path 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_path(ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Free a path structure. Does nothing if passed NULL. .SH SEE ALSO .PP al_create_path(3), al_create_path_for_directory(3) allegro-5.0.10/docs/man/ALLEGRO_AUDIO_DEPTH.30000644000175000001440000000133612157230676017143 0ustar tjadenusers.TH ALLEGRO_AUDIO_DEPTH 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_AUDIO_DEPTH \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ ALLEGRO_AUDIO_DEPTH \f[] .fi .SH DESCRIPTION .PP Sample depth and type, and signedness. Mixers only use 32\-bit signed float (\-1..+1), or 16\-bit signed integers. The unsigned value is a bit\-flag applied to the depth value. .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_INT8 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_INT16 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_INT24 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_FLOAT32 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_UNSIGNED .PP For convenience: .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_UINT8 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_UINT16 .IP \[bu] 2 ALLEGRO_AUDIO_DEPTH_UINT24 allegro-5.0.10/docs/man/al_destroy_event_queue.30000644000175000001440000000073712157230672020763 0ustar tjadenusers.TH al_destroy_event_queue 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_event_queue \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_event_queue(ALLEGRO_EVENT_QUEUE\ *queue) \f[] .fi .SH DESCRIPTION .PP Destroy the event queue specified. All event sources currently registered with the queue will be automatically unregistered before the queue is destroyed. .SH SEE ALSO .PP al_create_event_queue(3), ALLEGRO_EVENT_QUEUE(3) allegro-5.0.10/docs/man/al_register_event_source.30000644000175000001440000000114412157230672021263 0ustar tjadenusers.TH al_register_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_register_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_register_event_source(ALLEGRO_EVENT_QUEUE\ *queue, \ \ \ ALLEGRO_EVENT_SOURCE\ *source) \f[] .fi .SH DESCRIPTION .PP Register the event source with the event queue specified. An event source may be registered with any number of event queues simultaneously, or none. Trying to register an event source with the same event queue more than once does nothing. .SH SEE ALSO .PP al_unregister_event_source(3), ALLEGRO_EVENT_SOURCE(3) allegro-5.0.10/docs/man/al_shutdown_primitives_addon.30000644000175000001440000000066512157230700022150 0ustar tjadenusers.TH al_shutdown_primitives_addon 3 "" "Allegro reference manual" .SH NAME .PP al_shutdown_primitives_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_shutdown_primitives_addon(void) \f[] .fi .SH DESCRIPTION .PP Shut down the primitives addon. This is done automatically at program exit, but can be called any time the user wishes as well. .SH SEE ALSO .PP al_init_primitives_addon(3) allegro-5.0.10/docs/man/al_ustr_newf.30000644000175000001440000000176312157230675016704 0ustar tjadenusers.TH al_ustr_newf 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_newf \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_newf(const\ char\ *fmt,\ ...) \f[] .fi .SH DESCRIPTION .PP Create a new string using a printf\-style format string. .PP \f[I]Notes:\f[] .PP The "%s" specifier takes C string arguments, not ALLEGRO_USTRs. Therefore to pass an ALLEGRO_USTR as a parameter you must use al_cstr(3), and it must be NUL terminated. If the string contains an embedded NUL byte everything from that byte onwards will be ignored. .PP The "%c" specifier outputs a single byte, not the UTF\-8 encoding of a code point. Therefore it is only usable for ASCII characters (value <= 127) or if you really mean to output byte values from 128\-\-255. To insert the UTF\-8 encoding of a code point, encode it into a memory buffer using al_utf8_encode(3) then use the "%s" specifier. Remember to NUL terminate the buffer. .SH SEE ALSO .PP al_ustr_new(3), al_ustr_appendf(3) allegro-5.0.10/docs/man/ALLEGRO_COND.30000644000175000001440000000043012157230674016071 0ustar tjadenusers.TH ALLEGRO_COND 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_COND \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_COND\ ALLEGRO_COND; \f[] .fi .SH DESCRIPTION .PP An opaque structure representing a condition variable. allegro-5.0.10/docs/man/al_get_display_event_source.30000644000175000001440000000050612157230670021742 0ustar tjadenusers.TH al_get_display_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_display_event_source(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Retrieve the associated event source. allegro-5.0.10/docs/man/al_remove_filename.30000644000175000001440000000105012157230672020007 0ustar tjadenusers.TH al_remove_filename 3 "" "Allegro reference manual" .SH NAME .PP al_remove_filename \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_remove_filename(const\ char\ *path) \f[] .fi .SH DESCRIPTION .PP Delete the given path from the filesystem, which may be a file or an empty directory. This is the same as al_remove_fs_entry(3), except it expects the path as a string. .PP Returns true on success, and false on failure. Allegro\[aq]s errno is filled in to indicate the error. .SH SEE ALSO .PP al_remove_fs_entry(3) allegro-5.0.10/docs/man/al_shutdown_ttf_addon.30000644000175000001440000000046312157230700020546 0ustar tjadenusers.TH al_shutdown_ttf_addon 3 "" "Allegro reference manual" .SH NAME .PP al_shutdown_ttf_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_shutdown_ttf_addon(void) \f[] .fi .SH DESCRIPTION .PP Unloads the ttf addon again. You normally don\[aq]t need to call this. allegro-5.0.10/docs/man/al_ustr_find_cstr.30000644000175000001440000000065012157230677017714 0ustar tjadenusers.TH al_ustr_find_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_cstr(const\ ALLEGRO_USTR\ *haystack,\ int\ start_pos, \ \ \ const\ char\ *needle) \f[] .fi .SH DESCRIPTION .PP Like al_ustr_find_str(3) but takes a C\-style string for \f[C]needle\f[]. .SH SEE ALSO .PP al_ustr_find_str(3), al_ustr_rfind_cstr(3) allegro-5.0.10/docs/man/al_fwrite32be.30000644000175000001440000000062612157230671016635 0ustar tjadenusers.TH al_fwrite32be 3 "" "Allegro reference manual" .SH NAME .PP al_fwrite32be \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fwrite32be(ALLEGRO_FILE\ *f,\ int32_t\ l) \f[] .fi .SH DESCRIPTION .PP Writes a 32\-bit word in big\-endian format (MSB first). .PP Returns the number of bytes written: 4 on success, less than 4 on an error. .SH SEE ALSO .PP al_fwrite32le(3) allegro-5.0.10/docs/man/al_detach_audio_stream.30000644000175000001440000000070712157230701020637 0ustar tjadenusers.TH al_detach_audio_stream 3 "" "Allegro reference manual" .SH NAME .PP al_detach_audio_stream \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_detach_audio_stream(ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Detach the stream from whatever it\[aq]s attached to, if anything. .SH SEE ALSO .PP al_attach_audio_stream_to_mixer(3), al_attach_audio_stream_to_voice(3), al_get_audio_stream_attached(3). allegro-5.0.10/docs/man/al_get_audio_stream_pan.30000644000175000001440000000052512157230701021022 0ustar tjadenusers.TH al_get_audio_stream_pan 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_pan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_audio_stream_pan(const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Get the pan value. .SH SEE ALSO .PP al_set_audio_stream_pan(3). allegro-5.0.10/docs/man/al_fopen.30000644000175000001440000000252612157230671015771 0ustar tjadenusers.TH al_fopen 3 "" "Allegro reference manual" .SH NAME .PP al_fopen \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_fopen(const\ char\ *path,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Creates and opens a file (real or virtual) given the path and mode. The current file interface is used to open the file. .PP Parameters: .IP \[bu] 2 path \- path to the file to open .IP \[bu] 2 mode \- access mode to open the file in ("r", "w", etc.) .PP Depending on the stream type and the mode string, files may be opened in "text" mode. The handling of newlines is particularly important. For example, using the default stdio\-based streams on DOS and Windows platforms, where the native end\-of\-line terminators are CR+LF sequences, a call to al_fgetc(3) may return just one character (\[aq]\\n\[aq]) where there were two bytes (CR+LF) in the file. When writing out \[aq]\\n\[aq], two bytes would be written instead. (As an aside, \[aq]\\n\[aq] is not defined to be equal to LF either.) .PP Newline translations can be useful for text files but is disastrous for binary files. To avoid this behaviour you need to open file streams in binary mode by using a mode argument containing a "b", e.g. "rb", "wb". .PP Returns a file handle on success, or NULL on error. .SH SEE ALSO .PP al_set_new_file_interface(3), al_fclose(3). allegro-5.0.10/docs/man/ALLEGRO_COLOR.30000644000175000001440000000063312157230672016227 0ustar tjadenusers.TH ALLEGRO_COLOR 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_COLOR \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_COLOR\ ALLEGRO_COLOR; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_COLOR structure describes a color in a device independent way. Use al_map_rgb(3) et al. and al_unmap_rgb(3) et al. to translate from and to various color representations. allegro-5.0.10/docs/man/al_create_mouse_cursor.30000644000175000001440000000074712157230674020740 0ustar tjadenusers.TH al_create_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_create_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MOUSE_CURSOR\ *al_create_mouse_cursor(ALLEGRO_BITMAP\ *bmp, \ \ \ int\ x_focus,\ int\ y_focus) \f[] .fi .SH DESCRIPTION .PP Create a mouse cursor from the bitmap provided. .PP Returns a pointer to the cursor on success, or NULL on failure. .SH SEE ALSO .PP al_set_mouse_cursor(3), al_destroy_mouse_cursor(3) allegro-5.0.10/docs/man/al_uninstall_joystick.30000644000175000001440000000077212157230672020614 0ustar tjadenusers.TH al_uninstall_joystick 3 "" "Allegro reference manual" .SH NAME .PP al_uninstall_joystick \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_uninstall_joystick(void) \f[] .fi .SH DESCRIPTION .PP Uninstalls the active joystick driver. All outstanding ALLEGRO_JOYSTICK(3) structures are invalidated. If no joystick driver was active, this function does nothing. .PP This function is automatically called when Allegro is shut down. .SH SEE ALSO .PP al_install_joystick(3) allegro-5.0.10/docs/man/al_draw_ellipse.30000644000175000001440000000121612157230700017320 0ustar tjadenusers.TH al_draw_ellipse 3 "" "Allegro reference manual" .SH NAME .PP al_draw_ellipse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_ellipse(float\ cx,\ float\ cy,\ float\ rx,\ float\ ry, \ \ \ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an outlined ellipse. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the ellipse .IP \[bu] 2 rx, ry \- Radii of the ellipse .IP \[bu] 2 color \- Color of the ellipse .IP \[bu] 2 thickness \- Thickness of the ellipse, pass \f[C]<=\ 0\f[] to draw a hairline ellipse .SH SEE ALSO .PP al_draw_filled_ellipse(3), al_draw_circle(3) allegro-5.0.10/docs/man/al_get_first_config_section.30000644000175000001440000000140012157230670021706 0ustar tjadenusers.TH al_get_first_config_section 3 "" "Allegro reference manual" .SH NAME .PP al_get_first_config_section \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ const\ *al_get_first_config_section(ALLEGRO_CONFIG\ const\ *config, \ \ \ ALLEGRO_CONFIG_SECTION\ **iterator) \f[] .fi .SH DESCRIPTION .PP Returns the name of the first section in the given config file. Usually this will return an empty string for the global section. The \f[C]iterator\f[] parameter will receive an opaque iterator which is used by al_get_next_config_section(3) to iterate over the remaining sections. .PP The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG. .SH SEE ALSO .PP al_get_next_config_section(3) allegro-5.0.10/docs/man/al_fwrite16le.30000644000175000001440000000063112157230671016645 0ustar tjadenusers.TH al_fwrite16le 3 "" "Allegro reference manual" .SH NAME .PP al_fwrite16le \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fwrite16le(ALLEGRO_FILE\ *f,\ int16_t\ w) \f[] .fi .SH DESCRIPTION .PP Writes a 16\-bit word in little\-endian format (LSB first). .PP Returns the number of bytes written: 2 on success, less than 2 on an error. .SH SEE ALSO .PP al_fwrite16be(3) allegro-5.0.10/docs/man/al_ustr_insert_chr.30000644000175000001440000000120312157230676020073 0ustar tjadenusers.TH al_ustr_insert_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_insert_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_insert_chr(ALLEGRO_USTR\ *us,\ int\ pos,\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Insert a code point into \f[C]us\f[] beginning at byte offset \f[C]pos\f[]. \f[C]pos\f[] cannot be less than 0. If \f[C]pos\f[] is past the end of \f[C]us\f[] then the space between the end of the string and \f[C]pos\f[] will be padded with NUL (\[aq]\[aq]) bytes. .PP Returns the number of bytes inserted, or 0 on error. .SH SEE ALSO .PP al_ustr_insert(3), al_ustr_insert_cstr(3) allegro-5.0.10/docs/man/al_ustr_append_cstr.30000644000175000001440000000061612157230676020244 0ustar tjadenusers.TH al_ustr_append_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_append_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_append_cstr(ALLEGRO_USTR\ *us,\ const\ char\ *s) \f[] .fi .SH DESCRIPTION .PP Append C\-style string \f[C]s\f[] to the end of \f[C]us\f[]. .PP Returns true on success, false on error. .SH SEE ALSO .PP al_ustr_append(3) allegro-5.0.10/docs/man/al_destroy_font.30000644000175000001440000000052612157230677017405 0ustar tjadenusers.TH al_destroy_font 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_font \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_font(ALLEGRO_FONT\ *f) \f[] .fi .SH DESCRIPTION .PP Frees the memory being used by a font structure. Does nothing if passed NULL. .SH SEE ALSO .PP al_load_font(3) allegro-5.0.10/docs/man/al_open_fs_entry.30000644000175000001440000000114312157230672017527 0ustar tjadenusers.TH al_open_fs_entry 3 "" "Allegro reference manual" .SH NAME .PP al_open_fs_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FILE\ *al_open_fs_entry(ALLEGRO_FS_ENTRY\ *e,\ const\ char\ *mode) \f[] .fi .SH DESCRIPTION .PP Open an ALLEGRO_FILE(3) handle to a filesystem entry, for the given access mode. This is like calling al_fopen(3) with the name of the filesystem entry, but uses the appropriate file interface, not whatever was set with the latest call to al_set_new_file_interface(3). .PP Returns the handle on success, NULL on error. .SH SEE ALSO .PP al_fopen(3) allegro-5.0.10/docs/man/ALLEGRO_DISPLAY.30000644000175000001440000000044412157230670016454 0ustar tjadenusers.TH ALLEGRO_DISPLAY 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_DISPLAY \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_DISPLAY\ ALLEGRO_DISPLAY; \f[] .fi .SH DESCRIPTION .PP An opaque type representing an open display or window. allegro-5.0.10/docs/man/al_utf16_encode.30000644000175000001440000000115312157230677017145 0ustar tjadenusers.TH al_utf16_encode 3 "" "Allegro reference manual" .SH NAME .PP al_utf16_encode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_utf16_encode(uint16_t\ s[],\ int32_t\ c) \f[] .fi .SH DESCRIPTION .PP Encode the specified code point to UTF\-16 into the buffer \f[C]s\f[]. The buffer must have enough space to hold the encoding, which takes either 2 or 4 bytes. This routine will refuse to encode code points above 0x10FFFF. .PP Returns the number of bytes written, which is the same as that returned by al_utf16_width(3). .SH SEE ALSO .PP al_utf8_encode(3), al_ustr_encode_utf16(3) allegro-5.0.10/docs/man/al_attach_mixer_to_voice.30000644000175000001440000000077412157230677021232 0ustar tjadenusers.TH al_attach_mixer_to_voice 3 "" "Allegro reference manual" .SH NAME .PP al_attach_mixer_to_voice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_attach_mixer_to_voice(ALLEGRO_MIXER\ *mixer,\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Attaches a mixer to a voice. The same rules as al_attach_sample_instance_to_voice(3) apply, with the exception of the depth requirement. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_detach_voice(3) allegro-5.0.10/docs/man/al_get_system_config.30000644000175000001440000000073312157230674020373 0ustar tjadenusers.TH al_get_system_config 3 "" "Allegro reference manual" .SH NAME .PP al_get_system_config \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CONFIG\ *al_get_system_config(void) \f[] .fi .SH DESCRIPTION .PP Returns the current system configuration structure, or NULL if there is no active system driver. The returned configuration should not be destroyed with al_destroy_config(3). This is mainly used for configuring Allegro and its addons. allegro-5.0.10/docs/man/al_ustr_encode_utf16.30000644000175000001440000000125412157230677020224 0ustar tjadenusers.TH al_ustr_encode_utf16 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_encode_utf16 \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_ustr_encode_utf16(const\ ALLEGRO_USTR\ *us,\ uint16_t\ *s, \ \ \ size_t\ n) \f[] .fi .SH DESCRIPTION .PP Encode the string into the given buffer, in UTF\-16. Returns the number of bytes written. There are never more than \f[C]n\f[] bytes written. The minimum size to encode the complete string can be queried with al_ustr_size_utf16(3). If the \f[C]n\f[] parameter is smaller than that, the string will be truncated but still always 0 terminated. .SH SEE ALSO .PP al_ustr_size_utf16(3), al_utf16_encode(3) allegro-5.0.10/docs/man/al_map_rgb.30000644000175000001440000000064412157230672016271 0ustar tjadenusers.TH al_map_rgb 3 "" "Allegro reference manual" .SH NAME .PP al_map_rgb \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_map_rgb( \ \ \ unsigned\ char\ r,\ unsigned\ char\ g,\ unsigned\ char\ b) \f[] .fi .SH DESCRIPTION .PP Convert r, g, b (ranging from 0\-255) into an ALLEGRO_COLOR(3), using 255 for alpha. .SH SEE ALSO .PP al_map_rgba(3), al_map_rgba_f(3), al_map_rgb_f(3) allegro-5.0.10/docs/man/al_get_num_joysticks.30000644000175000001440000000102712157230673020417 0ustar tjadenusers.TH al_get_num_joysticks 3 "" "Allegro reference manual" .SH NAME .PP al_get_num_joysticks \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_num_joysticks(void) \f[] .fi .SH DESCRIPTION .PP Return the number of joysticks currently on the system (or potentially on the system). This number can change after al_reconfigure_joysticks(3) is called, in order to support hotplugging. .PP Returns 0 if there is no joystick driver installed. .SH SEE ALSO .PP al_get_joystick(3), al_get_joystick_active(3) allegro-5.0.10/docs/man/al_iphone_program_has_halted.30000644000175000001440000000202012157230675022040 0ustar tjadenusers.TH al_iphone_program_has_halted 3 "" "Allegro reference manual" .SH NAME .PP al_iphone_program_has_halted \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_iphone_program_has_halted(void) \f[] .fi .SH DESCRIPTION .PP Multitasking on iOS is different than on other platforms. When an application receives an ALLEGRO_DISPLAY_SWITCH_OUT or ALLEGRO_DISPLAY_CLOSE event on a multitasking\-capable device, it should cease all activity and do nothing but check for an ALLEGRO_DISPLAY_SWITCH_IN event. To let the iPhone driver know that you\[aq]ve ceased all activity, call this function. You should call this function very soon after receiving the event telling you it\[aq]s time to switch out (within a couple milliseconds). Certain operations, if done, will crash the program after this call, most notably any function which uses OpenGL. This function is needed because the "switch out" handler on iPhone can\[aq]t return until these operations have stopped, or a crash as described before can happen. allegro-5.0.10/docs/man/al_get_path_drive.30000644000175000001440000000077312157230674017653 0ustar tjadenusers.TH al_get_path_drive 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_drive \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_drive(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Return the drive letter on a path, or the empty string if there is none. .PP The "drive letter" is only used on Windows, and is usually a string like "c:", but may be something like "\\\\Computer Name" in the case of UNC (Uniform Naming Convention) syntax. allegro-5.0.10/docs/man/al_set_new_window_position.30000644000175000001440000000107712157230670021640 0ustar tjadenusers.TH al_set_new_window_position 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_window_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_window_position(int\ x,\ int\ y) \f[] .fi .SH DESCRIPTION .PP Sets where the top left pixel of the client area of newly created windows (non\-fullscreen) will be on screen, for displays created by the calling thread. Negative values allowed on some multihead systems. .PP To reset to the default behaviour, pass (INT_MAX, INT_MAX). .SH SEE ALSO .PP al_get_new_window_position(3) allegro-5.0.10/docs/man/al_set_fs_interface.30000644000175000001440000000064012157230672020161 0ustar tjadenusers.TH al_set_fs_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_fs_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_fs_interface(const\ ALLEGRO_FS_INTERFACE\ *fs_interface) \f[] .fi .SH DESCRIPTION .PP Set the ALLEGRO_FS_INTERFACE(3) table for the calling thread. .SH SEE ALSO .PP al_set_standard_fs_interface(3), al_store_state(3), al_restore_state(3). allegro-5.0.10/docs/man/al_register_sample_saver.30000644000175000001440000000150212157230701021232 0ustar tjadenusers.TH al_register_sample_saver 3 "" "Allegro reference manual" .SH NAME .PP al_register_sample_saver \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_sample_saver(const\ char\ *ext, \ \ \ bool\ (*saver)(const\ char\ *filename,\ ALLEGRO_SAMPLE\ *spl)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_save_sample(3). The given function will be used to handle the saving of sample files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]saver\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_sample_saver_f(3), al_register_sample_loader(3) allegro-5.0.10/docs/man/al_get_allegro_color_version.30000644000175000001440000000054512157230677022116 0ustar tjadenusers.TH al_get_allegro_color_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_color_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_color_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_destroy_native_file_dialog.30000644000175000001440000000052612157230700022226 0ustar tjadenusers.TH al_destroy_native_file_dialog 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_native_file_dialog \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER\ *dialog) \f[] .fi .SH DESCRIPTION .PP Frees up all resources used by the file dialog. allegro-5.0.10/docs/man/al_draw_bitmap.30000644000175000001440000000254612157230673017157 0ustar tjadenusers.TH al_draw_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_draw_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_bitmap(ALLEGRO_BITMAP\ *bitmap,\ float\ dx,\ float\ dy,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Draws an unscaled, unrotated bitmap at the given position to the current target bitmap (see al_set_target_bitmap(3)). .PP \f[C]flags\f[] can be a combination of: .IP \[bu] 2 ALLEGRO_FLIP_HORIZONTAL \- flip the bitmap about the y\-axis .IP \[bu] 2 ALLEGRO_FLIP_VERTICAL \- flip the bitmap about the x\-axis .RS .PP \f[I]Note:\f[] The current target bitmap must be a different bitmap. Drawing a bitmap to itself (or to a sub\-bitmap of itself) or drawing a sub\-bitmap to its parent (or another sub\-bitmap of its parent) are not currently supported. To copy part of a bitmap into the same bitmap simply use a temporary bitmap instead. .RE .RS .PP \f[I]Note:\f[] The backbuffer (or a sub\-bitmap thereof) can not be transformed, blended or tinted. If you need to draw the backbuffer draw it to a temporary bitmap first with no active transformation (except translation). Blending and tinting settings/parameters will be ignored. This does not apply when drawing into a memory bitmap. .RE .SH SEE ALSO .PP al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), al_draw_rotated_bitmap(3), al_draw_scaled_rotated_bitmap(3) allegro-5.0.10/docs/man/ALLEGRO_FILE.30000644000175000001440000000050212157230671016062 0ustar tjadenusers.TH ALLEGRO_FILE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FILE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FILE\ ALLEGRO_FILE; \f[] .fi .SH DESCRIPTION .PP An opaque object representing an open file. This could be a real file on disk or a virtual file. allegro-5.0.10/docs/man/ALLEGRO_TEXTLOG.30000644000175000001440000000043712157230700016471 0ustar tjadenusers.TH ALLEGRO_TEXTLOG 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_TEXTLOG \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_TEXTLOG\ ALLEGRO_TEXTLOG; \f[] .fi .SH DESCRIPTION .PP Opaque handle to a text log window. allegro-5.0.10/docs/man/al_get_sample_instance_pan.30000644000175000001440000000054112157230700021510 0ustar tjadenusers.TH al_get_sample_instance_pan 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_pan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_sample_instance_pan(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Get the pan value. .SH SEE ALSO .PP al_set_sample_instance_pan(3). allegro-5.0.10/docs/man/al_get_sample_instance_gain.30000644000175000001440000000055312157230677021670 0ustar tjadenusers.TH al_get_sample_instance_gain 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_gain \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ float\ al_get_sample_instance_gain(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the playback gain. .SH SEE ALSO .PP al_set_sample_instance_gain(3) allegro-5.0.10/docs/man/al_set_memory_interface.30000644000175000001440000000114612157230673021064 0ustar tjadenusers.TH al_set_memory_interface 3 "" "Allegro reference manual" .SH NAME .PP al_set_memory_interface \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE\ *memory_interface) \f[] .fi .SH DESCRIPTION .PP Override the memory management functions with implementations of al_malloc_with_context(3), al_free_with_context(3), al_realloc_with_context(3) and al_calloc_with_context(3). The context arguments may be used for debugging. .PP If the pointer is NULL, the default behaviour will be restored. .SH SEE ALSO .PP ALLEGRO_MEMORY_INTERFACE(3) allegro-5.0.10/docs/man/al_unmap_rgba.30000644000175000001440000000072112157230672016771 0ustar tjadenusers.TH al_unmap_rgba 3 "" "Allegro reference manual" .SH NAME .PP al_unmap_rgba \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_unmap_rgba(ALLEGRO_COLOR\ color, \ \ \ unsigned\ char\ *r,\ unsigned\ char\ *g,\ unsigned\ char\ *b,\ unsigned\ char\ *a) \f[] .fi .SH DESCRIPTION .PP Retrieves components of an ALLEGRO_COLOR(3). Components will range from 0\-255. .SH SEE ALSO .PP al_unmap_rgb(3), al_unmap_rgba_f(3), al_unmap_rgb_f(3) allegro-5.0.10/docs/man/al_get_next_config_section.30000644000175000001440000000101312157230670021535 0ustar tjadenusers.TH al_get_next_config_section 3 "" "Allegro reference manual" .SH NAME .PP al_get_next_config_section \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ const\ *al_get_next_config_section(ALLEGRO_CONFIG_SECTION\ **iterator) \f[] .fi .SH DESCRIPTION .PP Returns the name of the next section in the given config file or NULL if there are no more sections. The \f[C]iterator\f[] must have been obtained with al_get_first_config_section(3) first. .SH SEE ALSO .PP al_get_first_config_section(3) allegro-5.0.10/docs/man/al_draw_text.30000644000175000001440000000204412157230700016647 0ustar tjadenusers.TH al_draw_text 3 "" "Allegro reference manual" .SH NAME .PP al_draw_text \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_text(const\ ALLEGRO_FONT\ *font, \ \ \ ALLEGRO_COLOR\ color,\ float\ x,\ float\ y,\ int\ flags, \ \ \ char\ const\ *text)\ \f[] .fi .SH DESCRIPTION .PP Writes the NUL\-terminated string \f[C]text\f[] onto the target bitmap at position \f[C]x\f[], \f[C]y\f[], using the specified \f[C]font\f[]. .PP The \f[C]flags\f[] parameter can be 0 or one of the following flags: .IP \[bu] 2 ALLEGRO_ALIGN_LEFT \- Draw the text left\-aligned (same as 0). .IP \[bu] 2 ALLEGRO_ALIGN_CENTRE \- Draw the text centered around the given position. .IP \[bu] 2 ALLEGRO_ALIGN_RIGHT \- Draw the text right\-aligned to the given position. .PP It can also be combined with this flag: .IP \[bu] 2 ALLEGRO_ALIGN_INTEGER \- Always draw text aligned to an integer pixel position. This is formerly the default behaviour. Since: 5.0.8, 5.1.4 .SH SEE ALSO .PP al_draw_ustr(3), al_draw_textf(3), al_draw_justified_text(3) allegro-5.0.10/docs/man/al_get_allegro_audio_version.30000644000175000001440000000054512157230677022101 0ustar tjadenusers.TH al_get_allegro_audio_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_audio_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_audio_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_is_bitmap_drawing_held.30000644000175000001440000000054512157230674021342 0ustar tjadenusers.TH al_is_bitmap_drawing_held 3 "" "Allegro reference manual" .SH NAME .PP al_is_bitmap_drawing_held \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_bitmap_drawing_held(void) \f[] .fi .SH DESCRIPTION .PP Returns whether the deferred bitmap drawing mode is turned on or off. .SH SEE ALSO .PP al_hold_bitmap_drawing(3) allegro-5.0.10/docs/man/al_fixtof.30000644000175000001440000000112412157230671016152 0ustar tjadenusers.TH al_fixtof 3 "" "Allegro reference manual" .SH NAME .PP al_fixtof \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ double\ al_fixtof(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP Converts fixed point to floating point. .PP Example: .IP .nf \f[C] \ \ \ \ float\ result; \ \ \ \ /*\ This\ will\ put\ 33.33333\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixtof(al_itofix(100)\ /\ 3); \ \ \ \ /*\ This\ will\ put\ 16.66666\ into\ `result\[aq].\ */ \ \ \ \ result\ =\ al_fixtof(al_itofix(100)\ /\ 6); \f[] .fi .SH SEE ALSO .PP al_ftofix(3), al_itofix(3), al_fixtoi(3). allegro-5.0.10/docs/man/al_get_joystick_num_sticks.30000644000175000001440000000065012157230673021615 0ustar tjadenusers.TH al_get_joystick_num_sticks 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_num_sticks \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_joystick_num_sticks(ALLEGRO_JOYSTICK\ *joy) \f[] .fi .SH DESCRIPTION .PP Return the number of "sticks" on the given joystick. A stick has one or more axes. .SH SEE ALSO .PP al_get_joystick_num_axes(3), al_get_joystick_num_buttons(3) allegro-5.0.10/docs/man/al_draw_tinted_bitmap_region.30000644000175000001440000000102012157230673022053 0ustar tjadenusers.TH al_draw_tinted_bitmap_region 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_bitmap_region \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_bitmap_region(ALLEGRO_BITMAP\ *bitmap, \ \ \ ALLEGRO_COLOR\ tint, \ \ \ float\ sx,\ float\ sy,\ float\ sw,\ float\ sh,\ float\ dx,\ float\ dy, \ \ \ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_bitmap_region(3) but multiplies all colors in the bitmap with the given color. .SH SEE ALSO .PP al_draw_tinted_bitmap(3) allegro-5.0.10/docs/man/al_set_thread_should_stop.30000644000175000001440000000062412157230674021427 0ustar tjadenusers.TH al_set_thread_should_stop 3 "" "Allegro reference manual" .SH NAME .PP al_set_thread_should_stop \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_thread_should_stop(ALLEGRO_THREAD\ *thread) \f[] .fi .SH DESCRIPTION .PP Set the flag to indicate \f[C]thread\f[] should stop. Returns immediately. .SH SEE ALSO .PP al_join_thread(3), al_get_thread_should_stop(3). allegro-5.0.10/docs/man/al_draw_filled_pieslice.30000644000175000001440000000143112157230700020776 0ustar tjadenusers.TH al_draw_filled_pieslice 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_pieslice \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_pieslice(float\ cx,\ float\ cy,\ float\ r,\ float\ start_theta, \ \ \ float\ delta_theta,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a filled pieslice (filled circular sector). .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the pieslice .IP \[bu] 2 r \- Radius of the pieslice .IP \[bu] 2 color \- Color of the pieslice .IP \[bu] 2 start_theta \- The initial angle from which the pieslice is drawn .IP \[bu] 2 delta_theta \- Angular span of the pieslice (pass a negative number to switch direction) .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_draw_pieslice(3) allegro-5.0.10/docs/man/al_load_ttf_font_stretch.30000644000175000001440000000175712157230700021236 0ustar tjadenusers.TH al_load_ttf_font_stretch 3 "" "Allegro reference manual" .SH NAME .PP al_load_ttf_font_stretch \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_ttf_font_stretch(char\ const\ *filename,\ int\ w,\ int\ h, \ \ \ \ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_load_ttf_font(3), except it takes separate width and height parameters instead of a single size parameter. .PP If the height is a positive value, and the width zero or positive, then font will be stretched according to those parameters. The width must not be negative if the height is positive. .PP As with al_load_ttf_font(3), the height may be a negative value to specify the total height in pixels. Then the width must also be a negative value, or zero. .PP The behaviour is undefined the height is positive while width is negative, or if the height is negative while the width is positive. .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_load_ttf_font(3), al_load_ttf_font_stretch_f(3) allegro-5.0.10/docs/man/al_draw_indexed_prim.30000644000175000001440000000221112157230700020326 0ustar tjadenusers.TH al_draw_indexed_prim 3 "" "Allegro reference manual" .SH NAME .PP al_draw_indexed_prim \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_draw_indexed_prim(const\ void*\ vtxs,\ const\ ALLEGRO_VERTEX_DECL*\ decl, \ \ \ ALLEGRO_BITMAP*\ texture,\ const\ int*\ indices,\ int\ num_vtx,\ int\ type) \f[] .fi .SH DESCRIPTION .PP Draws a subset of the passed vertex buffer. This function uses an index array to specify which vertices to use. .PP \f[I]Parameters:\f[] .IP \[bu] 2 texture \- Texture to use, pass 0 to use only shaded primitves .IP \[bu] 2 vtxs \- Pointer to an array of vertices .IP \[bu] 2 decl \- Pointer to a vertex declaration. If set to 0, the vtxs are assumed to be of the ALLEGRO_VERTEX type .IP \[bu] 2 indices \- An array of indices into the vertex buffer .IP \[bu] 2 num_vtx \- Number of indices from the indices array you want to draw .IP \[bu] 2 type \- A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what kind of primitive to draw .PP \f[I]Returns:\f[] Number of primitives drawn .SH SEE ALSO .PP ALLEGRO_VERTEX(3), ALLEGRO_PRIM_TYPE(3), ALLEGRO_VERTEX_DECL(3), al_draw_prim(3) allegro-5.0.10/docs/man/al_set_audio_stream_playmode.30000644000175000001440000000070612157230701022073 0ustar tjadenusers.TH al_set_audio_stream_playmode 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_playmode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM\ *stream, \ \ \ ALLEGRO_PLAYMODE\ val) \f[] .fi .SH DESCRIPTION .PP Set the playback mode. .PP Returns true on success, false on failure. .SH SEE ALSO .PP ALLEGRO_PLAYMODE(3), al_get_audio_stream_playmode(3). allegro-5.0.10/docs/man/al_get_font_line_height.30000644000175000001440000000240512157230677021030 0ustar tjadenusers.TH al_get_font_line_height 3 "" "Allegro reference manual" .SH NAME .PP al_get_font_line_height \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_font_line_height(const\ ALLEGRO_FONT\ *f) \f[] .fi .SH DESCRIPTION .PP Returns the usual height of a line of text in the specified font. For bitmap fonts this is simply the height of all glyph bitmaps. For truetype fonts it is whatever the font file specifies. In particular, some special glyphs may be higher than the height returned here. .PP If the X is the position you specify to draw text, the meaning of ascent and descent and the line height is like in the figure below. .IP .nf \f[C] X\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \ \ \ \ /\\\ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ | \ \ \ /\ \ \\\ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ | \ \ /____\\\ \ \ \ \ \ \ ascent\ \ \ | \ /\ \ \ \ \ \ \\\ \ \ \ \ \ |\ \ \ \ \ \ \ \ | /\ \ \ \ \ \ \ \ \\\ \ \ \ \ |\ \ \ \ \ \ \ \ height \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\ \ \ \ \ \ \ \ | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ descent\ \ | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ | \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \f[] .fi .SH SEE ALSO .PP al_get_text_width(3), al_get_text_dimensions(3) allegro-5.0.10/docs/man/al_add_config_section.30000644000175000001440000000060412157230670020455 0ustar tjadenusers.TH al_add_config_section 3 "" "Allegro reference manual" .SH NAME .PP al_add_config_section \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_add_config_section(ALLEGRO_CONFIG\ *config,\ const\ char\ *name) \f[] .fi .SH DESCRIPTION .PP Add a section to a configuration structure with the given name. If the section already exists then nothing happens. allegro-5.0.10/docs/man/ALLEGRO_MUTEX.30000644000175000001440000000041712157230674016255 0ustar tjadenusers.TH ALLEGRO_MUTEX 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MUTEX \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_MUTEX\ ALLEGRO_MUTEX; \f[] .fi .SH DESCRIPTION .PP An opaque structure representing a mutex. allegro-5.0.10/docs/man/al_destroy_fs_entry.30000644000175000001440000000065012157230672020261 0ustar tjadenusers.TH al_destroy_fs_entry 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_fs_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_fs_entry(ALLEGRO_FS_ENTRY\ *fh) \f[] .fi .SH DESCRIPTION .PP Destroys a fs entry handle. The file or directory represented by it is not destroyed. If the entry was opened, it is closed before being destroyed. .PP Does nothing if passed NULL. allegro-5.0.10/docs/man/al_get_mouse_state.30000644000175000001440000000160012157230673020043 0ustar tjadenusers.TH al_get_mouse_state 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_state \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_mouse_state(ALLEGRO_MOUSE_STATE\ *ret_state) \f[] .fi .SH DESCRIPTION .PP Save the state of the mouse specified at the time the function is called into the given structure. .PP Example: .IP .nf \f[C] ALLEGRO_MOUSE_STATE\ state; al_get_mouse_state(&state); if\ (state.buttons\ &\ 1)\ { \ \ \ \ /*\ Primary\ (e.g.\ left)\ mouse\ button\ is\ held.\ */ \ \ \ \ printf("Mouse\ position:\ (%d,\ %d)\\n",\ state.x,\ state.y); } if\ (state.buttons\ &\ 2)\ { \ \ \ \ /*\ Secondary\ (e.g.\ right)\ mouse\ button\ is\ held.\ */ } if\ (state.buttons\ &\ 4)\ { \ \ \ \ /*\ Tertiary\ (e.g.\ middle)\ mouse\ button\ is\ held.\ */ } \f[] .fi .SH SEE ALSO .PP ALLEGRO_MOUSE_STATE(3), al_get_mouse_state_axis(3), al_mouse_button_down(3) allegro-5.0.10/docs/man/al_draw_rectangle.30000644000175000001440000000123112157230700017624 0ustar tjadenusers.TH al_draw_rectangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_rectangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_rectangle(float\ x1,\ float\ y1,\ float\ x2,\ float\ y2, \ \ \ ALLEGRO_COLOR\ color,\ float\ thickness) \f[] .fi .SH DESCRIPTION .PP Draws an outlined rectangle. .PP \f[I]Parameters:\f[] .IP \[bu] 2 x1, y1, x2, y2 \- Upper left and lower right points of the rectangle .IP \[bu] 2 color \- Color of the rectangle .IP \[bu] 2 thickness \- Thickness of the lines, pass \f[C]<=\ 0\f[] to draw hairline lines .SH SEE ALSO .PP al_draw_filled_rectangle(3), al_draw_rounded_rectangle(3) allegro-5.0.10/docs/man/al_get_joystick_num_buttons.30000644000175000001440000000055012157230673022012 0ustar tjadenusers.TH al_get_joystick_num_buttons 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_num_buttons \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_joystick_num_buttons(ALLEGRO_JOYSTICK\ *joy) \f[] .fi .SH DESCRIPTION .PP Return the number of buttons on the joystick. .SH SEE ALSO .PP al_get_joystick_num_sticks(3) allegro-5.0.10/docs/man/al_init_ttf_addon.30000644000175000001440000000062212157230700017633 0ustar tjadenusers.TH al_init_ttf_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_ttf_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_init_ttf_addon(void) \f[] .fi .SH DESCRIPTION .PP Call this after al_init_font_addon(3) to make al_load_font(3) recognize ".ttf" and other formats supported by al_load_ttf_font(3). .PP Returns true on success, false on failure. allegro-5.0.10/docs/man/al_detach_sample_instance.30000644000175000001440000000077612157230700021335 0ustar tjadenusers.TH al_detach_sample_instance 3 "" "Allegro reference manual" .SH NAME .PP al_detach_sample_instance \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Detach the sample instance from whatever it\[aq]s attached to, if anything. .PP Returns true on success. .SH SEE ALSO .PP al_attach_sample_instance_to_mixer(3), al_attach_sample_instance_to_voice(3), al_get_sample_instance_attached(3) allegro-5.0.10/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.30000644000175000001440000000212412157230673025116 0ustar tjadenusers.TH al_draw_tinted_scaled_rotated_bitmap_region 3 "" "Allegro reference manual" .SH NAME .PP al_draw_tinted_scaled_rotated_bitmap_region \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP\ *bitmap, \ \ \ float\ sx,\ float\ sy,\ float\ sw,\ float\ sh, \ \ \ ALLEGRO_COLOR\ tint, \ \ \ float\ cx,\ float\ cy,\ float\ dx,\ float\ dy,\ float\ xscale,\ float\ yscale, \ \ \ float\ angle,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Like al_draw_tinted_scaled_rotated_bitmap(3) but you specify an area within the bitmap to be drawn. .PP You can get the same effect with a sub bitmap: .IP .nf \f[C] al_draw_tinted_scaled_rotated_bitmap(bitmap,\ sx,\ sy,\ sw,\ sh,\ tint, \ \ \ \ cx,\ cy,\ dx,\ dy,\ xscale,\ yscale,\ angle,\ flags); /*\ This\ draws\ the\ same:\ */ sub_bitmap\ =\ al_create_sub_bitmap(bitmap,\ sx,\ sy,\ sw,\ sh); al_draw_tinted_scaled_rotated_bitmap(sub_bitmap,\ tint,\ cx,\ cy, \ \ \ \ dx,\ dy,\ xscale,\ yscale,\ angle,\ flags); \f[] .fi .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_draw_tinted_bitmap(3) allegro-5.0.10/docs/man/al_wait_for_event_timed.30000644000175000001440000000144312157230672021055 0ustar tjadenusers.TH al_wait_for_event_timed 3 "" "Allegro reference manual" .SH NAME .PP al_wait_for_event_timed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE\ *queue, \ \ \ ALLEGRO_EVENT\ *ret_event,\ float\ secs) \f[] .fi .SH DESCRIPTION .PP Wait until the event queue specified is non\-empty. If \f[C]ret_event\f[] is not NULL, the first event in the queue will be copied into \f[C]ret_event\f[] and removed from the queue. If \f[C]ret_event\f[] is NULL the first event is left at the head of the queue. .PP \f[C]timeout_msecs\f[] determines approximately how many seconds to wait. If the call times out, false is returned. Otherwise true is returned. .SH SEE ALSO .PP ALLEGRO_EVENT(3), al_wait_for_event(3), al_wait_for_event_until(3) allegro-5.0.10/docs/man/al_update_display_region.30000644000175000001440000000120112157230670021220 0ustar tjadenusers.TH al_update_display_region 3 "" "Allegro reference manual" .SH NAME .PP al_update_display_region \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_update_display_region(int\ x,\ int\ y,\ int\ width,\ int\ height) \f[] .fi .SH DESCRIPTION .PP Does the same as al_flip_display(3), but tries to update only the specified region. With many drivers this is not possible, but for some it can improve performance. .PP The ALLEGRO_UPDATE_DISPLAY_REGION option (see al_get_display_option(3)) will specify the behavior of this function in the display. .SH SEE ALSO .PP al_flip_display(3), al_get_display_option(3) allegro-5.0.10/docs/man/al_radtofix_r.30000644000175000001440000000107612157230671017022 0ustar tjadenusers.TH al_radtofix_r 3 "" "Allegro reference manual" .SH NAME .PP al_radtofix_r \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ al_fixed\ al_radtofix_r\ =\ (al_fixed)2670177; \f[] .fi .SH DESCRIPTION .PP This constant gives a ratio which can be used to convert a fixed point number in radians to a fixed point number in binary angle format. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ rad_angle,\ binary_angle; \ \ \ \ ... \ \ \ \ binary_angle\ =\ al_fixmul(rad_angle,\ radtofix_r); \f[] .fi .SH SEE ALSO .PP al_fixmul(3), al_fixtorad_r(3). allegro-5.0.10/docs/man/al_install_joystick.30000644000175000001440000000061312157230672020243 0ustar tjadenusers.TH al_install_joystick 3 "" "Allegro reference manual" .SH NAME .PP al_install_joystick \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_install_joystick(void) \f[] .fi .SH DESCRIPTION .PP Install a joystick driver, returning true if successful. If a joystick driver was already installed, returns true immediately. .SH SEE ALSO .PP al_uninstall_joystick(3) allegro-5.0.10/docs/man/al_init_native_dialog_addon.30000644000175000001440000000136512157230700021650 0ustar tjadenusers.TH al_init_native_dialog_addon 3 "" "Allegro reference manual" .SH NAME .PP al_init_native_dialog_addon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_init_native_dialog_addon(void) \f[] .fi .SH DESCRIPTION .PP Initialise the native dialog addon. .PP Returns true on success, false on error. .SH SINCE .PP 5.0.9, 5.1.0 .RS .PP \f[I]Note:\f[] Prior to Allegro 5.1.0 native dialog functions could be called without explicit initialisation, but that is now deprecated. Future functionality may require explicit initialisation. An exception is al_show_native_message_box(3), which may be useful to show an error message if Allegro fails to initialise. .RE .SH SEE ALSO .PP al_shutdown_native_dialog_addon(3) allegro-5.0.10/docs/man/al_set_audio_stream_fragment.30000644000175000001440000000075512157230701022070 0ustar tjadenusers.TH al_set_audio_stream_fragment 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_fragment \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM\ *stream,\ void\ *val) \f[] .fi .SH DESCRIPTION .PP This function needs to be called for every successful call of al_get_audio_stream_fragment(3) to indicate that the buffer is filled with new data. .SH SEE ALSO .PP al_get_audio_stream_fragment(3) allegro-5.0.10/docs/man/al_draw_filled_ellipse.30000644000175000001440000000105312157230700020636 0ustar tjadenusers.TH al_draw_filled_ellipse 3 "" "Allegro reference manual" .SH NAME .PP al_draw_filled_ellipse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_filled_ellipse(float\ cx,\ float\ cy,\ float\ rx,\ float\ ry, \ \ \ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a filled ellipse. .PP \f[I]Parameters:\f[] .IP \[bu] 2 cx, cy \- Center of the ellipse .IP \[bu] 2 rx, ry \- Radii of the ellipse .IP \[bu] 2 color \- Color of the ellipse .SH SEE ALSO .PP al_draw_ellipse(3), al_draw_filled_circle(3) allegro-5.0.10/docs/man/al_grab_mouse.30000644000175000001440000000120212157230674016776 0ustar tjadenusers.TH al_grab_mouse 3 "" "Allegro reference manual" .SH NAME .PP al_grab_mouse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_grab_mouse(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Confine the mouse cursor to the given display. The mouse cursor can only be confined to one display at a time. .PP Returns true if successful, otherwise returns false. Do not assume that the cursor will remain confined until you call al_ungrab_mouse(3). It may lose the confined status at any time for other reasons. .RS .PP \f[I]Note:\f[] not yet implemented on Mac OS X. .RE .SH SEE ALSO .PP al_ungrab_mouse(3) allegro-5.0.10/docs/man/al_get_num_display_modes.30000644000175000001440000000115012157230672021225 0ustar tjadenusers.TH al_get_num_display_modes 3 "" "Allegro reference manual" .SH NAME .PP al_get_num_display_modes \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_num_display_modes(void) \f[] .fi .SH DESCRIPTION .PP Get the number of available fullscreen display modes for the current set of display parameters. This will use the values set with al_set_new_display_refresh_rate(3), and al_set_new_display_flags(3) to find the number of modes that match. Settings the new display parameters to zero will give a list of all modes for the default driver. .SH SEE ALSO .PP al_get_display_mode(3) allegro-5.0.10/docs/man/al_destroy_thread.30000644000175000001440000000067512157230674017710 0ustar tjadenusers.TH al_destroy_thread 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_thread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_thread(ALLEGRO_THREAD\ *thread) \f[] .fi .SH DESCRIPTION .PP Free the resources used by a thread. Implicitly performs al_join_thread(3) on the thread if it hasn\[aq]t been done already. .PP Does nothing if \f[C]thread\f[] is NULL. .SH SEE ALSO .PP al_join_thread(3). allegro-5.0.10/docs/man/al_cstr.30000644000175000001440000000217412157230675015640 0ustar tjadenusers.TH al_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_cstr(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Get a \f[C]char\ *\f[] pointer to the data in a string. This pointer will only be valid while the ALLEGRO_USTR(3) object is not modified and not destroyed. The pointer may be passed to functions expecting C\-style strings, with the following caveats: .IP \[bu] 2 ALLEGRO_USTRs are allowed to contain embedded NUL (\[aq]\[aq]) bytes. That means \f[C]al_ustr_size(u)\f[] and \f[C]strlen(al_cstr(u))\f[] may not agree. .IP \[bu] 2 An ALLEGRO_USTR may be created in such a way that it is not NUL terminated. A string which is dynamically allocated will always be NUL terminated, but a string which references the middle of another string or region of memory will \f[I]not\f[] be NUL terminated. .IP \[bu] 2 If the ALLEGRO_USTR references another string, the returned C string will point into the referenced string. Again, no NUL terminator will be added to the referenced string. .SH SEE ALSO .PP al_ustr_to_buffer(3), al_cstr_dup(3) allegro-5.0.10/docs/man/al_get_sample_instance_position.30000644000175000001440000000063112157230677022613 0ustar tjadenusers.TH al_get_sample_instance_position 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_sample_instance_position(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Get the playback position of a sample instance. .SH SEE ALSO .PP al_set_sample_instance_position(3) allegro-5.0.10/docs/man/al_set_mouse_z.30000644000175000001440000000053012157230674017212 0ustar tjadenusers.TH al_set_mouse_z 3 "" "Allegro reference manual" .SH NAME .PP al_set_mouse_z \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mouse_z(int\ z) \f[] .fi .SH DESCRIPTION .PP Set the mouse wheel position to the given value. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_mouse_w(3) allegro-5.0.10/docs/man/al_get_thread_should_stop.30000644000175000001440000000124012157230674021406 0ustar tjadenusers.TH al_get_thread_should_stop 3 "" "Allegro reference manual" .SH NAME .PP al_get_thread_should_stop \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_thread_should_stop(ALLEGRO_THREAD\ *thread) \f[] .fi .SH DESCRIPTION .PP Check if another thread is waiting for \f[C]thread\f[] to stop. Threads which run in a loop should check this periodically and act on it when convenient. .PP Returns true if another thread has called al_join_thread(3) or al_set_thread_should_stop(3) on this thread. .SH SEE ALSO .PP al_join_thread(3), al_set_thread_should_stop(3). .RS .PP \f[I]Note:\f[] We don\[aq]t support forceful killing of threads. .RE allegro-5.0.10/docs/man/al_fwrite.30000644000175000001440000000107312157230671016156 0ustar tjadenusers.TH al_fwrite 3 "" "Allegro reference manual" .SH NAME .PP al_fwrite \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ size_t\ al_fwrite(ALLEGRO_FILE\ *f,\ const\ void\ *ptr,\ size_t\ size) \f[] .fi .SH DESCRIPTION .PP Write \[aq]size\[aq] bytes from the buffer pointed to by \[aq]ptr\[aq] into the given file. .PP Returns the number of bytes actually written. If an error occurs, the return value is a short byte count (or zero). .SH SEE ALSO .PP al_fputc(3), al_fputs(3), al_fwrite16be(3), al_fwrite16le(3), al_fwrite32be(3), al_fwrite32le(3) allegro-5.0.10/docs/man/al_close_native_text_log.30000644000175000001440000000065512157230700021234 0ustar tjadenusers.TH al_close_native_text_log 3 "" "Allegro reference manual" .SH NAME .PP al_close_native_text_log \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_close_native_text_log(ALLEGRO_TEXTLOG\ *textlog) \f[] .fi .SH DESCRIPTION .PP Closes a message log window opened with al_open_native_text_log(3) earlier. .PP Does nothing if passed NULL. .SH SEE ALSO .PP al_open_native_text_log(3) allegro-5.0.10/docs/man/ALLEGRO_JOYSTICK_STATE.30000644000175000001440000000123312157230672017545 0ustar tjadenusers.TH ALLEGRO_JOYSTICK_STATE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_JOYSTICK_STATE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_JOYSTICK_STATE\ ALLEGRO_JOYSTICK_STATE; \f[] .fi .SH DESCRIPTION .PP This is a structure that is used to hold a "snapshot" of a joystick\[aq]s axes and buttons at a particular instant. All fields public and read\-only. .IP .nf \f[C] struct\ { \ \ \ \ \ \ float\ axis[num_axes];\ \ \ \ \ \ \ \ \ \ \ \ \ //\ \-1.0\ to\ 1.0\ }\ stick[num_sticks]; int\ button[num_buttons];\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ 0\ to\ 32767 \f[] .fi .SH SEE ALSO .PP al_get_joystick_state(3) allegro-5.0.10/docs/man/al_get_native_file_dialog_path.30000644000175000001440000000055612157230700022333 0ustar tjadenusers.TH al_get_native_file_dialog_path 3 "" "Allegro reference manual" .SH NAME .PP al_get_native_file_dialog_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_native_file_dialog_path( \ \ \ const\ ALLEGRO_FILECHOOSER\ *dialog,\ size_t\ i) \f[] .fi .SH DESCRIPTION .PP Returns one of the selected paths. allegro-5.0.10/docs/man/al_get_joystick_stick_flags.30000644000175000001440000000065412157230673021733 0ustar tjadenusers.TH al_get_joystick_stick_flags 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_stick_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_joystick_stick_flags(ALLEGRO_JOYSTICK\ *joy,\ int\ stick) \f[] .fi .SH DESCRIPTION .PP Return the flags of the given "stick". If the stick doesn\[aq]t exist, NULL is returned. Indices begin from 0. .SH SEE ALSO .PP ALLEGRO_JOYFLAGS(3) allegro-5.0.10/docs/man/al_ustr_find_cset.30000644000175000001440000000125312157230677017677 0ustar tjadenusers.TH al_ustr_find_cset 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_find_cset \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_ustr_find_cset(const\ ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ const\ ALLEGRO_USTR\ *reject) \f[] .fi .SH DESCRIPTION .PP This function finds the first code point in \f[C]us\f[], beginning from byte offset \f[C]start_pos\f[], that does \f[I]not\f[] match any code point in \f[C]reject\f[]. In other words it finds a code point in the complementary set of \f[C]reject\f[]. Returns the byte position of that code point, if any. Otherwise returns \-1. .SH SEE ALSO .PP al_ustr_find_cset_cstr(3), al_ustr_find_set(3) allegro-5.0.10/docs/man/al_get_separate_blender.30000644000175000001440000000075612157230673021025 0ustar tjadenusers.TH al_get_separate_blender 3 "" "Allegro reference manual" .SH NAME .PP al_get_separate_blender \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_get_separate_blender(int\ *op,\ int\ *src,\ int\ *dst, \ \ \ int\ *alpha_op,\ int\ *alpha_src,\ int\ *alpha_dst) \f[] .fi .SH DESCRIPTION .PP Returns the active blender for the current thread. You can pass NULL for values you are not interested in. .SH SEE ALSO .PP al_set_separate_blender(3), al_get_blender(3) allegro-5.0.10/docs/man/al_stop_samples.30000644000175000001440000000045612157230677017401 0ustar tjadenusers.TH al_stop_samples 3 "" "Allegro reference manual" .SH NAME .PP al_stop_samples \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_stop_samples(void) \f[] .fi .SH DESCRIPTION .PP Stop all samples started by al_play_sample(3). .SH SEE ALSO .PP al_stop_sample(3) allegro-5.0.10/docs/man/al_save_config_file.30000644000175000001440000000065012157230670020137 0ustar tjadenusers.TH al_save_config_file 3 "" "Allegro reference manual" .SH NAME .PP al_save_config_file \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_config_file(const\ char\ *filename,\ const\ ALLEGRO_CONFIG\ *config) \f[] .fi .SH DESCRIPTION .PP Write out a configuration file to disk. Returns true on success, false on error. .SH SEE ALSO .PP al_save_config_file_f(3), al_load_config_file(3) allegro-5.0.10/docs/man/al_release_joystick.30000644000175000001440000000047612157230673020225 0ustar tjadenusers.TH al_release_joystick 3 "" "Allegro reference manual" .SH NAME .PP al_release_joystick \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_release_joystick(ALLEGRO_JOYSTICK\ *joy) \f[] .fi .SH DESCRIPTION .PP This function currently does nothing. .SH SEE ALSO .PP al_get_joystick(3) allegro-5.0.10/docs/man/al_map_rgb_f.30000644000175000001440000000061412157230672016573 0ustar tjadenusers.TH al_map_rgb_f 3 "" "Allegro reference manual" .SH NAME .PP al_map_rgb_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_map_rgb_f(float\ r,\ float\ g,\ float\ b) \f[] .fi .SH DESCRIPTION .PP Convert r, g, b, (ranging from 0.0f\-1.0f) into an ALLEGRO_COLOR(3), using 1.0f for alpha. .SH SEE ALSO .PP al_map_rgba(3), al_map_rgb(3), al_map_rgba_f(3) allegro-5.0.10/docs/man/al_toggle_display_flag.30000644000175000001440000000051112157230670020650 0ustar tjadenusers.TH al_toggle_display_flag 3 "" "Allegro reference manual" .SH NAME .PP al_toggle_display_flag \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_toggle_display_flag(ALLEGRO_DISPLAY\ *display,\ int\ flag,\ bool\ onoff) \f[] .fi .SH DESCRIPTION .PP Deprecated synonym for al_set_display_flag(3). allegro-5.0.10/docs/man/al_fread16be.30000644000175000001440000000103512157230671016413 0ustar tjadenusers.TH al_fread16be 3 "" "Allegro reference manual" .SH NAME .PP al_fread16be \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int16_t\ al_fread16be(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Reads a 16\-bit word in big\-endian format (MSB first). .PP On success, returns the 16\-bit word. On failure, returns EOF (\-1). Since \-1 is also a valid return value, use al_feof(3) to check if the end of the file was reached prematurely, or al_ferror(3) to check if an error occurred. .SH SEE ALSO .PP al_fread16le(3) allegro-5.0.10/docs/man/ALLEGRO_LOCKED_REGION.30000644000175000001440000000245112157230672017355 0ustar tjadenusers.TH ALLEGRO_LOCKED_REGION 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_LOCKED_REGION \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_LOCKED_REGION\ ALLEGRO_LOCKED_REGION; \f[] .fi .SH DESCRIPTION .PP Users who wish to manually edit or read from a bitmap are required to lock it first. The ALLEGRO_LOCKED_REGION structure represents the locked region of the bitmap. This call will work with any bitmap, including memory bitmaps. .IP .nf \f[C] typedef\ struct\ ALLEGRO_LOCKED_REGION\ { \ \ \ \ void\ *data; \ \ \ \ int\ format; \ \ \ \ int\ pitch; \ \ \ \ int\ pixel_size; }\ ALLEGRO_LOCKED_REGION; \f[] .fi .IP \[bu] 2 \f[I]data\f[] points to the leftmost pixel of the first row (row 0) of the locked region. .IP \[bu] 2 \f[I]format\f[] indicates the pixel format of the data. .IP \[bu] 2 \f[I]pitch\f[] gives the size in bytes of a single row (also known as the stride). The pitch may be greater than \f[C]width\ *\ pixel_size\f[] due to padding; this is not uncommon. It is also \f[I]not\f[] uncommon for the pitch to be negative (the bitmap may be upside down). .IP \[bu] 2 \f[I]pixel_size\f[] is the number of bytes used to represent a single pixel. .SH SEE ALSO .PP al_lock_bitmap(3), al_lock_bitmap_region(3), al_unlock_bitmap(3), ALLEGRO_PIXEL_FORMAT(3) allegro-5.0.10/docs/man/al_draw_pixel.30000644000175000001440000000165512157230673017024 0ustar tjadenusers.TH al_draw_pixel 3 "" "Allegro reference manual" .SH NAME .PP al_draw_pixel \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_pixel(float\ x,\ float\ y,\ ALLEGRO_COLOR\ color) \f[] .fi .SH DESCRIPTION .PP Draws a single pixel at x, y. This function, unlike al_put_pixel(3), does blending and, unlike al_put_blended_pixel(3), respects the transformations. This function can be slow if called often; if you need to draw a lot of pixels consider using al_draw_prim(3) with ALLEGRO_PRIM_POINT_LIST from the primitives addon. .IP \[bu] 2 x \- destination x .IP \[bu] 2 y \- destination y .IP \[bu] 2 color \- color of the pixel .RS .PP \f[I]Note:\f[] This function may not draw exactly where you expect it to. See the pixel\-precise output section on the primitives addon documentation for details on how to control exactly where the pixel is drawn. .RE .SH SEE ALSO .PP ALLEGRO_COLOR(3), al_put_pixel(3) allegro-5.0.10/docs/man/al_join_thread.30000644000175000001440000000113412157230674017145 0ustar tjadenusers.TH al_join_thread 3 "" "Allegro reference manual" .SH NAME .PP al_join_thread \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_join_thread(ALLEGRO_THREAD\ *thread,\ void\ **ret_value) \f[] .fi .SH DESCRIPTION .PP Wait for the thread to finish executing. This implicitly calls al_set_thread_should_stop(3) first. .PP If \f[C]ret_value\f[] is non\-\f[C]NULL\f[], the value returned by the thread function will be stored at the location pointed to by \f[C]ret_value\f[]. .SH SEE ALSO .PP al_set_thread_should_stop(3), al_get_thread_should_stop(3), al_destroy_thread(3). allegro-5.0.10/docs/man/al_get_fs_entry_atime.30000644000175000001440000000107612157230672020531 0ustar tjadenusers.TH al_get_fs_entry_atime 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_atime \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ time_t\ al_get_fs_entry_atime(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the time in seconds since the epoch since the entry was last accessed. .PP Warning: some filesystem either don\[aq]t support this flag, or people turn it off to increase performance. It may not be valid in all circumstances. .SH SEE ALSO .PP al_get_fs_entry_ctime(3), al_get_fs_entry_mtime(3), al_update_fs_entry(3) allegro-5.0.10/docs/man/al_set_mouse_xy.30000644000175000001440000000102212157230674017376 0ustar tjadenusers.TH al_set_mouse_xy 3 "" "Allegro reference manual" .SH NAME .PP al_set_mouse_xy \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mouse_xy(ALLEGRO_DISPLAY\ *display,\ int\ x,\ int\ y) \f[] .fi .SH DESCRIPTION .PP Try to position the mouse at the given coordinates on the given display. The mouse movement resulting from a successful move will generate an ALLEGRO_EVENT_MOUSE_WARPED event. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_set_mouse_z(3), al_set_mouse_w(3) allegro-5.0.10/docs/man/ALLEGRO_CHANNEL_CONF.30000644000175000001440000000102012157230676017221 0ustar tjadenusers.TH ALLEGRO_CHANNEL_CONF 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_CHANNEL_CONF \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ enum\ ALLEGRO_CHANNEL_CONF \f[] .fi .SH DESCRIPTION .PP Speaker configuration (mono, stereo, 2.1, etc). .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_1 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_2 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_3 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_4 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_5_1 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_6_1 .IP \[bu] 2 ALLEGRO_CHANNEL_CONF_7_1 allegro-5.0.10/docs/man/al_set_path_drive.30000644000175000001440000000064312157230674017663 0ustar tjadenusers.TH al_set_path_drive 3 "" "Allegro reference manual" .SH NAME .PP al_set_path_drive \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_path_drive(ALLEGRO_PATH\ *path,\ const\ char\ *drive) \f[] .fi .SH DESCRIPTION .PP Set the drive string on a path. The drive may be NULL, which is equivalent to setting the drive string to the empty string. .SH SEE ALSO .PP al_get_path_drive(3) allegro-5.0.10/docs/man/al_rest.30000644000175000001440000000107312157230674015636 0ustar tjadenusers.TH al_rest 3 "" "Allegro reference manual" .SH NAME .PP al_rest \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_rest(double\ seconds) \f[] .fi .SH DESCRIPTION .PP Waits for the specified number seconds. This tells the system to pause the current thread for the given amount of time. With some operating systems, the accuracy can be in the order of 10ms. That is, even .IP .nf \f[C] al_rest(0.000001) \f[] .fi .PP might pause for something like 10ms. Also see the section on easier ways to time your program without using up all CPU. allegro-5.0.10/docs/man/al_calloc_with_context.30000644000175000001440000000075412157230673020721 0ustar tjadenusers.TH al_calloc_with_context 3 "" "Allegro reference manual" .SH NAME .PP al_calloc_with_context \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ *al_calloc_with_context(size_t\ count,\ size_t\ n, \ \ \ int\ line,\ const\ char\ *file,\ const\ char\ *func) \f[] .fi .SH DESCRIPTION .PP This calls calloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface(3), .PP Generally you should use the al_calloc(3) macro. allegro-5.0.10/docs/man/al_get_path_filename.30000644000175000001440000000105712157230674020316 0ustar tjadenusers.TH al_get_path_filename 3 "" "Allegro reference manual" .SH NAME .PP al_get_path_filename \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_path_filename(const\ ALLEGRO_PATH\ *path) \f[] .fi .SH DESCRIPTION .PP Return the filename part of the path, or the empty string if there is none. .PP The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed. .SH SEE ALSO .PP al_get_path_basename(3), al_get_path_extension(3), al_get_path_component(3) allegro-5.0.10/docs/man/al_destroy_mouse_cursor.30000644000175000001440000000061212157230674021155 0ustar tjadenusers.TH al_destroy_mouse_cursor 3 "" "Allegro reference manual" .SH NAME .PP al_destroy_mouse_cursor \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR\ *cursor) \f[] .fi .SH DESCRIPTION .PP Free the memory used by the given cursor. .PP Has no effect if \f[C]cursor\f[] is NULL. .SH SEE ALSO .PP al_create_mouse_cursor(3) allegro-5.0.10/docs/man/al_create_fs_entry.30000644000175000001440000000060612157230672020034 0ustar tjadenusers.TH al_create_fs_entry 3 "" "Allegro reference manual" .SH NAME .PP al_create_fs_entry \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FS_ENTRY\ *al_create_fs_entry(const\ char\ *path) \f[] .fi .SH DESCRIPTION .PP Creates an ALLEGRO_FS_ENTRY(3) object pointing to path on the filesystem. \[aq]path\[aq] can be a file or a directory and must not be NULL. allegro-5.0.10/docs/man/al_get_monitor_info.30000644000175000001440000000077312157230673020227 0ustar tjadenusers.TH al_get_monitor_info 3 "" "Allegro reference manual" .SH NAME .PP al_get_monitor_info \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_monitor_info(int\ adapter,\ ALLEGRO_MONITOR_INFO\ *info) \f[] .fi .SH DESCRIPTION .PP Get information about a monitor\[aq]s position on the desktop. adapter is a number from 0 to al_get_num_video_adapters()\-1. .PP Returns true on success, false on failure. .SH SEE ALSO .PP ALLEGRO_MONITOR_INFO(3), al_get_num_video_adapters(3) allegro-5.0.10/docs/man/al_play_sample.30000644000175000001440000000220412157230677017167 0ustar tjadenusers.TH al_play_sample 3 "" "Allegro reference manual" .SH NAME .PP al_play_sample \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_play_sample(ALLEGRO_SAMPLE\ *spl,\ float\ gain,\ float\ pan,\ float\ speed, \ \ \ ALLEGRO_PLAYMODE\ loop,\ ALLEGRO_SAMPLE_ID\ *ret_id) \f[] .fi .SH DESCRIPTION .PP Plays a sample on one of the sample instances created by al_reserve_samples(3). Returns true on success, false on failure. Playback may fail because all the reserved sample instances are currently used. .PP Parameters: .IP \[bu] 2 gain \- relative volume at which the sample is played; 1.0 is normal. .IP \[bu] 2 pan \- 0.0 is centred, \-1.0 is left, 1.0 is right, or ALLEGRO_AUDIO_PAN_NONE. .IP \[bu] 2 speed \- relative speed at which the sample is played; 1.0 is normal. .IP \[bu] 2 loop \- ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or ALLEGRO_PLAYMODE_BIDIR .IP \[bu] 2 ret_id \- if non\-NULL the variable which this points to will be assigned an id representing the sample being played. .SH SEE ALSO .PP ALLEGRO_PLAYMODE(3), ALLEGRO_AUDIO_PAN_NONE(3), ALLEGRO_SAMPLE_ID(3), al_stop_sample(3), al_stop_samples(3). allegro-5.0.10/docs/man/al_uninstall_mouse.30000644000175000001440000000064112157230673020101 0ustar tjadenusers.TH al_uninstall_mouse 3 "" "Allegro reference manual" .SH NAME .PP al_uninstall_mouse \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_uninstall_mouse(void) \f[] .fi .SH DESCRIPTION .PP Uninstalls the active mouse driver, if any. This will automatically unregister the mouse event source with any event queues. .PP This function is automatically called when Allegro is shut down. allegro-5.0.10/docs/man/al_get_mouse_num_buttons.30000644000175000001440000000054612157230673021310 0ustar tjadenusers.TH al_get_mouse_num_buttons 3 "" "Allegro reference manual" .SH NAME .PP al_get_mouse_num_buttons \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ unsigned\ int\ al_get_mouse_num_buttons(void) \f[] .fi .SH DESCRIPTION .PP Return the number of buttons on the mouse. The first button is 1. .SH SEE ALSO .PP al_get_mouse_num_axes(3) allegro-5.0.10/docs/man/al_invert_transform.30000644000175000001440000000116412157230675020265 0ustar tjadenusers.TH al_invert_transform 3 "" "Allegro reference manual" .SH NAME .PP al_invert_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_invert_transform(ALLEGRO_TRANSFORM\ *trans) \f[] .fi .SH DESCRIPTION .PP Inverts the passed transformation. If the transformation is nearly singular (close to not having an inverse) then the returned transformation may be invalid. Use al_check_inverse(3) to ascertain if the transformation has an inverse before inverting it if you are in doubt. .PP \f[I]Parameters:\f[] .IP \[bu] 2 trans \- Transformation to invert .SH SEE ALSO .PP al_check_inverse(3) allegro-5.0.10/docs/man/al_get_target_bitmap.30000644000175000001440000000051112157230673020335 0ustar tjadenusers.TH al_get_target_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_get_target_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_get_target_bitmap(void) \f[] .fi .SH DESCRIPTION .PP Return the target bitmap of the calling thread. .SH SEE ALSO .PP al_set_target_bitmap(3) allegro-5.0.10/docs/man/al_get_display_mode.30000644000175000001440000000133212157230672020165 0ustar tjadenusers.TH al_get_display_mode 3 "" "Allegro reference manual" .SH NAME .PP al_get_display_mode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_DISPLAY_MODE\ *al_get_display_mode(int\ index,\ ALLEGRO_DISPLAY_MODE\ *mode) \f[] .fi .SH DESCRIPTION .PP Retrieves a fullscreen mode. Display parameters should not be changed between a call of al_get_num_display_modes(3) and al_get_display_mode(3). index must be between 0 and the number returned from al_get_num_display_modes\-1. mode must be an allocated ALLEGRO_DISPLAY_MODE structure. This function will return NULL on failure, and the mode parameter that was passed in on success. .SH SEE ALSO .PP ALLEGRO_DISPLAY_MODE(3), al_get_num_display_modes(3) allegro-5.0.10/docs/man/al_get_voice_channels.30000644000175000001440000000055712157230677020511 0ustar tjadenusers.TH al_get_voice_channels 3 "" "Allegro reference manual" .SH NAME .PP al_get_voice_channels \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CHANNEL_CONF\ al_get_voice_channels(const\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Return the channel configuration of the voice. .SH SEE ALSO .PP ALLEGRO_CHANNEL_CONF(3). allegro-5.0.10/docs/man/al_is_d3d_device_lost.30000644000175000001440000000074612157230676020416 0ustar tjadenusers.TH al_is_d3d_device_lost 3 "" "Allegro reference manual" .SH NAME .PP al_is_d3d_device_lost \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_d3d_device_lost(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Returns a boolean indicating whether or not the Direct3D device belonging to the given display is in a lost state. .PP \f[I]Parameters:\f[] .IP \[bu] 2 display \- The display that the device you wish to check is attached to allegro-5.0.10/docs/man/al_ftofix.30000644000175000001440000000164612157230671016163 0ustar tjadenusers.TH al_ftofix 3 "" "Allegro reference manual" .SH NAME .PP al_ftofix \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_ftofix(double\ x); \f[] .fi .SH DESCRIPTION .PP Converts a floating point value to fixed point. Unlike al_itofix(3), this function clamps values which could overflow the type conversion, setting Allegro\[aq]s errno to ERANGE in the process if this happens. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ number; \ \ \ \ number\ =\ al_itofix(\-40000); \ \ \ \ assert(al_fixfloor(number)\ ==\ \-32768); \ \ \ \ number\ =\ al_itofix(64000); \ \ \ \ assert(al_fixfloor(number)\ ==\ 32767); \ \ \ \ assert(!al_get_errno());\ /*\ This\ will\ fail.\ */ \f[] .fi .SH RETURN VALUE .PP Returns the value of the floating point value converted to fixed point clamping overflows (and setting Allegro\[aq]s errno). .SH SEE ALSO .PP al_fixtof(3), al_itofix(3), al_fixtoi(3), al_get_errno(3) allegro-5.0.10/docs/man/al_save_bitmap.30000644000175000001440000000122412157230674017151 0ustar tjadenusers.TH al_save_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_save_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_bitmap(const\ char\ *filename,\ ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Saves an ALLEGRO_BITMAP(3) to an image file. The file type is determined by the extension. .PP Returns true on success, false on error. .RS .PP \f[I]Note:\f[] the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler. .RE .SH SEE ALSO .PP al_save_bitmap_f(3), al_register_bitmap_saver(3), al_init_image_addon(3) allegro-5.0.10/docs/man/al_copy_transform.30000644000175000001440000000064412157230675017732 0ustar tjadenusers.TH al_copy_transform 3 "" "Allegro reference manual" .SH NAME .PP al_copy_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_copy_transform(ALLEGRO_TRANSFORM\ *dest,\ const\ ALLEGRO_TRANSFORM\ *src) \f[] .fi .SH DESCRIPTION .PP Makes a copy of a transformation. .PP \f[I]Parameters:\f[] .IP \[bu] 2 dest \- Source transformation .IP \[bu] 2 src \- Destination transformation allegro-5.0.10/docs/man/al_load_audio_stream_f.30000644000175000001440000000265212157230702020635 0ustar tjadenusers.TH al_load_audio_stream_f 3 "" "Allegro reference manual" .SH NAME .PP al_load_audio_stream_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_STREAM\ *al_load_audio_stream_f(ALLEGRO_FILE*\ fp,\ const\ char\ *ident, \ \ \ size_t\ buffer_count,\ unsigned\ int\ samples) \f[] .fi .SH DESCRIPTION .PP Loads an audio file from ALLEGRO_FILE(3) stream as it is needed. .PP Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain \f[I]buffer_count\f[] buffers with \f[I]samples\f[] samples. .PP The file type is determined by the passed \[aq]ident\[aq] parameter, which is a file name extension including the leading dot. .PP The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM(3) for more details. .PP Returns the stream on success, NULL on failure. On success the file should be considered owned by the audio stream, and will be closed when the audio stream is destroyed. On failure the file will be closed. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_load_audio_stream(3), al_register_audio_stream_loader_f(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_get_joystick_stick_name.30000644000175000001440000000070312157230673021552 0ustar tjadenusers.TH al_get_joystick_stick_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_stick_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_joystick_stick_name(ALLEGRO_JOYSTICK\ *joy,\ int\ stick) \f[] .fi .SH DESCRIPTION .PP Return the name of the given "stick". If the stick doesn\[aq]t exist, NULL is returned. .SH SEE ALSO .PP al_get_joystick_axis_name(3), al_get_joystick_num_sticks(3) allegro-5.0.10/docs/man/al_store_state.30000644000175000001440000000211112157230674017207 0ustar tjadenusers.TH al_store_state 3 "" "Allegro reference manual" .SH NAME .PP al_store_state \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_store_state(ALLEGRO_STATE\ *state,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Stores part of the state of the current thread in the given ALLEGRO_STATE(3) objects. The flags parameter can take any bit\-combination of these flags: .IP \[bu] 2 ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS \- new_display_format, new_display_refresh_rate, new_display_flags .IP \[bu] 2 ALLEGRO_STATE_NEW_BITMAP_PARAMETERS \- new_bitmap_format, new_bitmap_flags .IP \[bu] 2 ALLEGRO_STATE_DISPLAY \- current_display .IP \[bu] 2 ALLEGRO_STATE_TARGET_BITMAP \- target_bitmap .IP \[bu] 2 ALLEGRO_STATE_BLENDER \- blender .IP \[bu] 2 ALLEGRO_STATE_TRANSFORM \- current_transformation .IP \[bu] 2 ALLEGRO_STATE_NEW_FILE_INTERFACE \- new_file_interface .IP \[bu] 2 ALLEGRO_STATE_BITMAP \- same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and ALLEGRO_STATE_TARGET_BITMAP .IP \[bu] 2 ALLEGRO_STATE_ALL \- all of the above .SH SEE ALSO .PP al_restore_state(3), ALLEGRO_STATE(3) allegro-5.0.10/docs/man/al_draw_textf.30000644000175000001440000000100312157230700017007 0ustar tjadenusers.TH al_draw_textf 3 "" "Allegro reference manual" .SH NAME .PP al_draw_textf \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_textf(const\ ALLEGRO_FONT\ *font,\ ALLEGRO_COLOR\ color, \ \ \ float\ x,\ float\ y,\ int\ flags, \ \ \ const\ char\ *format,\ ...) \f[] .fi .SH DESCRIPTION .PP Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_text(3) otherwise. .SH SEE ALSO .PP al_draw_text(3), al_draw_ustr(3) allegro-5.0.10/docs/man/al_set_target_backbuffer.30000644000175000001440000000061012157230673021167 0ustar tjadenusers.TH al_set_target_backbuffer 3 "" "Allegro reference manual" .SH NAME .PP al_set_target_backbuffer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_target_backbuffer(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Same as \f[C]al_set_target_bitmap(al_get_backbuffer(display));\f[] .SH SEE ALSO .PP al_set_target_bitmap(3), al_get_backbuffer(3) allegro-5.0.10/docs/man/al_load_font.30000644000175000001440000000111012157230677016621 0ustar tjadenusers.TH al_load_font 3 "" "Allegro reference manual" .SH NAME .PP al_load_font \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FONT\ *al_load_font(char\ const\ *filename,\ int\ size,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Loads a font from disk. This will use al_load_bitmap_font(3) if you pass the name of a known bitmap format, or else al_load_ttf_font(3). .PP Bitmap and TTF fonts are affected by the current bitmap flags at the time the font is loaded. .SH SEE ALSO .PP al_destroy_font(3), al_init_font_addon(3), al_register_font_loader(3) allegro-5.0.10/docs/man/al_set_separate_blender.30000644000175000001440000000121712157230674021033 0ustar tjadenusers.TH al_set_separate_blender 3 "" "Allegro reference manual" .SH NAME .PP al_set_separate_blender \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_separate_blender(int\ op,\ int\ src,\ int\ dst, \ \ \ int\ alpha_op,\ int\ alpha_src,\ int\ alpha_dst) \f[] .fi .SH DESCRIPTION .PP Like al_set_blender(3), but allows specifying a separate blending operation for the alpha channel. This is useful if your target bitmap also has an alpha channel and the two alpha channels need to be combined in a different way than the color components. .SH SEE ALSO .PP al_set_blender(3), al_get_blender(3), al_get_separate_blender(3) allegro-5.0.10/docs/man/al_draw_soft_triangle.30000644000175000001440000000435312157230700020530 0ustar tjadenusers.TH al_draw_soft_triangle 3 "" "Allegro reference manual" .SH NAME .PP al_draw_soft_triangle \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_soft_triangle( \ \ \ ALLEGRO_VERTEX*\ v1,\ ALLEGRO_VERTEX*\ v2,\ ALLEGRO_VERTEX*\ v3,\ uintptr_t\ state, \ \ \ void\ (*init)(uintptr_t,\ ALLEGRO_VERTEX*,\ ALLEGRO_VERTEX*,\ ALLEGRO_VERTEX*), \ \ \ void\ (*first)(uintptr_t,\ int,\ int,\ int,\ int), \ \ \ void\ (*step)(uintptr_t,\ int), \ \ \ void\ (*draw)(uintptr_t,\ int,\ int,\ int)) \f[] .fi .SH DESCRIPTION .PP Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/tri_soft.c. The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of each segment may be absent if two vertices are horizontally collinear. .PP \f[I]Parameters:\f[] .IP \[bu] 2 v1, v2, v3 \- The three vertices of the triangle .IP \[bu] 2 state \- A pointer to a user supplied struct, this struct will be passed to all the pixel functions .IP \[bu] 2 init \- Called once per call before any drawing is done. The three points passed to it may be altered by clipping. .IP \[bu] 2 first \- Called twice per call, once per triangle segment. It is passed 4 parameters, the first two are the coordinates of the initial pixel drawn in the segment. The second two are the left minor and the left major steps, respectively. They represent the sizes of two steps taken by the rasterizer as it walks on the left side of the triangle. From then on, the each step will either be classified as a minor or a major step, corresponding to the above values. .IP \[bu] 2 step \- Called once per scanline. The last parameter is set to 1 if the step is a minor step, and 0 if it is a major step. .IP \[bu] 2 draw \- Called once per scanline. The function is expected to draw the scanline starting with a point specified by the first two parameters (corresponding to x and y values) going to the right until it reaches the value of the third parameter (the x value of the end point). All coordinates are inclusive. .SH SEE ALSO .PP al_draw_triangle(3) allegro-5.0.10/docs/man/al_get_current_transform.30000644000175000001440000000072712157230675021303 0ustar tjadenusers.TH al_get_current_transform 3 "" "Allegro reference manual" .SH NAME .PP al_get_current_transform \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ ALLEGRO_TRANSFORM\ *al_get_current_transform(void) \f[] .fi .SH DESCRIPTION .PP Returns the transformation of the current target bitmap, as set by al_use_transform(3). If there is no target bitmap, this function returns NULL. .PP \f[I]Returns:\f[] A pointer to the current transformation. allegro-5.0.10/docs/man/ALLEGRO_FILE_INTERFACE.30000644000175000001440000000335312157230671017451 0ustar tjadenusers.TH ALLEGRO_FILE_INTERFACE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_FILE_INTERFACE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_FILE_INTERFACE \f[] .fi .SH DESCRIPTION .PP A structure containing function pointers to handle a type of "file", real or virtual. See the full discussion in al_set_new_file_interface(3). .PP The fields are: .IP .nf \f[C] void*\ \ \ \ \ \ \ \ \ (*fi_fopen)(const\ char\ *path,\ const\ char\ *mode); void\ \ \ \ \ \ \ \ \ \ (*fi_fclose)(ALLEGRO_FILE\ *f); size_t\ \ \ \ \ \ \ \ (*fi_fread)(ALLEGRO_FILE\ *f,\ void\ *ptr,\ size_t\ size); size_t\ \ \ \ \ \ \ \ (*fi_fwrite)(ALLEGRO_FILE\ *f,\ const\ void\ *ptr,\ size_t\ size); bool\ \ \ \ \ \ \ \ \ \ (*fi_fflush)(ALLEGRO_FILE\ *f); int64_t\ \ \ \ \ \ \ (*fi_ftell)(ALLEGRO_FILE\ *f); bool\ \ \ \ \ \ \ \ \ \ (*fi_fseek)(ALLEGRO_FILE\ *f,\ int64_t\ offset,\ int\ whence); bool\ \ \ \ \ \ \ \ \ \ (*fi_feof)(ALLEGRO_FILE\ *f); bool\ \ \ \ \ \ \ \ \ \ (*fi_ferror)(ALLEGRO_FILE\ *f); void\ \ \ \ \ \ \ \ \ \ (*fi_fclearerr)(ALLEGRO_FILE\ *f); int\ \ \ \ \ \ \ \ \ \ \ (*fi_fungetc)(ALLEGRO_FILE\ *f,\ int\ c); off_t\ \ \ \ \ \ \ \ \ (*fi_fsize)(ALLEGRO_FILE\ *f); \f[] .fi .PP The fi_open function must allocate memory for whatever userdata structure it needs. The pointer to that memory must be returned; it will then be associated with the file. The other functions can access that data by calling al_get_file_userdata(3) on the file handle. If fi_open returns NULL then al_fopen(3) will also return NULL. .PP The fi_fclose function must clean up and free the userdata, but Allegro will free the ALLEGRO_FILE(3) handle. .PP If fi_fungetc is NULL, then Allegro\[aq]s default implementation of a 16 char long buffer will be used. allegro-5.0.10/docs/man/al_set_event_source_data.30000644000175000001440000000101412157230672021217 0ustar tjadenusers.TH al_set_event_source_data 3 "" "Allegro reference manual" .SH NAME .PP al_set_event_source_data \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_event_source_data(ALLEGRO_EVENT_SOURCE\ *source,\ intptr_t\ data) \f[] .fi .SH DESCRIPTION .PP Assign the abstract user data to the event source. Allegro does not use the data internally for anything; it is simply meant as a convenient way to associate your own data or objects with events. .SH SEE ALSO .PP al_get_event_source_data(3) allegro-5.0.10/docs/man/al_get_joystick_active.30000644000175000001440000000106212157230673020707 0ustar tjadenusers.TH al_get_joystick_active 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_active \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_joystick_active(ALLEGRO_JOYSTICK\ *joy) \f[] .fi .SH DESCRIPTION .PP Return if the joystick handle is "active", i.e. in the current configuration, the handle represents some physical device plugged into the system. al_get_joystick(3) returns active handles. After reconfiguration, active handles may become inactive, and vice versa. .SH SEE ALSO .PP al_reconfigure_joysticks(3) allegro-5.0.10/docs/man/al_ustr_has_suffix_cstr.30000644000175000001440000000061612157230677021135 0ustar tjadenusers.TH al_ustr_has_suffix_cstr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_has_suffix_cstr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_has_suffix_cstr(const\ ALLEGRO_USTR\ *us1,\ const\ char\ *s2) \f[] .fi .SH DESCRIPTION .PP Returns true iff \f[C]us1\f[] ends with \f[C]s2\f[]. .SH SEE ALSO .PP al_ustr_has_suffix(3), al_ustr_has_prefix_cstr(3) allegro-5.0.10/docs/man/al_get_fs_entry_name.30000644000175000001440000000145312157230672020351 0ustar tjadenusers.TH al_get_fs_entry_name 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ const\ char\ *al_get_fs_entry_name(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the entry\[aq]s filename path. Note that the filesystem encoding may not be known and the conversion to UTF\-8 could in very rare cases cause this to return an invalid path. Therefore it\[aq]s always safest to access the file over its ALLEGRO_FS_ENTRY(3) and not the path. .PP On success returns a read only string which you must not modify or destroy. Returns NULL on failure. .RS .PP Note: prior to 5.1.5 it was written: "... the path will not be an absolute path if the entry wasn\[aq]t created from an absolute path". This is no longer true. .RE allegro-5.0.10/docs/man/al_draw_bitmap_region.30000644000175000001440000000144512157230673020517 0ustar tjadenusers.TH al_draw_bitmap_region 3 "" "Allegro reference manual" .SH NAME .PP al_draw_bitmap_region \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_bitmap_region(ALLEGRO_BITMAP\ *bitmap, \ \ \ float\ sx,\ float\ sy,\ float\ sw,\ float\ sh,\ float\ dx,\ float\ dy,\ int\ flags) \f[] .fi .SH DESCRIPTION .PP Draws a region of the given bitmap to the target bitmap. .IP \[bu] 2 sx \- source x .IP \[bu] 2 sy \- source y .IP \[bu] 2 sw \- source width (width of region to blit) .IP \[bu] 2 sh \- source height (height of region to blit) .IP \[bu] 2 dx \- destination x .IP \[bu] 2 dy \- destination y .IP \[bu] 2 flags \- same as for al_draw_bitmap(3) .SH SEE ALSO .PP al_draw_bitmap(3), al_draw_scaled_bitmap(3), al_draw_rotated_bitmap(3), al_draw_scaled_rotated_bitmap(3) allegro-5.0.10/docs/man/al_cstr_dup.30000644000175000001440000000077712157230675016517 0ustar tjadenusers.TH al_cstr_dup 3 "" "Allegro reference manual" .SH NAME .PP al_cstr_dup \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ char\ *al_cstr_dup(const\ ALLEGRO_USTR\ *us) \f[] .fi .SH DESCRIPTION .PP Create a NUL (\[aq]\[aq]) terminated copy of the string. Any embedded NUL bytes will still be presented in the returned string. The new string must eventually be freed with al_free(3). .PP If an error occurs NULL is returned. .SH SEE ALSO .PP al_cstr(3), al_ustr_to_buffer(3), al_free(3) allegro-5.0.10/docs/man/ALLEGRO_EVENT_JOYSTICK_CONFIGURATION.30000644000175000001440000002700512157230670021640 0ustar tjadenusers.TH ALLEGRO_EVENT 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_EVENT \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ union\ ALLEGRO_EVENT\ ALLEGRO_EVENT; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common: .TP .B type (ALLEGRO_EVENT_TYPE) Indicates the type of event. .RS .RE .TP .B any.source (ALLEGRO_EVENT_SOURCE *) The event source which generated the event. .RS .RE .TP .B any.timestamp (double) When the event was generated. .RS .RE .PP By examining the \f[C]type\f[] field you can then access type\-specific fields. The \f[C]any.source\f[] field tells you which event source generated that particular event. The \f[C]any.timestamp\f[] field tells you when the event was generated. The time is referenced to the same starting point as al_get_time(3). .PP Each event is of one of the following types, with the usable fields given. .SS ALLEGRO_EVENT_JOYSTICK_AXIS .PP A joystick axis value changed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. This is not the same as the event source \f[C]joystick.source\f[]. .RS .RE .TP .B joystick.stick (int) The stick number, counting from zero. Axes on a joystick are grouped into "sticks". .RS .RE .TP .B joystick.axis (int) The axis number on the stick, counting from zero. .RS .RE .TP .B joystick.pos (float) The axis position, from \-1.0 to +1.0. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN .PP A joystick button was pressed. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was pressed, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP .PP A joystick button was released. .TP .B joystick.id (ALLEGRO_JOYSTICK *) The joystick which generated the event. .RS .RE .TP .B joystick.button (int) The button which was released, counting from zero. .RS .RE .SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION .PP A joystick was plugged in or unplugged. See al_reconfigure_joysticks(3) for details. .SS ALLEGRO_EVENT_KEY_DOWN .PP A keyboard key was pressed. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note:\f[] this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input. .RE .SS ALLEGRO_EVENT_KEY_UP .PP A keyboard key was released. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was released. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .SS ALLEGRO_EVENT_KEY_CHAR .PP A character was typed on the keyboard, or a character was auto\-repeated. .TP .B keyboard.keycode (int) The code corresponding to the physical key which was last pressed. See the "Key codes" section for the list of ALLEGRO_KEY_* constants. .RS .RE .TP .B keyboard.unichar (int) A Unicode code point (character). This \f[I]may\f[] be zero or negative if the event was generated for a non\-visible "character", such as an arrow or Function key. In that case you can act upon the \f[C]keycode\f[] field. .RS .PP Some special keys will set the \f[C]unichar\f[] field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the \f[C]unichar\f[] field will have the values 1 to 26. For example Ctrl\-A will set \f[C]unichar\f[] to 1 and Ctrl\-H will set it to 8. .PP As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the \f[C]keycode\f[] field. .RE .TP .B keyboard.modifiers (unsigned) This is a bitfield of the modifier keys which were pressed when the event occurred. See "Keyboard modifier flags" for the constants. .RS .RE .TP .B keyboard.repeat (bool) Indicates if this is a repeated character. .RS .RE .TP .B keyboard.display (ALLEGRO_DISPLAY *) The display which had keyboard focus when the event occurred. .RS .RE .RS .PP \f[I]Note\f[]: in many input methods, characters are \f[I]not\f[] entered one\-for\-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce \[aq]é\[aq]. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases. .RE .SS ALLEGRO_EVENT_MOUSE_AXES .PP One or more mouse axis values changed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. .RS .RE .TP .B mouse.w (int) w\-coordinate. This usually means the horizontal axis of a mouse wheel. .RS .RE .TP .B mouse.dx (int) Change in the x\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dy (int) Change in the y\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dz (int) Change in the z\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.dw (int) Change in the w\-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .RS .PP \f[I]Note:\f[] Calling al_set_mouse_xy(3) also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead. .RE .RS .PP \f[I]Note:\f[] currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis(3). .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN .PP A mouse button was pressed. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was pressed, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_BUTTON_UP .PP A mouse button was released. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.button (unsigned) The mouse button which was released, numbering from 1. .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_WARPED .PP al_set_mouse_xy(3) was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. .SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY .PP The mouse cursor entered a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY .PP The mouse cursor leave the boundaries of a window opened by the program. .TP .B mouse.x (int) x\-coordinate .RS .RE .TP .B mouse.y (int) y\-coordinate .RS .RE .TP .B mouse.z (int) z\-coordinate .RS .RE .TP .B mouse.w (int) w\-coordinate .RS .RE .TP .B mouse.display (ALLEGRO_DISPLAY *) The display which had mouse focus. .RS .RE .SS ALLEGRO_EVENT_TIMER .PP A timer counter incremented. .TP .B timer.source (ALLEGRO_TIMER *) The timer which generated the event. .RS .RE .TP .B timer.count (int64_t) The timer count value. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_EXPOSE .PP The display (or a portion thereof) has become visible. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was exposed. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) \ .RS .RE The top\-left corner of the display which was exposed. .RS .RE .TP .B display.width (int) \ .RS .RE .TP .B display.height (int) The width and height of the rectangle which was exposed. .RS .RE .RS .PP \f[I]Note:\f[] The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. .RE .SS ALLEGRO_EVENT_DISPLAY_RESIZE .PP The window has been resized. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was resized. .RS .RE .TP .B display.x (int) \ .RS .RE .TP .B display.y (int) The position of the top\-level corner of the display. .RS .RE .TP .B display.width (int) The new width of the display. .RS .RE .TP .B display.height (int) The new height of the display. .RS .RE .PP You should normally respond to these events by calling al_acknowledge_resize(3). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information. .SS ALLEGRO_EVENT_DISPLAY_CLOSE .PP The close button of the window has been pressed. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was closed. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_LOST .PP When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap\[aq]s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see ALLEGRO_NO_PRESERVE_TEXTURE) and restore them when the device is "found" (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof. .PP To ensure that all bitmap contents are restored accurately, one must take additional steps. The best procedure to follow if bitmap constancy is important to you is as follows: first, always have the ALLEGRO_NO_PRESERVE_TEXTURE flag set to true when creating bitmaps, as it incurs pointless overhead when using this method. Second, create a mechanism in your game for easily reloading all of your bitmaps \-\- for example, wrap them in a class or data structure and have a "bitmap manager" that can reload them back to the desired state. Then, when you receive an ALLEGRO_EVENT_DISPLAY_FOUND event, tell the bitmap manager (or whatever your mechanism is) to restore your bitmaps. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was lost. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_FOUND .PP Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was found. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT .PP The window is no longer active, that is the user might have clicked into another window or "tabbed" away. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched out of. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN .PP The window is the active one again. .TP .B display.source (ALLEGRO_DISPLAY *) The display which was switched into. .RS .RE .SS ALLEGRO_EVENT_DISPLAY_ORIENTATION .PP Generated when the rotation or orientation of a display changes. .TP .B display.source (ALLEGRO_DISPLAY *) The display which generated the event. .RS .RE .TP .B event.display.orientation Contains one of the following values: .RS .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_UP .IP \[bu] 2 ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN .RE .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), ALLEGRO_EVENT_TYPE(3), ALLEGRO_USER_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3) allegro-5.0.10/docs/man/al_get_fs_entry_mtime.30000644000175000001440000000064412157230672020545 0ustar tjadenusers.TH al_get_fs_entry_mtime 3 "" "Allegro reference manual" .SH NAME .PP al_get_fs_entry_mtime \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ time_t\ al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Returns the time in seconds since the epoch since the entry was last modified. .SH SEE ALSO .PP al_get_fs_entry_atime(3), al_get_fs_entry_ctime(3), al_update_fs_entry(3) allegro-5.0.10/docs/man/ALLEGRO_MONITOR_INFO.30000644000175000001440000000116312157230673017313 0ustar tjadenusers.TH ALLEGRO_MONITOR_INFO 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_MONITOR_INFO \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_MONITOR_INFO \f[] .fi .SH DESCRIPTION .PP Describes a monitors size and position relative to other monitors. x1, y1 will be 0, 0 on the primary display. Other monitors can have negative values if they are to the left or above the primary display. .IP .nf \f[C] typedef\ struct\ ALLEGRO_MONITOR_INFO { \ \ \ int\ x1; \ \ \ int\ y1; \ \ \ int\ x2; \ \ \ int\ y2; }\ ALLEGRO_MONITOR_INFO; \f[] .fi .SH SEE ALSO .PP al_get_monitor_info(3) allegro-5.0.10/docs/man/al_get_joystick_event_source.30000644000175000001440000000056012157230673022137 0ustar tjadenusers.TH al_get_joystick_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_get_joystick_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_EVENT_SOURCE\ *al_get_joystick_event_source(void) \f[] .fi .SH DESCRIPTION .PP Returns the global joystick event source. All joystick events are generated by this event source. allegro-5.0.10/docs/man/al_get_voice_playing.30000644000175000001440000000053312157230677020353 0ustar tjadenusers.TH al_get_voice_playing 3 "" "Allegro reference manual" .SH NAME .PP al_get_voice_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_get_voice_playing(const\ ALLEGRO_VOICE\ *voice) \f[] .fi .SH DESCRIPTION .PP Return true if the voice is currently playing. .SH SEE ALSO .PP al_set_voice_playing(3) allegro-5.0.10/docs/man/al_ustr_remove_chr.30000644000175000001440000000111412157230676020065 0ustar tjadenusers.TH al_ustr_remove_chr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_remove_chr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_ustr_remove_chr(ALLEGRO_USTR\ *us,\ int\ pos) \f[] .fi .SH DESCRIPTION .PP Remove the code point beginning at byte offset \f[C]pos\f[]. Returns true on success. If \f[C]pos\f[] is out of range or \f[C]pos\f[] is not the beginning of a valid code point, returns false leaving the string unmodified. .PP Use al_ustr_offset(3) to find the byte offset for a code\-points offset. .SH SEE ALSO .PP al_ustr_remove_range(3) allegro-5.0.10/docs/man/al_fungetc.30000644000175000001440000000155212157230671016313 0ustar tjadenusers.TH al_fungetc 3 "" "Allegro reference manual" .SH NAME .PP al_fungetc \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_fungetc(ALLEGRO_FILE\ *f,\ int\ c) \f[] .fi .SH DESCRIPTION .PP Ungets a single byte from a file. Pushed\-back bytes are not written to the file, only made available for subsequent reads, in reverse order. .PP The number of pushbacks depends on the backend. The standard I/O backend only guarantees a single pushback; this depends on the libc implementation. .PP For backends that follow the standard behavior, the pushback buffer will be cleared after any seeking or writing; also calls to al_fseek(3) and al_ftell(3) are relative to the number of pushbacks. If a pushback causes the position to become negative, the behavior of al_fseek(3) and al_ftell(3) are undefined. .SH SEE ALSO .PP al_fgetc(3), al_get_errno(3) allegro-5.0.10/docs/man/al_init_timeout.30000644000175000001440000000060212157230674017367 0ustar tjadenusers.TH al_init_timeout 3 "" "Allegro reference manual" .SH NAME .PP al_init_timeout \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_init_timeout(ALLEGRO_TIMEOUT\ *timeout,\ double\ seconds) \f[] .fi .SH DESCRIPTION .PP Set timeout value of some number of seconds after the function call. .SH SEE ALSO .PP ALLEGRO_TIMEOUT(3), al_wait_for_event_until(3) allegro-5.0.10/docs/man/al_get_mixer_channels.30000644000175000001440000000055012157230700020504 0ustar tjadenusers.TH al_get_mixer_channels 3 "" "Allegro reference manual" .SH NAME .PP al_get_mixer_channels \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CHANNEL_CONF\ al_get_mixer_channels(const\ ALLEGRO_MIXER\ *mixer) \f[] .fi .SH DESCRIPTION .PP Return the mixer channel configuration. .SH SEE ALSO .PP ALLEGRO_CHANNEL_CONF(3). allegro-5.0.10/docs/man/al_set_sample_instance_pan.30000644000175000001440000000161312157230700021525 0ustar tjadenusers.TH al_set_sample_instance_pan 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_pan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE\ *spl,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the pan value on a sample instance. A value of \-1.0 means to play the sample only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE(3) disables panning and plays the sample at its original level. This will be louder than a pan value of 0.0. .RS .PP Note: panning samples with more than two channels doesn\[aq]t work yet. .RE .PP Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_sample_instance_pan(3), ALLEGRO_AUDIO_PAN_NONE(3) allegro-5.0.10/docs/man/al_have_d3d_non_pow2_texture_support.30000644000175000001440000000071112157230676023533 0ustar tjadenusers.TH al_have_d3d_non_pow2_texture_support 3 "" "Allegro reference manual" .SH NAME .PP al_have_d3d_non_pow2_texture_support \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_have_d3d_non_pow2_texture_support(void) \f[] .fi .SH DESCRIPTION .PP Returns whether the Direct3D device supports textures whose dimensions are not powers of two. .PP \f[I]Returns:\f[] True if device suports NPOT textures, false otherwise. allegro-5.0.10/docs/man/al_get_backbuffer.30000644000175000001440000000201112157230670017577 0ustar tjadenusers.TH al_get_backbuffer 3 "" "Allegro reference manual" .SH NAME .PP al_get_backbuffer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_get_backbuffer(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Return a special bitmap representing the back\-buffer of the display. .PP Care should be taken when using the backbuffer bitmap (and its sub\-bitmaps) as the source bitmap (e.g as the bitmap argument to al_draw_bitmap(3)). Only untransformed operations are hardware accelerated. This consists of al_draw_bitmap(3) and al_draw_bitmap_region(3) when the current transformation is the identity. If the tranformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the al_draw_bitmap(3) and al_draw_bitmap_region(3)), and then use that temporary bitmap as the source bitmap. allegro-5.0.10/docs/man/ALLEGRO_TRANSFORM.30000644000175000001440000000076712157230675016737 0ustar tjadenusers.TH ALLEGRO_TRANSFORM 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_TRANSFORM \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_TRANSFORM\ ALLEGRO_TRANSFORM; \f[] .fi .SH DESCRIPTION .PP Defines the generic transformation type, a 4x4 matrix. 2D transforms use only a small subsection of this matrix, namely the top left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values. .PP \f[I]Fields:\f[] .IP \[bu] 2 m \- A 4x4 float matrix allegro-5.0.10/docs/man/al_get_standard_path.30000644000175000001440000000553512157230674020343 0ustar tjadenusers.TH al_get_standard_path 3 "" "Allegro reference manual" .SH NAME .PP al_get_standard_path \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_PATH\ *al_get_standard_path(int\ id) \f[] .fi .SH DESCRIPTION .PP Gets a system path, depending on the \f[C]id\f[] parameter. Some of these paths may be affected by the organization and application name, so be sure to set those before calling this function. .PP The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may be the same on some platforms), so you should be sure your filenames are unique if you need to avoid naming collisions. Also, a returned path may not actually exist on the file system. .TP .B ALLEGRO_RESOURCES_PATH If you bundle data in a location relative to your executable, then you should use this path to locate that data. On most platforms, this is the directory that contains the executable file. .RS .PP If ran from an OS X app bundle, then this will point to the internal resource directory (/Contents/Resources). To maintain consistency, if you put your resources into a directory called "data" beneath the executable on some other platform (like Windows), then you should also create a directory called "data" under the OS X app bundle\[aq]s resource folder. .PP You should not try to write to this path, as it is very likely read\-only. .PP If you install your resources in some other system directory (e.g., in /usr/share or C:\\ProgramData), then you are responsible for keeping track of that yourself. .RE .TP .B ALLEGRO_TEMP_PATH Path to the directory for temporary files. .RS .RE .TP .B ALLEGRO_USER_HOME_PATH This is the user\[aq]s home directory. You should not normally write files into this directory directly, or create any sub folders in it, without explicit permission from the user. One practical application of this path would be to use it as the starting place of a file selector in a GUI. .RS .RE .TP .B ALLEGRO_USER_DOCUMENTS_PATH This location is easily accessible by the user, and is the place to store documents and files that the user might want to later open with an external program or transfer to another place. .RS .PP You should not save files here unless the user expects it, usually by explicit permission. .RE .TP .B ALLEGRO_USER_DATA_PATH If your program saves any data that the user doesn\[aq]t need to access externally, then you should place it here. This is generally the least intrusive place to store data. .RS .RE .TP .B ALLEGRO_USER_SETTINGS_PATH If you are saving configuration files (especially if the user may want to edit them outside of your program), then you should place them here. .RS .RE .TP .B ALLEGRO_EXENAME_PATH The full path to the executable. .RS .RE .PP Returns NULL on failure. The returned path should be freed with al_destroy_path(3). .SH SEE ALSO .PP al_set_app_name(3), al_set_org_name(3), al_destroy_path(3), al_set_exe_name(3) allegro-5.0.10/docs/man/al_is_mouse_installed.30000644000175000001440000000044512157230673020544 0ustar tjadenusers.TH al_is_mouse_installed 3 "" "Allegro reference manual" .SH NAME .PP al_is_mouse_installed \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_mouse_installed(void) \f[] .fi .SH DESCRIPTION .PP Returns true if al_install_mouse(3) was called successfully. allegro-5.0.10/docs/man/al_set_sample_instance_playmode.30000644000175000001440000000072112157230700022560 0ustar tjadenusers.TH al_set_sample_instance_playmode 3 "" "Allegro reference manual" .SH NAME .PP al_set_sample_instance_playmode \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE\ *spl, \ \ \ ALLEGRO_PLAYMODE\ val) \f[] .fi .SH DESCRIPTION .PP Set the playback mode. .PP Returns true on success, false on failure. .SH SEE ALSO .PP ALLEGRO_PLAYMODE(3), al_get_sample_instance_playmode(3) allegro-5.0.10/docs/man/al_add_config_comment.30000644000175000001440000000117612157230670020460 0ustar tjadenusers.TH al_add_config_comment 3 "" "Allegro reference manual" .SH NAME .PP al_add_config_comment \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_add_config_comment(ALLEGRO_CONFIG\ *config, \ \ \ const\ char\ *section,\ const\ char\ *comment) \f[] .fi .SH DESCRIPTION .PP Add a comment in a section of a configuration. If the section doesn\[aq]t yet exist, it will be created. The section can be NULL or "" for the global section. .PP The comment may or may not begin with a hash character. Any newlines in the comment string will be replaced by space characters. .SH SEE ALSO .PP al_add_config_section(3) allegro-5.0.10/docs/man/al_is_bitmap_locked.30000644000175000001440000000057212157230673020153 0ustar tjadenusers.TH al_is_bitmap_locked 3 "" "Allegro reference manual" .SH NAME .PP al_is_bitmap_locked \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_is_bitmap_locked(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Returns whether or not a bitmap is already locked. .SH SEE ALSO .PP al_lock_bitmap(3), al_lock_bitmap_region(3), al_unlock_bitmap(3) allegro-5.0.10/docs/man/al_save_sample_f.30000644000175000001440000000137212157230702017457 0ustar tjadenusers.TH al_save_sample_f 3 "" "Allegro reference manual" .SH NAME .PP al_save_sample_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_save_sample_f(ALLEGRO_FILE\ *fp,\ const\ char\ *ident,\ ALLEGRO_SAMPLE\ *spl) \f[] .fi .SH DESCRIPTION .PP Writes a sample into a ALLEGRO_FILE(3) filestream. Currently, wav is the only supported format, and the extension must be ".wav". .PP Returns true on success, false on error. The file remains open afterwards. .RS .PP \f[I]Note:\f[] the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler. .RE .SH SEE ALSO .PP al_save_sample(3), al_register_sample_saver_f(3), al_init_acodec_addon(3) allegro-5.0.10/docs/man/al_ustr_dup_substr.30000644000175000001440000000117612157230675020135 0ustar tjadenusers.TH al_ustr_dup_substr 3 "" "Allegro reference manual" .SH NAME .PP al_ustr_dup_substr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_USTR\ *al_ustr_dup_substr(const\ ALLEGRO_USTR\ *us,\ int\ start_pos, \ \ \ int\ end_pos) \f[] .fi .SH DESCRIPTION .PP Return a new copy of a string, containing its contents in the byte interval [start_pos, end_pos). The new string will be NUL terminated and will need to be freed with al_ustr_free(3). .PP If necessary, use al_ustr_offset(3) to find the byte offsets for a given code point that you are interested in. .SH SEE ALSO .PP al_ustr_dup(3), al_ustr_free(3) allegro-5.0.10/docs/man/al_get_allegro_primitives_version.30000644000175000001440000000057112157230700023155 0ustar tjadenusers.TH al_get_allegro_primitives_version 3 "" "Allegro reference manual" .SH NAME .PP al_get_allegro_primitives_version \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ uint32_t\ al_get_allegro_primitives_version(void) \f[] .fi .SH DESCRIPTION .PP Returns the (compiled) version of the addon, in the same format as al_get_allegro_version(3). allegro-5.0.10/docs/man/al_get_font_descent.30000644000175000001440000000054712157230677020203 0ustar tjadenusers.TH al_get_font_descent 3 "" "Allegro reference manual" .SH NAME .PP al_get_font_descent \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_font_descent(const\ ALLEGRO_FONT\ *f) \f[] .fi .SH DESCRIPTION .PP Returns the descent of the specified font. .SH SEE ALSO .PP al_get_font_ascent(3), al_get_font_line_height(3) allegro-5.0.10/docs/man/al_draw_ribbon.30000644000175000001440000000131312157230700017134 0ustar tjadenusers.TH al_draw_ribbon 3 "" "Allegro reference manual" .SH NAME .PP al_draw_ribbon \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_draw_ribbon(const\ float\ *points,\ int\ points_stride,\ ALLEGRO_COLOR\ color, \ \ \ float\ thickness,\ int\ num_segments) \f[] .fi .SH DESCRIPTION .PP Draws a series of straight lines given an array of points. The ribbon will go through all of the passed points. .PP \f[I]Parameters:\f[] .IP \[bu] 2 points \- An array of coordinate pairs (x and y) for each point .IP \[bu] 2 color \- Color of the spline .IP \[bu] 2 thickness \- Thickness of the spline, pass \f[C]<=\ 0\f[] to draw hairline spline .SH SEE ALSO .PP al_calculate_ribbon(3) allegro-5.0.10/docs/man/al_fixcos.30000644000175000001440000000141612157230671016152 0ustar tjadenusers.TH al_fixcos 3 "" "Allegro reference manual" .SH NAME .PP al_fixcos \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixcos(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP This function finds the cosine of a value using a lookup table. The input value must be a fixed point binary angle. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ angle; \ \ \ \ float\ result; \ \ \ \ /*\ Set\ the\ binary\ angle\ to\ 45\ degrees.\ */ \ \ \ \ angle\ =\ al_itofix(32); \ \ \ \ /*\ The\ cosine\ of\ 45\ degrees\ is\ about\ 0.7071.\ */ \ \ \ \ result\ =\ al_fixtof(al_fixcos(angle)); \ \ \ \ assert(result\ >\ 0.7\ &&\ result\ <\ 0.71); \f[] .fi .SH RETURN VALUE .PP Returns the cosine of a fixed point binary format angle. The return value will be in radians. allegro-5.0.10/docs/man/al_get_new_display_flags.30000644000175000001440000000061012157230670021202 0ustar tjadenusers.TH al_get_new_display_flags 3 "" "Allegro reference manual" .SH NAME .PP al_get_new_display_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int\ al_get_new_display_flags(void) \f[] .fi .SH DESCRIPTION .PP Get the display flags to be used when creating new displays on the calling thread. .SH SEE ALSO .PP al_set_new_display_flags(3), al_set_display_flag(3) allegro-5.0.10/docs/man/al_create_mutex.30000644000175000001440000000066612157230674017355 0ustar tjadenusers.TH al_create_mutex 3 "" "Allegro reference manual" .SH NAME .PP al_create_mutex \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MUTEX\ *al_create_mutex(void) \f[] .fi .SH DESCRIPTION .PP Create the mutex object (a mutual exclusion device). The mutex may or may not support "recursive" locking. .PP Returns the mutex on success or \f[C]NULL\f[] on error. .SH SEE ALSO .PP al_create_mutex_recursive(3). allegro-5.0.10/docs/man/al_get_time.30000644000175000001440000000065512157230674016463 0ustar tjadenusers.TH al_get_time 3 "" "Allegro reference manual" .SH NAME .PP al_get_time \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ double\ al_get_time(void) \f[] .fi .SH DESCRIPTION .PP Return the number of seconds since the Allegro library was initialised. The return value is undefined if Allegro is uninitialised. The resolution depends on the used driver, but typically can be in the order of microseconds. allegro-5.0.10/docs/man/al_create_mixer.30000644000175000001440000000127712157230700017324 0ustar tjadenusers.TH al_create_mixer 3 "" "Allegro reference manual" .SH NAME .PP al_create_mixer \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_MIXER\ *al_create_mixer(unsigned\ int\ freq, \ \ \ ALLEGRO_AUDIO_DEPTH\ depth,\ ALLEGRO_CHANNEL_CONF\ chan_conf) \f[] .fi .SH DESCRIPTION .PP Creates a mixer stream, to attach sample streams or other mixers to. It will mix into a buffer at the requested frequency and channel count. .PP The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 and ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete). .PP Returns true on success, false on error. .SH SEE ALSO .PP al_destroy_mixer(3), ALLEGRO_AUDIO_DEPTH(3), ALLEGRO_CHANNEL_CONF(3) allegro-5.0.10/docs/man/al_set_exe_name.30000644000175000001440000000123312157230674017313 0ustar tjadenusers.TH al_set_exe_name 3 "" "Allegro reference manual" .SH NAME .PP al_set_exe_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_exe_name(char\ const\ *path) \f[] .fi .SH DESCRIPTION .PP This override the executable name used by al_get_standard_path(3) for ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH. .PP One possibility where changing this can be useful is if you use the Python wrapper. Allegro would then by default think that the system\[aq]s Python executable is the current executable \- but you can set it to the .py file being executed instead. .SH SINCE .PP 5.0.6, 5.1.0 .SH SEE ALSO .PP al_get_standard_path(3) allegro-5.0.10/docs/man/al_init.30000644000175000001440000000064512157230674015630 0ustar tjadenusers.TH al_init 3 "" "Allegro reference manual" .SH NAME .PP al_init \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ #define\ al_init()\ \ \ \ (al_install_system(ALLEGRO_VERSION_INT,\ atexit)) \f[] .fi .SH DESCRIPTION .PP Like al_install_system(3), but automatically passes in the version and uses the atexit function visible in the current compilation unit. .SH SEE ALSO .PP al_install_system(3) allegro-5.0.10/docs/man/al_set_audio_stream_pan.30000644000175000001440000000145112157230701021035 0ustar tjadenusers.TH al_set_audio_stream_pan 3 "" "Allegro reference manual" .SH NAME .PP al_set_audio_stream_pan \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM\ *stream,\ float\ val) \f[] .fi .SH DESCRIPTION .PP Set the pan value on an audio stream. A value of \-1.0 means to play the stream only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE(3) disables panning and plays the stream at its original level. This will be louder than a pan value of 0.0. .PP Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice. .SH SEE ALSO .PP al_get_audio_stream_pan(3), ALLEGRO_AUDIO_PAN_NONE(3) allegro-5.0.10/docs/man/al_set_timer_count.30000644000175000001440000000075312157230675020071 0ustar tjadenusers.TH al_set_timer_count 3 "" "Allegro reference manual" .SH NAME .PP al_set_timer_count \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_timer_count(ALLEGRO_TIMER\ *timer,\ int64_t\ new_count) \f[] .fi .SH DESCRIPTION .PP Set the timer\[aq]s counter value. The timer can be started or stopped. The count value may be positive or negative, but will always be incremented by +1 at each tick. .SH SEE ALSO .PP al_get_timer_count(3), al_add_timer_count(3) allegro-5.0.10/docs/man/al_set_errno.30000644000175000001440000000040512157230674016657 0ustar tjadenusers.TH al_set_errno 3 "" "Allegro reference manual" .SH NAME .PP al_set_errno \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_errno(int\ errnum) \f[] .fi .SH DESCRIPTION .PP Set the error number for for the calling thread. allegro-5.0.10/docs/man/al_set_window_position.30000644000175000001440000000056712157230670020772 0ustar tjadenusers.TH al_set_window_position 3 "" "Allegro reference manual" .SH NAME .PP al_set_window_position \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_window_position(ALLEGRO_DISPLAY\ *display,\ int\ x,\ int\ y) \f[] .fi .SH DESCRIPTION .PP Sets the position on screen of a non\-fullscreen display. .SH SEE ALSO .PP al_get_window_position(3) allegro-5.0.10/docs/man/al_init_user_event_source.30000644000175000001440000000313012157230672021435 0ustar tjadenusers.TH al_init_user_event_source 3 "" "Allegro reference manual" .SH NAME .PP al_init_user_event_source \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_init_user_event_source(ALLEGRO_EVENT_SOURCE\ *src) \f[] .fi .SH DESCRIPTION .PP Initialise an event source for emitting user events. The space for the event source must already have been allocated. .PP One possible way of creating custom event sources is to derive other structures with ALLEGRO_EVENT_SOURCE at the head, e.g. .IP .nf \f[C] typedef\ struct\ THING\ THING; struct\ THING\ { \ \ \ \ ALLEGRO_EVENT_SOURCE\ event_source; \ \ \ \ int\ field1; \ \ \ \ int\ field2; \ \ \ \ /*\ etc.\ */ }; THING\ *create_thing(void) { \ \ \ \ THING\ *thing\ =\ malloc(sizeof(THING)); \ \ \ \ if\ (thing)\ { \ \ \ \ \ \ \ \ al_init_user_event_source(&thing\->event_source); \ \ \ \ \ \ \ \ thing\->field1\ =\ 0; \ \ \ \ \ \ \ \ thing\->field2\ =\ 0; \ \ \ \ } \ \ \ \ return\ thing; } \f[] .fi .PP The advantage here is that the THING pointer will be the same as the ALLEGRO_EVENT_SOURCE pointer. Events emitted by the event source will have the event source pointer as the \f[C]source\f[] field, from which you can get a pointer to a THING by a simple cast (after ensuring checking the event is of the correct type). .PP However, it is only one technique and you are not obliged to use it. .PP The user event source will never be destroyed automatically. You must destroy it manually with al_destroy_user_event_source(3). .SH SEE ALSO .PP ALLEGRO_EVENT_SOURCE(3), al_destroy_user_event_source(3), al_emit_user_event(3), ALLEGRO_USER_EVENT(3) allegro-5.0.10/docs/man/al_color_name.30000644000175000001440000000060612157230677017003 0ustar tjadenusers.TH al_color_name 3 "" "Allegro reference manual" .SH NAME .PP al_color_name \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_COLOR\ al_color_name(char\ const\ *name) \f[] .fi .SH DESCRIPTION .PP Return an ALLEGRO_COLOR(3) with the given name. If the color is not found then black is returned. .PP See al_color_name_to_rgb(3) for the list of names. allegro-5.0.10/docs/man/al_fclearerr.30000644000175000001440000000113112157230671016616 0ustar tjadenusers.TH al_fclearerr 3 "" "Allegro reference manual" .SH NAME .PP al_fclearerr \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_fclearerr(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Clear the error indicator for the given file. .PP The standard I/O backend also clears the end\-of\-file indicator, and other backends \f[I]should\f[] try to do this. However, they may not if it would require too much effort (e.g. PhysicsFS backend), so your code should not rely on it if you need your code to be portable to other backends. .SH SEE ALSO .PP al_ferror(3), al_feof(3) allegro-5.0.10/docs/man/al_fread32le.30000644000175000001440000000104012157230671016417 0ustar tjadenusers.TH al_fread32le 3 "" "Allegro reference manual" .SH NAME .PP al_fread32le \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ int32_t\ al_fread32le(ALLEGRO_FILE\ *f) \f[] .fi .SH DESCRIPTION .PP Reads a 32\-bit word in little\-endian format (LSB first). .PP On success, returns the 32\-bit word. On failure, returns EOF (\-1). Since \-1 is also a valid return value, use al_feof(3) to check if the end of the file was reached prematurely, or al_ferror(3) to check if an error occurred. .SH SEE ALSO .PP al_fread32be(3) allegro-5.0.10/docs/man/al_clone_bitmap.30000644000175000001440000000066412157230673017321 0ustar tjadenusers.TH al_clone_bitmap 3 "" "Allegro reference manual" .SH NAME .PP al_clone_bitmap \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_BITMAP\ *al_clone_bitmap(ALLEGRO_BITMAP\ *bitmap) \f[] .fi .SH DESCRIPTION .PP Create a new bitmap with al_create_bitmap(3), and copy the pixel data from the old bitmap across. .SH SEE ALSO .PP al_create_bitmap(3), al_set_new_bitmap_format(3), al_set_new_bitmap_flags(3) allegro-5.0.10/docs/man/al_set_mixer_playing.30000644000175000001440000000060612157230700020372 0ustar tjadenusers.TH al_set_mixer_playing 3 "" "Allegro reference manual" .SH NAME .PP al_set_mixer_playing \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_set_mixer_playing(ALLEGRO_MIXER\ *mixer,\ bool\ val) \f[] .fi .SH DESCRIPTION .PP Change whether the mixer is playing. .PP Returns true on success, false on failure. .SH SEE ALSO .PP al_get_mixer_playing(3). allegro-5.0.10/docs/man/al_set_new_display_adapter.30000644000175000001440000000117112157230673021550 0ustar tjadenusers.TH al_set_new_display_adapter 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_display_adapter \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_display_adapter(int\ adapter) \f[] .fi .SH DESCRIPTION .PP Sets the adapter to use for new displays created by the calling thread. The adapter has a monitor attached to it. Information about the monitor can be gotten using al_get_num_video_adapters(3) and al_get_monitor_info(3). .PP To return to the default behaviour, pass \f[C]ALLEGRO_DEFAULT_DISPLAY_ADAPTER\f[]. .SH SEE ALSO .PP al_get_num_video_adapters(3), al_get_monitor_info(3) allegro-5.0.10/docs/man/al_read_directory.30000644000175000001440000000101512157230672017652 0ustar tjadenusers.TH al_read_directory 3 "" "Allegro reference manual" .SH NAME .PP al_read_directory \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_FS_ENTRY\ *al_read_directory(ALLEGRO_FS_ENTRY\ *e) \f[] .fi .SH DESCRIPTION .PP Reads the next directory item and returns a filesystem entry for it. .PP Returns NULL if there are no more entries or if an error occurs. Call al_destroy_fs_entry(3) on the returned entry when you are done with it. .SH SEE ALSO .PP al_open_directory(3), al_close_directory(3) allegro-5.0.10/docs/man/al_set_current_opengl_context.30000644000175000001440000000150312157230676022326 0ustar tjadenusers.TH al_set_current_opengl_context 3 "" "Allegro reference manual" .SH NAME .PP al_set_current_opengl_context \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_current_opengl_context(ALLEGRO_DISPLAY\ *display) \f[] .fi .SH DESCRIPTION .PP Make the OpenGL context associated with the given display current for the calling thread. If there is a current target bitmap which belongs to a different OpenGL context, the target bitmap will be changed to NULL. .PP Normally you do not need to use this function, as the context will be made current when you call al_set_target_bitmap(3) or al_set_target_backbuffer(3). You might need if it you created an OpenGL "forward compatible" context. Then al_get_backbuffer(3) only returns NULL, so it would not work to pass that to al_set_target_bitmap(3). allegro-5.0.10/docs/man/al_get_audio_stream_channels.30000644000175000001440000000061512157230701022037 0ustar tjadenusers.TH al_get_audio_stream_channels 3 "" "Allegro reference manual" .SH NAME .PP al_get_audio_stream_channels \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_CHANNEL_CONF\ al_get_audio_stream_channels( \ \ \ const\ ALLEGRO_AUDIO_STREAM\ *stream) \f[] .fi .SH DESCRIPTION .PP Return the stream channel configuration. .SH SEE ALSO .PP ALLEGRO_CHANNEL_CONF(3). allegro-5.0.10/docs/man/al_get_sample_instance_depth.30000644000175000001440000000056312157230677022057 0ustar tjadenusers.TH al_get_sample_instance_depth 3 "" "Allegro reference manual" .SH NAME .PP al_get_sample_instance_depth \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ ALLEGRO_AUDIO_DEPTH\ al_get_sample_instance_depth(const\ ALLEGRO_SAMPLE_INSTANCE\ *spl) \f[] .fi .SH DESCRIPTION .PP Return the audio depth. .SH SEE ALSO .PP ALLEGRO_AUDIO_DEPTH(3). allegro-5.0.10/docs/man/al_color_rgb_to_hsv.30000644000175000001440000000100612157230677020212 0ustar tjadenusers.TH al_color_rgb_to_hsv 3 "" "Allegro reference manual" .SH NAME .PP al_color_rgb_to_hsv \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_color_rgb_to_hsv(float\ red,\ float\ green,\ float\ blue, \ \ \ float\ *hue,\ float\ *saturation,\ float\ *value) \f[] .fi .SH DESCRIPTION .PP Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and value in the range 0..1. .SH SEE ALSO .PP al_color_hsv_to_rgb(3), al_color_hsv(3) allegro-5.0.10/docs/man/al_register_sample_loader_f.30000644000175000001440000000144012157230701021666 0ustar tjadenusers.TH al_register_sample_loader_f 3 "" "Allegro reference manual" .SH NAME .PP al_register_sample_loader_f \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ bool\ al_register_sample_loader_f(const\ char\ *ext, \ \ \ ALLEGRO_SAMPLE\ *(*loader)(ALLEGRO_FILE*\ fp)) \f[] .fi .SH DESCRIPTION .PP Register a handler for al_load_sample_f(3). The given function will be used to handle the loading of sample files with the given extension. .PP The extension should include the leading dot (\[aq].\[aq]) character. It will be matched case\-insensitively. .PP The \f[C]loader\f[] argument may be NULL to unregister an entry. .PP Returns true on success, false on error. Returns false if unregistering an entry that doesn\[aq]t exist. .SH SEE ALSO .PP al_register_sample_loader(3) allegro-5.0.10/docs/man/al_fixacos.30000644000175000001440000000155112157230671016313 0ustar tjadenusers.TH al_fixacos 3 "" "Allegro reference manual" .SH NAME .PP al_fixacos \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ al_fixed\ al_fixacos(al_fixed\ x); \f[] .fi .SH DESCRIPTION .PP This function finds the inverse cosine of a value using a lookup table. The input value must be a fixed point radian. The inverse cosine is defined only in the domain from \-1 to 1. Outside of this input range, the function will set Allegro\[aq]s errno to EDOM and return zero. .PP Example: .IP .nf \f[C] \ \ \ \ al_fixed\ result; \ \ \ \ /*\ Sets\ result\ to\ binary\ angle\ 128.\ */ \ \ \ \ result\ =\ al_fixacos(al_itofix(\-1)); \f[] .fi .SH RETURN VALUE .PP Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range. All return values of this function will be in the range 0 to 128. allegro-5.0.10/docs/man/ALLEGRO_SAMPLE_INSTANCE.30000644000175000001440000000173312157230676017624 0ustar tjadenusers.TH ALLEGRO_SAMPLE_INSTANCE 3 "" "Allegro reference manual" .SH NAME .PP ALLEGRO_SAMPLE_INSTANCE \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ struct\ ALLEGRO_SAMPLE_INSTANCE\ ALLEGRO_SAMPLE_INSTANCE; \f[] .fi .SH DESCRIPTION .PP An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a predefined sound effect. It holds information pertaining to the looping mode, loop start/end points, playing position, etc. An instance uses the data from an ALLEGRO_SAMPLE(3) object. Multiple instances may be created from the same ALLEGRO_SAMPLE. An ALLEGRO_SAMPLE must not be destroyed while there are instances which reference it. .PP To be played, an ALLEGRO_SAMPLE_INSTANCE object must be attached to an ALLEGRO_VOICE(3) object, or to an ALLEGRO_MIXER(3) object which is itself attached to an ALLEGRO_VOICE object (or to another ALLEGRO_MIXER object which is attached to an ALLEGRO_VOICE object, etc). .SH SEE ALSO .PP ALLEGRO_SAMPLE(3) allegro-5.0.10/docs/man/al_set_new_bitmap_flags.30000644000175000001440000001432512157230673021040 0ustar tjadenusers.TH al_set_new_bitmap_flags 3 "" "Allegro reference manual" .SH NAME .PP al_set_new_bitmap_flags \- Allegro 5 API .SH SYNOPSIS .IP .nf \f[C] #include\ void\ al_set_new_bitmap_flags(int\ flags) \f[] .fi .SH DESCRIPTION .PP Sets the flags to use for newly created bitmaps. Valid flags are: .TP .B ALLEGRO_VIDEO_BITMAP Creates a bitmap that resides in the video card memory. These types of bitmaps receive the greatest benefit from hardware acceleration. al_set_new_bitmap_flags(3) will implicitly set this flag unless ALLEGRO_MEMORY_BITMAP is present. .RS .RE .TP .B ALLEGRO_MEMORY_BITMAP Create a bitmap residing in system memory. Operations on, and with, memory bitmaps will not be hardware accelerated. However, direct pixel access can be relatively quick compared to video bitmaps, which depend on the display driver in use. .RS .PP \f[I]Note: Allegro\[aq]s software rendering routines are currently very unoptimised.\f[] .RE .TP .B ALLEGRO_KEEP_BITMAP_FORMAT Only used when loading bitmaps from disk files, forces the resulting ALLEGRO_BITMAP(3) to use the same format as the file. .RS .PP \f[I]This is not yet honoured.\f[] .RE .TP .B ALLEGRO_FORCE_LOCKING When drawing to a bitmap with this flag set, always use pixel locking and draw to it using Allegro\[aq]s software drawing primitives. This should never be used if you plan to draw to the bitmap using Allegro\[aq]s graphics primitives as it would cause severe performance penalties. However if you know that the bitmap will only ever be accessed by locking it, no unneeded FBOs will be created for it in the OpenGL drivers. .RS .RE .TP .B ALLEGRO_NO_PRESERVE_TEXTURE Normally, every effort is taken to preserve the contents of bitmaps, since Direct3D may forget them. This can take extra processing time. If you know it doesn\[aq]t matter if a bitmap keeps its pixel data, for example its a temporary buffer, use this flag to tell Allegro not to attempt to preserve its contents. This can increase performance of your game or application, but there is a catch. See ALLEGRO_EVENT_DISPLAY_LOST for further information. .RS .RE .TP .B ALLEGRO_ALPHA_TEST This is a driver hint only. It tells the graphics driver to do alpha testing instead of alpha blending on bitmaps created with this flag. Alpha testing is usually faster and preferred if your bitmaps have only one level of alpha (0). This flag is currently not widely implemented (i.e., only for memory bitmaps). .RS .RE .TP .B ALLEGRO_MIN_LINEAR When drawing a scaled down version of the bitmap, use linear filtering. This usually looks better. You can also combine it with the MIPMAP flag for even better quality. .RS .RE .TP .B ALLEGRO_MAG_LINEAR When drawing a magnified version of a bitmap, use linear filtering. This will cause the picture to get blurry instead of creating a big rectangle for each pixel. It depends on how you want things to look like whether you want to use this or not. .RS .RE .TP .B ALLEGRO_MIPMAP This can only be used for bitmaps whose width and height is a power of two. In that case, it will generate mipmaps and use them when drawing scaled down versions. For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled down version of the original. .RS .RE .TP .B ALLEGRO_NO_PREMULTIPLIED_ALPHA By default, Allegro pre\-multiplies the alpha channel of an image with the images color data when it loads it. Typically that would look something like this: .RS .IP .nf \f[C] r\ =\ get_float_byte(); g\ =\ get_float_byte(); b\ =\ get_float_byte(); a\ =\ get_float_byte(); r\ =\ r\ *\ a; g\ =\ g\ *\ a; b\ =\ b\ *\ a; set_image_pixel(x,\ y,\ r,\ g,\ b,\ a); \f[] .fi .PP The reason for this can be seen in the Allegro example ex_premulalpha, ie, using pre\-multiplied alpha gives more accurate color results in some cases. To use alpha blending with images loaded with pre\-multiplied alpha, you would use the default blending mode, which is set with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA). .PP The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that images are not loaded with alpha pre\-multiplied, but are loaded with color values direct from the image. That looks like this: .IP .nf \f[C] r\ =\ get_float_byte(); g\ =\ get_float_byte(); b\ =\ get_float_byte(); a\ =\ get_float_byte(); set_image_pixel(x,\ y,\ r,\ g,\ b,\ a); \f[] .fi .PP To draw such an image using regular alpha blending, you would use al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) to set the correct blender. This has some caveats. First, as mentioned above, drawing such an image can result in less accurate color blending (when drawing an image with linear filtering on, the edges will be darker than they should be). Second, the behaviour is somewhat confusing, which is explained in the example below. .IP .nf \f[C] //\ Load\ and\ create\ bitmaps\ with\ an\ alpha\ channel al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA); //\ Load\ some\ bitmap\ with\ alpha\ in\ it bmp\ =\ al_load_bitmap("some_alpha_bitmap.png"); //\ We\ will\ draw\ to\ this\ buffer\ and\ then\ draw\ this\ buffer\ to\ the\ screen tmp_buffer\ =\ al_create_bitmap(SCREEN_W,\ SCREEN_H); //\ Set\ the\ buffer\ as\ the\ target\ and\ clear\ it al_set_target_bitmap(tmp_buffer); al_clear_to_color(al_map_rgba_f(0,\ 0,\ 0,\ 1)); //\ Draw\ the\ bitmap\ to\ the\ temporary\ buffer al_draw_bitmap(bmp,\ 0,\ 0,\ 0); //\ Finally,\ draw\ the\ buffer\ to\ the\ screen //\ The\ output\ will\ look\ incorrect\ (may\ take\ close\ inspection //\ depending\ on\ the\ bitmap\ \-\-\ it\ may\ also\ be\ very\ obvious) al_set_target_bitmap(al_get_backbuffer(display)); al_draw_bitmap(tmp_buffer,\ 0,\ 0,\ 0); \f[] .fi .RE .PP To explain further, if you have a pixel with 0.5 alpha, and you\[aq]re using (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, the formula is: .IP .nf \f[C] \ \ \ \ a\ =\ da\ *\ dst\ +\ sa\ *\ src \f[] .fi .PP Expands to: .IP .nf \f[C] \ \ \ \ result_a\ =\ dst_a\ *\ (1\-0.5)\ +\ 0.5\ *\ 0.5; \f[] .fi .PP So if you draw the image to the temporary buffer, it is blended once resulting in 0.75 alpha, then drawn again to the screen, blended in the same way, resulting in a pixel has 0.1875 as an alpha value. .SH SEE ALSO .PP al_get_new_bitmap_flags(3), al_get_bitmap_flags(3) allegro-5.0.10/README_make.txt0000644000175000001440000000336111520362452015104 0ustar tjadenusersBuilding Allegro with make ========================== This document discusses building Allegro using CMake and GNU make from a terminal window. This document applies to Unix-like operating systems such as Linux, and also Mac OS X and MinGW. 1. Unpack Allegro. 2. Create a build directory under the Allegro directory and go there. cd /path/to/allegro mkdir Build cd Build 3. Run `cmake` with whatever options you want. See README_cmake.txt for details about options you can set. cmake .. Here ".." is the path to the Allegro directory. Alternatively, you can use `ccmake` (Unix) or `cmake-gui` (Windows) to bring up an interactive option selector. e.g. `ccmake ..` or `cmake-gui ..`. You may need to tell CMake which "generator" to use; cmake -h will tell you which generators are available. We recommend using the Makefile generator (default everywhere except Windows). On MinGW you will have a choice between "MinGW Makefiles" or "MSYS Makefiles". If `sh.exe` is on your PATH then you must use "MSYS Makefiles", otherwise use "MinGW Makefiles". More examples: cmake .. -G "MinGW Makefiles" cmake .. -G "MSYS Makefiles" 4. Now, if that step was successful you can run `make` to build Allegro. On MinGW your make might actually be called `mingw32-make`. make Since multicore processors are common now, you might wish to speed that up by passing a "-j" option, where is the number of parallel jobs to spawn. 5. You may optionally install Allegro into your system path with the install target. make install MinGW users might need to set the MINGDIR environment variable first. The DESTDIR variable is supported for staged installs. make install DESTDIR=/tmp/allegro-package allegro-5.0.10/demos/0000755000175000001440000000000012157230515013516 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/0000755000175000001440000000000012157230746017102 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/src/0000755000175000001440000000000012157230746017671 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/src/PowerUp.cpp0000644000175000001440000000222012031751243021761 0ustar tjadenusers#include "cosmic_protector.hpp" bool PowerUp::logic(int step) { angle += da * step; x += dx; y += dy; if (x < -radius || x > BB_W+radius || y < -radius || y > BB_H+radius) { return false; } Player *p = (Player *)getPlayerCollision(); if (p) { p->givePowerUp(type); my_play_sample(RES_POWERUP); return false; } if (!Entity::logic(step)) return false; return true; } void PowerUp::render(int offx, int offy) { al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, angle, 0); } PowerUp::PowerUp(float x, float y, int type) : SPIN_SPEED(0.002f) { this->x = x; this->y = y; this->type = type; dx = randf(0.5f, 1.2f); dy = randf(0.5f, 1.2f); radius = 16; isDestructable = false; hp = 1; da = (rand() % 2) ? -SPIN_SPEED : SPIN_SPEED; ResourceManager& rm = ResourceManager::getInstance(); switch (type) { case POWERUP_LIFE: bitmap = (ALLEGRO_BITMAP *)rm.getData(RES_LIFEPOWERUP); break; default: type = POWERUP_WEAPON; bitmap = (ALLEGRO_BITMAP *)rm.getData(RES_WEAPONPOWERUP); break; } } allegro-5.0.10/demos/cosmic_protector/src/BitmapResource.cpp0000644000175000001440000000120412031751243023305 0ustar tjadenusers#include "cosmic_protector.hpp" void BitmapResource::destroy(void) { if (!bitmap) return; al_destroy_bitmap(bitmap); bitmap = 0; } bool BitmapResource::load(void) { al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); bitmap = al_load_bitmap(filename.c_str()); if (!bitmap) debug_message("Error loading bitmap %s\n", filename.c_str()); return bitmap != 0; } void* BitmapResource::get(void) { return bitmap; } BitmapResource::BitmapResource(const char* filename) : bitmap(0) { this->filename = std::string(filename); } allegro-5.0.10/demos/cosmic_protector/src/wave.cpp0000644000175000001440000000152412031751243021330 0ustar tjadenusers#include "cosmic_protector.hpp" Wave::Wave() : rippleNum(0) { } bool Wave::next(void) { rippleNum++; showWave(rippleNum); for (int i = 0; i < rippleNum+1; i++) { float x, y, dx, dy, da; if (rand() % 2) { x = -randf(32.0f, 100.0f); } else { x = BB_W+randf(32.0f, 100.0f); } if (rand() % 2) { y = -randf(32.0f, 70.0f); } else { y = BB_H+randf(32.0f, 70.0f); } dx = randf(0.06f, 0.12f); dy = randf(0.04f, 0.08f); da = randf(0.001f, 0.005f); if (rand() % 2) dx = -dx; if (rand() % 2) dy = -dy; if (rand() % 2) da = -da; LargeAsteroid *la = new LargeAsteroid(x, y, dx, dy, da); if ((rand() % 5) == 0) { la->setPowerUp(rand() % 2); } entities.push_back(la); } return true; } allegro-5.0.10/demos/cosmic_protector/src/Asteroid.cpp0000644000175000001440000000167612031751243022150 0ustar tjadenusers#include "cosmic_protector.hpp" void Asteroid::init(float x, float y, float speed_x, float speed_y, float da) { this->x = x; this->y = y; this->speed_x = speed_x; this->speed_y = speed_y; this->da = da; } bool Asteroid::logic(int step) { angle -= da * step; Player *p = (Player *)getPlayerCollision(); if (p) { explode(); p->hit(1); my_play_sample(RES_COLLISION); return false; } dx = speed_x * step; dy = speed_y * step; Entity::wrap(); if (!Entity::logic(step)) return false; return true; } void Asteroid::render(int offx, int offy) { al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, angle, 0); } Asteroid::Asteroid(float radius, int bitmapID) { this->radius = radius; angle = randf(0.0f, ALLEGRO_PI*2.0f); ResourceManager& rm = ResourceManager::getInstance(); bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapID); } Asteroid::~Asteroid() { } allegro-5.0.10/demos/cosmic_protector/src/ResourceManager.cpp0000644000175000001440000000172512031751243023453 0ustar tjadenusers#include "cosmic_protector.hpp" ResourceManager* ResourceManager::rm = 0; ResourceManager& ResourceManager::getInstance(void) { if (!rm) rm = new ResourceManager(); return *rm; } void ResourceManager::destroy(void) { std::vector::reverse_iterator it; for (it = resources.rbegin(); it != resources.rend(); it++) { Resource* r = *it; r->destroy(); delete r; } resources.clear(); delete rm; rm = 0; } bool ResourceManager::add(Resource* res, bool load) { // We have to add the resource even if loading fails, if we want to be able // to continue without the resource (e.g. samples). resources.push_back(res); if (load) { if (!res->load()) return false; } return true; } Resource* ResourceManager::getResource(int index) { return resources[index]; } void* ResourceManager::getData(int index) { return getResource(index)->get(); } ResourceManager::ResourceManager(void) { } allegro-5.0.10/demos/cosmic_protector/src/LargeBullet.cpp0000644000175000001440000000051312031751243022565 0ustar tjadenusers#include "cosmic_protector.hpp" void LargeBullet::render(int offx, int offy) { al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, angle+(ALLEGRO_PI/2), 0); } LargeBullet::LargeBullet(float x, float y, float angle, Entity *shooter) : Bullet(x, y, 6, 0.6f, angle, 600, 2, RES_LARGEBULLET, shooter) { } allegro-5.0.10/demos/cosmic_protector/src/SampleResource.cpp0000644000175000001440000000120012031751243023306 0ustar tjadenusers#include "cosmic_protector.hpp" void SampleResource::destroy(void) { al_destroy_sample(sample_data); sample_data = 0; } bool SampleResource::load(void) { if (!al_is_audio_installed()) { debug_message("Skipped loading sample %s\n", filename.c_str()); return true; } sample_data = al_load_sample(filename.c_str()); if (!sample_data) { debug_message("Error loading sample %s\n", filename.c_str()); return false; } return true; } void* SampleResource::get(void) { return sample_data; } SampleResource::SampleResource(const char* filename) : sample_data(0), filename(filename) { } allegro-5.0.10/demos/cosmic_protector/src/Debug.cpp0000644000175000001440000000023212031751243021407 0ustar tjadenusers#include "cosmic_protector.hpp" void debug_message(const char * fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); } allegro-5.0.10/demos/cosmic_protector/src/Explosion.cpp0000644000175000001440000000161612031751243022350 0ustar tjadenusers#include "cosmic_protector.hpp" bool Explosion::logic(int step) { frameCount -= step; if (frameCount <= 0) { currFrame++; frameCount = FRAME_TIME; if (currFrame >= NUM_FRAMES) return false; } return true; } void Explosion::render(int offx, int offy) { ResourceManager& rm = ResourceManager::getInstance(); ALLEGRO_BITMAP *bitmap; int bitmapIndex; if (big) bitmapIndex = RES_LARGEEXPLOSION0 + currFrame; else bitmapIndex = RES_SMALLEXPLOSION0 + currFrame; bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapIndex); al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, 0, 0); } Explosion::Explosion(float x, float y, bool big) { this->x = x; this->y = y; dx = 0.0f; dy = 0.0f; radius = (big) ? 32 : 12; isDestructable = false; hp = 1; frameCount = FRAME_TIME; currFrame = 0; this->big = big; } allegro-5.0.10/demos/cosmic_protector/src/Player.cpp0000644000175000001440000001777212031751243021636 0ustar tjadenusers#include "cosmic_protector.hpp" const float Player::MAX_SPEED = 10.0f; const float Player::MIN_SPEED = -10.0f; const float Player::ACCEL = 0.006f; const float Player::DECCEL = 0.001f; bool Player::logic(int step) { if (!isDestructable && invincibleCount > 0) { invincibleCount -= step; if (invincibleCount <= 0) { isDestructable = true; if (lives <= 0) return false; } } if (lives <= 0) return true; ResourceManager& rm = ResourceManager::getInstance(); Input *input = (Input *)rm.getData(RES_INPUT); if (input->lr() < 0.0f) { angle -= 0.005f * step; } else if (input->lr() > 0.0f) { angle += 0.005f * step; } if (input->ud() < 0.0f) { dx += ACCEL * step * cos(angle); if (dx > MAX_SPEED) dx = MAX_SPEED; else if (dx < MIN_SPEED) dx = MIN_SPEED; dy += ACCEL * step * sin(angle); if (dy > MAX_SPEED) dy = MAX_SPEED; else if (dy < MIN_SPEED) dy = MIN_SPEED; draw_trail = true; } else { if (dx > 0) dx -= DECCEL * step; else if (dx < 0) dx += DECCEL * step; if (dx > -0.1f && dx < 0.1f) dx = 0; if (dy > 0) dy -= DECCEL * step; else if (dy < 0) dy += DECCEL * step; if (dy > -0.1f && dy < 0.1f) dy = 0; draw_trail = false; } int shotRate; switch (weapon) { case WEAPON_SMALL: shotRate = 300; break; case WEAPON_LARGE: shotRate = 250; break; default: shotRate = INT_MAX; break; } int now = (int) (al_get_time() * 1000.0); if ((lastShot+shotRate) < now && input->b1()) { lastShot = now; float realAngle = angle; float bx = x + radius * cos(realAngle); float by = y + radius * sin(realAngle); Bullet *b = 0; int resourceID = RES_FIRESMALL; switch (weapon) { case WEAPON_SMALL: b = new SmallBullet(bx, by, angle, this); resourceID = RES_FIRESMALL; break; case WEAPON_LARGE: b = new LargeBullet(bx, by, angle, this); resourceID = RES_FIRELARGE; break; } if (b) { my_play_sample(resourceID); new_entities.push_back(b); } } if (input->cheat()) { al_rest(0.250); std::list::iterator it; for (it = entities.begin(); it != entities.end(); it++) { Entity *e = *it; delete e; } entities.clear(); } Entity::wrap(); if (!Entity::logic(step)) return false; return true; } void Player::render_extra(void) { ResourceManager& rm = ResourceManager::getInstance(); if (lives <= 0) { int w = al_get_bitmap_width(highscoreBitmap); int h = al_get_bitmap_height(highscoreBitmap); al_draw_bitmap(highscoreBitmap, (BB_W-w)/2, (BB_H-h)/2, 0); return; } al_draw_bitmap(icon, 2, 2, 0); ALLEGRO_FONT *small_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); al_draw_textf(small_font, al_map_rgb(255, 255, 255), 20, 2, 0, "x%d", lives); al_draw_textf(small_font, al_map_rgb(255, 255, 255), 2, 18, 0, "%d", score); } void Player::render(int offx, int offy, ALLEGRO_COLOR tint) { if (lives <= 0) return; int rx = (int)(offx + x), ry = (int)(offy + y); if (!isDestructable) { al_draw_tinted_rotated_bitmap(trans_bitmap, tint, draw_radius, draw_radius, rx, ry, angle+(ALLEGRO_PI/2.0f), 0); } else { al_draw_tinted_rotated_bitmap(bitmap, tint, draw_radius, draw_radius, rx, ry, angle+(ALLEGRO_PI/2.0f), 0); } if (draw_trail) { int tw = al_get_bitmap_width(trail_bitmap); int th = al_get_bitmap_height(trail_bitmap); float ca = (ALLEGRO_PI*2)+angle; float a = ca + ((210.0f / 180.0f) * ALLEGRO_PI); float tx = rx + 42.0f * cos(a); float ty = ry + 42.0f * sin(a); al_draw_tinted_rotated_bitmap(trail_bitmap, tint, tw, th/2, tx, ty, a, 0); a = ca + ((150.0f / 180.0f) * ALLEGRO_PI); tx = rx + 42.0f * cos(a); ty = ry + 42.0f * sin(a); al_draw_tinted_rotated_bitmap(trail_bitmap, tint, tw, th/2, tx, ty, a, 0); } } void Player::render(int offx, int offy) { render(offx, offy, al_map_rgb(255, 255, 255)); } bool Player::hit(int damage) { Entity::hit(damage); die(); return true; } Player::Player() : weapon(WEAPON_SMALL), lastShot(0), score(0), bitmap(0), trans_bitmap(0), trail_bitmap(0), icon(0), highscoreBitmap(0) { } Player::~Player() { } void Player::destroy(void) { al_destroy_bitmap(bitmap); al_destroy_bitmap(trans_bitmap); al_destroy_bitmap(trail_bitmap); al_destroy_bitmap(icon); al_destroy_bitmap(highscoreBitmap); bitmap = 0; trans_bitmap = 0; trail_bitmap = 0; icon = 0; highscoreBitmap = 0; } bool Player::load(void) { ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); bitmap = al_load_bitmap(getResource("gfx/ship.tga")); if (!bitmap) { debug_message("Error loading %s\n", getResource("gfx/ship.tga")); return false; } trans_bitmap = al_create_bitmap(al_get_bitmap_width(bitmap), al_get_bitmap_height(bitmap)); if (!trans_bitmap) { debug_message("Error loading %s\n", getResource("gfx/ship_trans.tga")); al_destroy_bitmap(bitmap); return false; } /* Make a translucent copy of the ship */ al_set_target_bitmap(trans_bitmap); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_tinted_bitmap(bitmap, al_map_rgba(255, 255, 255, 160), 0, 0, 0); al_restore_state(&state); trail_bitmap = al_load_bitmap(getResource("gfx/trail.tga")); if (!trail_bitmap) { debug_message("Error loading %s\n", getResource("gfx/trail.tga")); al_destroy_bitmap(bitmap); al_destroy_bitmap(trans_bitmap); return false; } icon = al_load_bitmap(getResource("gfx/ship_icon.tga")); if (!icon) { debug_message("Error loading %s\n", getResource("gfx/icon.tga")); al_destroy_bitmap(bitmap); al_destroy_bitmap(trans_bitmap); al_destroy_bitmap(trail_bitmap); return false; } highscoreBitmap = al_create_bitmap(300, 200); al_set_target_bitmap(highscoreBitmap); al_clear_to_color(al_map_rgba(0, 0, 0, 0)); al_restore_state(&state); draw_radius = al_get_bitmap_width(bitmap)/2; radius = draw_radius / 2; newGame(); reset(); return true; } void* Player::get(void) { return this; } void Player::newGame(void) { lives = 5; hp = 1; score = 0; isDestructable = true; } void Player::reset(void) { x = BB_W/2; y = BB_H/2; dx = 0; dy = 0; angle = -ALLEGRO_PI/2; draw_trail = false; weapon = WEAPON_SMALL; } void Player::die(void) { shake(); reset(); lives--; if (lives <= 0) { // game over isDestructable = false; invincibleCount = 20000; ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); al_set_target_bitmap(highscoreBitmap); int w = al_get_bitmap_width(highscoreBitmap); int h = al_get_bitmap_height(highscoreBitmap); ResourceManager& rm = ResourceManager::getInstance(); ALLEGRO_FONT *large_font = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); ALLEGRO_FONT *small_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); al_draw_textf(large_font, al_map_rgb(255, 255, 255), w/2, h/2-16, ALLEGRO_ALIGN_CENTRE, "GAME OVER"); al_draw_textf(small_font, al_map_rgb(255, 255, 255), w/2, h/2+16, ALLEGRO_ALIGN_CENTRE, "%d Points", score); al_set_target_bitmap(old_target); } else { hp = 1; isDestructable = false; invincibleCount = 3000; } } void Player::givePowerUp(int type) { switch (type) { case POWERUP_LIFE: lives++; break; case POWERUP_WEAPON: weapon = WEAPON_LARGE; break; } } void Player::addScore(int points) { score += points; } int Player::getScore(void) { return score; } allegro-5.0.10/demos/cosmic_protector/src/LargeSlowBullet.cpp0000644000175000001440000000033312031751243023432 0ustar tjadenusers#include "cosmic_protector.hpp" LargeSlowBullet::LargeSlowBullet(float x, float y, float angle, Entity *shooter) : LargeBullet(x, y, angle, shooter) { speed = 0.20f; lifetime += 1000; playerOnly = true; } allegro-5.0.10/demos/cosmic_protector/src/render.cpp0000644000175000001440000000570612031751243021653 0ustar tjadenusers#include "cosmic_protector.hpp" static float waveAngle = 0.0f; static ALLEGRO_BITMAP *waveBitmap = 0; static float bgx = 0; static float bgy = 0; static int shakeUpdateCount = 0; static int shakeCount = 0; const int SHAKE_TIME = 100; const int SHAKE_TIMES = 10; static void renderWave(void) { int w = al_get_bitmap_width(waveBitmap); int h = al_get_bitmap_height(waveBitmap); float a = waveAngle + ALLEGRO_PI/2; int x = (int)(BB_W/2 + 64*cos(a)); int y = (int)(BB_H/2 + 64*sin(a)); al_draw_rotated_bitmap(waveBitmap, w/2, h, x, y, waveAngle, 0); } static void stopWave(void) { waveAngle = 0.0f; al_destroy_bitmap(waveBitmap); waveBitmap = 0; } void showWave(int num) { if (waveBitmap) stopWave(); ResourceManager& rm = ResourceManager::getInstance(); ALLEGRO_FONT *myfont = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); char text[20]; sprintf(text, "WAVE %d", num); int w = al_get_text_width(myfont, text); int h = al_get_font_line_height(myfont); waveBitmap = al_create_bitmap(w, h); ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); al_set_target_bitmap(waveBitmap); al_clear_to_color(al_map_rgba(0, 0, 0, 0)); al_draw_textf(myfont, al_map_rgb(255, 255, 255), 0, 0, 0, "%s", text); al_set_target_bitmap(old_target); waveAngle = (ALLEGRO_PI*2); } void shake(void) { shakeUpdateCount = SHAKE_TIME; bgx = randf(0.0f, 8.0f); bgy = randf(0.0f, 8.0f); if (rand() % 2) bgx = -bgx; if (rand() % 2) bgy = -bgy; } void render(int step) { ResourceManager& rm = ResourceManager::getInstance(); ALLEGRO_BITMAP *bg = (ALLEGRO_BITMAP *)rm.getData(RES_BACKGROUND); if (shakeUpdateCount > 0) { shakeUpdateCount -= step; if (shakeUpdateCount <= 0) { shakeCount++; if (shakeCount >= SHAKE_TIMES) { shakeCount = 0; shakeUpdateCount = 0; bgx = bgy = 0; } else { bgx = randf(0.0f, 8.0f); bgy = randf(0.0f, 8.0f); if (rand() % 2) bgx = -bgx; if (rand() % 2) bgy = -bgy; shakeUpdateCount = SHAKE_TIME; } } } al_draw_scaled_bitmap(bg, 0, 0, al_get_bitmap_width(bg), al_get_bitmap_height(bg), bgx, bgy, BB_W, BB_H, 0); std::list::iterator it; for (it = entities.begin(); it != entities.end(); it++) { Entity *e = *it; e->render_four(al_map_rgb(255, 255, 255)); if (e->isHighlighted()) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); e->render_four(al_map_rgb(150, 150, 150)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); } } Player *player = (Player *)rm.getData(RES_PLAYER); player->render_four(al_map_rgb(255, 255, 255)); player->render_extra(); if (waveAngle > 0.0f) { renderWave(); waveAngle -= 0.003f * step; if (waveAngle <= 0.0f) { stopWave(); } } al_flip_display(); } allegro-5.0.10/demos/cosmic_protector/src/LargeAsteroid.cpp0000644000175000001440000000146512031751243023117 0ustar tjadenusers#include "cosmic_protector.hpp" void LargeAsteroid::spawn(void) { // Break into small fragments for (int i = 0; i < 2; i++) { float dx = randf(0.06f, 0.12f); float dy = randf(0.04f, 0.08f); float da = randf(0.001, 0.005); if (rand() % 2) dx = -dx; if (rand() % 2) dy = -dy; if (rand() % 2) da = -da; MediumAsteroid *ma = new MediumAsteroid(); ma->init(x, y, dx, dy, da); new_entities.push_back(ma); } Entity::spawn(); } LargeAsteroid::LargeAsteroid() : Asteroid(32, RES_LARGEASTEROID) { hp = 6; points = 100; } LargeAsteroid::LargeAsteroid(float x, float y, float speed_x, float speed_y, float da) : Asteroid(32, RES_LARGEASTEROID) { init(x, y, speed_x, speed_y, da); hp = 6; points = 100; } LargeAsteroid::~LargeAsteroid() { } allegro-5.0.10/demos/cosmic_protector/src/Input.cpp0000644000175000001440000000376412031751243021475 0ustar tjadenusers#include "cosmic_protector.hpp" #ifdef ALLEGRO_MSVC /* "forcing value to bool 'true' or 'false' (performance warning)" */ #pragma warning( disable : 4800 ) #endif Input::Input() : joystick(0) { memset(&kbdstate, 0, sizeof(ALLEGRO_KEYBOARD_STATE)); memset(&joystate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); } Input::~Input() { } void Input::poll(void) { if (kb_installed) al_get_keyboard_state(&kbdstate); if (joystick) al_get_joystick_state(joystick, &joystate); } float Input::lr(void) { if (al_key_down(&kbdstate, ALLEGRO_KEY_LEFT)) return -1.0f; else if (al_key_down(&kbdstate, ALLEGRO_KEY_RIGHT)) return 1.0f; else { float pos = joystate.stick[0].axis[0]; return fabs(pos) > 0.1 ? pos : 0; } } float Input::ud(void) { if (al_key_down(&kbdstate, ALLEGRO_KEY_UP)) return -1.0f; else if (al_key_down(&kbdstate, ALLEGRO_KEY_DOWN)) return 1.0f; else { float pos = joystate.stick[0].axis[1]; return fabs(pos) > 0.1 ? pos : 0; } } bool Input::esc(void) { if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)) return true; else return joystate.button[1]; } bool Input::b1(void) { if (al_key_down(&kbdstate, ALLEGRO_KEY_Z) || al_key_down(&kbdstate, ALLEGRO_KEY_Y)) return true; else return joystate.button[0]; } bool Input::cheat(void) { if (al_key_down(&kbdstate, ALLEGRO_KEY_LSHIFT) && al_key_down(&kbdstate, ALLEGRO_KEY_EQUALS)) return true; else return false; } void Input::destroy(void) { } bool Input::load(void) { if (!kb_installed) kb_installed = al_install_keyboard(); if (!joy_installed) joy_installed = al_install_joystick(); if (joy_installed && !joystick && al_get_num_joysticks()) { joystick = al_get_joystick(0); } if (kb_installed) debug_message("Keyboard driver installed.\n"); if (joystick) debug_message("Joystick found.\n"); return kb_installed || joystick; } void* Input::get(void) { return this; } allegro-5.0.10/demos/cosmic_protector/src/collision.cpp0000644000175000001440000000035012031751243022355 0ustar tjadenusers#include "cosmic_protector.hpp" bool checkCircleCollision(float x1, float y1, float r1, float x2, float y2, float r2) { float dx = x1-x2; float dy = y1-y2; float dist = sqrt(dx*dx + dy*dy); return dist < (r1+r2); } allegro-5.0.10/demos/cosmic_protector/src/Game.cpp0000644000175000001440000000670112031751243021241 0ustar tjadenusers#include "cosmic_protector.hpp" #include #include #include bool kb_installed = false; bool joy_installed = false; /* * Return the path to user resources (save states, configuration) */ #ifdef ALLEGRO_MSVC #define snprintf _snprintf #endif const char* getResource(const char* fmt, ...) { va_list ap; static char res[512]; static ALLEGRO_PATH *dir; static ALLEGRO_PATH *path; va_start(ap, fmt); memset(res, 0, 512); snprintf(res, 511, fmt, ap); if (!dir) { dir = al_get_standard_path(ALLEGRO_RESOURCES_PATH); #ifdef ALLEGRO_MSVC { /* Hack to cope automatically with MSVC workspaces. */ const char *last = al_get_path_component(dir, -1); if (0 == strcmp(last, "Debug") || 0 == strcmp(last, "RelWithDebInfo") || 0 == strcmp(last, "Release") || 0 == strcmp(last, "Profile")) { al_remove_path_component(dir, -1); } } #endif al_append_path_component(dir, "data"); } if (path) al_destroy_path(path); path = al_create_path(res); al_rebase_path(dir, path); return al_path_cstr(path, '/'); } bool loadResources(void) { ResourceManager& rm = ResourceManager::getInstance(); if (!rm.add(new DisplayResource())) { printf("Failed to create display.\n"); return false; } /* For some reason dsound needs a window... */ if (!al_install_audio()) { printf("Failed to install audio.\n"); /* Continue anyway. */ } else { al_reserve_samples(16); } if (!rm.add(new Player(), false)) { printf("Failed to create player.\n"); return false; } if (!rm.add(new Input())) { printf("Failed initializing input.\n"); return false; } // Load fonts if (!rm.add(new FontResource(getResource("gfx/large_font.tga")))) return false; if (!rm.add(new FontResource(getResource("gfx/small_font.tga")))) return false; for (int i = 0; BMP_NAMES[i]; i++) { if (!rm.add(new BitmapResource(getResource(BMP_NAMES[i])))) { printf("Failed to load %s\n", getResource(BMP_NAMES[i])); return false; } } for (int i = 0; SAMPLE_NAMES[i]; i++) { if (!rm.add(new SampleResource(getResource(SAMPLE_NAMES[i])))) { /* Continue anyway. */ } } for (int i = 0; STREAM_NAMES[i]; i++) { if (!rm.add(new StreamResource(getResource(STREAM_NAMES[i])))) { /* Continue anyway. */ } } return true; } bool init(void) { srand(time(NULL)); if (!al_init()) { debug_message("Error initialising Allegro.\n"); return false; } al_init_image_addon(); al_init_font_addon(); al_init_acodec_addon(); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); if (!loadResources()) { debug_message("Error loading resources.\n"); return false; } return true; } void done(void) { // Free resources al_stop_samples(); ResourceManager& rm = ResourceManager::getInstance(); for (int i = RES_STREAM_START; i < RES_STREAM_END; i++) { ALLEGRO_AUDIO_STREAM *s = (ALLEGRO_AUDIO_STREAM *)rm.getData(i); if (s) al_set_audio_stream_playing(s, false); } ResourceManager::getInstance().destroy(); } // Returns a random number between lo and hi float randf(float lo, float hi) { float range = hi - lo; int n = rand() % 10000; float f = range * n / 10000.0f; return lo + f; } allegro-5.0.10/demos/cosmic_protector/src/Bullet.cpp0000644000175000001440000000203412031751243021612 0ustar tjadenusers#include "cosmic_protector.hpp" bool Bullet::logic(int step) { lifetime -= step; if (lifetime <= 0) return false; dx = speed * cosa * step; dy = speed * sina * step; Entity *c; if (playerOnly) c = getPlayerCollision(); else c = getAllCollision(); if (c && c != shooter) { c->hit(damage); my_play_sample(RES_COLLISION); return false; } Entity::wrap(); if (!Entity::logic(step)) return false; return true; } Bullet::Bullet(float x, float y, float radius, float speed, float angle, int lifetime, int damage, int bitmapID, Entity *shooter) : playerOnly(false) { this->x = x; this->y = y; this->radius = radius; this->speed = speed; this->angle = angle; this->lifetime = lifetime; this->shooter = shooter; this->damage = damage; cosa = cos(angle); sina = sin(angle); ResourceManager& rm = ResourceManager::getInstance(); bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapID); isDestructable = false; } Bullet::~Bullet(void) { } allegro-5.0.10/demos/cosmic_protector/src/SmallBullet.cpp0000644000175000001440000000046512031751243022611 0ustar tjadenusers#include "cosmic_protector.hpp" void SmallBullet::render(int offx, int offy) { al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, 0.0f, 0); } SmallBullet::SmallBullet(float x, float y, float angle, Entity *shooter) : Bullet(x, y, 4, 0.5f, angle, 600, 1, RES_SMALLBULLET, shooter) { } allegro-5.0.10/demos/cosmic_protector/src/MediumAsteroid.cpp0000644000175000001440000000116612031751243023303 0ustar tjadenusers#include "cosmic_protector.hpp" void MediumAsteroid::spawn(void) { // Break into small fragments for (int i = 0; i < 3; i++) { float dx = randf(0.06f, 0.12f); float dy = randf(0.04f, 0.08f); float da = randf(0.001, 0.005); if (rand() % 2) dx = -dx; if (rand() % 2) dy = -dy; if (rand() % 2) da = -da; SmallAsteroid *sa = new SmallAsteroid(); sa->init(x, y, dx, dy, da); new_entities.push_back(sa); } Entity::spawn(); } MediumAsteroid::MediumAsteroid() : Asteroid(20, RES_MEDIUMASTEROID) { hp = 4; points = 50; } MediumAsteroid::~MediumAsteroid() { } allegro-5.0.10/demos/cosmic_protector/src/SmallAsteroid.cpp0000644000175000001440000000023712031751243023131 0ustar tjadenusers#include "cosmic_protector.hpp" SmallAsteroid::SmallAsteroid() : Asteroid(10, RES_SMALLASTEROID) { points = 10; } SmallAsteroid::~SmallAsteroid() { } allegro-5.0.10/demos/cosmic_protector/src/sound.cpp0000644000175000001440000000043312031751243021514 0ustar tjadenusers#include "cosmic_protector.hpp" void my_play_sample(int resourceID) { ResourceManager &rm = ResourceManager::getInstance(); ALLEGRO_SAMPLE *s = (ALLEGRO_SAMPLE *)rm.getData(resourceID); if (s) { al_play_sample(s, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); } } allegro-5.0.10/demos/cosmic_protector/src/logic.cpp0000644000175000001440000000372412031751243021467 0ustar tjadenusers#include "cosmic_protector.hpp" std::list entities; std::list new_entities; long lastUFO = -1; bool canUFO = true; const int MIN_UFO_TIME = 10000; const int MAX_UFO_TIME = 50000; bool logic(int step) { const long now = (long) (al_get_time() * 1000.0); if (lastUFO < 0) lastUFO = now; if (canUFO && (now > (lastUFO+MIN_UFO_TIME))) { int r = rand() % (MAX_UFO_TIME-MIN_UFO_TIME); if (r <= step || (now > (lastUFO+MAX_UFO_TIME))) { canUFO = false; UFO *ufo; float x, y, dx, dy; if (rand() % 2) { x = -32; y = randf(32.0f, 75.0f); dx = 0.1f; dy = 0.0f; } else { x = BB_W+32; y = randf(BB_H-75, BB_H-32); dx = -0.1f; dy = 0.0f; } ufo = new UFO(x, y, dx, dy); entities.push_back(ufo); } } ResourceManager& rm = ResourceManager::getInstance(); Player *player = (Player *)rm.getData(RES_PLAYER); Input *input = (Input *)rm.getData(RES_INPUT); input->poll(); if (input->esc()) return false; /* Catch close button presses */ ALLEGRO_EVENT_QUEUE *events = ((DisplayResource *)rm.getResource(RES_DISPLAY))->getEventQueue(); while (!al_is_event_queue_empty(events)) { ALLEGRO_EVENT event; al_get_next_event(events, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) return false; } std::list::iterator it = entities.begin(); while (it != entities.end()) { Entity *e = *it; if (!e->logic(step)) { if (e->isUFO()) { lastUFO = now; canUFO = true; } delete e; it = entities.erase(it); } else it++; } for (it = new_entities.begin(); it != new_entities.end(); it++) { entities.push_back(*it); } new_entities.clear(); if (!player->logic(step)) return false; return true; } allegro-5.0.10/demos/cosmic_protector/src/Entity.cpp0000644000175000001440000000602712031751243021645 0ustar tjadenusers#include "cosmic_protector.hpp" bool Entity::logic(int step) { if (hp <= 0) { spawn(); ResourceManager& rm = ResourceManager::getInstance(); Player *p = (Player *)rm.getData(RES_PLAYER); p->addScore(points); return false; } if (hilightCount > 0) { hilightCount -= step; } return true; } float Entity::getX(void) { return x; } float Entity::getY(void) { return y; } float Entity::getRadius(void) { return radius; } bool Entity::getDestructable(void) { return isDestructable; } bool Entity::isHighlighted(void) { return hilightCount > 0; } bool Entity::isUFO(void) { return ufo; } void Entity::setPowerUp(int type) { powerup = type; } void Entity::wrap(void) { x += dx; y += dy; if (x < 0) x += BB_W; if (x >= BB_W) x -= BB_W; if (y < 0) y += BB_H; if (y >= BB_H) y -= BB_H; } void Entity::render_four(ALLEGRO_COLOR tint) { int ox = 0; render(0, 0, tint); if (x > BB_W / 2) { ox = -BB_W; render(ox, 0, tint); } else { ox = BB_W; render(ox, 0, tint); } if (y > BB_H / 2) { render(0, -BB_H, tint); render(ox, -BB_H, tint); } else { render(0, BB_H, tint); render(ox, BB_H, tint); } } void Entity::render(int x, int y, ALLEGRO_COLOR c) { (void)c; // To use c must override this in a sub-class. render(x, y); } Entity *Entity::checkCollisions(std::list& e) { std::list::iterator it; for (it = e.begin(); it != e.end(); it++) { Entity *entity = *it; if (entity == this || !entity->getDestructable()) continue; float ex = entity->getX(); float ey = entity->getY(); float er = entity->getRadius(); if (checkCircleCollision(ex, ey, er, x, y, radius)) return entity; } return 0; } Entity *Entity::getPlayerCollision(void) { std::list e; ResourceManager& rm = ResourceManager::getInstance(); Player *player = (Player *)rm.getData(RES_PLAYER); e.push_back(player); Entity *ret = checkCollisions(e); e.clear(); return ret; } Entity *Entity::getEntityCollision(void) { return checkCollisions(entities); } Entity *Entity::getAllCollision(void) { Entity *e = getEntityCollision(); if (e) return e; return getPlayerCollision(); } // Returns true if dead bool Entity::hit(int damage) { hp -= damage; hilightCount = 500; if (hp <= 0) { explode(); return true; } return false; } void Entity::explode(void) { bool big; if (radius >= 32) big = true; else big = false; Explosion *e = new Explosion(x, y, big); new_entities.push_back(e); if (big) my_play_sample(RES_BIGEXPLOSION); else my_play_sample(RES_SMALLEXPLOSION); } void Entity::spawn(void) { if (powerup >= 0) { PowerUp *p = new PowerUp(x, y, powerup); new_entities.push_back(p); } } Entity::Entity() : isDestructable(true), hp(1), powerup(-1), hilightCount(0), points(0), ufo(false) { } allegro-5.0.10/demos/cosmic_protector/src/StreamResource.cpp0000644000175000001440000000146712031751243023337 0ustar tjadenusers#include "cosmic_protector.hpp" void StreamResource::destroy(void) { if (!stream) return; al_destroy_audio_stream(stream); stream = 0; } bool StreamResource::load(void) { if (!al_is_audio_installed()) { debug_message("Skipped loading stream %s\n", filename.c_str()); return true; } stream = al_load_audio_stream(filename.c_str(), 4, 1024); if (!stream) { debug_message("Error creating stream\n"); return false; } al_set_audio_stream_playing(stream, false); al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); al_attach_audio_stream_to_mixer(stream, al_get_default_mixer()); return true; } void* StreamResource::get(void) { return stream; } StreamResource::StreamResource(const char* filename) : stream(0), filename(filename) { } allegro-5.0.10/demos/cosmic_protector/src/UFO.cpp0000644000175000001440000000353612031751243021024 0ustar tjadenusers#include "cosmic_protector.hpp" bool UFO::logic(int step) { Player *p = (Player *)getPlayerCollision(); if (p) { explode(); p->hit(1); p->die(); my_play_sample(RES_COLLISION); return false; } int now = (int) (al_get_time() * 1000.0); if (now > nextShot) { nextShot = now + SHOT_SPEED; ResourceManager& rm = ResourceManager::getInstance(); Player *p = (Player *)rm.getData(RES_PLAYER); float px = p->getX(); float py = p->getY(); float shot_angle = atan2(py-y, px-x); LargeSlowBullet *b = new LargeSlowBullet(x, y, shot_angle, this); new_entities.push_back(b); my_play_sample(RES_FIRELARGE); } bitmapFrameCount -= step; if (bitmapFrameCount <= 0) { bitmapFrameCount = ANIMATION_SPEED; bitmapFrame++; bitmapFrame %= 3; // loop } dx = speed_x * step; dy = speed_y * step; Entity::wrap(); if (!Entity::logic(step)) return false; return true; } void UFO::render(int offx, int offy) { render(offx, offy, al_map_rgb(255, 255, 255)); } void UFO::render(int offx, int offy, ALLEGRO_COLOR tint) { al_draw_tinted_rotated_bitmap(bitmaps[bitmapFrame], tint, radius, radius, offx + x, offy + y, 0.0f, 0); } UFO::UFO(float x, float y, float speed_x, float speed_y) : SHOT_SPEED(3000), ANIMATION_SPEED(150) { this->x = x; this->y = y; this->speed_x = speed_x; this->speed_y = speed_y; radius = 32; hp = 8; points = 500; ufo = true; nextShot = (int)(al_get_time() * 1000.0) + SHOT_SPEED; ResourceManager& rm = ResourceManager::getInstance(); bitmaps[0] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO0); bitmaps[1] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO1); bitmaps[2] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO2); bitmapFrame = 0; bitmapFrameCount = ANIMATION_SPEED; } UFO::~UFO() { } allegro-5.0.10/demos/cosmic_protector/src/cosmic_protector.cpp0000644000175000001440000000365712031751243023755 0ustar tjadenusers#include "cosmic_protector.hpp" ALLEGRO_VOICE *voice; ALLEGRO_MIXER *mixer; static int check_arg(int argc, char **argv, const char *arg) { for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], arg)) return true; } return false; } void game_loop() { lastUFO = -1; canUFO = true; Wave wave; int step = 0; long start = (long) (al_get_time() * 1000); for (;;) { if (entities.size() <= 0) { if (!wave.next()) { // Won. break; } } if (!logic(step)) break; render(step); al_rest(0.010); long end = (long) (al_get_time() * 1000); step = end - start; start = end; } std::list::iterator it; for (it = entities.begin(); it != entities.end(); it++) { Entity *e = *it; delete e; } entities.clear(); } int main(int argc, char **argv) { if (check_arg(argc, argv, "-fullscreen")) useFullScreenMode = true; if (!init()) { debug_message("Error in initialization.\n"); return 1; } ResourceManager& rm = ResourceManager::getInstance(); Player *player = (Player *)rm.getData(RES_PLAYER); ALLEGRO_AUDIO_STREAM *title_music = (ALLEGRO_AUDIO_STREAM *)rm.getData(RES_TITLE_MUSIC); ALLEGRO_AUDIO_STREAM *game_music = (ALLEGRO_AUDIO_STREAM *)rm.getData(RES_GAME_MUSIC); for (;;) { if (title_music) { al_set_audio_stream_playing(title_music, true); } if (do_menu() != 0) { break; } if (title_music) { al_drain_audio_stream(title_music); al_rewind_audio_stream(title_music); } if (game_music) { al_set_audio_stream_playing(game_music, true); } player->load(); game_loop(); player->destroy(); if (game_music) { al_drain_audio_stream(game_music); al_rewind_audio_stream(game_music); } } done(); return 0; } allegro-5.0.10/demos/cosmic_protector/src/DisplayResource.cpp0000644000175000001440000000141212031751243023477 0ustar tjadenusers#include "cosmic_protector.hpp" bool useFullScreenMode = false; void DisplayResource::destroy(void) { if (!display) return; al_destroy_event_queue(events); al_destroy_display(display); display = 0; } bool DisplayResource::load(void) { int flags = useFullScreenMode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED; al_set_new_display_flags(flags); display = al_create_display(BB_W, BB_H); if (!display) return false; events = al_create_event_queue(); al_register_event_source(events, al_get_display_event_source(display)); return true; } void* DisplayResource::get(void) { return display; } ALLEGRO_EVENT_QUEUE *DisplayResource::getEventQueue(void) { return events; } DisplayResource::DisplayResource(void) : display(0) { } allegro-5.0.10/demos/cosmic_protector/src/ButtonWidget.cpp0000644000175000001440000000117712031751243023011 0ustar tjadenusers#include "cosmic_protector.hpp" bool ButtonWidget::activate(void) { return false; } void ButtonWidget::render(bool selected) { ALLEGRO_FONT *myfont; ResourceManager& rm = ResourceManager::getInstance(); if (center) { if (selected) { myfont = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); } else { myfont = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); } al_draw_textf(myfont, al_map_rgb(255, 255, 255), x, y, ALLEGRO_ALIGN_CENTRE, "%s", text); } } ButtonWidget::ButtonWidget(int x, int y, bool center, const char *text) : x(x), y(y), center(center), text(text) { } allegro-5.0.10/demos/cosmic_protector/src/Resource.cpp0000644000175000001440000000171612031751243022160 0ustar tjadenusers#include "cosmic_protector.hpp" const char* BMP_NAMES[] = { "gfx/large_asteroid.tga", "gfx/small_asteroid.tga", "gfx/background.tga", "gfx/small_bullet.tga", "gfx/large_explosion_0.tga", "gfx/large_explosion_1.tga", "gfx/large_explosion_2.tga", "gfx/large_explosion_3.tga", "gfx/large_explosion_4.tga", "gfx/small_explosion_0.tga", "gfx/small_explosion_1.tga", "gfx/small_explosion_2.tga", "gfx/small_explosion_3.tga", "gfx/small_explosion_4.tga", "gfx/medium_asteroid.tga", "gfx/large_bullet.tga", "gfx/weapon_powerup.tga", "gfx/life_powerup.tga", "gfx/ufo0.tga", "gfx/ufo1.tga", "gfx/ufo2.tga", "gfx/logo.tga", 0 }; const char* SAMPLE_NAMES[] = { "sfx/big_explosion.ogg", "sfx/collision.ogg", "sfx/fire_large.ogg", "sfx/fire_small.ogg", "sfx/small_explosion.ogg", "sfx/powerup.ogg", 0 }; const char* STREAM_NAMES[] = { "sfx/title_music.ogg", "sfx/game_music.ogg", 0 }; allegro-5.0.10/demos/cosmic_protector/src/FontResource.cpp0000644000175000001440000000054312031751243023004 0ustar tjadenusers#include "cosmic_protector.hpp" void FontResource::destroy(void) { al_destroy_font(font); font = 0; } bool FontResource::load(void) { font = al_load_font(filename.c_str(), 0, 0); return font != 0; } void* FontResource::get(void) { return font; } FontResource::FontResource(const char *filename) : font(0), filename(filename) { } allegro-5.0.10/demos/cosmic_protector/src/GUI.cpp0000644000175000001440000000376712031751243021025 0ustar tjadenusers#include "cosmic_protector.hpp" int do_gui(const std::vector& widgets, unsigned int selected) { ResourceManager& rm = ResourceManager::getInstance(); ALLEGRO_BITMAP *bg = (ALLEGRO_BITMAP *)rm.getData(RES_BACKGROUND); Input *input = (Input *)rm.getData(RES_INPUT); ALLEGRO_BITMAP *logo = (ALLEGRO_BITMAP *)rm.getData(RES_LOGO); int lw = al_get_bitmap_width(logo); int lh = al_get_bitmap_height(logo); ALLEGRO_FONT *myfont = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); bool redraw = true; for (;;) { input->poll(); float ud = input->ud(); if (ud < 0 && selected) { selected--; my_play_sample(RES_FIRELARGE); al_rest(0.200); redraw = true; } else if (ud > 0 && selected < (widgets.size()-1)) { selected++; my_play_sample(RES_FIRELARGE); al_rest(0.200); redraw = true; } if (input->b1()) { if (!widgets[selected]->activate()) return selected; } if (input->esc()) return -1; if (!redraw) { al_rest(0.010); continue; } /* draw */ al_draw_scaled_bitmap(bg, 0, 0, al_get_bitmap_width(bg), al_get_bitmap_height(bg), 0, 0, BB_W, BB_H, 0); al_draw_bitmap(logo, (BB_W-lw)/2, (BB_H-lh)/4, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(myfont, al_map_rgb(255, 255, 0), BB_W/2, BB_H/2, ALLEGRO_ALIGN_CENTRE, "z/y to start"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); for (unsigned int i = 0; i < widgets.size(); i++) { widgets[i]->render(i == selected); } al_flip_display(); redraw = false; } } int do_menu(void) { ButtonWidget play (BB_W/2, BB_H/4*3-16, true, "PLAY"); ButtonWidget end (BB_W/2, BB_H/4*3+16, true, "EXIT"); std::vector widgets; widgets.push_back(&play); widgets.push_back(&end); return do_gui(widgets, 0); } allegro-5.0.10/demos/cosmic_protector/include/0000755000175000001440000000000012157230720020515 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/include/Input.hpp0000644000175000001440000000070412031751243022325 0ustar tjadenusers#ifndef INPUT_HPP #define INPUT_HPP #include "cosmic_protector.hpp" class Input : public Resource { public: Input(); ~Input(); void poll(void); float lr(void); float ud(void); bool esc(void); bool b1(void); bool cheat(void); void destroy(void); bool load(void); void* get(void); private: ALLEGRO_KEYBOARD_STATE kbdstate; ALLEGRO_JOYSTICK_STATE joystate; ALLEGRO_JOYSTICK *joystick; }; #endif // INPUT_HPP allegro-5.0.10/demos/cosmic_protector/include/ResourceManager.hpp0000644000175000001440000000072212031751243024310 0ustar tjadenusers#ifndef RESOURCEMGR_HPP #define RESOURCEMGR_HPP #include "cosmic_protector.hpp" class ResourceManager { public: static ResourceManager& getInstance(void); void destroy(void); // Add with optional load bool add(Resource* res, bool load = true); Resource* getResource(int index); void* getData(int index); private: static ResourceManager *rm; ResourceManager(void); std::vector< Resource* > resources; }; #endif // RESOURCEMGR_HPP allegro-5.0.10/demos/cosmic_protector/include/LargeBullet.hpp0000644000175000001440000000034112031751243023425 0ustar tjadenusers#ifndef LARGEBULLET_HPP #define LARGEBULLET_HPP class LargeBullet : public Bullet { public: void render(int offx, int offy); LargeBullet(float x, float y, float angle, Entity *shooter); }; #endif // LARGEBULLET_HPP allegro-5.0.10/demos/cosmic_protector/include/UFO.hpp0000644000175000001440000000071612031751243021662 0ustar tjadenusers#ifndef UFO_HPP #define UFO_HPP class UFO : public Entity { public: const int SHOT_SPEED; const int ANIMATION_SPEED; bool logic(int step); void render(int offx, int offy); void render(int offx, int offy, ALLEGRO_COLOR tint); UFO(float x, float y, float dx, float dy); ~UFO(); protected: ALLEGRO_BITMAP *bitmaps[3]; int nextShot; int bitmapFrame; int bitmapFrameCount; float speed_x; float speed_y; }; #endif // UFO_HPP allegro-5.0.10/demos/cosmic_protector/include/LargeSlowBullet.hpp0000644000175000001440000000032512031751243024274 0ustar tjadenusers#ifndef LARGESLOWBULLET_HPP #define LARGESLOWBULLET_HPP class LargeSlowBullet : public LargeBullet { public: LargeSlowBullet(float x, float y, float angle, Entity *shooter); }; #endif // LARGESLOWBULLET_HPP allegro-5.0.10/demos/cosmic_protector/include/Weapon.hpp0000644000175000001440000000016612031751243022461 0ustar tjadenusers#ifndef WEAPON_HPP #define WEAPON_HPP const int WEAPON_SMALL = 0; const int WEAPON_LARGE = 1; #endif // WEAPON_HPP allegro-5.0.10/demos/cosmic_protector/include/Explosion.hpp0000644000175000001440000000054212031751243023206 0ustar tjadenusers#ifndef EXPLOSION_HPP #define EXPLOSION_HPP class Explosion : public Entity { public: static const int NUM_FRAMES = 5; static const int FRAME_TIME = 100; bool logic(int step); void render(int offx, int offy); Explosion(float x, float y, bool big); private: int frameCount; int currFrame; bool big; }; #endif // EXPLOSION_HPP allegro-5.0.10/demos/cosmic_protector/include/cosmic_protector.hpp0000644000175000001440000000250112031751243024601 0ustar tjadenusers#ifndef COSMIC_PROTECTOR_HPP #define COSMIC_PROTECTOR_HPP #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_audio.h" #ifdef ALLEGRO_UNIX #define MAX_PATH 5000 #endif #include #include #include #include #include #include #include #include #include #include #include "Debug.hpp" #include "Resource.hpp" #include "BitmapResource.hpp" #include "DisplayResource.hpp" #include "FontResource.hpp" #include "Game.hpp" #include "SampleResource.hpp" #include "StreamResource.hpp" #include "ResourceManager.hpp" #include "Input.hpp" #include "sound.hpp" #include "collision.hpp" #include "Entity.hpp" #include "Weapon.hpp" #include "Bullet.hpp" #include "SmallBullet.hpp" #include "LargeBullet.hpp" #include "LargeSlowBullet.hpp" #include "PowerUp.hpp" #include "Player.hpp" #include "Explosion.hpp" #include "render.hpp" #include "Wave.hpp" #include "Asteroid.hpp" #include "LargeAsteroid.hpp" #include "MediumAsteroid.hpp" #include "SmallAsteroid.hpp" #include "UFO.hpp" #include "Widget.hpp" #include "ButtonWidget.hpp" #include "gui.hpp" #include "logic.hpp" const int BB_W = 800; const int BB_H = 600; #endif // COSMIC_PROTECTOR_HPP allegro-5.0.10/demos/cosmic_protector/include/Wave.hpp0000644000175000001440000000023312031751243022125 0ustar tjadenusers#ifndef WAVE_HPP #define WAVE_HPP class Wave { public: Wave(); bool next(void); private: int waveNum; int rippleNum; }; #endif // WAVE_HPP allegro-5.0.10/demos/cosmic_protector/include/ButtonWidget.hpp0000644000175000001440000000052112031751243023642 0ustar tjadenusers#ifndef BUTTONWIDGET_HPP #define BUTTONWIDGET_HPP class ButtonWidget : public Widget { public: bool activate(void); void render(bool selected); ButtonWidget(int x, int y, bool center, const char *text); ~ButtonWidget() {}; protected: int x; int y; bool center; const char *text; }; #endif // BUTTONWIDGET_HPP allegro-5.0.10/demos/cosmic_protector/include/SmallAsteroid.hpp0000644000175000001440000000025712031751243023774 0ustar tjadenusers#ifndef SMALLASTEROID_HPP #define SMALLASTEROID_HPP class SmallAsteroid : public Asteroid { public: SmallAsteroid(); ~SmallAsteroid(); }; #endif // SMALLASTEROID_HPP allegro-5.0.10/demos/cosmic_protector/include/Player.hpp0000644000175000001440000000170312031751243022462 0ustar tjadenusers#ifndef PLAYER_HPP #define PLAYER_HPP class Player : public Entity, public Resource { public: static const float MAX_SPEED; static const float MIN_SPEED; static const float ACCEL; static const float DECCEL; bool logic(int step); void render_extra(void); void render(int offx, int offy); void render(int offx, int offy, ALLEGRO_COLOR tint); bool hit(int damage); void destroy(void); bool load(void); void* get(void); void newGame(void); void reset(void); void die(void); void givePowerUp(int type); void addScore(int points); int getScore(void); Player(); ~Player(); private: float angle; float draw_radius; bool draw_trail; int weapon; int lastShot; int lives; int invincibleCount; int score; ALLEGRO_BITMAP *bitmap; ALLEGRO_BITMAP *trans_bitmap; ALLEGRO_BITMAP *trail_bitmap; ALLEGRO_BITMAP *icon; ALLEGRO_BITMAP *highscoreBitmap; }; #endif // PLAYER_HPP allegro-5.0.10/demos/cosmic_protector/include/Resource.hpp0000644000175000001440000000420612031751243023016 0ustar tjadenusers#ifndef RESOURCE_HPP #define RESOURCE_HPP #include "cosmic_protector.hpp" const int RES_DISPLAY = 0; const int RES_PLAYER = 1; const int RES_INPUT = 2; const int RES_LARGEFONT = 3; const int RES_SMALLFONT = 4; const int RES_BITMAP_START = 5; const int RES_LARGEASTEROID = RES_BITMAP_START+0; const int RES_SMALLASTEROID = RES_BITMAP_START+1; const int RES_BACKGROUND = RES_BITMAP_START+2; const int RES_SMALLBULLET = RES_BITMAP_START+3; const int RES_LARGEEXPLOSION0 = RES_BITMAP_START+4; const int RES_LARGEEXPLOSION1 = RES_BITMAP_START+5; const int RES_LARGEEXPLOSION2 = RES_BITMAP_START+6; const int RES_LARGEEXPLOSION3 = RES_BITMAP_START+7; const int RES_LARGEEXPLOSION4 = RES_BITMAP_START+8; const int RES_SMALLEXPLOSION0 = RES_BITMAP_START+9; const int RES_SMALLEXPLOSION1 = RES_BITMAP_START+10; const int RES_SMALLEXPLOSION2 = RES_BITMAP_START+11; const int RES_SMALLEXPLOSION3 = RES_BITMAP_START+12; const int RES_SMALLEXPLOSION4 = RES_BITMAP_START+13; const int RES_MEDIUMASTEROID = RES_BITMAP_START+14; const int RES_LARGEBULLET = RES_BITMAP_START+15; const int RES_WEAPONPOWERUP = RES_BITMAP_START+16; const int RES_LIFEPOWERUP = RES_BITMAP_START+17; const int RES_UFO0 = RES_BITMAP_START+18; const int RES_UFO1 = RES_BITMAP_START+19; const int RES_UFO2 = RES_BITMAP_START+20; const int RES_LOGO = RES_BITMAP_START+21; const int RES_SAMPLE_START = RES_BITMAP_START+22; const int RES_BIGEXPLOSION = RES_SAMPLE_START+0; const int RES_COLLISION = RES_SAMPLE_START+1; const int RES_FIRELARGE = RES_SAMPLE_START+2; const int RES_FIRESMALL = RES_SAMPLE_START+3; const int RES_SMALLEXPLOSION = RES_SAMPLE_START+4; const int RES_POWERUP = RES_SAMPLE_START+5; const int RES_SAMPLE_END = RES_POWERUP+1; const int RES_STREAM_START = RES_SAMPLE_START+6; const int RES_TITLE_MUSIC = RES_STREAM_START+0; const int RES_GAME_MUSIC = RES_STREAM_START+1; const int RES_STREAM_END = RES_GAME_MUSIC+1; extern const char* BMP_NAMES[]; extern const char* SAMPLE_NAMES[]; extern const char* STREAM_NAMES[]; class Resource { public: virtual void destroy(void) = 0; virtual bool load(void) = 0; virtual void* get(void) = 0; virtual ~Resource() {}; }; #endif // RESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/FontResource.hpp0000644000175000001440000000044012031751243023641 0ustar tjadenusers#ifndef FONTRESOURCE_HPP #define FONTRESOURCE_HPP class FontResource : public Resource { public: void destroy(void); bool load(void); void* get(void); FontResource(const char *filename); private: ALLEGRO_FONT *font; std::string filename; }; #endif // FONTRESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/MediumAsteroid.hpp0000644000175000001440000000031312031751243024135 0ustar tjadenusers#ifndef MEDIUMASTEROID_HPP #define MEDIUMASTEROID_HPP class MediumAsteroid : public Asteroid { public: void spawn(void); MediumAsteroid(); ~MediumAsteroid(); }; #endif // MEDIUMASTEROID_HPP allegro-5.0.10/demos/cosmic_protector/include/Debug.hpp0000644000175000001440000000016212031751243022252 0ustar tjadenusers#ifndef DEBUG_H #define DEBUG_H #include "cosmic_protector.hpp" void debug_message(const char *, ...); #endif allegro-5.0.10/demos/cosmic_protector/include/Bullet.hpp0000644000175000001440000000070412031751243022455 0ustar tjadenusers#ifndef BULLET_HPP #define BULLET_HPP class Bullet : public Entity { public: bool logic(int step); Bullet(float x, float y, float radius, float speed, float angle, int lifetime, int damage, int bitmapID, Entity *shooter); ~Bullet(void); protected: ALLEGRO_BITMAP *bitmap; float speed; float angle; int lifetime; float cosa; float sina; Entity *shooter; int damage; bool playerOnly; }; #endif // BULLET_HPP allegro-5.0.10/demos/cosmic_protector/include/Entity.hpp0000644000175000001440000000203112031751243022475 0ustar tjadenusers#ifndef ENTITY_HPP #define ENTITY_HPP const int ENTITY_LARGE_ASTEROID = 0; const int ENTITY_SMALL_ASTEROID = 1; class Entity { public: virtual bool logic(int step); virtual void render(int offx = 0, int offy = 0) = 0; virtual void render(int x, int y, ALLEGRO_COLOR c); virtual void spawn(void); virtual bool hit(int damage); float getX(void); float getY(void); float getRadius(void); bool getDestructable(void); int getDamage(void); bool isHighlighted(void); bool isUFO(void); void setPowerUp(int type); void wrap(void); Entity *getPlayerCollision(void); Entity *getEntityCollision(void); Entity *getAllCollision(void); void explode(void); void render_four(ALLEGRO_COLOR tint); Entity(void); virtual ~Entity(void) {}; protected: Entity *checkCollisions(std::list& e); float x; float y; float radius; float dx; float dy; bool isDestructable; int hp; int powerup; int hilightCount; int points; bool ufo; }; #endif // ENTITY_HPP allegro-5.0.10/demos/cosmic_protector/include/LargeAsteroid.hpp0000644000175000001440000000042112031751243023747 0ustar tjadenusers#ifndef LARGEASTEROID_HPP #define LARGEASTEROID_HPP class LargeAsteroid : public Asteroid { public: void spawn(void); LargeAsteroid(); LargeAsteroid(float x, float y, float speed_x, float speed_y, float da); ~LargeAsteroid(); }; #endif // LARGEASTEROID_HPP allegro-5.0.10/demos/cosmic_protector/include/SmallBullet.hpp0000644000175000001440000000034112031751243023443 0ustar tjadenusers#ifndef SMALLBULLET_HPP #define SMALLBULLET_HPP class SmallBullet : public Bullet { public: void render(int offx, int offy); SmallBullet(float x, float y, float angle, Entity *shooter); }; #endif // SMALLBULLET_HPP allegro-5.0.10/demos/cosmic_protector/include/render.hpp0000644000175000001440000000017712031751243022511 0ustar tjadenusers#ifndef RENDER_HPP #define RENDER_HPP void render(int step); void showWave(int num); void shake(void); #endif // RENDER_HPP allegro-5.0.10/demos/cosmic_protector/include/Widget.hpp0000644000175000001440000000034712031751243022454 0ustar tjadenusers#ifndef WIDGET_HPP #define WIDGET_HPP class Widget { public: // Returns false to destroy the gui virtual bool activate(void) = 0; virtual void render(bool selected) = 0; virtual ~Widget() {}; }; #endif // WIDGET_HPP allegro-5.0.10/demos/cosmic_protector/include/StreamResource.hpp0000644000175000001440000000052612031751243024173 0ustar tjadenusers#ifndef STREAMRESOURCE_HPP #define STREAMRESOURCE_HPP #include "cosmic_protector.hpp" class StreamResource : public Resource { public: void destroy(void); bool load(void); void* get(void); StreamResource(const char* filename); private: ALLEGRO_AUDIO_STREAM *stream; std::string filename; }; #endif // STREAMRESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/Game.hpp0000644000175000001440000000063612031751243022103 0ustar tjadenusers#ifndef GAME_HPP #define GAME_HPP #include "cosmic_protector.hpp" #ifdef ALLEGRO_MSVC /* MSVC (up to ver. 9 at least) ignores exception specifications */ #pragma warning( disable : 4290 ) #endif const char* getResource(const char* fmt, ...); bool loadResources(void); bool init(void); void done(void); float randf(float lo, float hi); extern bool kb_installed; extern bool joy_installed; #endif // GAME_HPP allegro-5.0.10/demos/cosmic_protector/include/sound.hpp0000644000175000001440000000013712031751243022356 0ustar tjadenusers#ifndef SOUND_HPP #define SOUND_HPP void my_play_sample(int resourceID); #endif // SOUND_HPP allegro-5.0.10/demos/cosmic_protector/include/BitmapResource.hpp0000644000175000001440000000050712031751243024153 0ustar tjadenusers#ifndef BMPRESOURCE_HPP #define BMPRESOURCE_HPP #include "cosmic_protector.hpp" class BitmapResource : public Resource { public: void destroy(void); bool load(void); void* get(void); BitmapResource(const char* filename); private: ALLEGRO_BITMAP *bitmap; std::string filename; }; #endif // BMPRESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/SampleResource.hpp0000644000175000001440000000052512031751243024160 0ustar tjadenusers#ifndef SAMPLERESOURCE_HPP #define SAMPLERESOURCE_HPP #include "cosmic_protector.hpp" class SampleResource : public Resource { public: void destroy(void); bool load(void); void* get(void); SampleResource(const char* filename); private: ALLEGRO_SAMPLE *sample_data; std::string filename; }; #endif // SAMPLERESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/collision.hpp0000644000175000001440000000024012031751243023214 0ustar tjadenusers#ifndef COLLISION_HPP #define COLLISION_HPP bool checkCircleCollision(float x1, float y1, float r1, float x2, float y2, float r2); #endif // COLLISION_HPP allegro-5.0.10/demos/cosmic_protector/include/logic.hpp0000644000175000001440000000031012031751243022314 0ustar tjadenusers#ifndef LOGIC_HPP #define LOGIC_HPP bool logic(int step); extern std::list entities; extern std::list new_entities; extern long lastUFO; extern bool canUFO; #endif // LOGIC_HPP allegro-5.0.10/demos/cosmic_protector/include/PowerUp.hpp0000644000175000001440000000056712031751243022636 0ustar tjadenusers#ifndef POWERUP_HPP #define POWERUP_HPP const int POWERUP_LIFE = 0; const int POWERUP_WEAPON = 1; class PowerUp : public Entity { public: const float SPIN_SPEED; bool logic(int step); void render(int offx, int offy); PowerUp(float x, float y, int type); private: int type; ALLEGRO_BITMAP *bitmap; float angle; float da; }; #endif // POWERUP_HPP allegro-5.0.10/demos/cosmic_protector/include/Asteroid.hpp0000644000175000001440000000062612031751243023003 0ustar tjadenusers#ifndef ASTEROID_HPP #define ASTEROID_HPP class Asteroid : public Entity { public: bool logic(int step); void render(int offx, int offy); void init(float x, float y, float speed_x, float speed_y, float da); Asteroid(float radius, int bitmapID); ~Asteroid(); protected: float da; float angle; float speed_x; float speed_y; ALLEGRO_BITMAP *bitmap; }; #endif // ASTEROID_HPP allegro-5.0.10/demos/cosmic_protector/include/DisplayResource.hpp0000644000175000001440000000063312031751243024344 0ustar tjadenusers#ifndef DISPLAYRESOURCE_HPP #define DISPLAYRESOURCE_HPP #include "cosmic_protector.hpp" class DisplayResource : public Resource { public: void destroy(void); bool load(void); void* get(void); ALLEGRO_EVENT_QUEUE *getEventQueue(void); DisplayResource(void); private: ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *events; }; extern bool useFullScreenMode; #endif // DISPLAYRESOURCE_HPP allegro-5.0.10/demos/cosmic_protector/include/gui.hpp0000644000175000001440000000011012031751243022001 0ustar tjadenusers#ifndef GUI_HPP #define GUI_HPP int do_menu(void); #endif // GUI_HPP allegro-5.0.10/demos/cosmic_protector/CMakeLists.txt0000644000175000001440000000532412114121273021631 0ustar tjadenusersif(SUPPORT_FONT AND SUPPORT_AUDIO AND SUPPORT_ACODEC) else() message(STATUS "Not building Cosmic Protector") return() endif() set(DEMO_SRCS src/Asteroid.cpp src/BitmapResource.cpp src/Bullet.cpp src/ButtonWidget.cpp src/Debug.cpp src/DisplayResource.cpp src/Entity.cpp src/Explosion.cpp src/FontResource.cpp src/Game.cpp src/GUI.cpp src/Input.cpp src/LargeAsteroid.cpp src/LargeBullet.cpp src/LargeSlowBullet.cpp src/MediumAsteroid.cpp src/Player.cpp src/PowerUp.cpp src/Resource.cpp src/ResourceManager.cpp src/SampleResource.cpp src/StreamResource.cpp src/SmallAsteroid.cpp src/SmallBullet.cpp src/UFO.cpp src/cosmic_protector.cpp src/collision.cpp src/logic.cpp src/render.cpp src/sound.cpp src/wave.cpp ) set_source_files_properties(${DEMO_SRCS} PROPERTIES LANGUAGE "CXX") file(GLOB_RECURSE DEMO_GFX data/gfx/*.tga) file(GLOB_RECURSE DEMO_SFX data/sfx/*.ogg) set(DEMO_ICON data/gfx/Icon.icns) include_directories( include ${CMAKE_SOURCE_DIR}/addons/main ${CMAKE_SOURCE_DIR}/addons/image ${CMAKE_SOURCE_DIR}/addons/font ${CMAKE_SOURCE_DIR}/addons/audio ${CMAKE_SOURCE_DIR}/addons/acodec ) if(APPLE) set(DEMO_EXECUTABLE_TYPE MACOSX_BUNDLE) else(APPLE) set(DEMO_EXECUTABLE_TYPE "${EXECUTABLE_TYPE}") endif(APPLE) add_executable(cosmic_protector ${DEMO_EXECUTABLE_TYPE} ${DEMO_SRCS} ${DEMO_GFX} ${DEMO_SFX} ${DEMO_ICON} ) fix_executable(cosmic_protector) target_link_libraries(cosmic_protector ${ALLEGRO_MAIN_LINK_WITH} ${FONT_LINK_WITH} ${IMAGE_LINK_WITH} ${AUDIO_LINK_WITH} ${ACODEC_LINK_WITH} ) if(NOT BUILD_SHARED_LIBS) set_target_properties(cosmic_protector PROPERTIES COMPILE_FLAGS "-DALLEGRO_STATICLINK") endif(NOT BUILD_SHARED_LIBS) # Mac OS X bundle support. set_target_properties(cosmic_protector PROPERTIES MACOSX_BUNDLE_COPYRIGHT "Copyright 2008 Allegro Developers" MACOSX_BUNDLE_ICON_FILE "Icon.icns" MACOSX_BUNDLE_INFO_STRING "5.0, Copyright 2008 Allegro Developers" MACOSX_BUNDLE_SHORT_VERSION_STRING "5.0" MACOSX_BUNDLE_LONG_VERSION_STRING "Cosmic Protector v5.0" MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.CosmicProtector" ) set_source_files_properties(${DEMO_GFX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/data/gfx" ) set_source_files_properties(${DEMO_SFX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/data/sfx" ) set_source_files_properties(${DEMO_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) copy_data_dir_to_build(copy_demo_data data .) #-----------------------------------------------------------------------------# # vi: set ts=8 sts=4 sw=4 et: allegro-5.0.10/demos/cosmic_protector/data/0000755000175000001440000000000012157230515020005 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/data/gfx/0000755000175000001440000000000012157230720020567 5ustar tjadenusersallegro-5.0.10/demos/cosmic_protector/data/gfx/large_explosion_1.tga0000644000175000001440000000623712031751243024705 0ustar tjadenusers @@ Š4kՃ~1f(:o$[R'Z}:G@]R}RJTa|@x0}Caυtg^|m ]UlE_x1  N"p ?w|=< nIy.=#Zdk  CbE<MR KY|)xx7j~6{$yOv4X*#F/g C9^(jX Ǐ %܇܍n|kRŅ >1[ihG6x D:݁TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_explosion_2.tga0000644000175000001440000000364712031751243024726 0ustar tjadenusers  R_APrX,]:z brhz@v J A ?ς,+Z ;YPrp(*~+~RoS-)} V8>. [^ #PFwkD nsb q7 _*-/Y;]#s aR9##:.~.F o;~Z 62 X7` d-[bp-DV/ vtLy7Bx1.?Tu?$|Z  M<kZ{ 5_=}! cAj- v ? ?TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/background.tga0000644000175000001440000061366312031751243023421 0ustar tjadenusers         !((/*,)&&)/6; :;;:9$72 69 6 .$$)*)('"        #6]`VYZ`VK H HTZ;F Z` Y1 % %   )/ +16 ,. 2P`MY`^95/A!4;2 )     #"&0R`7 7 9 ]`5.9 `M`M92ZZR? ?;6 0 %!!   !  %2/?`l22q<<``]^MC < :2,#     " 7"$,C ^`F:P`f"`M8)   *$&4`H626;!:6 .2%    " " -(,: `6)&2K`<'       / # %!+; `@Bbe w8-`9`K?RH< K!       ! !" # */1: `%T`64q)&s/,`:9 ? 7]`Y`;@ 6 &       %""" ') %2T`}4Am=?x?@`%`Z6`K |BTq9Fq)w='s<%w@)o9"3M>JI ?'     0 V`VF <`@8o'#`x54f##LMf9]: ^`z;?c`]CY`YR`%(, ? `_/?9>HIL~@w=O2M9tD4`2#V,6-     )(+ . / 04 :C M4 *9 V`w6<`-f<?[%%4:P? `ZY` RC4329aszC?OI|?9}>8DACBi&%c" `6Pb&$`$/m@?896 ; q;GKRy26>C?E~8@|7ABI;?C>B3}9f% f%p22IFPC`@]6V,Oh95 9      "4 FP`Y5 ) %-.<`?`Z? ``"%nw9=BE}<>z77|;9JI}EB`K`H `)?`]#<`LQp*,DI>F~8B?G<@?=>5|5!I5}<6`#"c,,VP`L|H,Y6EK(m5l9&:6     < `P;`]F`K C`z=Ja#w8C>I~HAF=?==>?=C~9>>Bq/,n2#w=)v<)e+g&u/,es)"o'w4 x;%b+wF)Y1="     !+ 59M`Z27 `j'(b`d!*`8`?`T`b`h%*{47?@<F}9F?Qz8AJ>v:$F/};*FB48~12?=?9G<<,?(E"p;g?I); "   "/<`P`e `DD`g"!`" !/R```$]`y9E;G9E9C=H9F49/DB=C9;I;F/zC,o>&sC,^2e:'/ 6    "5C^`^`: 3? ;`?><`]`K `K`g$"`VH :2`p**`Z`.{5B@L<@:6EO,#   !6]`xC=P822,`/,?>Y?>````b ` 6aq9=Jm5;}DJr9?`9Z`,<`y0;v(5e!8BAAB; ` <;z@?t99};[#R(*   &1HR` r86`9?^?R4Y49]?>`MC `PCT^` ]e%%t;FY8=V7;Z9<5^`M `%Yy?Gl;8^1*< 4 <?p?Kt@Mt>Mp:I|GWq`:8`?>V?>`9 `^RK h/;m2=a!` ]`r9>v>F|CL|EOs:Fv6Gu5Gz=Mx>Lv>JISp9@`Ph7;]%*`&b"#Mw@ HK!H%F'[-??";pC{26<.q8$m5<S";$   !0 9 `?>`YY`T`^`e);j/Ds8L~DVy?F'S"0S'V %s9?v9>EI@E<@}9?u18JQFL}:=<_)?>CY]"4```RYc,,`V` C `m4DuE ?>`? `14k?B2`z=Gu9Gm0BF^]#]%^!(`g2/?``zADx?C~DGu<=f%%R`$);h@3W(=Fj,(G THH s8Ho:DtAH`Zs5C{>:IAC7|9*?0<-{=-`)EF 6+  )5`P ?>PY]?>U.9 )6)<b66?>`2zFMm?E^`H`6v;9`< `q=m9,tE2m7%c.8 `;" ,R`<Z`P`?>L/?>]W?>k1``<i2:s>Fj6?2`2; *KZ`9`_``F`)6F <`CTY*&B1}?,{12y,>2n7/\)%? 7s=?P):]`]\%`<}M>?>`)O"H';F#?Y*3: ?>E)A%^:`r7=`P`6^?>/;-`F TKT`? `Y`?`?}B;>6d`c+$k?/uI8pA/}G8}<1>6HBC9F8s=,n;+`,>47 6 M`f"*<`f2Mf2Kh0Ds7DFL<;EI).9(5?>X;H2X@H `M 6X(?>M)]3=N (8`]`^`?>V`H j+(`C@}=9z@2zD2yF1zD2x?2q642YTV`b"*`Rz@X` Zz?D;89/=2=1s-$y8+`F` V3 %  2 `?>H Y`,?>97B#V'a?>`/6(9?>-<Z`?>U.,]9?M#2p>RC[w7My:Le#,` H T;M< T`K;2`?>`?<`RP `Za}CEzFFq<@u;L>s?.m6(~@:z4/<4```8 Z` b`2+,@F;8D?LC{B7j/&` M5 "  Y`T?>@ 6?>>X 4M-@ Ma%?>`26/`?>\76`?F>&f2Kp.L}7U`VP`9`:?>`?>`2`?>`9]?>`H`2`yCJo?FlIIj4/j<5m@5i/'F `V8(  +`?>@I ?>@]%R Q K Y%S#?>])?>6: <;4`?>a26sAL<n6OTVb 7``Z?>`!?>`ZY``]!#9 P<]`ZT}>Om,/v8&>*=+`C`Y` ^/?h>IsGNj>@pCFj@?b@;c?9vC9O?>L ?@UN <L? ?>V#?>&M')Y22f867`^?>ZM ]Z*]`?>`a27`]`!(:`f"/`^#v3G9EEF<8>9FF_",GYI`_8Gz>?C;C2F/:!D.f l+%c 9 ` .Fb ^SGe3,@]=9V36B 5Y'?>](Ij7]n9Zp7N`?>^`F ?>`Y`P`<}?I@@?:FA99d",b"5V.c":?S])_%'_&"D?A<~:2C6|<.K=~;.~]?>`4)?>U26+.?>U,6?%F (9(4`e!*`^P`?>`?>3`H `}FLz@Bu:8y77CE>I=Jo;@PP\($j))h!"FEJF@8?3=/F6G8v<.ad%%`9^j1?` M Z`<,  :PV`}?<`3?>[?>95)& ;04 "< `m)2`F0M`?>M`?>Y9 F`1< `Ty9:<`V5`c.2~LSw=F?G>C79B?C?j96pIG~YWzLLPSe9;:8E?C:A6C6E8w?2g2)a`Y```m=+?Y`V*! " "T` xEC`<`2?>C)2+! D%:O.9P&&.`R`?>^`]`6W"?>Z",Z%`_PF T`j),IPZR`R`j& `<c6Do:Iu6A<@=:<2G??95A;<6}>6xA8vF;}IAC=j##F`f`_ `^` ?   %Rb)%`C`?>U?>FL"?>`/>?>c=6?>`<P 6?>9 "C#`?>^#]*R_`T6 9 Z`bLDo+)u:=/ 7 n?Pt??|C@wB;xB:y<4c`o@9p81`d`?     $R`Y`H `R?>N?>]"'?>5I,Y8?>1`P62`?>D+,9 `?>`^]2c%=`!`"V9 j9:BE:>`q2<0 #l?Nc/B6;}69JI?><;7 T#9J3E2?3V,CR/?>2? `?>`6 ?>B%2*oGYY%`6`?>`Y":X/Z#/ 4`<M `M`^,2< 9h'<7Oz.F6K6E7AI>C I/,?> ? A=?"J3?/7.G$:0LT?>37&h>Wj6Qs1V"<5?$n=NO)3`Ta/` 2p1]3&8```F2b)"l5+d ^H`^    F`o/.Z`K ?>@ MK=?> E CV#'@ V%,E<W(2P%c%2m(6b)?>_2F5k=Wi2Sz0`3_|2I}9@`<X?>S!?5#R#gAOf>Ec669`n2@z?Bz?C{>Bs4:DJz*bF `z<3f `K 1 ! b]p"/    "`HC?>Y#-@ c-28H ?> F QP59081f*2J S Pe2?>^4GY0F4"A/a1Pn5\M8[>`??>b&,a&)?>L-/P"@2 '4 #c9Kj:C`sS: T%]%,J>?>S;b))9?>TF SLP?> k*6?>F(,9 'T*H8 ,I>8,<12)H,P%K`TY?>Y?>U?>O6V"I@;LHF;a)H`s6C}>L`Hy7E{;Iv:Gv>Jf1<`<Va%,jA`&/J8?>6UV ['?>L #L "?>Y"CE <@)?>Y-K@3LAL@6+`K `C`?>cZb[?>a$1I'3!9/6.2%R e%>`2CMq4>s2=`CLx;E7C `,`a #`c+/`U8/#cD6[8*zRB]/L;N<`|A5r5,w<6m2/2`P*  ,`1,`,?>3F <?>7P?>K &\9B?>T'6?>Y+E6"F29 %c@M[2?`^R??>i'"?>n,)?>a2H[)<`9y@?k206`Z`l-,69h-,wB?5K `M 5`e?8?%NC4E<,K=,cI:qH;p8.adcl+'`Y`{<;`R,   (:`T`]?>; %?>6H ?>]"?>]'3I%C"?G#`5?>k5D6k=Ab5;`c(`]P P `;`?>b58?>`3m2.x>98`F `^`V`Y, +%)#XI@"1[+?>_ 2>R"?>]!?>Q(C b(@L)?>Y,,?>a/8?> <#2 "6!CC ?>`Y"Y"M64R`;?>X]Yo((?>`?g%%` . eICB,%^IBL5.I-%P+#tG?q:2@8`C *   - ]`8}BCp=<9 /?>3. P#?>S+?>R,7=,-?>cG5cI6?>_ #`?>o-'Ye!f_`]?>`c`;:` <T,`;9%N2.fKCjH?uG>s:1B9m&!`V*     9 `|@A4/?>Q0?>H!B?>X…?>]/>`]?>`?>f\ÒaT^S?>[ f"?>]+AF&2B )Z<`f"/`9&&"qLCnD9p?3j-$r8,`]`"   * ^`<`H0?>R"?>?$`(H?>D&@?>[?>5> "?>`/$k<,`^`]`:5;`?>e?>jczoSIfYYO?>k(?>C %N/QCYFT7_=d/`: U0'd@6[8+}SFe+"w=1?`dx7:Y`M+    <`3K ?>;%D/S??>.N,?>S%?>4S2?>S/AM#`?>`M 39V?>faPKf_c\d]?>_$'P?>MH#YWS ?>`.ND2< )A,6?>[?><M-E?>c/2?"%`8[!?>joSSLKSSNMYW?>Y&HU%?>k4;KZY_`<`+ Y+$?b"n5*`2 !/T`9`n/4K `T`?>a(W*?#@-Y'FI6H/?>X?>4=?>822 ?>_?>`<6P`85N?>`(Yc`jbj[c]e?>c,/?>]2`V`< 49 g2&`J?`{;7`?`2  ,R`^f-/xCGy7?`]`?>L S61B,[)??>6C#?>a59_:??>a?>`*\%VTY?>c?>I?>YgW!?>`PZ``pD3b"`ag$!p-*`<`R, %H`?c!!r?Ah.2`?>0X":B*Y(@?>1%NFK9E +?>cg?>]&?>Z]o(,`f?>v.$ats]!(?>T/Ud?>`V` Vj?2rF6`P `D>cC=p51`Z`F-  , :`Yf/2tBFn<<`1?>X$IS"39 ?>P$FF"XCJ9]#JN5P0?>`&"?>j"%?>]?>nc?>eYg_ZZRU?>di?>l#da]SOQRc*/V]U *?>`e#7^`P HR ^`^3: 9`:C=y;7q51e K `V1    !;`?`kCKS+2: `3?>GN#b ? &D/?>?m1?Vm&0V"m%=S*`9Q0K*?>c!?>W?>^!\?>_"%?>^%$["?>[]_aVYcf`]dc[[?>P\!&JP\&,U!&w|X$%k22?>F%Y,?>K`d$*HFg-,?>`;cj+'x=6F`<y@7`^`^  $5 `Pj-*{JIa:@<R`4 ]-'?>`/?S']%1, k>??> yHcK?2)E6O0S"` ZP j,]*X/Y 9C %?>f) ?>`)*vwLOL?>^fcl?>``?>cc?>`'0~IVZfO)c2;Z&,W""?> `8?a5GL)?>L FY/?>Y+I"^< ?>8K ?>H V`i&#`6c"s<2`]` %    &6 `Zs86p85o;78`8b84?>U-?29 D!?>; *Kbcc ?>`"Tr5:SP?>d ?>df?>X!+]i`mOYP?> W%9DfN +V0]$8C"?>P3M2 7L?>F?>*?>`; `h"!`Vcd {?6`Ts<6`e K`^`%   !, -8`K h&%z@?}FD7Y`1QYEH #(X/D6 >`59?>.Q"=L5;P!S\m-,F X*F%;#J4m6P_(7?>b)\?>bc?>i#%?>L c$#Z`! ?> X] 'b%.`#-?>Z!,?>Xbcj] ?><?> }OcD'V4P/P/](C6 &/,<"2Y*3?>YOX(?>8 `g$"az=5`Z`7`n-*j&$}=9`.    $MT`:p//IHu<7?> I)F*-N)6UF C 9=N/p:YY#C??>x9"?>Q grZ#c?>bc?>bcSLS ^i%"?>d"e!?>e!?>_e?>_?> cBIN+[?>H `n-)e"}A7`F `g" ]R`K :` "   ",`DE}DFj56p=?:`?>; &?>]'9C?>Y")=I?>^)3:9 ?>z;?>\Ze`+?>bc?>f$_?>c?>c"?>lh?>fR?> bDJM/`^c`y=3s;0V<`i&#`VT` !  ,<`M CFp69n7Ca/6< `vE.`?>X/??>J%:?>K?>F"? ?>V?>bc?>bcLLbc?>bcGB]bm("?>V4>]2@< T)?>k9?7 M?>`d h&!f$m/%`^p-%`}>6`9`}>6`##2`8yFC `3A<?>](2?>|5?>bc?>bcRRbcWWbcca_f'?>P[T?>f9V-?>F Z`P y;5`v<+y@,c$`t5'?0u2'p/&m5*`9<`  !,T`r?Jf7B@: PzIP4`?>H#T '?>bcopbcg$n%+SVbc|66]^PPbcx0,bc?>a-)?>_((?>M"J?>kB9?>Z` z?5yF1}H/q2 |<&`s8%v=+k/#k+"{?2d"`f-%`7),`VR<L$g7C; @. `^`Y`/?>O)`/?>4'?>b?>||ÇWUbcbh"%s,2bc?>SUbc?>]?>r-?>`?>`Y` s>)l5`<({<&H3I5G3l+ z<,m/%f)!f-#`Y+    "/3``/j7@`/ m]*?>fbcÇbcbcXXp.+TUbc?>bcRSbc?>bc?>YL?>j2"`2?>`),CYK `;^^ *Y` |@/I2N7M9}<(=*>,?-F5}H6zE3w=/g$^`)  0/ 0< `M`0sN"?>\1?>bcOGÇbc?>bc?>KK?>bc?>bc``?>^?>{:>';$?>Y/4Z!^BY;]7]/a/` ^`}C1}A/w3#>.E6G9}@0|D3zB1w<,|<,C3`C`C    V0 ,R`7x:<`3`M`c !`T`F "?>< 8?>a?>bcÇbc?>bc?>bc?>bc?>@$z8?>m+?>[ "?>T1;R`iB`_`E:H>C8C8<1<04 %]#;?>bc[]bc~bc?>Çbc?><"?>:?>n2?>`C?R/<[f!D]%` h"A=B>61z1*A:?7H?F:C6J8 ?>_0F'?-?>`(IR?>6?>k((c%/^"/\$,W?>a(bcÇbcËbc?>hgX ?>c&-?>];G5 % 8f03=6d`Y`Z`V*  - 9D$%(YZ`?#K`^ 4F 6?>k4:?>: = ?>68"?>Y +L?>Yb`cb+%] ?>bcÇbcÇbc?>j""Åo(*?>`;F^:Fc;E<`z47a9:GF?<96FDz:9?k"'?>6?>:&?>`26?>M'2=L!'`36?>d!\!?>^b]WÕ?>n/<bcÇbc?>]"'?>k)-?>Y2<`;}GD}9>v=B?FAE86FC98?>A=zD?`5`R%Y)": `_`   /KG4(H`Z"`k$,`Z*, ?>Y"b*,?>Q5?>IS,C9/?>c(8?>`4N KTalij\SaL?>`%bc?>]?>]a?>`9V|=9m% H<=.}C2vC6`/+V"#` &{6;;<<>s<6yJC`/)-<6U<,/`; P```,   %KMC+ 6`/ 2`s,/`^`]7`?>\3C6)7*V*:%?>c99?>^,JB32?>P"?>c26?>gkPS]ahgd]?>bc?>bc?>]b?>9)`Rb$!b|<.>2z6,I?^&xC6VI`$o.,CG9=99D?}C'V2Y>,#c**c'*2` _Z+  ' 2 I52)]`/`9^w]1I/*V,P?>^'KH>, ?>k2M>,L/?>\/>]+7CF?>_e[`g#_$"`$?>bc?>bcj #s+.bc?>c$#?>` )`!,]!)?>\69Y9:`? `Z`V`e&i)j& ?7<6`!I6Ò{Q@]!`!CICF|85|B9QiC'\8Y2fA"' jI=`v?C`H` C :KM"&&R`0`]`u9AGRf4@P`]YI:?>;+){7b?>B 6,5%*Z>X?>9 (C8/!?>X*?>S/F, "kBOC= ?>]]?>f /?>k+4?>bc?>b"?>]?>-Y56`}8I`Y`< `r<+z;2AX.;?>L.?>e,?>9%2.Y3UH&CJ&D@9ICF;7?>;#L2LG2H]9F>?>OL?>[g,n%/?>[$?>bcÇbc?>bc?>Yc\hV`?>Q ?>j)`"Y?>`?>`?>`6i/'r50DAB;` mS}]áp\HBa"&FQ}6>s2.OpGnBrF\+6M` Y     &7 `HV`9; RZ`<`V}=Pt=T%?)`?>X1K,+2 46 0]/F?>0`-@6 P?X &0 ?>_Y?>NJ?>r1'?>k)2lx?>bc?>bcÇbc ^!%?>_ .?>`)CJSYch^f?>bc?>\`?>Y?>] ?>a#?>t(,m ?>`:8P`Y`8`EAD:dL6fLz]qYbS^#"6I9K??v<-o?"pCsApAc;<`F`7    8`], HR`+`V`1^&"K^`m,;|>Qw8Pm6RX4MR%`2`?>W2S`7]/%?>R0F( @ @&G6K ?>]lVb$+?>]'bco%.bc?>\e]b`b]`?>bc?>`"?>k)%?>_ _f?>RX?>bcf?>`Y`^`=3mQ@fQ[A}eO<[" {1Im8f"%f)~I6uB)o6xB%g:"tE2P `K T`^, 1P`!' . T`Y9' &`};?`: `t:Ls:QP/q9V5 &:(<?>Q7B12 9 )i9Z3"?>S,M)?>C1) %6+?>2%K/`0Sc?>`/a#*]!&["(?>b$+bc[]h*bcWYbc_`bc?>]c_a?>bc?>ik?>`%?>jn?>bcÇbcp,/ad?>`6`C `ZY}?CB=feY^NaLmXj8)e,,{2Li8JQp2.WH?A6F6p>)p?)n-$V`~CF`8`R`V "<Z3 <`) #H`P`KL`.: !4<"O47"[-??>R02%I?Y"@v;XF ,I.? I$L$V3=)K?S/LX1F?>\1;c8@?>|>v6?>c.l%6N`]n?>b0P"?>x]$*?>`")?>??bcu,2bci#/KTSYbcÇbc?>bc?>bc?>Y(?>is?>T?>bcVc$(ILo?>9 K^? MsDMf5<9`/z?9zD5r=)C2C9K M`_` !c<^`3 ?`]%$)`%0 `Z`.;"[9Q1 *Z&F\ ?8?>c&0?>:&X-N?>5#I-H,`PMASEVA=L FY0]#3^"0[*ev9?>PZIX?>R'n)6?>_ /?>c"0?>\"QSbcb"j")bcYITh$0s-:f)bcMPbc?>ys?>bc?>]^`+VackWb^&2`(4?>V%k*3?>bc?>bcKTnu\!?>V]K`C e=Jh;F9`FCL}58a\ ^EM)B%?>I2'"6 <29?@<,K:3.; 2)n0IN"k;D`U#V"Va&R#O=? 3?>w3'?>`#2Wiiz?>_)?>bc?>bcSXi"+b%bcd'+NSs}`+p-8?Ic%bcÇbcZ[bcijbc?>bcFVf 3Yd[cP]Y!/?>[*bc?>bcm*6g'0b%)?>`,4?><!R ,K`2V$>D@9L@z90=:BL`*j'2["o/2EIj,7{7F8HM `VZ0m63y>2f)"` 8 !   3H`,6 ]`M`8``C"6)J/N""i9WA"?>[-E0 ?>A,YME ?g9eH"@S4BO4^[_U?>s0?>CZ?>Z%ccY`LXn);?>_$"`%#?>a$%bcj#-~9Cy6?Y]bc\!'MS_",S^h'2_%c'bcÇFDbc?>abci"2d/k)1\aZ)?>bcOLÇwwbc[\bcc"&Z*'?>`?>H!S$2P):]`<j2;w>Dw=9E6`m+'R `6l7?`?/e+33 " `'V`28` .mC\42.*a-LC %D#?>B+O:YJC 6V)MdCZWR ?>k''?>])o9p"6?>jcFE^ik(8?>Ybc LQf *|6B?Iz8CEObcLT{CK]%-f,5w:E[&bcFCÇbcÇbcRSbch#-^%]c?>b!,bcm)0bcÇ_`Z\bc{IIZ.)C ?>_d?>`,8?>/\/B7 <05M`Y`+8r@BwFG}GG~A@CFu<:|FCz??;L76$9 *W0L`9VkCdf6Vo6NO(]8D%M 9E 4qLcI#+LWJ? +??>Z?> M zl1Sf?>@?II]a?>['?>]bc PUEM?Ku2>{:Fd&2GRe,6S'qzd-7}BLc&0bcFJbcÇRPÇbc?>bc_bc?>b'?>bcm)3Wk)/bcÇONbcm/)`%[$?>`/C?>`K ``Y`)`-)c),o2<}2=s?8yE;zB7<7@>?B?C:P8N6Q89 \6FV/6?>S1gV+GL '\.6b44?>a?>W?>_"c+{/;@EZa?>PSafUZ?>^ bc k,2q2bc?>bc`#,{?Fa#*UYbc[]GCÇbcU$?>h'?>`2s@>p=;<`V]-t6C9D:FMz4>:?41P?{F/z=)}=,`K `V}?MY)2?>P)d>S:@,8!O,?>.!C 9S,FG+[6a8b6R $`/?> 6 YALZAFW99Y75bCAcCCZ69Y04?>i,?>i2j6AC?>Yd[fn(1?>NbcW#)S!(X&-W%,S&Y]bcn,1ORZ]i'0w6AEPh#-bcÇbcssYYbc||\]bcÇbc?>bc ?>^#b'*k22bc}LPQVY%+s>C`&,SVbc?>L"?>`PR`F`LL`P`F `o,4{Cz?Du;D@Oz>Fs>2J8B866FRz5C7?C@m2%I7C3G;`^`r2Ew9G}@?{9"Ay8Q"   #M`'V`Hm&(<<`Z`C?>C%X /g?E.L ;?>P'>U,F>&X/a-c)p'7IZ(?>`7AI,4X9B\>DaBG?>[47?>c24?>H&C"V*?>^(?>TlPabp?>c-?>[%m28Z")\&,d/4|HMbcMRbcBIl'1^#\bcÇbc[\bcssÇbc?>bc?>bc{PO]^nADMS]%)bc\]]^?>vm?>d!?>`K P`<p21HHt==v??`e&,z?I{@Pl0Hg.>|HCO@v;/A=u7>}>Hv7;w<9yD7zE6x=1j& }<0`6`}@Us`7>6 V";I )Q3C-?> P%?>AC "D `$4VYc!L M/P?>2@42'k6J?>W0C`-?>Z%_q?>Va?>]+,Ij03Pt/6bc``u39BJr,4bcÇbcÇbcÇHBbc?>bc ?>bc?>bc]]]_QSs>CRo/1bc[[?>_!?>n+(?>3`K `4w>

    ''kA:cF58PJwCAX/+cI?qF9m@1pN>`k-/`3X(7IVy7@`R`3?>46I-W B!DM %F]0b"5f(9[(I J c$"Pc(#3?>],6?>])2?>E &4'2 /N)LqCX?>M'S,K "S$^,k%2?>U?>k(,?>`!,?>b"+a$a^d&?>Fp25m'+bc[[bc[\ZYVUbcXVÇHBPLbcÇbcZWY'&OP`)*YZd%$bc?>]&$`1,?>bc?>f# ?>`?>6`T`A@|CB3` `"(S$/3, `Y"`d2/V22V)(gB:sL@`]`Kh8Go37B/F'Bb.%   9`8GII<]`T`]?>Y3;`)>E$U9?"?> K!a2V "c.l#8i#5^)K OPS$O$F ? ?>D?>E < *,"b8Z]3Q?>FZ!2S#U#X,S(V(V"?>^?>Y%?>nt][F@RJW?>c "bc\]GBbcfgRMÇbc{C@ÇIEbcâbcr=6xB?OO\]bc?>k43?>bc?>Z?>`YY?>b%}y?>`3t<:`^7 E!a;<_69 M^k8LH6jF@jE2`/V`_t6G}DGyA>}@>C?B:@,Cl:F "   K`;r68s<=,`K``|<<`Z4`?>2P0E &?'?>L f!5V [QLj%/g '_S ]$L!B<CX?>S49`?D1 ?>A 4?>^,9Q*O ZVY+\4c6M ?>^c_?>f``)"?>cmY`SVd_QIb v1/PV?>bc\]ijÇbcÇbct;5Yj./@BbcÇbc?>bc?>bc?>Y?>/`sC?)`C` /`e#=: )o>0u@1? KwB?```m:CB@?<3A)|D"g6I! "T`^M`M :<}?@{DD6Y`b"!`8C 6?>P66 9#,f=XtIb5E I Y!U]m1,K `] qbOF,?>D \,?Z>FI46V?A5V25X.0?>P%QX bU#[4_4Q!?>`yrb?>e?>b]?>hc[R?> Y^g]c]_`Yi`^[?>il?>bc?>bcÇssSSVVÇbcyzbc?>bc?>cc?>bc?>l($\?>4M`R`H ;?`~;6`d"!Y`^`2 rFIo>=}?=<=;<>=D5yDg<:""`^K9`^s02{<=|@A1`F r:?`T`?>S62_FCZ9EhCW/+R ,JUYVV SYew piLM]13?>M":D+`DLV@@Y??L./^89[//?>]&6S%L f`T"L %DJ ?>c?>d?>]"?>VRaS?>df[cY^cc]TbY?>`e?>bc_`ÇbcF@bcÇbc_#?>`"(?>bc?>bc?>`?>,YY/7M`e !Yt02`1`Y3~>?v02``;`6?>9 Q6F "`#.L W q*#VRV"a$] s s"Zf(36?>9 b;Ab>??>F KYYX%FZ)U?>k%"?>bfSWbjh*?>^YYMmYeVaabjY`_`bY^X?>b"?>h%x,4bcYYbcÇbcXWbcÇbc?>bc?>bc?>bc`Z?>C*`?>`Pp//`; `?3`[") Z1Gs2HDS7<<>.I,P*<>Blk!V["O Wj%Z'=WK"5?>T2^%5WR::R?>n($?>ghWZchPYFS`fgccV^Lj\_`TZ_f]`_Zb^?>Q ?>a#bcSQbcÇl]ÇCEbcijbcRYbcj)j#*_`f%(bcFFbc?>bc?>bc?>?`55`p>607`_`T]8 6p+#<,e2#]5,. V,@L,w6Kt6?HL6<:;I@:+}<)`0,   %<]b'(i??,`($]`]`Z?>;)" I,l5?Ns0-W ddS^%S ]-S &L 'Q6% L)?>C.L9? "E9?>cf]ccj^fZ_WSQFhZ`URSmsSYY`dd^?>_"?>a#/?>bcDE?>OPbcYYbcÇpdÉÇøÇWVbcbc?>]?><`]`$9`T`4 < 7 ;:j<01~G:x;6w9:e,1l]2=V/D<+`+DO$F M ^`Q _%O _6]7S2W9L/? ?>Z/H?4*8R#?>ehW\PX]cVYcb}wwv^YbcUZ_hV_^d?>\%-?>Z(1?>`+?>z/6bcÇûðÍôÇ_`bcC?bc `$h"0j"4h"4]'j"2j$2ALDN}:By8>c#&bc?>k"a`?>k8`?`"j:Bf6C8b,1h:(c:_1]/!sF=~KIw2:}6>r68pCF," qE`s5I68C?8>}69?0z<'`/F"   C`&<`4`8Y`<w9?`?>Pf# ?>]?>b6>J+;) W2F`.??>Y?>`?>ejY_]caiUZa`c^rlrkD@XWY]^cW``mYe?>V "yHLim?>o(1bcÇbcÇbcÇdVáüöëÇ|;9Çbc d"%IS=IFVq,>b0^*y8C_R __WW`?>a@CU=C" 0_`8Y`H1P",5+<*?>`T]`C`6,L$k2>d0,FW"zF:f55Y",AU`oCCR4.(0 @!?YEKz<;?CGGE8A-x;)g4$5  "`3`R;t9A`?>R 0["I;$j9_ Z b PJJ H <>!< D?>f# ?>X?>Z9@\=F]5??>^?>VZ?>d"Yb?>ZcU]ai[eadb\cWf]hcVXhlfj?>PaOZ[%'?>ccef?>["m"/bcVVÇZYbcÇÇÇèqâíéÇbcLJÇbcÇbc j*,[!b!,g%3N]etQ_{>Hx9C=H};Fj(/QTbcÇbc@bc]?>`;AP6?,V5:^8;?>O$4 '%7;-2,8*?>`? P`s<=K/ v=Pm6BwCC61s>9w>DCS9 Y]5<`DF?%(6<G m5V BiV!L<-o#B[h)\ZE ?>V'a9CW9?V=AY:n)'?>f( ?>[cir?>Vclzf)?>]iU`W``aUI]Pjaca]c^"d?>c/?>c2)`+$b]baYZ?>^?>](bcZ]bcÇâáôNjÇÉÇSTbcÇZYbc QWj,8`jw:Ej.8q7?y=F`"bci"e?>] !?>:&C)?>V` }CLF Y/]n>I5E`RT"V7@+cF@[74p@Hw>Jx9CDDC6H6=,<.i,J   +`:`}FP`&j57?> Y V.5$B1c9e/:? BM ?>`@A?>V30?>`?>j)W ?>_dV_^i]h?>`?>Ya\d?>jcbYSPFERX?>Z.)?>[Wge?>bcXZ_e\c?>k'/?>bcXUÇâËëÇbcYZÇbcYYbcY&b(0IPr;?yBFy>C?Ij%/bcIGbcÇ@?bcp)2bcfc?>Q)?>`d(<]2,wCJsA@b$!.0C`]!1?"' 9)U?75 oC/b6=^06L?>z3?>`a]]cc?>i#"?>]b_b`e\`SX?>Z%%cdcf?>dg?>XZ^aSU^e]e`h?>bcGU]2b6b2JVp'2X[bcÇZ\bcOSbc[]bcYY~MI[&$OOXYo),bcÇbcc`Z?>`>D`EDd `R/ ? ```1I77M<>0]9Ei;IwAF|>2I9;9AA?:|4"Y3    '/)`^,a@0T)4?>V)-E!?>r2?>c`f`?>`%?>ah?>i?>fj\cZcSZck?>bf?> fh?>_cbgW`b+4q`P `9^`V8H06E29V=FL,8Y/>p?G}D?@<:?3<@@z0g6 A#       ,'2 `;[(c,c/?̅?>a ?>f( g?>c"%?>\a^iOXeo?>jm?> ] $Y %])/L!b3;Y%1]1CWf$3`(n*1bc}bcÇÙÇbcB?bcRObcd"n%0l"+BA~<9`#Vbc[]bcz>Ef)2}@Jy]!\YXn-)?>6`Rd%(`5`]a$`!?>[b#[\_?>`?>fh?>e?>X `!*?>d$f%?>di?>[]?>T&j)7bcÇbcYZbcÇbcáäbcXUbcNQ^e%%AIp.4q3.k-(FIc#'bcZZXVbc n/6\(^",a%/w9Fk/=f/?6h27l32u96h)%bcÇbcÑÇbcLNS?> \_!US] !] V`"?>bc?>Z?>6Vf-,9 `:, i@JV,8g8DrBQD+b-B;R4Eu6<{A8g(p:X8&   9%$/`^9>Nw7I]V`?>XZ?>a'"?>[W?> c b'?>V ^ e?>f!?>^Y]EEZZ?>em)"?>dh?>bcY[bck).j(+bc\]bcÇDBWVPKbcOGbcPKbc wCAY&$IGHFd10d62< X*%j20d'&XXbcZZbc `*ESs6Ev9Im/AJ B46 I,^+6m99_'$Tbcssbc?>bc}=bc?>? H_)//`_MwEPj9Dk9m*%I=g=%?"     /3`0Cp/@Z- ?>V?>b]c^b%?>ac!?>o,"?>_?>be^]?>b"?>bc?>bc\"Y[bcÇbcbc V)$Pf20].(tIB\0/pB@j61v=9]^XbcÇbcb"/c%4<6AM%P1TFJ@C27i6?qk%$i""?>bc?>Y?>[?>`TC`j&%`p8Aj5=u@J`1B,!%A -u7Pz9???c(RQ~L/V1   "K`S?>[Si_cX?>]?>\ `?>bc?>]!?>`'?>]0^0].?>bc?>bcZ[bc\'i*4X\bcYWbc_`ÇbcopbcÇSQbcYXbc_`bc ])*W%%Y$q93BH`"(S`)$d"*o'/bc]%o0>Z.[!3W2V0j+CV9MDPKL;I/@!i.Cw9Dr29{9?m'/`#r)4m#2e2bc?>bc?>Y?>[_$T?>^))?>: 6`?>`}CLKSb2@Y/I;14&l6M7CAJe2|c&Y?>`Q ?>YTVQ?>]?>W#^%%?>Wd?>WkYoc!3`/bc?>bca!/c"0bcZ[ÇLIbcÇbc\[bcPDbcMPMMCA\TYuv]""g%,bcd$-p4?D U,[ 5`"9T-`"?R@M@W"CH-`%AS,o39p2.x:5==?Kbc?>[!$?>_.?; ? ?>3`Z`sCN`4G-9$9BV1F7N`]AwI!g?$$     #%%`m2DB a):Dž?>]`\`GL`f^f?>b'?>YRe\?>i'"^?>p.$?>`(e5Yp_/k)5?>bc?>bcSZ`/c"2Y]bcÇbc[\bcÇbcyzbcSVACbcÇbc c%]%bcFHXch+m(/c&ISl$1bcRGP9 Y .c(8CN!^ 3B \#=]E<v8L{?E}Cbc?>bc?>X"?>`+0?>8`)] #/``*,M7K`[9pC?    "#"*`H `g+40 F%…?>fY?>L[&$?>VBC?>Xb`jV`?>]'Yfa$.?>ee?>[Ve]aXf^?>`i?>q[,^1?>k+6?>bc_a^,LY(m%2b"k(w,3bcVt<@2HNOV$]*`&/P&f"GH)w3L}Z?>C ?>`M`:`R}.U=Oc`dIuK^?    '%H`R`]M?>V*?>n3)?>W"?>GMPZdpU'`of!/^gfj`^d_f`^V[Tc]^Z?>VZ?>V?>_-?>X",Y(f(-a #bce!0Y 49PQFy?"z@ w9%s,3f/bcNQbc?>]S?>`V`c <`}0A9>`c1Y? 6     %)`5?>S%?>r+'`"?>S ns?>[$[%?>S#?> X!^gY]ba]WYS_We_c_VT?>if?>U^`?>`(4?>Y\???>bc]#;H|2Am"/bc}HMp8?{?GbcSYbcTSU~FCS["#T\YVPX)hBfE>:Yz85L6{?%C5b'bcb#]"?>^` ]*`j$*~6:`[9}Y5T3   #2!#C`V?>c2F7]"?>qj[# ?>`")X ?>a,f".JTcga`_ZÁ|Íd_YVgh]]?>n)'J ?>`f?>c%'?>k"-?>Y\bc?Fc#6Ac"bc\]bcÇbcZZPx?bcF;\?>O;`Y``Kj"%`bN?>+  , =#-`F`P`YZ?>F %?>` ?>p]?>])j"0?>Qb`*dpYb\`]]YUaYc]\Y`_YZ?>ifc_a""SY#NTdjGK`"?>bcl &bcÑbcj"*m&-RUbc`&"m4/JJ a" ^`b\'Y2f KYBR 4m&Dc.ADv22\bcÇbcÇFLbc?>k+$?>L ;`M`9`?>SIC?>@9    8;'F`K `g,,RC <?>]#;?M?>]*?>b!?>^oWkSdUeXe\eZ_YXkgc]WS_]_aZ_fg^YFC?>c(*["(OUW]jmMK[b!?>_bcÇbcD=bc~??bcj$,i#*o(-bcC@c)&h.)L Zdc[If/?R3]@D#{9Sy8Cw79]cbcÇbcÇbc?>Y Z?>`^` Y`4[!4`?>t*2?>SO ?>L%Vƅ?>]%bsOc\m_o^jQZ_e`dVV[Zdc`bY^[a\`c`SPcc_$&_#)bi`f\`a`?>]?>p0?>bc\]bc_`ÇbcÇbcQV]h!&bcV{A<=8V^[HN,Y%9Z!9D"w7Lz9Dz9`:<`TpC<^!#;H "?>N=?> #    (:%1 Y`C?>Z̅?>^pa)?> `)c)IR\e]fZeZee'^eZZHG[Z?>dl]d\aQS^[?>bcXYbcÇbcRLÇC?bc`S w/2bcopbcz@:f/)n:5j84D-20E*P 2F%g,Az;L}9E]p(+bc\[S;bc[]Ç99bcIL` ?>`?>^`?>\)23<`P2p<2R `6_,/% V(H?>c$#?>^;f.G    $1 $9`Kх?>]!c-?>X(?>`".?>S]?> XZedSS^`TXFG\b[`jnRS[ ?>bc\$bcNLÇíÇbcj%%x01bc y@`eg?>`?K `3j@6b&"V`M2Z/v3A>>It^?>f%j9     R`M `ޅ?>a)?>]daaYV?>ff?>MPAAv46`#'Y^?>bcn%-bc[]bcÇòÇD@bcYZbc _`r75SRe02T#(|JQk6>EM](Wp)0bcK?bc^mk?>`Y<`y?BxBD}KLc%%`^`Zf=3F<`C ?>V.!?>~B"$     %"`6?>X҅?>w?>] *])c$.W!?> aia`SPki[[?>^f%(cf^b???>[%jq?>bcHDLJbcg#+m)3j&0\!s*6b VZbcV!bcÇmmÇYYbcIH~?@FG^%%P[YbcLBWPbcÇYYbc?>Y$?>^$?>C V`K `7k-/u8<=C>F}k56?>t,v4E"    $$ ( `?>AՅ?>Y&QXZcLVVa?>[X<;[YVU?>ZZ\`_f?>X!+h,9bcHFbcg!+a(v3>y6AU%_,%?>Sk+$?>F `0h?6`8`7wBDx '     (- $ 5`7?>:ͅ?>m%'?>Y!?>`j`j?>b*i"/\e`ahfSRUTgdZ?>SUAA?>Y#/^"2bc m)3DM~?I@KBLny`&c%bc]'m/9CMbcÇbcXXQPbcÇbc[[\]bcÇLLbc?>^/'W$bc?>[?>6Z]"2`'nEDf'(` 86 rAEHLz5<7     /1 $ P`Y`0?>49΅?>dh?>^#)S?>['?>ZfXc`nP]?>V!dp\`YY`abbc`[XSPifa`HI<S$bc r17CJy;Bw:Cs4=@Iz:C{9Cl'1|9C|=GV"Y\lnbc{|ÇbcYXbcÇZZWWbcÇbc?>jeKFbcVV]^`?>;H)Z 7`!`Hn@ItGSi)7L      ) )#"!`V*`Vi+,1T`?>C4?>Q?>b"?>k(-`j?>S?>os[ &w}]"*?>`pUd`qCKTg[j\b_b^aVVXWVSgcLIec?>_#$^!%g)0AJbcSUOPXTXw:?}BGz=D|?Dz;ASYz9?}bcWX<;e`?>X&?Jh,?     )$'`T,`u:=w./?>]?>Yd?>k'/?>]$!["}w`%?>^iahfmu;COWWa^",?>],?>Vh_-s/9p,9XlYjV``gY]Y]``SScaYU^Y?>BA?>bc WWbc]!"]!#ILp36e')Z\FGh+,SUZ]bcÇÓbcÇbcmmbcÇbcÇbcÇbc?>Y!!?>bcfc?>3%Y?``%2`V]C~?@CC~<9~GAb?5` al-,9`<`2` %`=+j='`?> S &  %4$%< `# `K w<^&.9?>U]?>k*6?>c(+TUecIF`%#?>j",v/6GK??`&/^$-ISZ)?> a 1[,Sf?>Y+a4]nZfipX]?>bcYY`^kfV?>bc[\bc\]bcXYUUk,,j,+bc{|bc{|bc??v44bc~bcbcTSÇbcÇbcÇbc?>bc?>< ,V,_2a`Y9`x57v54zDBfA<#` j+)?Yf%%zDD`_A?cA p/4    29$+` `6FF`g)*:`9?>^g?>_")b%,UXceZ !?>a+|9<]",z=Hw;Fm. b"6a 1m%1@Ggmbg^[`W[cd[Y[Xv63TTbcZZbc?Bbc\[bc[]bcàbc?>bc?>`\,d"7`Y}:BFOyAId;@.`o54g**K`|HIc$#` 3<IS^`Z<`V`9 ?> U!    9+ "7` `<`<`P`?>lpQX] +?>[)S]T"dmcjPV["?> `,b/QIS{?Ij,7FQc#/`-S[bcY^Q"Y,a%5b'7Y)FMJN_cPUDLp&/jr?>XZ@??>bcfgÇbc_`bcLLp,.bcÇbcÇbcÇbcÇbc~bc?>bcUVk%'?>Y`^`V`]`a`t3?j/ s8'  ,D"]`+ 0`5?>`b?>`%2?>[)V!]%?>}c%0IRV"l-7f'1ISbc IS]gR%q{T\YZLLVYb).z;Dm*5]$v08?>p16bcÇbcJGSSbc[[\\bcj$&bcÇÍbcYWLAbcyzbck%'?>8Y&;ZM`%/`4` ? m?Be;=lCFeDB=))P4`?><   !/CL'%`Z`Y;?>n,)?>\]?>T!%[(-?>c)6?>b2V&Y]bcX\c%,_`bcVZbcLR]")]#)zDIc/3V"(}LNYTV(#kjOSY(O\]/Y-?>Y)Y#bci")bc[\^$%h+,bcZYZXbcg"$bcCJ_"+]"-^"*Y[bca?>]?>Q?>LD ?>4 e S2)  ,NOJZ`V`?> c'"?>fd?>YX?>L$V)1Q+V!.Z!1?>\%?>\/btAJbc[]bcz>@k02w=?c-.Lvv]2/g^pg_[xBDbkxBQSgc*A?>P &;?\/d%6p,:bcY[p26ɬbcjjbcYYbcÇbcfgbc`"/i0>xARtbcÇZ[bcPMbcÇbcY]?>f!%?>5 ?>L):T3C8: ` e9?Y(*aCF^BHG*83'OCCTDFZ9C? `_?>[3E    7 _&+H<' `9C9?>s)'?>c&$?>a^?>CC?>dm`'2CP{],?>pzc%/`+?>^.CRX\bcUVbcWXd)(w>~98v21cc?>S?>k=I?>X.;4 ` p>EZ*/[7=V0;nBUW.?Q8=W !^9Cf5F\*`":M?> M' j<D"   #)* "- <C`?>m"mff?>[ "\')Q ?>Z"?>ei?>`a``aaaadg_cX`PZY )?>]%U[zCGRVbcUYJRj)2bcb&!ICwAPj/0p/5i"+bcJGÇGDUQbcÇ}Ak2-?>P ?>2`Y8`h!`Zf`c`e,4`Y`y;I`9`_K?>2     &>$59#Z`8?>p$?>m"?>`?>`"j/5W]emY`?>hlcfbcUUYYabY[_d^!?>`*/e/1bcZ]BLENbcVTYKESM`\R#"],+e*,bcSV]^`%c&n%0FSKYJ[\m_pi/X]f"5c1bc_`bc[\bcZ[g("o2,s92w<7b &a&bcÇbcBDÇbc]]][bcÇbc_`Çbc?>B ;p4<FP`Y9:H`c!!`.E^`a`T`z2?z2Gg!/`Y;T2F?> E c1_: , ) 7 I$22 9 `H`H zv4?>a`[^]`ÒVZ`c?>]`dfcfPUkpahk(-?>_#)bc[ &c)1`#*bcVRo?;YW}NLbc Y\_`h&,u19>IFS^lScp$5["]^MZP[FSbcCGSU[\RPbcÇbcfgbcÇbcWu72z=8q31c%bcÇbcIIÇRN]]bcÇbc?>`^`a+2i=M\0C]3 ? `P`0L``h,:`P  C  7D>&&&`H`u6D9?>V?>k%?>};'?>f?>VRececabÇbd^_\&&M?>fhY\X]RY`iPU[c?>_"?>bcWZbcRPbcc"&?Et08CMXcQ^`%>L};I^.HV]^U!f%0d"*bcSTUSbcÇ}bcyzbcÇbcwwbcZ[bca]t62z;:o,0bcÇbcÇÇbcÇ~99bc?>\]c.'?>Y]'$]).?>C`VC6`9 ,7%Yc2@?>`]C `Y?>6`c,k?b(Y`R`a!`c!!``_Y/S/P?>Y?>2' $ DJ* ",-,`7 ``8?>> V?>j$?>k&?>z2'?>x7$?>f"?>_\^[kfTQw?<]"!@?eh\dV`YfEIcn?>c%?>X%?>bc`bcYZc%)c$*PVcj`'z7B>I}?Jo4?\!,j,9o}['j*3[]bch'%bcÇbcXWbc]m.-DF` bcPOÇêÇbcUSbcÇbcBCbcCC\]`("?>l&"dP?>Y%?>Y`R`?>`<`_,<`V"7F?>`M?>/^ w6"L 1LI"Z^9`9/`d #?>C ?>\%?>a"&?>f?>]~<'u2?>t2"?>f&f(]~99kj?>hdVR^Z]YWSc^HC`"c&$DCVU?>s*/?>P]S]?>q(0bc?>bcÇbc Y[j/2z?CSXf&-ms}@Iw;Cq9A}EN[+l-X &?>`g#4`?>k1$7`f%*```\5?>`K Z?>>$YA[<``Z9 ? `b#`y9]P?> ^?><    !=PC,`81 V`Z`R`H?>V?>Z ?>]n'e?>y4?>bb ?>w4$?>\fMZ]mIP_$'?>cfPPIHLIa]VRjdfc_]II`c[]`eAC}6:?>v-6Xfc#/9bcÇ?6bc VVIIYZ[^EH`%*X#{q9?q9Axk,'?>c,$?>j2"?>Y+/?>`6?>,a`a*]"?8$?>`P];?>C ,R?T:_`2```d54H`c`j';``m%@`T`U2?>`C<_69?>%   (DP>9`]#<`K c)*22?>j-"d*?>k,'?>v9?>k%ojo("u/'?>^Z?>b?>abmCIVfY(?>n).`fVYcdIIc`[YVSNMbc`c]`AAv48m{p+6Xh??p~f)4\&bcÇbcMJVVY%"KK_`a()wzJM}DGk57}FLt9F[-a%/Y]bcVYUXbcWRYV\]VTbcÇbcÇbcXZp',d"bc\]ÇVVbcijbcKFww]\``bcÇNNbca!i'"?>k43?>`` #`H?>4`SA8!?>`Z /Y?>A /S d43 CEL&!`.`7]`8:+?>f(f)?>Yb^bd?>r(2f!.Y)?>^$]f_gTYegOPbdZ]`dX]Y`[b?>Z )c%3_0s5Fb$2`!/Z(a(2bc?>bc?>bcIIg//FGc)+\$%[]`)._%.[ +]^h&.d")bcÇbcTUbcÇbcr).u,2bcUXXZPSbc``bcUNÑbc\]bcÇvwbcÇbcWX?>j&"?>``#d%`SA6"?>F P?>5"U(`Vv?I|FCs?2xE5sF8gC?)`e#`^i1T; ,f9GnIJ0S12?> n=$]>  #=B<%9Y`,2`H`^?>cL?>]"?>q1'Y ?>a ?>k%+\kZj[f?>QZcn]f]c?>W]PU\cLU`icmLSPXY*r6Fsbcu-.bcc)*^%%bcGJIR]^X[Zb#bcNKbcYVbc\]bcÇbcÇbcÇbcÇbcÇbc_`bc]]bcÇ}<:LLÇbc?>]?>f \?>S?>Z0?>`\7`YO:? ?>`?>Z*CW&<`i",^p9In77}G`c`z%?]`V V%IwGXY18X9=]<=?>e<9 %?<)!&('9<"]`^+S)+?>j%"?>n[n]S?>xrTs.8eq?>\ ?>X?>Rdg/j+e ?> alOY`kf&j)?>^jfrJUX"?>T`f)7{CP{IVU ,YfdoC@?bc?>bcOPXYbc~EFf,1]^[]bcÇbcTSbc\]bcÇbc[YVQbcXRbcÇbcMLÇbc\aV bc?>V$?>V 95T)?>5V2Fc_`YAC*Z)?> <`^<wCTwm<V,   $J"":#1 %)`9 ?E?>[ ?>k[]Ln`W?>[?>]aj%,["jy?>cfca?>c"%?>^%bjdn?>k,?>`#.?>b#,?>fqVbWc]iO$_"-Y&d4;S"&v46bcYZ]^?>bc[]bcm22IKY[n.1XbcZYbcÇYWbcÇbc\]bcÇZ[bcPNbcÇbcJCÇbcYYe"bcN?>=F+?>@ $S=S4R_`Y(l(MR?>``"49"d2HCL?<|<1I?a<9`c#`x)?`^#?I22pHWU/6?>g3# $A>"+R`R?>9?>l\fT?>n%?> YaVX?>YO\Xe?>cmY]_\?>k)2?>e)I\]o?> n).] ZdalzDN`iHRV$Y%,?>Tbc?>bcSPbcKJbcTTbcp--bc\]bcYYbcÇbc[[bcXVbcOIbcÇbcmmÇbcRObc]?>Y+)c:I2 '9 ,P$Z%BVb!,`_a>\6[&?> b10?>`6Z,K7C%z9D=>D<|?7kDB]47`M a`m';``],c&G=)b:L`5=?>o4"F #%7$!M`< M`?>\!'O?>c%VGgS?>k(-?>fm%?>a]j"%?>U`Zefp[c[b?>x3?>`,Vj]mjx?>tw?>_hckclOSUZ?>v57?>bc?>T?>bcXZQNbcb)&bc`_`[" _`bc\]bcssƬbcopbcYY=;bcÇWTbc[[bcc?>b$i.?>Z1>V0IY/Nb2R]H ^#`c+?`9>?> .W%;I/7%z6Ff2* . ""   #`P`?M?>@ ?>f-?>YR?>p%ka^f!?>z7"?>]f[`ZbPW_d?>|<}:?>\,?> Y#Y`^'?>]c]aX]ag?>b&,?>bctD>PL_'$bcj"%bcÇbc\]bcw//XYbcVPbcÇMGbc\]bc?>]?>S#Z/?> C/K2X%A`R`P7,94C?>Z*?>R%:I#C2#<])*`f"(`]%:W:I0?>w9'F! T02!&   2`H1s-?>f/i2jT?>e?>ci&"?>z5$?> c"ao_fV[`dfj?>o+$?>w7"?>u5?'?>_e?>\cah`")?>s~?>bcWWY!bc\]bc\]bcZ\SSbcopbcÇbc\]bcj%"bcTQbc\]bc~Çbc[[wwbc?>]?>=?>='PAL=P7] (K?>G ?>a,5?> / 5 (<%}8O4B68ECmCF_6=}CMC `CS`c!/`Z"=Vs4Y%%  .",C`9 aC`?>21?>Z T?>\?>z3'?>SZVZ_c_bccf ?>??>_)0V%?>bcX\Y\bcWXbcÇbcZYVRw?9~E?bcQR_%(h)/bcYYbc[[fgbcÇbcYYbcTPQLq5.OIbcÇFDbcRTÇ]J~J9SJbcÇåSEbc?>S?>V%@K8YCaC`>F?>a?>X-1?> Y1>?,Q,Y/Dw:PvBGm>Af;Fb5Dg2B`|/KZ`\(Y?@,F.V&9?>s;'+&A.$"/`R`;?>/6?>VR?>_ ?>r)'q()?>]b[c_c?>g"?>?'?>o/?>["?>rx?>b#,?>bcKSu)1bc[\bcSLbcÇbcZZbcÐ}FCÇbcHLc'.f'.bc\\bcNGbcI?bcÇZ\bc[[bc[\bcPHbcWRSMÇÞÇbcY[FNÇbcF?bc\[bcL5Çbc?>Sb$?>]3@:)?*]@fAa<; ?>L?>b?>  `#2m*o6"5 ,4")    !`V3 ?>,@ ?>i'"^Y?>`?>]d\d`e?>a?>] !ikrv?>^"+?>V?>bc_`bcYX||ÇbcZ[bcB?bcÇbc[\bcOSm,2h")bcJ>bcZYbcZYbcy<6ÇVSbc``bcÇÊÇàÞbcZWbcÇâPc$ ?>P,9P5Y8Z6aA9"?>`%-pyr%'?>`**^-2?> .[0a1Z\ ygg?% &9 79 6 `?>I .Q?>Z?>]?>w/"?>YcWa?>z6?>x5z5'?>_ ?>k+-?>`&)U"TZ^",?>Z!'?>a#/SYbcc))bcbc[[bcÇbcábcPSb"s-1bcÇbcZXbcHBbcZYbcÇwwC>F?bcPLÇìèçÇyB5bcssÇbc?>[V?>b<>Y7`#.?>`"?>^(/?> [2I\0MP'V )Y;YBJ-< =$]%Dp6P`h /`b`m!>j?j?c:`j)CA(h3Te9QX5C[:D`<@?>d9  #@<% & 0".`d`Z2?>,2?>dienMWYc?>~7$?>W?>ow?>rz?>a%/bcWYQbcbcV!bcÇbc\]bcÇbcÐbcRLbcÇbcÇbcÇæÇYWYYbcÇèÇÊy?5bcYZbcRSLLbc?>]^[Y?>[65];k.=V/?>M4?>z,?>XXV#?>2$e!?^4eHSC*  &-<+ 99 )< `^`?`3q;=`35?>`KQ[(Y(?>^,?>S$c&0bc {CAd.,]#$j/1ILbcfgP 'PXc%,bcÇbcZ\ÇbcÇFFbcÇbcPEbc\[bcYYbcTQbc\\bcYYbcÇFBÇmmÇ}C]^`?>_:9?>R"0?>Q?>; (C5X4mCY&  %%  ;F` 1KZKF1 C<`CH`6?>sx?>]$0?>w6?>x~9<_*?>[d?>c))?>_!?>a%2`$/bc CBY%"b-+^!"bcJMS!%N!'T\v?H^%:=bcwwbcZZYVbcÇbcÇbcYWbcQTc"(w29c"l!*n#,TXbcÇbcUQbcSQSObcWTbcÇbcÇ[YÇãÇbcVWbc?>bcTU]^bn*)?>],0?> ^08 %S#EW 3j?`?[?]?[;[;a?a<`%``f4`i%7i"?b`F  # 23`5YC`4 R`BFC`4?>UXU$?>W *?>Yc$s1$?>a?>] )n)4c/?>aj^b?>b%c"bc?>bcLYY'bcLJNLbcc%)MSTZuELr6@h#-QSbc||bcÞÛbcRTÇbcbcÇbcÇbcI?bcc$*f$,]VZ:E}2bc?>_?>D N?> ]0HB0c?l@n"I][7b!>]*c7c/`p%<` g"=^*_:O(I!Y7[CB /V&D?>`?I?>`%?>c4]?"% P+),6`5?>U?>\?>Y )]c?>a%!zpk)?>njk*"xs?>^b?>`$"?>bcFQa'/bcYZbc[$Y#+b)2e,i)bcXVbcWYÇVXbcWVbcÇbcDJk)0bcVZm"/a"k".f",bcÇbcZ[bcÑbcPLbcÇbcSUÇQMbc?>]?>s/'?>k/-?>K ?> a6I<(f?n@e<`4]%d#f-amZ0{C5   ) 2 /`H`?>gj?>\?>\ ?>`?>_ *?>] "`#"BBbcq3:HPY%a%'s11bcw29CJbcYYbcÇTVbc[Y\[bcZ]i#/_$bc[]bcÇÞbcÇÇbcML[\bcZ[bc?>j#"_?>W?>n,)?>C !?>b8FF$b7j:`f!4```d"?_7f'?]:]FL9H5c.JR2?>OZc?~Y%K0    %4 `M`6 `?>V?>k,0?>bcZ]Y Z]f,1FGVWbcÇbcÏ>@HKÇbc@;bc\]bcPVe#,k*0DGbcÇD@bcZ[bcRRbc?>t1'?>6C+J 2F/?>Y$*H"c7`b#`]``"7`_^,|_LD 0C *?>]jeK{Q%Y6    "C`P2 s=GR R?>m&?>`!,] *Yc?>bcZ]a"&bcIKi-.bcWVbcYZbcâbcÛbcÇbcPPÇKMFFbc??bc["bcWSbcÇbcÇËÇbcbc?>Wj(?>^-HF9[IYEB21?>X-<`m:`a``%]`_/f%CW>I3u6_="L *?>bneV]p)?>a"-^j]i`k?>bcVXbcd%%bcÇbcYYÇbcÇ\]bcUUbcTSbcÇbcÎãbcÇbcWSbca",a#*bc\]bcÑbcÇbcY[bcY[bc?>L"5 &6 2ZLP==/^3C?> ^?>`!?>``m;c!]`Y1^< `[2Z4\,^*_7\@J2s2YS8F'?>a!%S]e`WBb9E      1 :`d`GC`)pBJo:F5C?>p)?>|6'?>a'`",f)4U`Vchw`-bcVWbcZZbc[[bcYYYYbcUSbcYXbcÕbcãbcÇssbcij}CCÇbcÇB@JIÙbcCCÇbcYYbc[ZbcVQbcf)2q5o+'?>B"D 9I"CS"EL96#?>Zf`?>Yh2`_```s7Li2?`)2^Z#Y2^<`j'D]@fLB%p1ST9?>Y]d]bSH^3l; ) ) ,2`C `0 `s>IT'3J V?>T?>]?>_"?>UZw[(MX?>P!?>`-bcÇbc~C=bcÇssbcÇopbcÙbcÇbcZ]j(+bcYVfgI?bca")V"b'-b',bc\]bcÇbc\]ÇbcÇbcSUÇJIbc?>c%?>N)9>0)Q*?6!. ]39?>k+)c&?>Z ?>_=CV/<`7j7a`Fu8Tm6GvCSX2? ]!@^i'AV0`AYVdiVdZWT)w?   -29 `FF`?>C `'0[(?>w/'?>}6y7?>oy?>f!%?>k05?>cc?>c"%?> ^$-W)R]?>~:=?>`,f /l%0b$n,/FGbcYZbce)$bcQLppbcÇmmbcNLÇbcKMÇbcRTbc_$c")f%,NPbcÇbc]]bca"(`%*[]bci+'x;6bcÇPL\]LFYYbcÇbcAFKOZ\ÇtwÇbcZYbcYWbc?>R2EO);?>Zfa?>X"?><!```s8Yj5Iq;Oi,H`]#`w5Pu1RZ=V:U4F'H4@.R18?> a$?>`m]Zc9q<    ,YR",, `?>b7A7C)9?>q1'cS?>]k\,?>V"?> V!)b-5LSX&-?>SXP"Y%+u>Cs:?y?Bd),bcXV`,(U!ZY``bcÇÑbc[ZbcYUbcppÇbcÇyzbcVYAIbcÇWYÇbcKQÇusombcf)'z<=YZbcPY`"/t6E_ )bcÇbcIC{A8bcTH\YYWbcNPn12bcj#2h%0`%%WVbcÇIFÇyzVTbc\\XVq2,bcÇbcYTbcNKbc\]bcÇMObczDEÇ}Çbc?>V,KH&CX6N?>\$!?>^?>ab?>W)?>`1C`c#``H $`,So>Ut;P~2Q``j":S/F*N 6B)pAM8cAN6'X9GP0=_9D?> dW[8wL2    `? 7`C?>' "`CP?>c&b%?>`?>a?>`1?>atY,?>Y]?> T %zV$(?>|}?>]^{LLRR])*_)*IJbc`#$bczLIsGCNK[\bc]]bc}bcPObcZ[bcÇbcÇÎÇXZEGÇAIOVLTÇPTEFbcÇULbcc%%j*,bcCLbcZ(Y)b%,VY\]bcÎÇbcÍÇbcTHbcÇbcYbc`#c+s/<]!"WVbcÇbcVUbcÇbcP@bcYQbcÇbc\]bcD?bc``ÇbcvwÇbcIKÇbcTVILÇbcÇbcVUbc?>[?>L$B34X?YP2F?>Y?>X"?>`]]'Pn/U2C?>fUL:?>,       R`Z `:?>2 $;)/?>d%f&?>Pc?>[+` ,?>X &k05T#?>]^IKY!bcSV[]bcPMURbcyC@a-)\Y]^OIbcZ[bcZW[W[VbcÇbcYYÇY\bcQSbcQSbc_`c"$bcÇ bcPa&$c"i$$m)%>9bcÇILÇUXbcÇbcÇbcÇbcf(*m.5Vq)3o/1bcÇbcUQbcÇYYbcWS[[D>bcÇbc\]bc\]bcÇbcÙ[[bcÇOOÇbcLIãbc\]bcÇbc?>c?> , X]%?>U?>o,?>^` ^(S7:h:Q9%Y?]5W/]AA/a-V/`2=?>]8D>(A(L",b58?> s(,YX[OiIB<];%S<;  !^R`K`??>6c8H?>qe?>d?>lp`b?>\?>Y"?>]^XYg),e%(bcKNbcp-,IG``bc\\]]KEbcÇbc[XbcÇbcÇCNÇXZbcIKk-/ÇbcSVf%%WXbcÇ}?:bcPLb`<;j%$bcÔbcÇbcLIbcLN`!f%Z[bcssÇbcTM]^ZZbcâbcËbcTKbcÇbc~ijbcSSbcPPÇbcÇbcÇbc?>f!?>]>?>~:$?>_` pA]<["U'5B F?>o"(lmSKiN?>^<" S99 HR`P`Y`?>7 9?>j'?>o((?>`d?>n)3f,?>k+-?>]^UV]^LOe $bcWYbc[\bcn//STbcTT}IEbcPObcábcUMbcSJbcÇbcTVbcÇLT~9CWcS^ÇbcRObcÇbcUUbcÇbc[]bcA<_]p)0e%bcËbcYYbcijbc[ZPK_`bc×bcÇbcÇbcVUbc?>bcV `?>d?>_><]:8]01?>a:=:`h"(c,kE\7T!9PEJ>L-?>A +V/LY hbfS^DpT4   3% ,H ``?>C7 ?>\"_j\g?>YZ?>]^o%,bcEDbcSTbcccT"FDbcÇbc[[bcWQbcVKbcCGÇbcÇDGHPx}u|bc]?>U?>c]4J2%Sdp(*YVNG^I?>-  G!"/1` ]`T`?>,?>n))?>b %_f]iS]dn`?>`?>a"?>c!]^NQ]^o%,bcORf)+II]-*T# VVbcÇbcZYbcÇbcÇ}EI|CIÇCJÇGTÇWXm%%?>K [(Q?>b;@. `R?>B?>c"7[3ZB<%?>]:D-)A/8?> fadSS1?>c #?>eoS]U`?>]e?>]^RS]^?>]^h&k!,bcj%)`"%LNU$#URbcSIbcZWbcYVbcCHÇHN}EKmrÇHS_kVbÇfmÇbcÕbcZXXSÇNRÇ{`&|o_%$?>V )?>@?>Z39*` CV?>A?>W+K "`EF /\,=?>F,7R9B?>S?>p(*?>``^S?>]>       *OV #`]+`Ņ?>PXHM_i`j?>a$.c%/?>` "?>f"#]^Z\f 'm)2bcf"bcb"d%)QRQQRQbcÇ}DJÇ =GfqUb^j[cBIÇLROR_`ÇGDÇÊÇbcTYbcGHUs65a#%NUb!,}bc?>bcWXbc?>c?>Z!T?>Z+S,L/P>7 #?>H`?>C-B.T07?>\ )?>]/8?> e Y]bZYs/"?>`)?>itTa\,?>[-Xecn_icj?>]^LLb#j)/bcg$)LQ`b`azKKbc\]bc[XVPbcMQÇÈÇKSWcYeV`emFJÇX\z@CFFÇËáÙÇbcJJQVFO}bc Wi.,j//bc_ac$.Y$j.0TV_abcY]ÇHPbcYYÇbcÇbcÇbcGEÇZ\bcÇbcWLbcÇYVbcFAzzÇABBbc?>bc?>g?>Q,aFXFK@?4W)D?>VY]`RH ?>J6/?>b"%?> c`B=tF8!   /UV"  `M`?>j&?>~]%?>a"0IXGWc%7W-L]~BPb#1?>c"&?>Y&?>]^WX]^RUY\bc FJbch&,`%_evCF}PSPQbcCFbcSVÇPWEPÇÉ?EÇãÇäÇbcPSJPÇYY_`PZ$KMbcEJVY^'k(2}6AbcÇbcÇijÇbcCHbcÇbcÇIFÇbcÓbcRRbcWPbc[ZbcËbcÇHCbcEA>9bcÇbc?>bc?> H+B6\"S_PI9912 &? %:8#*-%<(?>5`[%M?>\-Cj?T^4??>e?>c"?>['(?> UUnNY/"   .PO% "```?>y7'?>a?>`"?>a&?> pz`"-^!.X,Y-J\\me)9a"0^hai?>[)`f?>]^YYOO]^Y bcc).b$+p29JPNSY,0wILbcY[ÇZcÇopKQÇ[[bce(,GHbc]&?Fz7Ae"-bcX\ÇbcÇbcÇbcÑbcKIÇbcÇbcÇbcÇbc\\bcPJVSbcäbcÇWVbcÇ?>bcWXbc?>c ?> B +QFJBL2?>`K]K"?>^*BrBZa5H?>Y]?>\ ?>c7>[6;?> [XZbFT-\='    (C?"2`7`?>f c?>_`?>ps?>c?>itj,9FVHYZ,Z*d#/[d?>cf]]ÓÊ]^?>P]^LNbcIzAG}CIO"RVM"&]^Y]bc:BÇbcGEÇbcÇVWbcÇbcIFÇJLbcÇQSbcÊbcOHbcZZbcwwbcÇbcÇ?>BBbc?>RRbcGFbc?>DZ-!?> T,?>+I8V)HA5V2M8.I=TGSIJGCK(#?>Z2-(/R,>?>c/M<&J(?>]c?>V?>F-26A?>a$imcK_;X6   ) & %:`?0 `CT?>X?>euqd?>ovh*?>i"/zi#'?>_)u_-?>a)?>Vc?>_bbbÂ~]^?>]^KKbc|FKc04n9>}GLRYSYS(,xIMbcSLbcÇbcWYbcÇZ\bcÇbcÇ\]ÇbcÇbcYZbcÇbcYY_!_y8;s7bcGFbc?>bc?>V%?> E%9 7 X)=?>@/QBYISL@G-)?>`?>\7M`?VI+>]> $;.;+H#?> m"&Wajcj]V?>F/6C6<]EFa? lWßmS    %/P `,&`?>N!J] %?>Zd?>[?>j""?>v3$?>e%?>`/?>`'?>n)3?>P ?>`f?>]^Z\]^VVbczFJPTvAIP#~NUoBHR&,W'.CLbcXo),bcÇbcWWÇbc[]z@BÇTVbcÇ_`bcWWbcppbce'%VWx69t27l,/c&'^ SPbcC@PQÇbcTSÇyzÇyEAbcÇbc_`ÇRSbcuwÇbcÇyzbcHCÇIG?>bc?>bcGFbcZ[bc?>bch?>I &T8cFXC0.G'??>&1/^:]Z9]"+2'?>R%@A<< 0a)=?> _"'Xcd`[TU?>E5<=9@N>?Y<;?> [JN>?>9"     %.K ` 3< ?>[ ?>cp*'?>rr?>eh?>]^?>x96bc MP[),^).U%]dlsQ'V]m)6IQbcj$&bcÇbc\]bcÇbcÇÇY\ÇbcJMbcTTj&&`` "U_$"bcUSbcmmÇLIbcÇQMÇyzYYbcÉÇbcÇppÇJLbcWYÇbc~ÍbcPOÇbcÇbcÇbc?>bc?>bc?>bc\]bcq"$h?>?J-d@X8, ?>0 0 )6 ,)!-.S,??>^2E3"?> `%+]i[]?>i#%?>VBIG>CF33[=eYÜ?> "0T`T` - 6?>5?>c"?>f!?>]^?>`)"?>p3.?>bcJHbcKLOR\a]fZ'i)6JVbcw-/bcÇbcssÇbc_`bcÇbcÇRWWZbcÇPTbcXV]]XTbcJHSh)(bcËbcÇbcUVbcXYÇbcÇbc}6Z^ b!?>@(`"JF%U*I?>D <?>i")af?>Z?>_9;Z?=?> XVeSH:V: '&66 `cY`<9$H". 6?>a;;, ?>o.'?>w4?>z;w8?>q.?><'?>w/"?>]^Ê]^?>c]?>bc YXJGWV`%&_a]cfoZe`*f!2bcÇ_`CGÇYXbcCCÇbcÇ}opÇbcPQÇmmICbcÇÎbcÇ{|bcÇ~bcÇÇbcÇbcÇbcGDbcZWbcFDbc?>KI\]bc?>bca'"U?>]?>Z)8P>Nb"g'j",?> accS[4V9 '%",`}:B2`Z9'`3L"?>$3 ?>Y%˅?>]^Æ]^?>bc[[ UT\##~EFcfX_aj`,e"2PYW\bcÇbcÇVVbcÇbcÇbcZYbcHDZg,*bcZ[bc_`bcY[Çs83ECHFÇCCbcÇMMVVJKÇbcÇbcÇbc[[bcmmbcTVbcÇbcÇbc?>ÇbcYY?>bcÇÉbc?>bcYZ`" VTVT?>W?>CM9?.3F?>i)?>y?> [YXKI7|C6 %$)`P j&*4`V+ )`?>k?>,?>k68E$b7A?>F?>p*$c?>x6?>z7"?>]^os]^?>y~ci?>bcijÇbcSQc,*TTIKGLb%,`#-u6A` .bc\]bc~bcÇbcSRbcKIbcRRWWbc?>bca"#bc^`ce?>^/7?>Yk),?>^?>b ^[r`ÙlwL  !$#)`Vs6;4`P&`s2@F?>)?>`7;M%,X2;5F,T*?>_(9?>w.'?>X Dž?>Y%b".?>]^CCbc?>V ]^RUp6;}CI|?H])b )bcqpbcÇbcKKÇUWbcÈÇbc{zbcf"/}8Id /FSbcTWÇ\WÇbcYY_$"bcÇ}bcÇXXÇRPSRÇbcÇEEbcbc?>bc?>bc?>MMbc?>bc?>JM`f?>\?>p("?>^?>k*/?>^jc?>dfI&   (% "`|BEH`H)`T``?>C?>]39?>T,:8 9L"?>i?>c?>^?>a'?>]^WY?>bc?>EE]%'a'*W"a%,`$,bcYWbcWYÇuwY\bcADÇbcZYbch"4])](s+=^&bclnÇzA>bc``bcÇbcÇæÇbcÇKK_]pmSQ}~ÇyzÇbcÇFGbcÇbcRRbc?>bc\]ÑbcBBbc?><Y?>h\?>T?>W\^cf]ak)-["?>a%?> bc?>îpT&  , -"CMe&(`9.`?>". S?>? :R%L?>q-$]?>]?>Y?>>'?>??>x6"?>s~^,?>]^?>AA?>`#%?>@?]^?>]^IIbcÇbcÇbcJLÇbc LUZ]}Y!f,bcMSÇssÇ\]bcLLbcÇNMuvLJÇJLFHWYbczzbcÇbc\]bcZ\bc?>IGÇ?>WXbc?>a)?>Yccj?>c%?>k4%?>YO?>^hm`g?>fnS?>[?> `& ]$!Ybc?>[vZ,% - 2 #`bR7`;d(2`?>'#X!?>\!1P]%8?>t0'?>ch`?>y8?>}<?>n)"?>_?>b3_.Yc?>`$s02>=IIRSNOFGTUbcXYbcVY_`bcIHÇbcUVÇbc_af"2z6Hh&9bcÇy=9bcTSÇÇ{HFÇQSbcÕbcTUÇ~ÇHCbcWUbc?>{|ÇbcssÇ?>RQbcs.6v06r*2{48j&?>hm?>W ?>],%?>\c"?>^f]d?>\#?>a!c ?>gh!`?>bc?>W~98bc?>Wc5I6  %(- /`^p=>1`5 <`?>_8=6?>K Mc#9?>[c]d?>V p-'?>c?>bc?>]"STbcÉbc}=<ÇbcÇbcÙbcÇbce&*i%,LQbcd /z6Hf%7a.bcÇtsÇbc|>:bcVWbcRRbcÇbc}CDÇbcfgÞ||bcD@Ç[\bcÇbcÇbck'0g,j)?>[ o-"]'?>n)2?>i`j,a'?>tm?>]^?>\(?>Z\?>]$?>Wsi]"?>YWbcSQbc?>_!k+'bcÇM:  "% F`Pd%%K `Z`]' Y6?j17?>b2?L%?>O\U<?>f"#?>a!?>j,?>b%?>b!?>u2'?>c)bcz57XYbcCFm)-bcÇZYbc{|LJÇUTbcijbcc$]%b&/CLs4;x6=`%bc_p)/s*/Y\bcg 'f )j%/R]ALc#/RXbcYYÇbcTSbcÇÍÇbc}?CbcÑbcÇbc[\bc[\Çbc?>ÇÙÇPLNMbc?>a'(c$.?>bc?>Yd'?>lh?>]^?>a2*?>bc?>a)?>W"?>Sj*)bc?>bc{7"  $#Y`?`6 ?>X6C]:IY6D2Q)ILFQ?>j[?>]"g]?>Z?>bcBNbcs26VYj%)s.2d$i'bcVWGF{|Çbcl%%p),bk%-w4?w9Fc)7: Dp5:g(.a!%p.1{79??\df FEw42CC|<>i,,LJbcÇÞÇbcFEbcÇbc\]ÇbcyzÇbcDBRRÇbcÇ?>ÇäÙÊÞÇbcUVbc[es(*s((gbc{>6\?>]^[[?>_`bc_ )?>\$?>]%?>[0#V&Çd,*[bc?>bc?>bc~yL  $656 `V`<s<=l>CJ05Z>D?>_7DY7F8)/ Y%5X-6C?>k=?`<j,"?>k.%?>bcY$d /bca)bcY\c%i#*=Fbco%/bcÇbcÇZ[bcYYbce"%w38|8?t1=j,:DL&H"M"b*2]"(puYw57w21<995w1-|72>6{:4w93z=6c&bcÇäÇéÇ\][\bcYXbc\]ÇCIbcWWÇOLbcÇbcÇ\]ÇopFFbcYYbcÇ`SáúçÇMMTVbc?>bcx0/bcBBbc?>bc Y[]^TS]^BA?>bc_([#x38bc?>]"b)(?>uhZ,$bc`''[ bc?>bc?>bc ~I2zmS%   (TK `]K`xGKU6;`?F?>`?>Y-@J'L&R-?>X=;Y<;?>k+%?>Y?>YY?> `")`!,?>`"/bc?>['bcX[bch)/}T54j5Dm6Cf+6SCG>@87FD95C2f'|>2m/%bcÇbcx=6KELFÇêÇPVbcYZbcàbcRRÇm02ÇbcPQÇîëá}`SÇbcÇbc?>bcSSbc?>bc?>bc?>ecda?>]^zLAZWbc|ACbcÇu<+|`pT&'  %]5*`|<<` ? `& < V?RfAGb:B?><]^?><&S9U7F $L%?>c@>?>i$"?>cc[[Y?> a'5bc?>`(1]#,SYHPV!AJ{9Cb(bcSOÇbcÇbcYYbc||Çbc|DFs8=S L]!6f)CT5P5\$CpbcYYbc[]bcSTbc?>YX]^SIIDbcTMÇ`1   %Z6<`w22`1fE8??`'`M `?>8%Q&FH8L*=`?>[.?>`"?>c'?>]`mp_cX]^e[?> V -V"-?>_+3?>|f.7u9Cs6?}>Ij&2bcÇbcLEÇ|D>bc``YYg25c-2C a(9Q-\ SCD .D(I#V)f/z/<;DBH68C@;7IDl)"=9>BY(?>]^]]]^?>bc zqP!9"  %V2 6 `7 7jG<`8 `^`8 .S'?>T%CA5[IX:v(T_$FF%?>o(*?>f'?>|o`"?>a?>f<[",?>\%4\%2?>X!*\"*\(i*4c!,^%bcÇbcÇbcÇyzbcÓbcTM[YbcNOf27A X"4Y$;S6V@bcÇbcÇbc?>bc?>]^LJ?>bcÍ}V*<   'CZH`!<`R` f#W6=  )X;c:6A0eFjII2p/cS+Q/?>Y?>`?>c!KPY]ad[Wf]?>pd(8X*`$1?>]#bcÇbc[[bcÇbcÇbcÐbcd+)d15b2<%`&IZ?\;Y/C>J6C;w8/z95=Ac"BIi %m%*bcbcÇìÑÇyDB[]ÇLPÇbcuwSVopÇbcÇbcLLÇRPbcÊbcYYbcEFÇ=?bcDCÇbc?>]^IHbcÇN).   "+5 9 `'`^`HRZBF73?-C-S$ 6 U,N,?81 9Q;]'"?>p.$?>aV?>`?>io?>j"'?>gfj"i ?>br+'j$?>a",IXU'b$2Uc]*?>bcw),bc_`bcWLbcZ[bc^! s9>q:Da,<^+?C(? %H-L4\$G@+_"DN.h'?CV:DH]bck"(bcGCÇIFÇVYÇUWY\ÇUVbcÇbcÇbcYYbc_`bcÇbcÇTVbc[]ÇKKLLbc?>bcUNÊ^:8 "-`b`&`Z}6@R59XFLd?N9 \6CR(3w=P^0G81J/6PE?V:0;LAk`j&?>kk?>b?>p'$?>p%&g"k"'?>b?>Y*?>Z(?>`%?>bcWObcYYbcVJ]]bcf')}3<8H6L}6Pp6O]1IL/E73MFPCQ@f(MH(z8Rs-A:J9D?G6;>A8;w/2<=i!$i %g%bcv7/bcD@ÇOLPPbcÇPS|>@ÇÊÇCBbcÇÞÍÇbcf&"bcÇbcFINPIJÇop[]bcVXÇbc\]bc{82bc?>bc_p-/bc}C:ÇL'/ ``]`6`BFzBHo26zOM`76_-4P)6A5F D;JOBJF93N;/cG9?>]s/'g#?>[?>_jfs[aj!r*"?>b!'?>bcÇbce"*b"#Zn/)WWbc\]bcçÑ\V]\bcNVA$C>Rbc_c!p*,bcmmÇV1F  `) `]<s)/?.f<>~<<><}AO[8A?>]\^_?>dUcLZcl?>~<'?>bc}bcXZbcp,3?BFEA;f# QTbcÇbcLMp>El::?>=B`!+P DY+?>b&?>g?>}5'?>r(0?>e?>[)?>W%?>bcn).p)0VYbcÍbcg#*\~9=v32}<6=:p).bc].,R,/2F%0J#2J,E }7Kv3Im9N`4Ff7Hj9GA u=Ep26LMFD<8?:B=82y.(m"bcÇbcXUVTbcÇìÇbcÇàÇWTÇHGÇVWbcVXbcÇbcÇbcXWbcPSÇbcÇKLbc>CÇuwÇZ\ÇbcFHbcÇbc?>`bc?>bcU1c3    `<&`PF?CF`6`y/C6SV0]0M2%?>b*?>po?>V ?>t&$?>s4?>m,"?>mpd(0ck_g^"+?>`#,?>a!%b %?>bcp/5b%t.6p&/bcÇbcÇUPÇbcm'/=?w30=8B?h%|2;bcYV\Y?eAC- ?#<D GGV9Ft?Hhbc`?j9 #, `R2 `C]BEM ` b (M `>]y-Pt7[I*J+.Y-HM/?>v8?>b"$?>m?>wo?>[%?>^")c&-?>]"bcj)0w4>DNg)UYbc[YÇbcf )?Bw30v2-z62;@a bcYV]^}NFM!h<:~FCm2.u73[YZ}87Y]j%'bcc!i)%bcppÇfVéÇ`VÇTOÇlmÇ|A?ÇFFÇRSbcYYbcÇbcÇbcÇ[]bcÇLLJLÇOTÇbcÇbcWVbcQObc×bcU2l< &0 T`]^`R`]#PW!f6[&%M8S6-C%"?>\a#i,?>v6?>k+'?>WX\!#?>`%)?>jm ?>s2"?>b$+]%?>b!'g%*bcWZc"+{8C~9Df)bcÇbcw22GCx6.{827;@Hg$bcYYbcWLbc{C=` <@~6;BG;?|Kwi#3bcd" i*&a#WUbcSNPJÇàÇãáÛêÓÇibÇÇ}{f_PIÇ_]ÇTUwxÇÇY[EHbcZ[bcÇbcUYÇDEbcopÇGHLNbcSUÇ}JLÇ~LLÇbcZ[bc`Bi9 ,()  ! . >?` F(P'?+]:SA5G%*&)Y/W ?>zmQ?>z9'?>Z" ?>j"?>]YX?>fgSTR?>n(.?>y8$?>W]a")MSbcLSCN=IBOl%0bcXXbc\Ybc_`s//?9w5,v2-JNw.6r)/bccn"$<@?CFFz96p92m6.p2,}<7?:};6w53}::w25X\[ch#-u0?e!0GZ{7KV^bcZ\f'%j,)LGbcÇ ÇæìÇsaÇáçáåÇLObcÇÇÇm=5uoÇvr\VYTÇQR[\moabÇ_`bcIPÇYYq78ÇQSbcOPÇPQ_`bcHJÇvCEÇDGÇbc\\bcÇbcÇbc\8i9# , <4``$79?>b6FR2C%>'T/?>c$?>fZW ?>z9'?>mj?>ÙVYPS\%(cf?>x9z;$?>c!)bc;;bcILj)/g'0|;F_(c+i"-OUbcÇbc]Zbca@9B6t3,{68p).c bcPMe"!YV}:6?89/RF<1HÇ[^ÇVYFHbcÇbcÇJLÇ{@Cbc_`ÇÇbcUVÇ~ÇNMÇLLÇC@bc[\TSbcÇbcYWbc\]bcijbcÇbcT0]^ %%!+-`^`?>Z6G2'<*?>tk?>s1?>|8'?>âY]Y #Z"%?>` a%?>bch%)e$'bcFLn%-am)bcm'bci),DJl-6CM`+bc\]bcZ\j*%I@m/"I?>>j"(bcmmbco0,Y=6?52$9*B2:,?2C6<2<3B<<7>`>K,c3F?>V e%S?>k,2[b?>w|\a?>["?>X]Z]?>c ?>Z?>bcf&)f%)j)/c!'RVp)0IPo",n(bcf"%bcRTf&,_ )a +f"1bcf)"w9.r6'z<0}<:SUbcÇbcde?5B5A/I8I7E5@0z6&b5D<!?>]#)^"+?>[!*]fYb]cUZ?>ns`%?>[d?>`b?>Z ?>bcZ\bc?>bc_`KOg),@FbcFLbcq&/bcc",d /bcÑbcÇbcUQn2%`$t7*A=f$&bcNSLSbcD@bc[]bcp%}2)A6<1=2F;B6C8<0~;/|9,s/#{9,C5E7}:+s1"y6'?2:6p%'bcQPYYÇçìäÇRLMHÇëÇ NSX]Y_Y]NPÇKJÇ[XXVÇ_`bcvwbc[]bcÇbcÇBEbcUWHIQL^VÇjh^^ÇxF@ÇSMLKÇbcÇbcçWTbc\]bcTSbcXTbcy?3Çbc`;]^ ']`k-*`S/C @. )C&?>PZ?>`k]f?>a!`?>[%\ )a$1P`Z+`efi?>h"?>bc?>bcFJbc_`bcSUbce!/bc[[bcjgbcH9d*o4%j+'g')f%%[\bcÇbcebcc"R LDHG7:BE}58<=@?=<=9C?92C:A6C7F79*<096|45k#$s,-YYbcLLbcÇñ¢äçÓÇFCMJÇÓÇ_]ÇOTdj[`imorCEÇ_]OLJGYWÇbcÇbcÇbcÇRTbcFIbcÇbcÇLIÇppÇÇsmÇ_]ÇbcÇbcbcÕÉbcÇbcÇbcXTbc\ZPCbcÇXVbc`W\  %<`K `C `^6[.KR)EM3N'?>h$?>^q(?>6$?>\%-^)2?>]#.`$.\&?>^ ?>y5?>]!,?>^!.?>bcDPZ%CRbc[[bcV A8|;9s02i%'h%$bcÇCLbc_`bcp#'r#)m%@Hbcp6-O [_CH?A>??@=9A9B:Cb Æz?>p*"?>^?>fp?>b]c'"mm?>]+?>Wac*bcd",a-|:Lx6If"5APbc\]YUbcp.,s//?Cs+0q).i"&bcMPÇW[bcf$&CFc"bcYY[?<<9;8?>>?@D@ECJx>FJu@HvBGm9?x@BFC}=9{:9y77r/2bcÇâèáÚéÇGIÇÎÇicÇ_`cf[^V[z}imY^ÇIIbcRTÇbcÇâüÎÇbcÇbcÇbcMSÇFGbcÇ_`bcVSÇbcC6bc\[bc]]ZVbcTVÇB>bcÇ\]bcM:É_~N'0  43 !"5^`^.`9 Z`Y^V6H&?>M"?>uhm-"\?>h%?>cwqh"?>]?>b' ?>zZ#-[&.?>bcSPbcY\j&5y8IATu5Ha 1_)bcSObcZ]c"b ^n%+f$bcMSÇCJbcYYbcIFd%%d#&bca$n+%@I?>M ?>g'?>b?>b?>i)?>sw?>k(/?>X&?>c"-bc?>bcSPYXbcCMa-p/?z9Hr2?g'0bcXVbcd"$m,.]f$'Y[bcf%bcÇIPZ]bc[[_`bcUVbcÇbc~@>[bp# 42:k14?>]?>V#bcEE?>bcVS[\bci'0j)4EP}k%/?>[&bc?>EE@?bcTXEI_`VX~?=bcFEbcÇXYZ\bcHKÇYYXVbcÇbc e"z9=CL{?Ln5E=M&I [-I z:Z )?>n3u6'?>nv?>os?>bc_`bc\]YYbcÇbcÇbcUVbc Ta!$H EPx>L|BPa%3n1>i)5}>Eq23To/.bcILÇããyÇÑÇMTAJLSÇIIz>?^_ÇFHÇILÇbcÇKLbcÇ\]bcÇbcvwÇbcÇbc_`ÇáÇÉÇbcopbcz:9VVXYÇWXPQbcXWbcÇKIC?bcPMbcÇXYbcI@ÇYzP&  %2/!`FB`]`P*V/Q\0W> 2C(?>R%/B ?>^ ?>p2?>] ?>^)?>\!'b(+?>bcSSbcLLRRbcábcÓbcÇÉÇÛÇWVbcQSbc YY]^_#)u9Bs9Bs7BHSz;Er08`"]l,+bc_`bcÇãêÇôÇ`WÞÇÛÇz;AKRÇdeÇTUCDÇ}>?ÇbcÇbcÇbc[\ÇbcÇopbcyzbcÇCEbcÇæÇäÇbc{|éÇÎÇbcÇbcÇbcÇbc_`bcÇÞÇSVbcÇ bcyE;ÇY~W, !2/`T\!9 "?>:!E $L)?>E(1?>G?>f$?>j$"?>px?>X!%YZRS?>@?UVbcÇbcÇbcZ[BAÇèÇ~WVbc ZZm2+z?;Z !wI?>78?>b%bj?>k&"?>Y ?>S%?>]',ru]"%VXbc[[bcÓFFbcÇyzÇbcÇbcÇbcVQJCS]^ "n.1`!j))bcYYÇç§êÇÞÇËàcYÇrsÇæÇHIbcÎbcOObcÇbcÇbcÇFFÇbcÇQQbcÇbcZYbcÇbcZZbcWVÇbc Ç[\bcPFÇW|X-  4 `V`R{@?`9 j4F^)??>`6C_6Gf8LM/Q,?>U]aj?>c?>S$RVc(+bcÇbcSQbcTSbcÕbcÇ_`WZbcÇbc@CÇbcVQbc_`MJj))f$$f%#PMbcSTÇ“êëÇáÇlmÇbcÑÇbcÇY[bcCKbcWYÇîÇbcÇbcHLÇSTÐbc\]bcÇZZLFbcÇ>CKObcVXÇbczI>ÇSpE . `;3IF`H `1p:QF "?>[1Dc6Ls?X=?>^#?>`i^")V?>_("`'$?>H\*1p=DSX`%,CCbcfgYWbcVUbcÇbcXYbcÇbcÇFEbcY[ÇbcbcPJYWbc[]bcÇãéäÛÇÇzzÇÇSTbcÍbcÇbc_`ÇAFbcY\bcÇFDHFDCÇbcÇbcÇ_3Fh:Rh5S6C&L)?>X`?>^]VZ?>n%/?>Vc?>zy`! ?>a,1yGN\,2LSY#+?>CCIJbc[\bcÇbcRVÇPPbcÇEFÇbcYVbc\]bcÇãåÇãÇ]UÇabPP{}ÇYYbc\]bcÇbcÇbc{:9ÇbcÇâÇGFÇbcONÇbcÇbcnmbcYWbcÇ bcYYÇSJÇXd? !#!`2g)&;`F;K?>`?>c6Ic2MvAbI7M8J/C?>\b?>fh?>\"an_k?>c"%]?>ZaW'/|HP]%/bc?>bcSQbc\]ÇbcÇbcBIÇÕÇbcÇLMÇÙǕ×ÇÍÇa\Çz>?ÇÎÇbcÇbcÇbcÇbcÇbcÇÇbcÇbcXYbcÇTVbcRIbc ~CBHFWXÇbcÇ~QX1  ""`2`]`^%?>V]RMYk;O,< ,? 2L?4 ?>]acc?>b]?>Wb[fYd]&?>Z!\"*V"+PW^hR%{>HbcÇbc Ç~JFÇbcRPFFÇbcNPÇbcÇ[]ÇQRbcSOÇbcD?ÇbcÇÐÇÎÇÓâîÇéÇPMÇYYÇmmyzÇSUY[ÇbcÇbc\]VPbc_`PPe%&f&(b"bcEEÇbcVYÇTXbcWY?CVYÇbc_`CEÇbcRSbcYWbcÇpYÎanE  ! `]`2j>9,` ]KR=R%U#U*Y%`C6 ? 1\'SPGN??>VYfj`acfi#,?>g$?>`fRZeo] *?> h1h.?>[`^dMVqzQ )N%b+5f(2bcWUbcÇsrÇbcss}HHÇbcÇbcÇbcÇbcÇÞÙÇáÇINlpÇbcg()]bcl),g"&bcÇbcÇMQbcZ[bcÇbcWVÇÇbcÇUTÇWSÇ}QnC`^TQ<`.pB=0`V[*9U!@W Cl.SV;X!7X,?>;$<%<%?>s(*ag\d?>i#,?>VTfiY!?>`")?> h2Ym\fIPKUa"-MZ['4n8EwYbWf?>m%3?>m.$?>k+4?>_""?>]!?> o(5Xh[fn%0f*L`CXY 6W,L]j*3Zb)'bcÕbcÇbcÇçÇPMssbcÇ[]bcopFHDGbcÇSUbcÇbcFFÇ[ZLMÇPSQTÇAEÇېâzóÇbcÇbc[]bcX[BHÇFIÇbcÇbcÑÍbcÇECbcÇbcÇZ]WZÇpdDf;  #+ % 2`:`m/.``VPK `g:cBH#< "?>Vi?>lm?> Va@MSg\s_8Y6bcY(CLXY]]bcbc||bcUXÇbcppÇbcÇbcÇQSbcÇÇëdžÇadÇLPY\ÇêéyqPëÇÍÇHLbcÇMPÇbcRPbcÇbcY[bcEFÇbcYVXVbcÇbcÇSY=HLJXKXm%6?>NXYfcvm3T,^%:bcY]q/7bc[[bcHIÇvsÇIGbc{;<ÇbcLNbcdžÇïëÇSQÇ[]ÇRVÇäåîÇbcopbcPTrtÇbcÇbcÇuwSUbcÇVXÇbcVVbc[[bcÇbcÇ`DS( !* ) .%`^`Mp2V`!BM``s>(`R!`3I?>H ?>c$Va?>n%3?>`d?>X!?>[ 5bcAIbcWUbcÇ~}ÇvwbcÇbcÇbcÓbcÇñÇÍÇãÇèÇVXILÇãð­eQÇbcÇbcÜÇÈÇu<=ÇbcÇbcLMÇbcÇbcY\ÇbcONbcÇbcÊbcD^),?>PZ?>_pa)]1X/a"2bc\]ÇbcÇNKÇbcÇbcÇ?BbcCGbcWXbcÇOQY\bcY\UWÇááäÇÙÇFIÇ£ôõþâiYÇíóÇY[bcYVbcvwÇbcNPCEÇFIbcSRbcÇbcEHÇbcÇbcÇbc||ÇF@ÇGCbcÇ|\[?, >    0 ^`A@`^n3HF`F 8%Y3M`6K?>Sb?>7$?>XnsU"?>V`qWji);h,!! )< `R`j,J*@17"?>j.?>C?>Ue?>w?>]!"VXY%?>c)^m]m>MP]`!,bcÇJLÞbcÇXVÞÇbcÇbcFGÇîÇbcÇbcZ]?EÇbcÇÑÇåÇèác\ÇéÇëÇ÷þòñùäáÇÙÇbcÇbcÇKLÇbcijbcÎbcÇbcÇbcopÇbcLPÇN2H  <"- 3 T`]w4Zi2Z4)S?S1`,\#?>Y&?>w?$?>c1?>Xc]aa?>r(0?>St?>Wcf%1OZ`!+`!*bcÇbcÇMPbcÇvwRQÇbcÇKLbcZ\ÇijXZÇUYÇæåäÇjnÇ “ñôñòîîäÇbcÇbcvwy??ÇMLbcUKbcHJÇ>AbcY[bcÇ gU9@  ' $$, &4 `i!C?>m5?>s;'?>^/c5i"6?>em?>Sa`oc,`,h&4b"+?>k(0Y!p/9Y"e'.\#bccbcÇbcÇJFbcÇbcED||ÇbcZ\[]bcTVÇLPbcLRÇWZÇÓÇâÇJLEIadÇyV-2?>`uV'?>VcXgo(8c.['?>]"w~sz?>bcÇbc{|bcÇbcmmÇbcÇbcXYÇLIÇbc}BCÇLMJKÇNQbcÇbcÇèÇÞÇçÇuwÇvxÇILCGÇad}?BÇ ¥ðþïû±°ãêÇbcÇbcXXECÇbcÑbc{|JIÇzDBbcÇbcOAbcYVbcÇFICFYZbcÇbcÇbcÇEAbc[]bcUUÇ qPhK'    "*`UAL/fG`?>c"-?>\+t~_&?>` ?>QZ^l^mTcWf?>[g?>bcÇbcÇbcÇbcÇÇ^[ÇIHbcÇz@AOPÇz<>bcINÇÎÇáÇÊÇIMÇmoÇ æñ•ÐÇbcIJbcÇbcÇbcTSbcÇbcÇÇbcyzbcÇKJÇbc[[ÇbcLHbcxwbcILÇbcÇbcTVÇ? ]!,?>\"-?>]%?>c"$|zx53mh?>Vb]j\iZib*?>`%'?>Z&_m?>[f>FbcÇ]YÇbcÇÇPSbcQSÇéÇz|lmÇLPÇ æîçëáÇRTÇbcÇbcÇbcÇbcFFÇbcÇbcÇZ\bcÇACbcÇ~?a/@?>k1A\)n,)i)"?>XcZf?> ]%&Z""?>XZWZk,3]+PaL`Pec-r/9bcÇbcyGAjfÇbcXYbcÇáÇFG[]bcBEbcÇopZ\ÇCFÇçñçÇ@DbcÇbcÇbcÇbcÇOPbcÇbcÇbcQObcÇbcZ\ÇbcÇbcÇbcÇWXÇ|T1rA&2  "!#1 `b.A` M7V-<<"? &? %E/H39'O1?>N?>]#`)?>c%?>c)?> Z"$dcgfRShl?>b!0ViQj}7$?>cfc26?>c"?>Ta?>Y?>kr?>[%%feVVde?>`.b1IeId?>bcÇbcÇSMwF?ÇÉvwYYbcOOÇéÇggÇlmÇx;?z=AQUÇáì‡à‡ÛÇZ]Çbcz}bcÇ@EbcÇbcÉbcÇ~bcZYbcY?^;< )!"&R`M w?H` c"*_V%@V#VA_!KRANC? /C ![,?>u6$?>YfSf]pQ]?>ac^b`e\f?>i0`-?>bcÇbcÇÎ×bc×bcÇKIbcGFÇbcÇPMÇìÇÓÇ}VYÇçÛãÇãÇbcopPPÇbcmmbcÇbcÇCDÇ}BCbcSSÇbcÇbcÇUWbcÇbc XYbcwbcF  9` _*Y/P l2VE/9'L"z9?>JfZw\s?>a*s}c!'?>qm?>^ '?>V`MX]$/?>bc\]YXbcssbcÇbcssbcÇbcÇbcÇbcÇ[YÇëÇÉÇêÇåÇabÇÇÕÇbcÇqpÇmmwwbcÇbcÇNJbcÇbcÇ}@?ÇbcÇbc\]bcZZbcÇbc fGbY  Y` `#_7Pm5U,5 "9&@6-4&)Se%?>v2?>Lh?>MZ?>c$.?>of?>TbR&?>bc?>bcÇbcäbc{|bcFCbcÇbcÇbcÇÇÇz~ÇåÇÊÇäÇëÇÇÇbcÇbc]]ÇbcDDÇÇbcÇbcMMÇbcGJÇbc[[bcÇbcè{fC  Y`b%`r:Y_,IT%AN":;.,*E'?>%?>a!\?>="{9?>l1?>Z"] %?>_"/b%6HX]$2?>\"*?>a"(?>bc?>bcÇbczzbcÇÇÇbcÇbcEFbcÇIJIIÇSTKQÇëÇÍàÇÐÇõÇ|wÇIPj)"?>vz[?>]&y?>Uf}AS["2?>c(2nw?>bcQLbcâbcFEbcÇbcÇffÇYYz|OPFIÇçÇîÇçÞÇZ_lpÇbcÇbcombcSSSTOOÇvwbcÇQQbcÇbcWUbcSQbc_`bc\]bc\2Y6     *% ?`^` }C]d.L@ ,]-Lj=SjCLY6<2F/H(?>Vbdbi`R ?>c" ?>`?>`?>`#,|]$)?>`#5X0?>T$?>bc?>bcÇbcâbcÇbcÇz|GHÇáÇz|NPÇÊÇsmÇçÇ{}Y^ÇbcÇbcÇ×åÇZXbcÇbcÇbcRQbc}CDÇbcÇbcÇbc[[bcJCbcÇbcÎbcÛbcÇbc3  + M`H` ^h0M2p;\m;So?I`6<2$J)@/?>`nZYaYk)$?>i%?>jo?>_,?>Y%W"V#?>ca?>_"+P]]2?>bcPLbcEDÇbcÇäÇëÇbcPTÇxzÇDGÇbcÇbcÇbcÇbcÇbcÇbcÎ|CAbcPOPPÇGFbcÇopÇbcÇbcÐbcÇbc [957 `Y` _,`]C']~CSc3?I/F01B*?>^?8kE9?>ccd`?>p`?>s5?>r6?>ju?>k'6?>FZZ1?>[j])?>a%-?>]2?>R)?>a"2[$bcÇbcOJbcÇ|~ÇACILÇbcÇÉÇðÇbcijbcÇòãÇ hgVVUWGJ|FHzFFbc][bc\ZbcÇbcYYmmbcÇbcw<:ssÇutÇbcÇbcÇbcÇbcÇbcXSbcKKÇbcA@ÇVVbcyzmmÎÇbcÇbcyj+  $ )V` a*^Jg]Zs6Nn;QN/K204?>X89`<6?>f! ?>X?>z@?>`)?>]"?>Z*Xk]s[2\qM[^!+?>[q]0v2;k(1s.3bc?>bcZ[bcYYbcÇbcÇbcÇæÇçÇçÇbcvwbcàÇCFUVbcÇrsÇÔÇFKÇ}``ÇbcfgãÊbcÇZ[bcÇ^__]ÇPObcÇbc\\bcZYbcLLÇB?TSÇssF?bcF=bch?'" :/$#6 ``,Z7\?U<>%p<].%C4C?>_9Fc:O?>iY^P?>}?'?>\c_c`c?>\#[dLXXea"3Y*c$/^)?>[/_3??CI?>]i?>bcÇ_`bcIIÇkgÇéàÓÇbcVXÇGCbcÇ[]ÇfkÇzLHbc^ZbcÇbcKIbcÇbcRSÇLJÇbc~bcXUbcZYbcZWbcVNbc]\YTbcÇbcÇbc\]bcZ\bcÇZG_9'  ?!"8$ 9` `^];Y?A /V!Hm1]L 4F#?>]-<5 10)!?>p/|;'?>w<?>c,`fac?>Vko\aMV\)Tac%2uQZ?>c!3JXTb`l\g?>bcÇvwÇbc}ÇÑÞêÙÇËÇJEÇ_`bcÇæÇáÇZ]}EIÇ}NIÇQCbcÇbcÇbcÇbcÇmmÇbcZ[bcYWbcYS\[bcPB]\bcopÇVUbcYXbcJDj`bcR-  B !?!(RV`^#[>k6Y<+y.\n&P[)C?>,/?>t8?>MX~8;^d?>c"%?>clk-9p3@AP\,?>Y"?>k(/?>`,bmV`?>n%1e+?>^ ?>bc[\bcÕbcÇbcXYvwbcÇigÇàøòæËÇQNÇXWbcSVÇÎÇpsÇY_}GIÇbcìbcÇbcÇ{;>bcÇKJÇ{|IGbcfg…bcÇbcÇQMbc[[bcYSbc[ZÇOIbcY[ÇbcÛbcÓ`LV60  >B )?`](X ?Y]Y/: %?>) +,,]3?>w7$?>`$rz\"?>`"?>Y'a"2Y,?>PX^gb )?> f#?>`%?>\&?>\(?>a +bk]f?>bcÇbc~bc_`bcy;9zzÇäñàÇ~E>Ç`V[VÇbcÇ}Cw>a.I$?>c,`)Vb?>ly?>a.p-?YmLb?>b&/bja",]&?>`jVb?>ZgNXVa?>RX?>bcÇáÇbcRMbcÇOMbc\\bcÇbcOOÇCDxzÇËÇåÇ_bbhbhlpjnÇbc||ÇbcVXÇbcVYÇbcHCbcbcICbcE?ÇSQbcÙbc\]bcG?bcÇVVbcåbcXpJ'  &1 H4 <^]`^,[!;V/P < !?>Z1?>e j#?>b)ozk%/?>YhXj`/\,?>V$]#,?>d#Yf?>Ubfq?>]!Z?>lr?>i9`2?>bcijbcÇñÇbcÞÇbczzÇbc]]bcÇfg}lmÇÓÑæÇLOin[aÇ_cÇbcMGÇbcÈbcJMbc}@FbcÇbcÇbcäÇábcJIÇD@bcÇbcQIbcÞWH]Z]]bcYV\[bcÇbcÇLLbc[\Çbc`6fB    )(DC4^C `]/[K%^-DZ +?>i"?>Y?>\SW]cLSel?>k)0jr?>Ve_l]iYa?>`.?>CcLg?>bcijÇêÇÇfWÇbcÇbcssbcÑbcÇHIÇstÇëáÇ@CFLDJÇ bcFDbcJFÇee{FIbdbcCITWÇPUbcÇCFbcÇbcÇ{GBbcJLÇPQbc\Ymj]\Çbc[XbcÇbcËbcWVbcA<Ç`3V2    '"8C!9/ 9 ``^"4W#;?>@]?>E?>p)'zw<;_m%?>xs?>` af]`VX?>Y%+?>Q"dj?>Vch[?>Tc[hZf]d]b?>hj?>IX_1h!??YbcÇbcÇbcÇbcÇaVÇbcijbcssÇbcÇbcÇbcÇrsfgÇçÇbcz}xzopijbcÇNOLPÇXZÇbcYVzSKÇ\YbcÇNPbcTTbcÇWKbc\YbcÇbcÇbc^9,    !+9- ! "8`d`]!`Y?><33%= +< ,= %?>c`k%"c\?>rj?>k/[lWeaf^`?>R!!`)*?>SaFSfq]fc#,Yb?>clYc\jBGb1z6Lb2e$5bcYZbcÇVXZ[bcÇÉbcLKÇéÇ[]bcÇssbcVRbcÇFLbcÇbcÇbcÇbcÇ]\bcbcÇmmÇbcYXbcÇbcOPÇbc; !"99, `f ` Z,V%?>_/Y/*B<; 2*B,`2:?>t(6QfZj?>ed?>eqS_CN`*Z%v39PXKSFKOZS =Lz6G{8I^/e&4bcY\ÇopÇbcfgbcSQÇÊÇbcÇmmbcÑÇèÇãÇHKÇ}CEÇbcOMÇzDDÇÇbcQLbcÇfgRDÇsp]YÇVRÇLHbcXUbcWVÇbc??ÇÊ\VrE6(  5> 5R`c&7[4 ?>s=a@11&_6P?>r(2?>[fgh?>ecghVX?>Y))T$%?>])Yd[fcm??GK?>W`^i?>n*2v17]'f!1`,]^T%`%+bcÇbcÇ??bcÇbcÇbcÇäÇãÇäÇopÇçÇbcÇbc||ÇbcÇbcNIbcmmbcÇáÛÇCIbcppbcWXÇP=Y/ # *6   .`a}ASV":> )?>])Gd3O2^2C?>q'"p(f?>]]?>fj?>VZcfV%)?>a!/^*gsBLa!*?>elZa^fCEb)Çp*6bcSYV]yDLWYbcRQbcYZbcÇbc_`bcZ[bcÇbcÇFIbc@FSUÇÎÇijbcÇbcfgbcUSbcÇbcMDbc@DbcÇbc ?   " '   $3H`]i.CJ)4?>6 $b6Ic.=?>j ?>j?>c#?>a$%ms?>\e]e]d?>Ye_ih(1Xgm[aW]?>bcIPbcY]]%,o=?W$#bcÇbcÇbcÇRSbcÇbcÇCLÇjjss[YÇçÇèÇbcÇLLy?>Çbc\]ÇbcÇbcÇbcyw2  -(  %6<^`q8MP/D+?>R'=?>p'?>u,'?>z:$?>` #?>bm?>Yd`+?>\(`#0Z*[(?>Z"]"?>fi?>bcMOSRNg2,ǬbcÇbcwwbcÇøÇbcZUbcLz5?>z;$?>[#+?>b%/`")?>Q"?>bcVUc.)KEǬbcÇbcssbcÇàÇjhÇbcÇbcÇ~JKWXt@AZ[Ç~]]ÇXYÇ_]b`~CBÇëÇìÇRTbcÇQ\s7>ÇbcÇbcXYÇbcÇbcÇàÇDHbcRDbcYYbcp9* +  < " 6<VHR`}=?Z`\":P7S @L:L1P.?>V%-]*2?>>$?>v:z;$?>TcP``,T)]'4?>bh]a[',t~]$0?>bcWX?>bcICѬbcÇbcÇKIbcÇxwYSbcSKbc\]Ç]\``ÇãÇáÇÞÇEDPOÇIIVTÇxyÇÛÇbcxzbcÇFSÇbcÇbcZ[ÇFIbcZYbcZUbcTHbc ZYbcXOi4%    3 6#:* ,<`JL8`]4TSBX@O2??>9 a2:?>|:?>w;?>Q`SdXlTgk%3?A]l?>]eW]QXY*c)6?>bc?>bc?>bc`!"bcçbcÇbcVPbcÇbcÇbcÇYYÇìÇssÇijÇ[Y`_WVkjÇ|ÇbcDCRRbcÇ_`TSbcÇbcÇ@BbcÇbc[\ÇÇÕÇbcXQbcXTbc\Y6 %) &,%%" + `bP `^2XI?>y4?>~:$?>u7?>b%?>Oc?>f.]#c'?>cg\a?>bcGGbc?Fp,6_aLSbcVYȬbc~?=Ç}?b'Uh?>[.[)c)/?>a),MN_b`&/Y ,?>_%?>bc`bcÇ`'l)5O bc_ag,/SVbcÇbcÇbcÇbcbcOJbcÇggÇYVÇuta`ÇåçÛÇy;9ÇbcÇbcÇbcA=ÇbcÇbcÇëÇbcVO, """" 7 $& ' T```/[;j,SH93#w7`[==?>c+Ym[qHZl/9imV "?>a$1\"/k+7j"2?>c)(`#%?>bc^ VYbch&+g%,@Kn*9]*X]bcW]c'.a$bcÉbcÇbcÇbcÇGFÇZVÇäÇIGÇNLXVÇäîâÓÇÓÇspÇB>bcÇbcÇbcÇCEbcÇbcÇVWbcTTbcTQ[[bcl2&)   !% "& 3"'C``%Z%V=[Cp2[[%KC2;"?>IXUkRfd%4V XX?>tv?>_'`oScl.m,?>` )?>bch%/]^X\bcFOb!,=Lq.@_/N[bcc,c!*m'.bc{|ÇbcÇbcZ\bcÇbcÇäbcÇbcÇUTÇûáÇwwÇàäßâçÎËÇUSbcPPbcÇbcijbcÇQRSSÇbcXWÇbcÇbc@ $   $ 3)?)  )T`T```";K `T=`/S9 ,?)T/?>_ *?>c%cnWfap`pg%?>a'?>bc X$n1>~ANS!FRVaU#~Y?>dy?>Xg?>c (]iAE\kZic*?>Ya?>bc ]"/Q)RbaoYfHVL]}ÇbcÇbcHHÇbcÇbcÇbcopbch7/,       "(;9!%,  -+ `<?`a`%9U2U">L9; ,?>lu?>m"1p%6IZ?>N]Vfb-?>bc[]bcX[q+3OV]!.\#1V)]hZeanW'a2l()   ),6#! % ,<+/`8 `}=?`^_Y#P:= 0?>m3?>_(,?>^.b/?>c%bcZ]qf#5d"1[d]cMS\b\bai[db!,IU`lES{6Eg.bcVZ[]bcÇbcÇyzbc\]bcÇbcÇbcÇbcÇbcÇàÇbcopijbcÇbc?AÇbcbcWWÇbcÇbcÇ:  " '),5% * /C"`9 F`^[(S<9*C,?>c!?>fgdi?>`-4V ,V)?>m2TgYj?>^f?>NP"?>O$?>bcU[a*b/c!5]0b!2V]tvWY\^cgX\PURXHO]c['MXj&1HPbcÇbcÇPObcÇbcÇbcÇPQÇ[[bcbcbcFIÇbc_`bcÇbcRLbcr6,6  "#&:) ;$Y`V4 `Yd+@X?P*?>c{t?>k?>a'"?>pzTc?>c+['?>Q%U"%f16bca!4`1?>`"-Z*?>Y"?>bc?>d+}7GDW|9Mq/Dd%6h+0CCHK]`h%)EHfj^bY_cjbhf(1_`bcÇbcÇppfgÇbcxwbcÇbc\]bcÇacÇÙÇíÇïÇQPbc}bcÇbcÇFIÇbcm6+%  (B+ 0, V`1`ZW4?(Su,$` ?>b/1?>k,6?>b(VbYc?>]#.bcKNbcrw?>n}a%2?>\(^j?>bcSV]^c+>Nu0Bw5G[FY?>^ka)^)?>bc?>tY+?>k+4?>^jUa9L?Mx4Cr1Bw6Fa#2\bKNf,/RWGMn16z>El29a)/LS]")c%,h&.bcXVQIbcRLbcZZábcTO\]bcÇbcÇbcÇbcXWbc[YbcÇbcÇHKbcÇ TUÇegÇY\ÇLOhj~ZYÇæÇY[bcYXbcÇbcyzbcÇCFPSÇbcKMÇbcXUbcD     MF2  ) 3 H,8M`^` `i%/``/\7RVV%X=Y2Y`?>coU`?>c$.b(0?>bcb &?>c*?>Z*].?>Y&?>a)]^d.z6E>LDSz9Ha$1enOUU"[bYbV`]!)GPFNW'u}^fc&/LSbc×bc[YbcYWbc\]bcTPbcZ[bcmmbcÇbcuwbcNQS?>\fa%/?>bc?>SfX)?>]^Y]d!-?Jz9Dt2@w6Cd%3P%PZ|CMd)4cnP\a#/p6@y@IT&~GPd,5}@J])bcRVbcÇbc\]bcQMbcZYbcYVbc[\bcSRbcYY\]bcÇIMbcÇbcÇbcÇ MPÇ{}JMPS}AFÇFKKN[\Çjj]\ÇbcmmbcQSÇbcZ]Çbcz<>ÇXYÇJJbcppssbcN!   :e"S/%  0"/7,>6 Y`]`i#/`b,[;^EV;Z<`Z?>Z?> `$^h_j_jIS`!,?>bc?>bc?>^/\mc$2`"0?>a ,SY]^PWf%1x7Ce$/U`[)r}|X?>ZdYd`kFRg$0bc?>a.]sVeam\)Xc?>b#-IS]^c",y6AISfp](W /p;K`(9CU^0^/IY^0]!1w_4n.I_K `_dY?>}8'?>`g]g\g`m`*bc?>PZcp?>` $?>W"TZo.9c"+`(MUOVZcV -qc"&?>Wb?>bc?>ajYgMZ]jZ!?>`!*V`JRf"*PWNU\cKUP]U*^"0W'O^Z)?>bcf(6c"2h%5bcPSbcÇbcJ>ìbcÇbcÇ_`bcÇ~a`Ç]\]]Ç\[PPÇÜÇïÇADLPbc_`bcÇHJÇFJbcÇ9  $!%18LI@+/22% ( ( Z`k#;c2]#`=]7]?>|7$?>lfYV?>m%3bc?>ZdXj?>]*` )?> ]e]celOTciU[IQU]en?>])^'?>bca-X"bc}.2bcÇbcÇbcNHbcÇbcÇbcÇYZbcÇSRVV\[a`ÇGFIHÇÊÇbcÇy{Çbcn?7   " ##7DJ$ /E!< 2%6' /P``f=c@]?c"F`?>[i?>bc?>XX?>`!(]d^eZaej]c]`ffii?>bc?>v16WYbc[[bcÇbcC`-f 2?>q(6bc?>a ,?>\cafSY[`_a?>k.,?>bc_"_ bcYYbcÇʬbcÇ]\ÇKJ]\ÇÇMLbc\]bcVSbcÇbcOPÚäÇbcÇbcR?bcÇ%  9P"B: ) +"$ 8`_/Z7c!LA/SAZA`?>` ?>`"+s?>bc?>`""c%?>`gX]Z`?>]^?>bc?>bc?>GG?>bc[[ÇbcÇbc\]bc\]άbcÇ[Z``WV]\\[RPÇÇäÇbc\\ÇbcÇbcÇbcÇFHVXLNÇbcÇbcuC5"    B9 %4  "-%/"6M``(^<^C\HWCg"L`?>_%?>Q ?>b%*?>bc?>T`_7^3?>mp?>b (?>^fW]?>]^[\bc?>bc?>bcZ[bcÇbc[]bcÇbcÇbc\[bcÇCD{}ÇVTÇ_]ZX\ZÇáÇ[\bcQNbcPLbcmmbcVVÇbc_`ÇLLHJÇbcÇQSbc][bcf9/   .6' / 6$<'R`R` `i7iC\>cE`jS?>bcN]^!2[!/?>W"&?>b )?>Y!*?>a"1]^?>bc?>bc[[bcZVÇ}zbcÇbcÇbcÇbc\]RLbc[YbcÇçÇ^]igÇ[W^Zcb]]ÇNOÇIIbc bcDCbcTTbcÇDESSÇbc YQbcXW9    $ #  # %6>"0 6^H, 8 `j<];`Aa:hFYFP?I+?>T?>^*/?>bcW]bcKZ`%6S)?>k68op?>\b?>`%?>b%/?>M)?>]^v-9bcXJVMbcÇbc[VbcÇ FHÇppcb]ZÇTPc`zz\ZIJÇêÛÇbcÇbcÇbcÇXXÇbc\Ybc 2/)   ! % :!)= >"$%"&+ 2 T` g:aC]CZ6_>R<=+{6`U8L/??>Z#(?>bcc +`,bc?>]d?>`0_,a-bcÇá]YZG}N:bcJ?bcfgbcssbc\\bc\\YVbc_`Ç IJFGijww]\_]kjqpIHFF}ÇÊÇbc\]bc[\bcÇbcÑÊbcÇI    8* %8 -9)$ 1V` ^A]D];]|6'?>bc` &?>Y)bc X)?>\)Y$`%*R?>`%)VW!?>\?>\ )?>bc_aj&5bcSVbcÇábc]ZÍbcÇXU[ZVQbcZZ[\bcYYbc\\bcÇãÇDEÇRSYZ}z}ÇãÞÇmoQRFG~ABIJÇÙçÇbcÇXYbcÇbc SIbcA69  &!<%I!,/     %Y` Y,\EeEc BW(Q2Q?D7C=A5?>abcMRZ`O?>`%/PYbc^ ,?>bj?>bc?>W?>]%bcVYk).XZr--bcYL]VbcÇI=bcÇbcmmbcÇRLbcRLbcÇ}TWSVÇY^ÇbcÇWYÇijbcÇÓbcÇbcvwbcMBj6+"    $ *"# . ?"+     5<Y` [/Z?_>[%W,R4Q??z`]>4?>p)"g!q,?>p%,bcSTNP`dLPFI\)Y&?>bc?>bcf%)b!$p.0bcWGbcspÛXTbcÇbcopbcopbcÇbcÇbcÇbc\]bcÇJLÇ};AÇouÇÉÇGCbcÇ}>?ÇYZbcYWbcÇbcÇbcopÇRSbc us:    # (@%)"!627"$/    # (0<` `/]^`X$<]c!MUCUJ2"?>i'?>bcR[!$?>VZ] '?>_f?>bc?>bcPRbcWR[XbcVIbcÇbcZXbcZ[bcOLbcÇinÇSYZbJRÇipÇbcONbcÇVXLNÇbcPObcGFÇ{CAbcNNÇOPbcj6*%  ' !9$ . 6$       "/ R`_a;>#W @Y=F+C-<"V2?>c#"?>b!'?>["c^?>d%?>abc?>c&f'?>bc[]bc?>bc_bcÇ[YbcÇbc„bc\]bcÇbcYYbcÇbcÇbcÇbfW]uyZbÇèÇçÇIIRSbcÇGEÇbcÇbcGHQQbcÇbc\[bcvwÇPPbcÇbcF=@?>d?>`"%^$'?>Z'?>U ?>bco(*?>bck%/?>Q`c$2[,\h?>]#,bcäÇYVbcbcÇbcÇbcÇbcÇbcZ[bcÇbcÇfkGMIQFPHJ %?>_dc`?>\&`l?>z}?>bc?>bc?>`/?>yS'?>\'1QXbcÇbcÛÇbcÇbcopbcÇbcUSbcVUbcÇbcÇV`ALÇÍÇbcopÇVWÇY]ÇCCbcMLÇbcÇijÇbcÞbcXVbcYYbcj70 1' !   2 ,2#+ /%)"1 V```/ZEB-?>]eYV?>_"'S?>c*?>bc?> V&?>_$4X-T+?>O#`*4c)/WYbcÇbcTSbcYYbcwwbc_`ÇbcDFÇbcÇCLGPÇbcÇbcÇxzÇbcÇbcÇbcDCbcÇbc6    *(  /7!  1! 8 7 2# <`a_,WC0?>P1?>d c`[X?>c%%` &?>bg?>bc?>e,?>^ /Z,Z_bcLTUYXZbcÇbcssbc[YJ=bcÇbcÇbcRQbcÇÙYYbc?CÇHP@GÇRTbcVYbcSUÇbcÇbcÇbcZ[YZbcÇbcf4-! #%! % &, " G&;N%: 9``d@XFTA<?>2S:?>_!X?>\^a?>bcÇbc?>bcRTbcY[bcCDq&&bcssbc[[bc\]bcZXÇbcÇbcÍbcijbcÇbcY[ÇêÇbcPRÇOPbcEHÇELÇbcMPÇbcÇÉbcÇbc8     )"  !  :$05#? I"M#L%507^`Y4i4UH7T7K,b0IA-2 ?>]c?>]%a%bc_`bc?>i"+bcq)4bcàâbcÞbcSMbcTKbcÇbcZ[bcÇbcÇbcÇbcÇèÇ~9>bcÇbcÇ\]bc;?ÇbcÇ|8?bcAEÇ{|bcÇZTbc5      "     "6; `^S$?H6R;C /Y%POI+I-?>M ?>]fd!JSkoV]\(?>f"-z49bcp46LIbc?>bcPQbcINn(2f+e,}7DISbcs$*bcÇwwbcÇÞbcXVbcXUbcÐbcXYbcRTÇbcÇbcÇbc<>Çbc@Cbcàbc=CFLGPÇbcBEÇbcVYÇz;BÇbcÇSLbc f0%)   3#%     $8) : (T`^k:Qf8PC %WELFB VRsq?>c&Z]]b?>bcBFg,/HJbcXZbc?>bcf+~8Eb)p)6KSbcijbcn&'k$bcSMbcPCbcZYbcÇbcÇbcÛbcÇbcPPÇbcÞbcÇbcUWÇLRÇbcNQSUÇbcÇKIbcVXÇbc[]ÇXYbcÇWWbcYVbcfg4"   "    )" * P`c*ARR7P>OA:,?>S ?>\mVj?>Y%?>[?>o2bc_'bcKVbcPYbcY]bcopbcr)4]^l!-bcl'&bcs'-t)/bcbcÇbcÍSSVWÇçÇbcÇbcSVbcÇSVbcÇMPÇbcYYbcÇwwbcF($" #  " "  <#,  *"'C``!^#c&?Y%Y @T@?,?>F =?>F`?>\# k/+]?>l,VZbcq$8]^k2Y]w'])?>< !M7E)?>]#$R[_)?>bcSY]%W\bcp*9{7F=L@Ps2@t3?@KNSbc[]bcÇbcÇbcÇ\]bcYWbcÇbc\]bcÇèÇbcÇÎÇbcTVÇDHY\ÇjjÇbcORÇäÇbcÇ`Ybc ]<:       '``%;Y(]Q4`?>L0?/G98 ?>_nXla,?>i%?>bcy2Ag 09Eh )m'1c(=F|;F}?Ip2S(C) &C92?>_ /?>f /?>bcY]m)4u:?{CFp69|?CAE|:@|8?FLIQz5?^%c,s2@i+9s7Fe%1bcWZbcjjbcLJbc[]bcPJ_`bc\]bcÇbcÇåÇêÇVUÇ_`ÇHIbcÇbcÇbcNKÇSQÇbcÇbcÇbcÇbcb:5   ; #!  "&!+    :;`89`;` f%4`f)EZ!_`?>[-L<9?9<.?>bc\p8;|GIs<=u:<}?B?@=?|7;x38Y'` ,?>f0bcWXk).v6s5@zZ[?>Y%z_0?>a,bcY\i",|8?~>Bb%(bc\%%^&(|AF{>Hz9Gy6G#  16"     & ' H ` `e7](]<]DS(K (KC ?>R2,?>m}?>Z2^/c.bco#1:F?He#(bc]"%FLu5>w4@Çbc\[ÓÇbcÇyzbcCCbcÇbcÇbcÇTSfgbcÇG  ) .! ,+    0C`R``b(b,e?VM"2[6?Y;z7$?>]?>Pj\qX"bch,h*g)bcf"'_#HP}:E}9Gc.a&bcd(/`)/}BGbcSUbc NKm)&STbcd 'UYi%,bcZ]bcVW\]bcÇCBbcIBbcÇDCbcZ\Y\ILÇbcopÇOLbc[]ÇIJQR\]ÇçÇãÇbcbcÇUSbcYXbcURÇzDAbcÇbcÇGFbc\]bc~ABÇvwHDPGÇs:6'  "+ " .9* ) %! 8`d(m%:`X;I2l,VI 2XAX=Y6M ,]-I%/,E4=?>l~?>bcj -bc@Hbcj'ALt/:?Kn/=bcKNOQbcn))bcILVWbcÇbcXVbcijNJPNÇbcÇbcÇbcvwÇOLbcÇmoPR`cjlÇ×ÇáÙÇbcÇYWbcÕbcTSÇ}DCbcÇbc{|Y\JMÇbcÇbc> *  -4  :?")  5#-"" !V` d@P 6\EZCW>`AZ 5Y9l<\% #L>SK9JQ*9?>k*)?>bc {+6bcu#/bcz}w)7w,9BQx2CW$bc~bcWVbcÇbc?>bc?>bcY[?>bcÇbcp*.k%(bcj bcÇbcÇbcÇa`ÇHCbcÇbcÇbcÇZ][]prÇÞÇRRbcÇÔÇbcijZZÇPPbcUWÇfgbcfgXX[]ÇbcÇ?CVWÙbcÇuHA$    + 8""," 6"5%6!]`$ 2` b(cCPp0?>bci"1^)bc[^a+9Lk2v'}69[]bcEE?>bcWXbcSXbcm$bcÇbcÇbcVTbcÇbcÇC?bcÇbcijÇbcÇ~@CcfLPÇÛÇbcÇbcÇbc``bcâÇbcÇbcÇbcÇ{|bcOPÇ fcÇlgULME5 "* 1" * *:"`8 "C``j!CV<<&R6T4cESbcc/}7Kv/F:Rg6C^s"=M]V\bcfgÇËbck,Zgk%/LP?>k+2p-2?>EEbcVVbc[]bcb$d'JSbcY\bcmmbcæbcwwbcÇbcÇbcÐÎbcÇbcÇSUjlÇSTÇèÇbcÇbcÇbcWKbcÇbcRSÇbcKNÇLOVYbcÇLMbcDCÇ[YÇYSkcm;4/   , "&#    C`:% 0 `T`ag?c ?Y(^(FL8Po%)bcm7d2h6?^Lk]/w-LbcÇ\]bcn,k/ZjZjDIP!?>p5:?>bcWWbcRVbcVXbcf)j!,s+6bcp(,bch#bcÇäÇbc``mmfgbcfgbcÇbcçÇGCbc~ÇbcÇyzbcVXÇQSFGÇbcÇCDÇbcÇfgbcZ\ÇVYVYÇUWbcÇbcÇ USIFjgmjc\I    "" .6!1% -21- "?`7Z```%^*W/Tz9'?>bc Y\r$1bcKVg/bcg4e6f9`5f";`.bco!.HYi2BUIZ`%2?>bcu&,bc})2bc_",bca#bcNVg)2Z(ÇY]`,c,bce"*}s-2IJbcPTm&x(3bcS[g"3i$6W 6_IYEE)i>PV,N<9, %V/A?>`1h/?>q?>W,bcp%1bcINe)/bcQV`+w,A@Tbca$%d).u6D`"3Pef%8?>b*BCbc =LbcimZ^W]Y^]^e/n(5b&bcV[8Sq%DbcT]l"6bcXZg%*bcxzbc~bcÇçÇbcÇPRbcÇbcYVbcopÇbc[]bcyzÇbcÇÇ[fGRÇwxUVÇbcÇbcUYÇvwbcÇbcÇbc_`bcÇ]Y`\a^[V[Uc[mF<   ""(2 =H"9 D#0 28":"Z`2F`R` f4o$M]FZEA #e6L; /1&g9Nl`#-?>bc?>bc}~81O 4?>a,?>c ?>bct*2VYbcY]bcl$6q(:k 1bc m.4w7Cv6H` 6b!9Pgs/;s/8?>v27?>\'c,?>]^?>bc[ z3Bs-={6F}9H>Lj#0bch"0Z&o(8h!1a)k%2bcYYbcXVbc{z^Y_[ÇbcÇbcÇbcÇ\[bcXYÇbcINÇ{>ByzÇMFÇbcopÇbcvwbcÇbcuwIOÇbcÇbcÇNC`Wc][Vc^l96 #G#V!+P&=$9"9!0, 9""4`9`b,cBW >bIQ2d,GT@TF2 &]7Q8*C0]BL*3?>n:$?>bc?>bcMWbcv/4bc DMf%3c"6]2Y/`6`2l}Wcp,4c"1?>bcc'j&2g"1z6C~9Db'bcX\d!+fpj'1c (bcRTbcZYbcÇbcçÇ|zppbcXYÇbcÇbcÇbcÇbc\]bcZ[bcÇbcSTÇPOÇäÇNPÇOPbcijbcFCÇbcTWÇbcÇbcÇbcÇkgÇbcHKÇ`S[PYRidx?<2 "0 ?J$/ %% / %9^< `F*K`m&A`@`E]CY8U4YASC.'e?_[(JA)cHf%K/?>t)'?>bc?>V!?>uzbcf!(bcX_bcs.;|6<[(?>P]@Cc"5?>c%?>bc_"bcVZm'2z6?o)1bcÇbcVX]^m,0`"TWbcÇbcopbcom]]ÇäÇbcÇbcÇbcÇVTbcÇbcÎbcQSÇáåäàÇMPkmÇCCbcÇbcÇv7;Ç=Abc||?;Ç{|bcXZbcÇPAjWk]]Qf]|w= !  "# /B#<=25  -/ -+3 C) 0 V`^!_?X=Wbc?>bcj'/Y\bcs.:[(?>k%/?>Pa?>bcn(0d%f"&bcVXbcYZRTbcRVp$,bcZX[YVQbcÇbcÇbcÇbcÇbcçÇIGEC~\]bcijÇáèî~èÓÇÇñÇVYÇbcYWbcÇbcÑbcÑSTÇWYbcfgbcÇbcFJÇ~B?]LhR{pSF\Rm<9#   "" %? : A?!;%$++& ) /#K` ]*]@q3V@"vbc?>`&?>n)3?>bci'/j(/bcj%*j(/j'2]'?>bcZ]?>U)^0?>k)5\(?>bcRTÇbcRVp$-bcl'bcÇbc\]bcÇ[VbcÇbcÇbcjjPKbcÇFFbcÇbcÇbcVUbcvwbcXYÇOHTRbcÇbcÇÞïøáÇßÇ\a_b`bceÇCCbcyzÕbcÇbcÇbcONbcMPÇbcÇzËÇ(  "! $# * 1FB AF@& %9%- 2/``[":]$A@#? h3Cc/?C ]<^<^@]IU?Y:F?>^c?>k)-?>bcj)/DLbc_`_&?>b!,a)`'?>`"-R`?>cr\k\(?>n(1bct,/bcÇbcl%,i!)m"-l*bc~bcÐbcÇbcODÇbcÇbcÇbcCBÇbcYYbcYZbc[]ÇCFbcÇÕâäøÇPSZ]GIÇRSbc[\ÇbcÇbcÇbcTVÇTSbcÇj[f@7  !#  ( =H%FY"V&2$, (9``d(`_ %`X%_+Cc1Dma?>bcj(,s29bc?>a",?>Sa?>n)2j",bcÇbcb$n&/VZbcVZbcÇbcÇÇZ\bcbcmmbc_`ÇbcbcGE_`ÇXYbcÇbcY[ÇDFY\ÇbcXYÇbcFFÇbc|;9bc ÇCFbcÇbcom{wbcrJ=,  "$" ! # < S#Y ^+A%& %R`b#`_`%?Ze2Fk9Im2VJ9%_*9?>VX?>\c!?>S?>_?>bcPSbcVVGGbc?>_&?>R?>^*?>j"-bcÇbcd%t*5SYbcbc||ÇbcÇbcÇbc[]``bcHEbcÇbcz}bc[]ÇPPÇ}STbcmmbcÇbcÕbcÐÇbcPQÇbcuwÇbc3   %$1 - I =J#C$/"5?T`M`]`d*m&<` Y2;}F]h4FsAR_.?tDSa6FZ7I]9T< 92-oFdk;F?>[%4?>]a\a?>]"%UX?>bcssbc?>bc?>k)0?>`)NQRTbcÇbcf%bcPEÇbcÇYZbcÇbcÇbc[]bcÇbcÇGEÇbc×bcZ\ÍssbcJHÇ>BbcÇFDÇPObcÇHIÇbcf>4"  "$,1  $% $  99/3MY-' R`V`YFF6 5M`Z`c *a?Z%Mm6K`uBYj7MJ3eAY<9*-*-K2JS6C?>942(C?>_c[`?>d&?>]+[ +?>a!*?>e'bcÇbc?>\%?>jx?>bccbcÇbcÇbcÇbcÇbcHJbcÇbcONÇ{|ÇbcÇbcÇbcÇbcRPbcÇVWbcÇbcQSXYbcíÇVXbcKIMJÇbcDFÇOPbczJD#    !, .*  )5 9Y`C7T`V]V1))% ) 9`m%2` `<`@[,\!H "Vj5Q[,GO%C'#0 6bBfA#6?>k@FI(G1)<_""?>XZPSck`iVc?>n)3ScYgft?>[)`*al_f^fXcl"1j/PYbcÇzzÇbc?><k%6_q?>orbcÇbcãbc||ÇbcÇOSÇbcÇbcÇbcÇbcÇbcÇMFbcNPÇbcppbcPQÇÇÇbcijbcÇbcPRÇÊÇIIbc<  "!:",*     % <` ^// 2 #6` b:c@]4[7[BO;U@V@L8REFG6 0?> q)'?>hlY`S]fs?>f.?>L]Vj?>],?>]gXbL[>Pr#9v%:bcÇbc?><=`0_1Ka?>bcijbcÇbcäbcÇäÇ>@bcÇbcYYbcUSÇbcÇ]\Çbc}JLÇbcÇFGÇbcHJÇYZÇGIbcY[bcv;='   !!" 0- ,    ;`' #&  %;` c/cS3?>Y]]eV`?>Vj_u?>s(6?>QZTc`qATg)bc?>b/a.n)3?>f"-?>k%/bcijbcÇbcLQ[]bcÛbcGCÇVV||bcppbcÇbcÇbcmmÇppbcjjÇbcÇYZFFÇSUÇbcÇLLbc ?<9  " "   ( `<  $ H` c%k D(],=?>c%&?>[`fp?>e,?>Vj?>u2?>cp]jXeXc?>bc?>bc?>p|?>bcSUbcÇbcÇccÇbcNIbcÇbcssmmbcÇijbcÇbcÇbcÇbcÇbcÇbcÇbc``bcV     ) ^` V:") T` i,_fHc)XC>LBL=I6XBH2I(?>[-;?>Se_r?>SX?>r(-bcMLbcVV?>Z[bc[?>a!/?>ŬbcÇijÇbcmmbcXYÇÍÇPSbcÇbcmmssbcÇbhCFÇáÇbcÇbcVSÇbcÇbc]\bcQQ<  2 `?! !/` e2\\(Uc]no(6n"5o%2?>bc?>a$?>b %?>bcZ[bcPSÇbcmmbcÇbcuwÇbcVVTSÇbcÇbcÇzzXYFJKOÇQP\YÇFEbc[]ÇbcNCusQCbcPBbcÇQ,    ""<`P+ $;` n#4^H(T)J2%G5T8W9VCY#CE?>Vb[jSfa!4?>bc?>bcUVbcn),?>`!%os?>k(0bc?>bc?>bc~ÇbcC?bcÇbc_`ÇbcÇbcÇbcHFÇQSbcÇbcYZbcZ]Ç[]PSÇRQVQÇbcÇbcÇVTIDbcÇSCbcbcf2/6      "C`P2" ) 16Z` b!^":Zf;T]+II)^@TDJWaZf`pX!2?>r3'?>k%5k%4[]bc?>bc?>]%bcÇbcHGÇFGÇEDÇbcÎbcÐbcÇbcÇbc{|bcÇbcÇbcSUÇÇÔÇTXDFÇÇëÇbcÇbcÇbcÇbc``bcÇbcv>;E      !  %<`M/'8 H"Z`h9Mok+)?>\)S!,?>_/V)n)9q*9bc?>bcÇOLbcÇÎÇGFZ[Z[bcvwbcRQbc\]bcWXVWbcÇbcÇbcÇbcÇQWinÇëÇçÇbc_`bcÇ]\ÇzC=bcPEbcÇbcG$    " ! ! )2 VZ`C/K^` <W,t3U>%MCV OLAS[Y?>b"3PeYoY+?>q(5x/9?>bc?>bc?>bc?>GFbcLLÇbcZZÇbc[\bcRSbcÇbcLKbcÇàbcijÇbcÇbc``ÇLKÇGFbcÇÙbcÇbcÇbcÇbcÇY]IMÇ`WÇJIbcZ[bcÇbcÇbcPFbcq65/    )( :9 `]7 `T4#4` `!`^`#JSID >XMVCV3V $?>`"/Vh]p`2k'6nz4;`,|6]%?>bc?>a#?>bcOMbcÇbcÇbcÇðÇyzÇijbcÇssIDUSbcÇbcáIFÇbcÇbcÇbcWUÇbc~bcábcIGÇz}FIÇbcÇbcopÇSPbcÇjjbcv66A    " & + 6`' /V`]#Sge?>b%.?>l~b"5Y,?>bc?>bcOMbcGFbcÇCFÇbcÇbcÇbcLFÇkhÇmmbcÇbcbcÇnmbcKEÇGFÇbcÇêÇ||bcÇbcx32Z"",   !$),ZP`4   <`P:L?IW,x:Mb#5Pa?>bc?>bcÇbcÇbcÇKMbcÇSSÇ}FA}D?ÇbcÐbcQQÇbcÇ}D?bcÇbcWRbcjj[WÓÇÇÇbcÇ]]bcopX)   !&%K!3```Z/ <`f7SLB]LS?f"RO9SD"A?>W(h,?S)Y,` 1?>b)?>c"?>`%?>i#,bcYYbc×bcÇbcYZbcÇáÇæÍÇbcÇbcbcÇbc}B@ÇbcÇIJbcÇbcÇbcÇbcWTÇbcbcÇ}ÇSTÇáÇTRbcMHbcFI=    !%9 "1`H "  ! '`t5M22&P2n)VD,L3])E<?>Y1?>G,P7F*U3?>c$2Rcb#5O`^,?>am?>fo?>px]"?>bc~bc[[VVbcÇ]]ÇbcVUbcÇbcÇbcÇbc\YèÇbcÇlpX^Y]LOHIÇbc CC?(    (,7`m(/CO`Z:#*$ 9`i8Sa0PS4Y J !F S/o-LH )C )`*ID/Q:J.DZ?>YlXkWiVf]iU`?>c%?>bcIDÇùÇÙÇbcXYVXÇbcÇbcÇbcÇbcÞbcÇbcÇbcHAÇ[ZÇ~AB~CEKMIKÇIL[_egSTÇYYbcYYbc w:9F*    ''8 `<2 < `]4R C &W2cEM3C )?> L+G-[>X9[j+TfYkSccs_lU`m%,?>["?>bcWVbcÑSNÇÊÛÇUYbcÇbcÇàóÇbc[\fgÇbcÇbcÇgg][bcSVÇbcÇbcÇbcÇ utVR]XÇa^`]a`^]SSLMÇFGUV\]ÇbcI%  !'4`M`\`z3N]`PM`W;]n)LZ;L3; ?>; %N"AI 5c"K]"AQ5] A[BG6T IEC99-(: *\#9?>p"-O`?>csTdWc]g?>bcY[x--bcFIRTbcÇòÇbZÇb[ÇDKbcÇbcJMbcÇbcÇbcÇbcKSÇHIJILJJGÇbckcc\ÇáÇbcÇRLbc v026      )* `C}6M``<]!c"@P6F-?>X-?>/ <3VEV>r4RW5\o"0?>\jZe~89f!%?>bcyzÇbcÇbcÇfcÇY[bcmmbcÇÍbc<=ÇbcINÇ}[\_Yb[ZSb]Çb^LHÇäÇbcLLbc BD? "  +!% -7 ]`q)7`b#````7Y<9#k6M; *,p@]c6WT"HK9aCa6h!9]7Z?WE=,u4\P8L?>e-?>z??>^'k(/?>V?>f"(k,,?>`&bcssbcÇ}|ÇrsÇàÇbcÇ~fgbcÇXXbcÇZ[bcBCÇ{?@Z\JKÇ}}YYPPÇZYÇjjÇUSbcp>?4  ,# & ' 3 ? R```e,d2bA^6W;7-)f8]Y%IP8P.e7g9Z;WBRAC/o)PU4R9Q>OCD5?>l/?>Wm0c[?>z9'?>[,?>`#?>a%i,w]?>]+?>bcm%,bcspbcÇéÇÙÇÉÇçÇbc[[bcÇ||bcPJbcÇbcÇbcÙbc||bcÇVVKLÇbcÇKKÇ|~ÇTSÇIGÇbcFI6  % # * )  2$""( - `]`k$(```h?fAa?U8<#k7M?>P%J'!d2YG2S3d'?a9Zo"VSffh?>}7$}8"?>MbL__-?>b".?>^ '?>b")?>b)q~?>YW?>[+KNPSbcRVWZg%*bcÇ\\KEÇY]ÇILfgÇbc[[bcÇbcyzbcÇbcÇÇOOÇY\lmÇSTÇut|A?ÇäÇbcADL /87  , , !# !%) 7 `^`h"#`b#_fCaC`CW9H.],GB26.= 4Y"II0X/Y,`8T9QFSLN@\IS;X9h#DY;<2I@?>cjVYIEp%?>ZoYlas?>_-?>Yd['?>](?>bcÇ[[bca!%i),LNbcÇbcÇäÇbcÇ_`ÇbcÇbcÇbcÇ_`[]ÇzzÇ][USÇàÇbcmmbcL%"  ./6$  %  % )' *P`c%],eH`F`GYSSf_h#?>YmSf_.?>k+2v14bc`!%j,.LMbcÇ~bcÇbcopbcÇÊÇLLfhY\}ÇbcÇmmbcÇbcÎbcUUÇppÇGFFDÇp74ÇbcÇbcYYbc vCB,   "' , " )K``_;fK`IcKZa9?>X?>b"!?>a!l,"?>a'?>b2?>_2?>T%?>b &RSbcÇbcWWbcNP\ bcÇbcÇijyzppÇ@CÇILÇbcXYbcIFÇ?L6_"OJ/F?>j{Y)?>`!4m?>c&-?>bcÇbc_`RTbcKLbcÇbcÇprVVIJÇWXÇ|??LNÇCFäbcÇbcÇbcÇbcÇðÇ}ÇNP@CÇéÛÛÇbcÇk72)  !   )3!,0/? `c2c?X:cF]=_>Z9aD`FaE[;`7e$/Tg"3b4jAd?`;].MQ@N%*W"Av;fE 6@ )?>["P> P]])?>_0Tg\/?>]-OX] )]^`"(?>bcxzbcÇbcÊbcÇFJ}ÇstÇc]~LBÇáÇ}?@ÇmoÇFGbcÇ~~bcÇbcÇbcÇbcYZÇoqÇfhÇÙÍÇbc Çbc[/*    9/"4 `]*\#i"F^=\<`BeF]=fBf >V'f&9E]<^CS6d ]#ESAK1?>j2cDIPH1?>p\?>a /?>k+6?>`$,] ']^k+/f &]^?>]^f"#?>bcÇbcbcY[WYÇrC6ÇÐ×Çbcop{|bcijbcZ\ÇbcNPÇãÇäÇbcÇD     !"   2) F`j'A\%a?fE];a>fCc>V0f$?CV7J2\E]B@`` 3Y+/IDU-] GYGM0c/)?CICA-`28[)"?>a",]^?>]^?>]^?>bcÇbcYZÇogTFÇèÙÇDCbcÇJLbcÇZ\ÇîÇbcF"    -!%   # !H`e"/c7ceEY2Z0V!2}L]W"9S8P?VCcI?>O1F>CCA91"= %?>a!*?>]^?>bcVUbcmmbc\]bcRQbcÇeYk`ÇÎÇbcÇbcÇbc\]bcÇbcijbcÇ\[GFbcÇKKXYÇz|Çbcmmbc}>?,   ) ,"   .R`a%a(i>`/r&I]a>^?U9O9B,N 5l"Hf]^IL?>]^VVbcÇbcÇbcVTbcZYbcÇKAPFÇTTbcÇWYÇbcÇ{|LJÇOObcEDÇbcÇbcÇijÇbc@B:.   3!! 2 ]```d!(``*],f#F6n9U,E -Y7p>UV $d9_9S:> 7`.[6 q*T`"FI.2uI\T7@Y?FO0>6'3&?>]^CTe/~6;??]^LLbcÊbc\]bcPLÇbcÇbcÇbcÇÊbcYZÇbcÇbc}ÇbcÇbcÇbc\]bcÙbcn977"  ) &;"% "1?`d%`c2k#GZ=]h8P[-DA 'Y5c+b#P ],T0ZD1*d0\Q6P *?>`2=];:?>\*CZ!CC"?>]&]^o"7?>???>WYbcÇbc\]bcÇbcppbcÇbcÇbcZ\bcSVbcÇ_`bcÇbcHJY\bcÇbcyzbcY[bcÇbcÇbc~âbcqC?7   #G'#)<"-   !&9`]f*`[%?#R/3e?L\6CG%LCm-,QW8K9H9N;?>Z?>`e'?>i3]^fa/?>c!'bc?>bcwwbcYYÊÇbcÇÊÇbc[]bc_`bcALÇFRbcÇ~ICbcÇbcÇbcÇ_`ÎbcÇbc}CDÇbcUTbc ÇbcwIE%  ' 1 >('  , M``e*`c/`;r3Yi2Sf:Pg=Ll@LZ-3DIc%!OR 4T#CVERf!?>n,'\?>xa(?>g4@Xs*k+/LL?>bcÇ~ssbcWSÇRSbcÇEL_`ÇbcÇyzbcÇbcÇbcÇbcKJÇdcÇbcLMÇbcsEC#   ", /%   ""T``o*2`k#=^c!/`TUAf/Pv=W}9Lz8F> T -h%/a*S"2R?]JXH?0?>`%?>R ?>xzk),?>_"?>`0b!2?>c#)bc?>bcUSbcXU[ZÇYVbcssÞÇbcÇbcÇbcÇbcÇbcÇbcÇbcÇ\]bcvwÇbcY[ÇILbcSSÇCAÇbcZ\bcÇßÇbcÇbcj=>'      $ ) ( # , `c```;^?f)<_Y]V#`2H9Ip=RB%b0^-S"6I6S ?hY4,?>^#?>a$.YdKVZ(v59?>z69v15bcÇbcÇbc``PCbcYXbcÇYRÇbcK>bcÇbcÇY\bcÇbcÇbcz?DbcÇbcÇ[]bcHIÇutzz|}ÇbcZZbcm<<,      " &'  ! Z`b`];^(^*Z`",]h]jIP?><=n+2Zbc[[[YbcZYbc]\bcijÇÇTUbcÇ{|ÇbcÇVVbc_`ßHM[]bcÇbcÇXYÇIHbcÇÇyzÇSRÇZYbcv??)       " "  &   ! H ``#f?`]#\XccpVaOXU`@A?>bcÇbcYVbcLIÇ~bcÇbcÇbcÇbcbcÇbcSSijÇbc[\bcÇFDÇprssÇ\[ÇZYÇ~ÇbczB@.(          *   $C```_`?`j8Kg7F`U7; //(M?WG= -X*DrT0?>Y%Yd`nYf`nVb?>bcSLbcÇbcÇfg\\bcÇSTbcÇbcijbcRPÇbcÇÇbcYYbcÇsvjnÇFGYXÇssÇCBÇbcjjbcÇbc vCB1(        # (R`cj"7`!```^/CH"`V7`1Y\.\NF6)X)EqEXuAT,H;4 )E/A%S2?>]?>Xf_m?>bc?>bcÇbcÇbcYWVQbcJAÇbcfg~bc[ZÎ{|bcLIÇbcÇbcÇbcOPÇgknp^_Ç\[Ç]]bc Çm<<0$        1`^W%P#^+A\I;> :?B60xA]n6Jq?S1?8ga?>b+?>\#?>bc?>bcssbcQNOJfgbcÇbc~bcmmbcÇbcÇ\[bc\]bcÇbcÇbcÇ]_WY]`WXÇbcÇbcFKT!&,   " "   9%`S,R#?Y*Z7Q?>6LL2,t9Sj.Cp=S]0M'#b6`PCO:T=H %?>w2?>k'*bf?>j")?>k'0?>])?>g-m"/?>bcÇbcfgÇbcÇ``bcÊbcÇbcÇÇGHYXjjÇ]]ÇdcÇbcÇbc UW\,2$       7 R`9"a/O`]/R/K?SIPA?"S2I+m8\//ACP?U=T?F (?> UZcjUZai?>]e^fU`_kVfs-8j"2?>bc\]bc[[bcijÇbcbcÇbcÇbcÇmmÇwwÇNMÇ[[Çbc EGF         "+ 5 < ^``j!*`U/o6Wf%?g&?]$AN:VFL:Y_j?>`j`kVbaqQcz4;](d/?>bc?>bcWRYSYUbcjjbcÇbcÇÇbcVRbcZ\ÇDCYYÇbcÇbcYWbc }?>J$       " '/ < `]`l!2`i"7\*Z!_`_4VN?V"F];W4_(KD8Ik"-c$?>Ye]iWf]m^pZl]pVh?>bcÇbcTPbcZZ[\bcijbcbcÇ\]bcYWbcVSbcÇbc_`Ç_`bcPRÇGEÇTSIHÇbcCBO    %)1C`b`a!f*`T^(_/m&FZ(P -J5P6W=W?9)?>i.?>k"-?>`%cn`kPZ?>Wg?>]pYl[mf"1bc?>bcXUbcKFbcZ[ÇbcÇbcDCÇbcLNbcÇPNÇa`Çbc[[bcs52C*        "'(. C `k `d/]#V,V=S6C(< -a1Q4s6TS6U9P5ZC=/?>Lo4\ ?>n)$?>Z"?>_-m%4c,z29ZgUbMX?>c.?>^+n)3?>bcmmbcWVbcÇbcÇbcÇVRbcÇRIbc}NPÇÑÇÎÇXUbcÇbc p;;6    ! !    ! ( 7^`^```q.:``k5"l`?>bf?>n)9DSOeSfXjSbLXn(1?>_/?>άbcÇbc_`opwwÇmmbcÇbcÇbcÇÑÇbcuAB-     +: RR`a#b*``BYLPCb?x0YM+L;9l8Im/_n?>^3?AMeL`?>c"-f"/?>_,?>jz?>],?>bc?>bcÇbcfgbc\]bcWXwAAzGF[\ÇbcÇbc\]bc~<>Ç_QÓÉÇYZLLÇbcssbcV6      /; 6 .`M ^`_ZN*K2W2V*) )K*BSs4E]96'SIF2?>\jf 2GZpj"4?>\ePXk(0?>bc?>bcÇbcÇbc[[bcÇbcÇppbcÇbcÇçÓÇbcOLÇbcÇbcÇE /      " `;6 K`u4:`^5U4?n@Z<)YJ=))L2Gp9UW ,f5s)M6 61 2B!?>o(0?>i"2?>c$-?>_a`a?>]b?>bc?>bcÇbcÇbcÇbcÇbcÇbcÇ^PÇzzbcÇikÇYQÇ``Çbcfgbc LPK!      : `- %. < 6`9#)Z9C_;Ba2Cj6NP4: +- "V-Ft9V}7VLV8_4]G@?>hz?>jj?>ih`cSX?>h%bcXTbcÇ\]bc[[bc[[bcÇmmbcÇbcCf")?>XZNMbdZ^Y`cl?>bcÇbc~bcÇbc[[bcRIbcA8bcbcZYbcÎbcEDÇVXÇbcVTbcÇbcssbc\\Çppbcr29A %   /(!H"Y;" 0  M`;Y!_a*c!~?Fz;Nu2PL-T4q` .MPcdY]fkZcZf^ku(1?>bcÇ̬bcI@bcWPZYbc\]bcÇbcbcÇbcopÇbcèbcÇbcijt9?<  & 'V`,  2 <` i'>Q7\`8E9Un'I4,K)IcAN(i*4j$4:?>fm\`]c?>YdTa?>Xf?>bcÇĬbc\]TSbc\]MGbcÇbcRLbc[[bcVQbcÕ||JHÇbcyzbcccÇbcssbc Z\bca!%3    ': `< $"  F`67#7 !Y5M5YY<019^?>bhYad!?>\i?>\j?>bcÇͬbc\]bcSPbcÇbc[Ybc[[bcXVbcTNLEbcÇIFÇ\\bcÇ`VÇbcyzÇbc_`LPV"'   $(5 V`^R]V 9` R2h8Xc7Jc2E`Y!x6g1%> 5QBX8?>:"P9A?>L]Xl`-k'5?>]!#?>f,?>bcijbcÇbc}bc~I?bcÇ]]\]bc\]ÇbcmmÇbcÇ]]bcÇbc\YbcÉbcÇbc=D1   & )M`9(% +` M2<3f;Fq?Lh-OF :568 9@76J%?>@% N8??>RfVk?>`!,?>b&'aih%?>]%}69??FIbcÇbcÇbcÇbcZYYYbcLBvpKAbcÇbcÇbcÇbcÇbcVTÇbcÇbcÇssbca"8+     *C`ZZ`Y` [M#rCKi9?]V%M#)N.VP2PW-FI%?>C"S-5?>z6?>XhZmVfc".[%?>^"$`hT`?>k'2n(2e+bcÇbcYYÇbcRJbcÇbcÇbcÇbcÇbc[ZÇbc[XbcÇYTbcFJ\$7      !/`FT` ^!Rn?C`KK!6 )\3Tb>Wk9I?>`#V?>w4?>`Y`?>^j?>_j?>b*?>n,6IMv/8bcbcppbcÇbcbcÇbcÇbcPObcWWÇbcÇbc``bcÇ]YÇbc[VbcÇqpbc x26W.      #6 `Z/ , F`P_< `a#?>S?>p0?>Q`_qKZVfmzS]U`?>`$,?>`#-[']^c/W]S\a)bcËbcÇbcÇbcssbcD=bcVVZ\bcCBÇÉbcbcÇWTÇbcÇbc]YyIAÇSH][bcPFbWÇbc }GI2 %$1 `^) :`]`_`?>s/'?>z<D`wRdS`YfYd`jYadl?>k*1?>mz?Qw2F~8Np(:bcijbcÇbcZZbc\]bcSSÇbcÇbcÇ`[ÇbcWTÇ ZUbcbcÇá||bc\ZssÇbc K0  $'&2 Z`3 "7`6?>e,b,?>^l%%?>~@|?|>"?>cs?>YbUZ?>f'?>RVb.@J-  %((2 PR5)%: `Y]`;4`^< ?>j.]2Y-?>\_]?>hO?>a'BTc"?>{<|>?>b)?>e)?>W`jp?>\b?>bct-B}7MbcRTbc[[bcÇbcyzbcCMbcMLbcXYÇssbcÇbcÇbcÇbcssÉÇbc]YÛ``Çbc zzICbcÇT9' .V`( , H`^`V< P_%?>e4Y6?3A 1?>S Öf?>j6?>_1?>f +Ri?>p-f%?>[cSZgnW]?>bcY CXs,Cg2bcÇ[[ÇbcfgbcÇbc+:SYq(-bcÇbcÇNFXSbcÇ]]ÇbcWSbcOIÇbcÇ\Ybcss]]]ZÇbc\]bcÇ{9;N+"     1 Z^K* & 5 ]` _^`b2o(=x2BR^?>uA"?>F]Ykg)?>_ ?>YfXe_m?>bci,d-?WM[bcCGbcTO֬bcÇbcYVbc[XÇbcÇ``bc[[ÛbcssÇbcmmbcÇZW\[YVbc TRY/"    %)9 E!A"44 7 F`H<`T!L=M!@L8C ?>_ ?>Ynt%i")?>f$?>l)Y\bcf4j1bc[^bcMWbcÇbcYXbcYYbcijbcÇbcRTbcYVbc_IMf$RVbcu)+bc[[bcÇbcSSÇbcWTbcÇbc_`bcbcJHbcÇyzbcÇC?U    *>I'I)D'6 ) % +%9`P`Q%4P/Y!p4UZ?U5?>n).YlVmMitb?>bc?>f+?>k+2\)j"6r%bcMYk7q?w&?:Pf-]^2Hk/bcÇbcÇbc\[bc[]u&,bcÇbcÇUQbcÍÊbch#(~;?Y[bc\]bcÇbcÇ\]bcÇijbcFIÇbcÇbcYY`)'/#     % :IP$C2, <+## 15C `^]`3a?X9S9G.^>?>`"!?>bc?>^?>bc?>k(.?>bc?Abcj4h,?>bck-CYV^bcY]j!.m"16Fs$4SYbcCHbc\[bcÇywbcÓÇbcijbc\]bcZXbcÇbcÇVSbcÇbc?Dp+/ORbcVTbcÇmmbc|A?ÇY[ÇbcIJÇbc[9 0   $4 E M!A +"/! %/: `Y*`^\@c'IW>H2L+V?>W ,V1?>KX?>bc?>bc?>bcl.8;bcw*8j2bcZi(s(2bcz)2bcYVbcÇbcÇbcÇbcÇbcHIUVÇbcFFÇ`[^YÇÉÇUQWVbcuwWYf'-2%   %'#6:<?#1"  ! 2 V`K^` ]]6 K'5 %?~>^II 0C(?>bc?>_"QYbfbc@Lm&bcc(g,bcÇVX[]bcÇbc}|bcSLbc[\bcRObczzbcÇKSÇbcUVÇ^YÇbc Ç[]V,# =9  & -A!.9)) 1 HZH`F ``< !?>S.B?>M&j+XSB=?>Y6<%P5?>d-?>q(.?>bc]"k%6:Qbcj&.bcMHbcY\bc8EbcYVbcÇ}bcÉÇYYbcÇZeÇbcÇbc Z[P0!  %(&#  ". 2/%  &9`2`Z?>U5A ?>N )A ?>p%1?>bcg 0j#6Z!k%/MRbcDJbcF?[\k)%bcs#0bcKUv"3w$2bcPHbcÇbcÇbcWUbczzbcÇbcÇbcÇRObc\]bcÇ}B?FC  # ', ))V`9 C`p)2`?>S "?>a$?>BI ?>bcZYIJg bcr%0w+7p$2bcc(h.7H9IPXbct$2PVbc\]bcâÇbcXWbcZXbcÇbc}|ÇbcÇbcÇEFM,  !"  $'E K))H`^?>bcZ\c"`s,%bcg(9Fbc s/;~:Iy5Dz6GV][^@P[]9H|0>m".bcWQbcÇbcÇbcÇbcÇbcäÇbcÇFMZ&2!        &ES)90M`?>m2bcy5*UQbc j+h,Z!d ,j)4FSx9GHYw9It5Fc"2_*`)}6Cbc\]bc\\bcÇbcÇbcÇbcspWNbcSMbc`N0   7S$I<6?`5?>io?>Y"?>`1?>[P`#?>[==bc x;Hapj/=z=Lt6Ddsc-d+Y\[]bcE?[\bcZYbcZZbcÇÎbcÇbcbcÇh[ÇbcÇbc CGOY%-  ") < ;J&);:^`YP?>`?>\&f3Y,P"V?>n0$?>bct*/bc5Dp'z$2bcVYbc X]n.`?>Q-^%6c%?>bc?>bc?>bcVWbcv#,bcCQ]^y5AZ]PWbc[]bcq'2bcyzBAbcp2,SNbcYWÇbcÇbcÇbc]Y\WbcHFp0/bcÇ||ppÇbcÇ~I6bcYSbcwwQGUQbcSWYg+2<      !$%/7M`9R`T`?>c1=?>bc?>bc?>bcxzbcMWv$8W]x,9:EbcBBbcFDbcÇbc\]bcÇbcÇbcÇbcÐÇbc}HAÇ\]bcC?bc[YÇbc_`bcÇwjÇbcL v.;8'  0V`F.5 6Y`Z`^;Y2?>i,?>m'$?>LZ?>bcPXbcY]cpW]]^p)bcBB?>bcMLbcÇYYÇTObc\]bcÇÇbcÇSA][XQbcÇóÇbc4M`?>g#?>z(6?>bcV[bcp1?>o-?>bc?>bcVYMSbc[]]^o1]^[]bcÇbcÇbcÇbcXO``YDdVcS][ÇbcÇbcÇ~|bcÇbcRV2>s,8S!2 "     # %$$ " / `^`d/2K?>`?>a6 ?>`5"?>k3/?>I`?>bcW]bc?>bcW\bcSVbci!)KU]^i!3bc?>bcÇsmÇggbcfgFDbc OBbc_S_KaW``bcÇbc[VbcjjbcÇbc~|ZMVETBbcÇbc s,0j5:N!'6 % $F`Y`9`d7\`?>a2$?>[]bc?>bc?>c)?>m&bc?>d2[^DJbcX\pNYMVbc?>bc?>bc[ObcCBZ\?>bcÇggbc]\[Sbc[S``bcYMbcYHbc]ZbcÇYYbc <@c(-4     )M`]!P\*^?S,\?>U P ?>bcc?>c%2?>bcinbcFX'=u".bc?>bc YQYP]]YMUH\YYQ[W\\UJbc\]bcÇbcÇbc o79Z')<"  1``Z`YH ?>DL?>bcf)?>jjZ47c9??>bc?>[^bc?>j"0bc?>bcY\bcWZbcÊL?ÇbcÇbcmmbcÇopbc s;`?>]%?>U2)hd?>HX?>bc?>BBbc?>PZ?>]%?>bc?>o.bc?>['_"-j)4|.;=IbcjjbcwwÇbcÇbcVWl22U$$#   % /; `?>M `?>`7%?>f/bcPW|-;s4bc?>`)?>_&4CPbcÇbcÇbcEEbc]%&< %% # '3 F]`; <6 `M?>C,M4Z!`?>cY?>X`?>Y 0uzbcn1?>Ç?>bc?>T?>[$3bcbc[]VXb,-&/     ;6`ZFFR`c6@( /P,Y]#Cd%B_?>\,)?>R!%?>] /?>_/?>b/`3`4[.?>_-?>f+r%2l)bcilbcm'6\)^$2bcfg\]bc z}bcs(.p-263!'     "/9`P` 4 ]MTV^`Z]Y@?>i"?> Ob?>VpVq?>a6Ocdtm}W)w^jXe?>bcNVi*4TYbcÇbcEE?>SV?> q(0?9 /%   #"/C V` d/h(Y ^'U"^,?>|b%0`"4?>TpSra6a%3?>`'0?>bcHJ?>k-6W)G0,/%   %*.< `H ``_%`?>Q ?>L )>"8Z!?>I?>f?>V?>b&,?>b!0?>Tg?>bcY\LMBB?> x49\"// $%  &7 < ( "M`R`?>k.FR>C *N79?>c?>bcÇbc[]bc?>q%2d+V"?/&       &6 ]`a*_]`?>P"m?WF%V=ZC=,F 3?>U ?>bcRRGGbcÇZ[bc?> N$< 0- &       ' 6`a*_/F``(`;H`Z(Z,U,TFLB<,I-?>M?>}8"?>bc?>BB?>9<<=`".Y ,92 +      'FR`]TH C ??^``#` 2Z,Y!-?/L;A $W.?>bc?>bc?> <i%/]"/C0%     /6 2&%P`Z`_e.?X%76 $Q&AE.?>S%LS%?>c (?>bc?> `x25?>S> </   '/ 9 R`]Q)<<!J(Y0?>].=9 C'M.I$?>b?>k*)~}km?>bc?>bc?> @2 (     '0 <]` <_/@`):]"4I S%S)?>S#4; C)D%D ?>k%s",?>c+U!I @;1    #-2 9<C < : 8 7 ; <S%PZ !\ k/a(?>]/W-`$6Y+^(?>a"0W'LF< 5, "  / C>HLW IJ F I!Q*L"Y&?>w"5?>o"-?>d%?>f$t"2?> a//Y&)\(-^(/Z"+?>\+[)N J 91, ) '       " # ( %&""  " 2 9 :C >F9 Y*9 EIa2`/k)6?>k.6`'0\%-[%*?>^%&O624 1 2"!  #          1   " ' % ( ' #,2/25 4 / )"##&*+ $                    www        TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_explosion_0.tga0000644000175000001440000000107612031751243024716 0ustar tjadenusers  UB x4MY, Z4Kӆ 3$&0 2}r}?s (E1s\ot f,. lKOnTRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_explosion_4.tga0000644000175000001440000000115412031751243024717 0ustar tjadenusers  #hH<:'2`7m04( 0oe kH  Ul *q,֑GyI R#  v j Y` Rj$!TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_font.tga0000644000175000001440000007316612031751243023436 0ustar tjadenusers V TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_explosion_3.tga0000644000175000001440000001160112031751243024676 0ustar tjadenusers @@ 70! PXތnf,7->BC k}`t~4rA XzaUb}$}b'NZUFn-(y߁ ˂WƂ2T2j1݂7.|4F^rŃDlMib6& ( +a z=} pB -]MMZ`7@ M!\F1^'~ wl-T{Dr)Rb}aj*Wa .e\fq:5F0 {qwX@2(a$ -f)n#ևڂY+|jE&L1JZ@PwZxCpK3=`nYG0?>/155M* yO9TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_bullet.tga0000644000175000001440000000046012031751243023724 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/trail.tga0000644000175000001440000000107612031751243022402 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_font.tga0000644000175000001440000017061312031751243023413 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_explosion_2.tga0000644000175000001440000001413512031751243024702 0ustar tjadenusers @@ u{m@  \Tzc^pd}v@Ԃ'~NMk*Ճ-pnHj̉cgTKcA{ {)z%tvqK><Nb[Y~m'ND t3 ^$^z| eBك") ?vp.]*u#Q& O) P+N#-m_ j-=`6,6il7,qsIo G ,݂~Mg;j)"Uw'WVUq}5f[us% ˃"^:Delé}(pl->Z+zÂ6 {+|*/%#\`]jH}}: B}kO{9 {k2m1hr0%lR}I*?_$ac~Mgkunk8.փ@* YS{}P"M;BԐ59h({Mup xƁ  R_yQw#K+xO9I>‚My",6̆ wR}TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/ship_icon.tga0000644000175000001440000000142512031751243023240 0ustar tjadenusers  ND ]F1u9 7X¬oGF/pK_ &NPwT{{}>vM)TΰL f9{W]U {L:T C* L~ qd|}\ wB<3..,*54,#|{z{ {}%,249<:8;=6)}zzz|!~%),*2BE)|zzz{{{"~0?@0|zz!~.<@5<$zz!~3HF3I:,!~z {|{zz| }!}):=;::1&,0}z |"~',(}|+1/2>McP?7&{&;(zz{|}$-53.(}|(*,17.?dW8B5$z{+0#z{&,/3-%!~}{zz{{|}!~ }1KLCCD5#z},-|z}./+$|z#17@BC3#z%5"~zz}|z{zz},!}&6BD7#zz!~3'{z{%}z{(0#z|,8CH:%z}1/|zz"~&}z#0({zz%3@F9$zz!~9;#zz }0#zz},}zz%3>C6$zz|07*&${z%5%zz{(0#zz%3>A6$zz#243/}z{(,}z#1)}z{(5>F:%zzz }!~ }zz|z {*5-*#|z }09>J?(zz #2301,$*47E@+{z z }!~ }&-6@<2B-|zz}{z{},DK@BD/|z|||!~0#zz{1IO?/}zz#,.,.7"~zz&AO@>1!~zz&53.3B: }z%=J=>3#z!~89&|%86!~z{zz%>M;3$zzz'5*{zz }!~zz{&'{z%?O;7&{zz(7/}z{)0%zz&@P87({z(:9%z|&0&"~|z{+GR;<*{%:(zz{(2:/$"~|z{1QZ?D1*/7(zz{&724:/#z$@_eCLEI3$zz z!~ }*747,&;[ncGSWY4{z z|}"~(2HGCRhgJKVYB({zz| }} }}|}'.04:FKPTVKEKVS>,$ }} } "~&+/137.,6>@BDFGD@ ;GOID;2/./.167BLBABADEC?< -7DOKB;9;77BGD>?A?<TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_explosion_4.tga0000644000175000001440000000421512031751243024702 0ustar tjadenusers @@ j6* H**7kd@L[1܁+.032 !?a 'a B3 TՅ GJ+Ca0 -tY0v5KBh9KUW:unpL&"tyMf^K?' P\##=)+< .\R F4g = "]Y+D^W&<څ4Q8TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/ufo0.tga0000644000175000001440000000771512031751243022146 0ustar tjadenusers @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffff͍͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}~~}͍͍}͍}̈́}͍͍}͍}͎͂̈́}͍͍}͍}͈͎̓}͍͍}͍}͎͋̈́}͍͍}͍}~͎͌́}͍͍}͍}͎͂͐̀}͍͍}͍}͉͏͆~}͍͍}͍}͎̈́̀}͍͍}͍}͍̓͋͂~}͍͍}͍}͍͊͆̓}͍͍}͍}͍͂͊̓}͍͍}͍}~͋̈́́}͍͍}͍}͈͌̓ͅ~}͍͍}͍}͍͇͂͊̀}͍͍}͍}͉͉̓͌́~}͍͍}͍}~͈͍͉̓́}͍͍}͍}~͍͈͉̈́͂~}͍͍}͍}͉͍̀́ͅ~}͍͍}͍}~͈͍̈́͆̓~}͍͍}͍}~}~͇͉͈́̈́͂͌͆͂ͅ~}͍͍͍}~̀ ͈͇͍͈̓͆͊͋͆͋͑͐̈́ͅ}͍͍͍~͇̀̀́͂͆̓́}͍͍͎͍͎͍}͍͍͍TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/ship_trans.tga0000644000175000001440000000454612031751243023446 0ustar tjadenusers @@ TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/ship.tga0000644000175000001440000001743312031751243022236 0ustar tjadenusers @@  !$F[.0o1BX*E hWW-G*i[y +P]2*q LfyGG qC :}q< u_16,y`vG Ma|Kx250!qif f%H2N[[U>dYtkG  P n7WZZJ!H<J% *Kpsqq]yzi~uG `w{[rqsoC~ xW]yAv>j'd=v3^ %vn1)^!NiaeC ,j [mD f(q#Q41EX ]R Fd(uR?&`h (^;9rHb[Qh N2 =4:x rZ<kj ;%_r x9:'"dp4wkpQK KPnmv0Sw,!s- haw y pB-~ y+A{ rv y]m3)3  8b;qfbw `gqk!c{yz{{{zy|d l uc fqf dq5l  9Ci \ro b[ 'L{yufdkry|K*|` _tp_bF} q7z Btk er jf16~||v=p9Zy=~||~2 /kn j f e 9a&&2'S y\ m{_*x~~'^TVqr~~v,^x l_|U$oU  M. uc xq^'k{R (oT~ k}`o sel4(e +Dgf HW <|=`Cg2 UDke=V0D9B `D py}I VL3&@S;`uOB I2B:NXMGveC&T/.kRL{S .pw3ex XTS0GNCu & vTBK%)#;F{:LXXlWgHX&sb}P|f& y+m)RO  ^S!yy$6a7@  ~KBcY |Uwsr<t + ).*L<|"{xPz, "qMZm? i@@/DsFBms+ \V#:5q % a;:%OHNh)&- X   Z4'*[ 7+Jt!u6BGECDBMA<!uq91 8}v S?2:9:9:9cv!N '` ,5e)*+*+)"x]09`? =jgvyzk.6g Ub+9'&! (YQXQYQ/"&BTRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_bullet.tga0000644000175000001440000000022412031751243023740 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/life_powerup.tga0000644000175000001440000000143212031751243023763 0ustar tjadenusers TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_asteroid.tga0000644000175000001440000001461312031751243024254 0ustar tjadenusers @@ LRIH;*FURVX[]VI;5<91.?K7)*/7MVXQB9CKB?+|z|05+{z"~AK9?FHB9&{$?A.(+/>MD){z }49+{z$DT< =G90-8F<+)@I3 }z{"2?/{z{2B-{z }. }{ }.=?;9HJ0{z{/7"~z%DP-zz|6P369=9%zz%4C<>H; }z'=(zz|.@O8|z}8N3:F?9.{z }./<=$z#8/{z{-9.9A/{z!~>M2C?5(|z{}&++|z }4<) }zzz*B6 }%?E'z }>S9A6%zz{{{zz%489'|z }:F*z{-B4({z!~0{z|6D'z">G4>F(zz&;?74644479:2$zzzzz(6"~z"~+-}zz }9G{z|z&AC+${z|.-|z{,:4:.|z!~84 }z }39A(zz{{|}.>4}z{(5>?"zz }'*+./5D:%zz|0@G?"z }4>=;8:9+{z{.BQD#z|,=7(#"~" }{z{'4 YM,|"~%$&2F9$zzz|{z!~.U ;/;B=6)|z}20"~z%7/|z{%0"KeZ<*{z}20"~z"~41 }{z{+=?)VjT7 }z }30!~z{(:0/"~zzz},@KA#=_bH'zz{+91}z 'GHB6,'+;A@4FikK*zzz)AH2|z #?B=BHFHLB4,.QtrQ%zz%;HO2{zz{|".6*")1696+4Plf;|zz }%*6EXW9'$%(,02'8H]W9'|z{}"~#*5CKGLZ\H@;4.0& FUZS9)"~ }"~&'(2;< ?@KVPLHNF;=1"~O`RE>@ID36=<=?CGDC;21OSUHA9TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_explosion_3.tga0000644000175000001440000000256612031751243024726 0ustar tjadenusers  a+  j i =M -M!L v, i^0FrA_ 4A*8Kq(]+ 7j X}h Rzr6#d su 2 ctO#\)u!C 1 iSs7vaZXR QjA"WY 5LViO^T0CH)`58EK*gSTRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/ufo2.tga0000644000175000001440000000771512031751243022150 0ustar tjadenusers @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff͍͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}~~}͍͍}͍}̈́}͍͍}͍}͎͂̈́}͍͍}͍}͈͎̓}͍͍}͍}͎͋̈́}͍͍}͍}~͎͌́}͍͍}͍}͎͂͐̀}͍͍}͍}͉͏͆~}͍͍}͍}͎̈́̀}͍͍}͍}͍̓͋͂~}͍͍}͍}͍͊͆̓}͍͍}͍}͍͂͊̓}͍͍}͍}~͋̈́́}͍͍}͍}͈͌̓ͅ~}͍͍}͍}͍͇͂͊̀}͍͍}͍}͉͉̓͌́~}͍͍}͍}~͈͍͉̓́}͍͍}͍}~͍͈͉̈́͂~}͍͍}͍}͉͍̀́ͅ~}͍͍}͍}~͈͍̈́͆̓~}͍͍}͍}~}~͇͉͈́̈́͂͌͆͂ͅ~}͍͍͍}~̀ ͈͇͍͈̓͆͊͋͆͋͑͐̈́ͅ}͍͍͍~͇̀̀́͂͆̓́}͍͍͎͍͎͍}͍͍͍TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/Icon.icns0000644000175000001440000001571412031751243022344 0ustar tjadenusersicnsics#H????is32&ĞU)ıR-Ȇ‘2湙 iȡ& U֬ ,жƻ6~ؿ4 {_ԅ P q<238&`YgaygԄ\d҄ {4 jw]j|arr ~qd|}\wЀ,뭦{Բ޾ 䶈{˄ ̂mTj!\݂;;\_ct 2VuKNuN%.? &&E  66   UT L:Z0fL feT{ʂn/uKs8mk ]vd*~ {H]*wM DFich#H???~||p???~||pih32 9XF(GgjmU&Uz -lF! PnY/ Cmp; JX"bmî{Riγ߷庒kxѭߺŪxUn؛ͻxn޹ٸ²qü¾{;cäQmڿ˶~ďEVϪUv¾п¼˗gŶdYӱ墛Ȓf1Ҭ|AȤ밐Vשrq͠Ӷ]ֶưhӧĸej~ã̾wW{ϟ7gd̺ θkǼЯoJųȁͤsυ̟᩼ӄؕNс˦ɥԁәm"˨Ƣ̙f* ɬĥؘ](*ʬʿ}j=̬˹Ρd Uʮʲݓv3ǯϯ긄%_IJ̑U\Ͼ~ff;kءrYuf_纗3r۰txlȓN D`N^8&V2(W<   &+*+*! 4@@A@A:$ $2I AB*':VO?/ @wL2K#oSt0JHڋT #c7 ŝv+E})`4fɌ|1!D½َX7jЯrߝw@VhޭU3f昄]޹o2H{䉄K廥OW}=d>ci*ɬv?6U!ҬPT:享[3[M$Ҳr; O滿{IJm7%X껚]2ɤl5 6\s# dL%+SdZa‘jSg0Dsp|KaCuBxtvM (qtlhAp}x{{B]nq~~<SqqyuS:y}{|nz|G?u|pqg#Xjmfd|GH{yxslsvy}W;x}idmj{o! Xp`rq5Z}~~}n1dwdj}k!JwskFyM`tscE\WiL~Q+Eã QdK>۹_^N9)7ӳg^T3OгodZ)'ErĜld҄H*D˚jud] W䷒mjsb^.8o֚k_g\ρ>9⽈jIuw}LXFHڡ{i&3UzUZˁZCsy/!вZ:ԣL~ _z DB&     #"@K&4_]?Kheclj ](ZF*NY K{?e   do4mqY%uH  4`1o8O@ķ`}ƺoq i_çp N+0W)5b8 w]ZG  h]F    'p+n=    E] JL    UAe                 c{43&%kxTm( A+2/ 7\p=R46? F^RP 87 9t5z/!lH [! vq!%gkKw/:6!~IOn Y^"TyzvI7syy^/)O[S#K\U5 ''#h8mk R_ ! I/>|/D\zx HGK$Dc +.k 02tp 3%eu 9/>d ) N7bS%kKd!q#%1_:=Hc[6YHdFcb e( $1Jco_allegro-5.0.10/demos/cosmic_protector/data/gfx/small_asteroid.tga0000644000175000001440000000240212031751243024263 0ustar tjadenusers  CED?zFFCF<5?=zzBP J@=;9.%",C:zzD<6/)-;'|zz2A?z zB/ ~}|z#6{z|==@C=%|zz%1|zz0'3BF=!zz50z.4 ~,;BD9z|8|z}2|z&8LzD4z3.z/%z ~8NB1zz)zzz||zz4KK2|zz&0#z.DBN9%z{4D. ~z|D]RL8@4|z00z/9<83(S`\+$?#z1;{zz|+-CL_z0z4717)z{z{(<z="~;@|z:,z{;;<60*" ~|A|zz}%zDF?<80;1679=Az<DCFDBKNNDz@BKNzTRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/weapon_powerup.tga0000644000175000001440000000143212031751243024335 0ustar tjadenusers TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/large_explosion_0.tga0000644000175000001440000000365712031751243024707 0ustar tjadenusers @@ SWWf:pHuAC!O9)'y@Mh qy=)4&J?p7Q!rMx++.qh Ӂ11rTr8HAHn/|HPs { j4t֏ __:|ou&DCe4`zwTRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/logo.tga0000644000175000001440000020116212031751243022225 0ustar tjadenusers>4   ; ; ; ;      ; ; ; ;          ; ; 3D@@`````@@@@@@@`UUUUfffffffffffffffffffffffffffffqUU`@D3; ;         ; ; ;      ;                 ; ; ; ; ; ;     ; ; 3D@@@@@D3;      ; ;      ; ; ; ; ; ; ;      ; ; ; ; ; ; ; ;          DqmuvvzmfU`@DD@`Ufmzvvvuuvv  """""######################""""" vvvvvvvzmUD  DUmzvvvzmUD   DUfduuuzdaqU@DDD@UfmzuvvvvudmfqUUUfadzvvvvv{vudmmmdzuvvvvuzdmmmdzuvvvvvvuzzzzzuvvvzmf@  Df #&()++))(&%"  #%&()++++)))(((())+,,.0000000000..0000111333333333334444444444433333333110..,+))((((())))))(&# m`;   Dfz#%(()((%# uaUD; ; DUau"%&&(&&%#  "#&(()))(&%#"" "#%&()++++++))))++,..000..,+)(&&%%%%&&())))))((&%%%%%&&()+++++++)))))++++,+++)((&&&&&&(((((&# fD  @d"&+0369::<::97431..,,.013679:<<<<<::9999:< <>?AABBBBBBBAAAAAABBBDDDEEEEEEEEEEEEEEGGGGGEEEEEEEEEDDBBA?> <::999999::::99630+(#vzmamu %).147999741.)%"vv"%).1467776431.,,,,.014699:::97643100113679:<< < <<<:::<<>>?AAAAAA?><9776666779::::::99766666779:< <>>> <<<:::<< <>>>><<:9977677799997630+& vf; 3m{#)06:ADGJLMMMMLIGDBA?>??ABEGJLMOPPOOMMMLMMMO P"R"S$U$U#W#W#W#W#W#W#W$U$U$U$U$U$U$U$U#W#W#X)X)X)X(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z(Z)X)X#W#W$U%S"R"RPOMLLLLLLMMMMLJHEA<71,(#"""%(.39>BEIJLJIEB>940+(&&(+049>AEGIJIHEDB?>>>>?ADGIJLMMMLJHEDBBBBDEGJLMOP P PPOOOOOO P"R"S%S$U$U$U$U%S"R#POMLJIGGIIJLMMOOMMLLJIHHHIJJLMOP P P P POOOOOOOP P P P PPOMLLJIIIJJJLLJJGD?:4.&zD Uv")19?GL"R#W(Z,]+`-a-a-a-`+^,](Z)X$U"S"R"R"R"R%S#W)X'[+^-`-a,c0e0e1c,c,c-a-a-a-a-a,c0e/f1h3i2k4k4l4l4l4l4l4l2k2k2k3i3i3i3i2k2k2k4l4l4l3n3n3n3n3n3n3n3n3n3o3o3o7o7o7o7o7o7o7o7o7o7o7o3o3o3n3n3n4l4l2k2k3i/h/f0e,c-a-`+`+^+`+`-`-a-a-a-a-`+^'[#X"SMHB<630.037<BIO"S#X'[,],],]'[)X"SOJD?:64469>DIO"S#W(Z'[)])]'[(Z#W$U"R POO P"R"S#W(Z)]+^-`-a-a-a-`+^*[(Z#X#W$U$U$U#W(Z'[+^-`-a,c0e0e0e0e0e,c,c,c,c0e0e/f1h3i2k2k2k2k3i1h/f0e-a+`+^)]'['[*[,]+^+^-`-a-a,c-a-a-`+`+^,])]*[)],]+^+^-`-a,c0e0e0e0e0e0e,c,c,c,c,c0e0e0e/f/f0e0e,c-a-`+^+^,],],],]+^+^+^+^+^)](Z#W"RLD <4+"v@ f{%.7?H P#W+^0e3i3n6q7s9t8v8v9t5s6q3n4l3i1h/f/f/f/f3h2k3n7p5s8v:w9y9y9y9y9y:w:w8v8v8w:w9y8z<|;~<==?>>>=====<<<<>=====?>>>>>>>>>>>============>>>>?==<;}<|8z9y:w8v9t7t7t7t7t9t8v8v8v8v9t5s7o2k/f-`(Z"SLEA><>AEL"R(Z+`0e3i3n7o6q7o3n2k/f-`(Z%SOIEBBEIM"S(Z-`0e3i4l3o7o7o3n4l2k1h/f1c,c,c,c0e1h2k3n6q7s8v8v8v8v9t5s7p3n4l2k3i3i3i2k3n7o5s9t8w9y9y8z8z8z9y9y9y9y9y9y8z<|;}<====<;~<|9y:w9t5s6q7p7o7p6q5s7t9t8v8w:w:w8v8v9t7s5s6q6q6q6q5s9t8v:w9y9y8z8z8z8z9y9y9y9y9y9y9y8z8z8z8z8z9y:w8w8v7t5s6q6q6q6q5s5s5s5s6q7o4l1h,c)]%SLB7.#D f(1<EO)X-`3i7o8v<|=>@@??@@=>=:<|<|8z8z<|;}<==@AAABBBAAABBAABBDCDEDDDDDDEEDBCCCCCCBDDEEEEDDDDDDDDDDFEEEEEEEEEFFDDDEDBCDABABA?@@@@@??A?@@><9y5s4l0e,]#W PLJLO"S'[-a3i6q8w<|==>?=;}:w5s4k0e+^)X"S"R"R"S#X,]1c2k6q:w<|<=>>==;~<|9y:w8w8w:w9y<|<==@?@BA?@=?=<;};}:===@?BABBBBBB@@BBBADCDFEDBCABAA@@====@@?ABBBB@?@@@@@@@?@AABBBBBBB@AA@BBBBBBBAB?@@@<<@@@@@=><8z9t4l0e(ZPD9."z  f)4?J%S+^1h6q8z=@@DDDEDDDEFEBDABBBBDCEFDFFHHHHHFGFGHHGGGIHJJIIIJJKHIIIIIIIIIIIIIHHIIIIIIIIKJJJJJJJJJJJJJJKIIIIGGHHFFFGDDDDDGGGGDEEDA<:8v3n/f-`'[(Z(Z,],c3i6q8z=@AACCCDB?><|8v3n1h,c-`-`,c/h4l7t<|=@@ACDDBCABABAABABDDFDGFFFGDDECDDDDCDDDGFHHGGGHHHHHHHGGIIHIHIIGHHFGDEDDFEDDFFFFFFFGDDDDDDGFFHHHGGHHHHHHHHHHHHHHFFFDDEEEEEEEEDBAA=;}7t3i,]#PD7+f  f(4?L#X,c3n9y=ADDFHGIKJIIJIIIGGGHHHGJIJJJLKJJJJKKKKJKLMLNMNNNNNONMMNNKLLLLLLLLKKKNNNNNNNNNNNMMMMMMMMMMMMMNNNLLMLKJKIJJKIIIIJJJJIJIHFDB@<8w7o2k1h3i4k6q9y=@AEGHHGHHFEDA=;}8w6q3o3o6q8v<|>BDFFHGGJGGGHFFGGFFHGIKIJJIJJIKIJGGGGGIIIJLJKMMMMKLJLKLLLKNNMMNKLLJLJIJIIIJIJJJLLLLLJJJJJJJJIKKJKMMKKJJJJJJLKKKLJKLJJIIJJJJJJIIGHDDA>:w2k,]PA4&v3@&3?L(Z/f6q;}@AEFO^otuuuupeRLLLLKLLMLMKMVjruutm[NNNNPOPP\haRPPTfrutn\POPPP[ntuuuusk\TTaotuutocVVdptuutpcTPSaotuuuto\NNNLMMMP`ouuutkZLIFDB<:9y8v8v9y:=BIZntuuuuurjSDCA==;};}=>@DIYntuuuto`OLJJJJJIKLLVjruutm[NLMLMMLMLN^puuuup^OOPPPOO[mtuuuutm\PPNNNMNNNP`ouuurjVNNNNNNNNN^puuuup^PPMNNNMVjruutm[NOLMMMMMZntuuuto\J=:w3i(ZL<. f  u#0>J)X/f5s<@BFPh}zcNOPPPPONe||eRQRQ`}|cRTuuQPPPRj~}fLGFCA<>?=AAIpmHEDBB@ADDIp|YNNLLNNNe||eNOPPONRyxRQQQ[z}fRPOPPQj~|ePPPQQRyxRRRRf||ePPPPPpoI>7t0e$UD6&v;  f,9G#W0e5s>AELc|zTRRRRRwwTTa~z\Tk~wQHHDDB@BCDYZGFEEEEFHYRPPPPRwuRRRRQyhTTrwSRRj~wTSRRyjRTyuRRS_iA;~3n,]L<,U; v&4B"R-`7o;~BEQukRRTzrRJGDDEDGHkoJIGHHGIJkhSSSRySSRh~k|u~jVot~^UwsF@8v0e"SB3#d f .<L'[2k8z@DOy|LJGFFFHHrߔuKLJIIJKMpsSTSy}^_}zߖuFB;~4l(ZI9);  &4D"S0e7t>AFpVJJIGGIJruNNLLLMNNrsUUyzGD=7t-aO?. U`+:L'[4l<|BE\TKKJIIIKmoPNNNNOMOoiWkwJGA8z1h#WD4%z m"1A"R,c7s>DN||yPOLJIJJLWYQQPPPPPPc|[[||^LHD=3o)]J:)3 &6E#W3h9y?D`ztSPNLJJJJMNmrRSSRRQRRQRa^`}uyQLIF@8v,c"R?0 fD+:J)]3n:BGr}}u|ccmnSPONMLJLMNO|UTSRRRRSSST|~``mp~fhmwj~kz|NNJFB<|3i#XE6&u `.>O-`6q>DHz~\VW[~|w~f~cddiwRRNLLLJLMNNuaUTTTSTSSTTx|aau|w}f|fhik}uc|pcuzPNJGB>6q+^L:+{Df 0A"R,c8v6q+^L9);  m#3D$U1h9yAEsߚpTTTUVWZ\^`acksnuNMMJJJJLNp~SE@8v-aO>,@ m#3D$U/h9yAEoߚSTTUVWZ\puwy~juuPNJJIJKLNpkGB9y/f"RA0 Uf"1B"S/f:w@D`ZTTTVYtzayuNMLIJKKLNpuFA8z/h%SB1"ff"0A"R1c8v@FRuTUVWmw`ywuMLJIHIKLNpwFA8z1h$UB1"fU.>O-`5s>DHy_TV`}fth^wz^rrLJIIIJLLNrw~|r|~pwD@9y/f"SA1"fD{+:L,]3n<BFroou~yRTTyyY[pj[YuaJIGHGIJMNu~u~yTYzuSSRur}zURuuE@9t,c P?0 U v(6G)X3i8z@Ea|WVj~~hRRQRQuyTUWY[WVSf~xNIHFFHIJMO|wRSi~~m\kZSTRwsRPQOOf~aSRh~~hQQQWoB=3o+^L<,@ m#1B"R1c9t=CPwUUSRau~|r`PPMMPONP[u}tmoturkhmtwwuurmku~mWWjz~hRSSTVpzWTTTRR`pz~rimruraNHFEDEFGILm|wuusoozWQPPPau~|r`RQRRh~\RQRRQ^r|u^ONNNNNNO`py|pimruuw}rVQRPQQat~|r`PNOOOOUouwuusoozT@9y1h#WG7(v; U,<M,]3n:BDjwTRRRPPPWecTMKMLKJJLMLLNNP`kfSOPPPPPPPONOPNNNNNNNPaoo`PNNNNOTenk[OPQRRRT\~UTRQQPPOPQUTNNMLMJIHFEDBACFFHWzRQRQPPONOThrnUNNNONNNNWecTMPOPPPQP|TPPPNPNNNNRdonaRNLLJKIJJLKKMKPTROPPQPRRQU~SPPNPNONNNNWecTNNLMLLLMLLLLMLLLMLKThrnU?<|3n+^O?1#d ; v(6E$U/f8vM+^3n;}AEQzuPONLJJIGGFGEECDBBBBBACEEDFHHHGGGGGGGHHHHFFFFFFFFFFFFFFFFFFFFFHHGIJJNNORppPPNLKJIGHFFFDEED@@>:=z9y8z;}>ADFsjPNMMKJIIGGHHHHFFFFFFFFFFFFHHHGIIJKMLt`MJJIJHHFFFFFFFDEECDBAABBABACEEGGGGIJJKMMNLtvLIIIGHGFGGDDDDEDEDCDDAAADDCBDEEEECD@@=9y3n,c#WJ<0#z D(6E$U0e7s=BGRxuNLLIHFFCBA@=?<;}=z9y9y9y8z<|:=>@?BBBBAAAABBB@AABB@AAA@@@@@@@@@@@@BBABACDFGIMNOttOMJKGDEDBAB?@==;~8z8v6q3n4k2k3n5s8z>BEruNNLKIHGFDCABBBAABA??????@BAABBDDFGHGII`w~LIGFEBABABB@@A@@=?=;}8z9y:w8w:w9y8z<|<==@BBDBDDFHIIJI`w\GFDEDBA@?@@@@@=>?=<;~;}<|<|<|;}:<==>>>>=<<|8v7o1h+^%SI>3&@ m".<J(Z3i:w=DFQymKHHEDA<=<|:w9t6q3n2k1h/f0e0e0e0e/f3i4k3n6q7t8v:w9y8z8z8z8z8z9y9y:w:w8w8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8w:w:w9y8z;}=@@DFIKNooKJGDDB=<<|9y8w9t5s7o4l3i/f,c+`,])],]-a1h7o8z=DktOJJGGEBA==<;}<|8z9y:w8w8v9t9t7t7t7t9t9t8v8v:w9y8z<|:==@BCEFHGQ\hfYMGDDA@=;}8z9y8w8v8v8v9t7t6q7o3n2k1h/f1c,c-a,c,c/f1h2k3n7p7s8v9y;}=>@AACFGGHGQ\f`QECB?==<|9y8v9t7t7s5s5s6q7p3o3n4k2k3i1h/h/h/h1h3i2k4l4l3n3o7o3o3n2k1h1c+^#WOE<1(q 3v&3AO,]4k9y@DFRwTHDD?=9y5s4l1h1c-`)](Z#W"S"R PP P P"R$U#W(Z*[+^-`-a,c1c0e0e0e1c,c,c-a-a-a-`-`-`-`-`-`-`-a-a-a-a-a-a-a-a-a-a-a,c,c1c0e/h2k3n9t<|=BEGJ[\IHDA?8z5s4l1h0e-a-`,]'[)X$U"S PMMMP$U*[0e7o<|@U~fLJHDCB><|8v6q3n2k1h/f0e,c,c-a-`+`+^+^+^+^+^+`-`-a-a,c0e/h3i3n5s8w<|=@AABEDDECBB=<9y5s3n3i/f1c-a-a-a-`+`+^,]'[)X#W"S"RPOOOP"R"S#W)X'[+^-a0e/h2k3n5s:w<|==ABADCCDBA@?;}:w6q4l1h0e-a-`+^+^+^,])]'[(Z)X#W$U$U"S"S"R"S"S$U#W#X)X(Z'['['[(Z)X$U"RLG?7.&f  U)6D"R+^4l9y=ADL`wzurnkkmjTGCA=:w3n/f-`(Z$U PLIEDA?>>>>?ADEGJLMOOOOOOMMMLLLLLLLLLMMMMMOOOOOOOO P"R%S#X)],c2k9t<@FHJttJFC@;}5s3h-`(Z$U"ROLJGEBA?>>?BH P(Z0e6q<|@ThmjhhhhhhhjmpstoaPIHDD?=9y6q3i,c,](Z#W"S"R POOMLLJJJJJLLMMO#P"S#W(Z+^,c3i3n9t8z:==<<==;}9y5s4l/f-`(Z#W"R POMMLLJIGEBA?><<<>?ABEGJMP"S#W(Z+^,c1h4l6q8v8z;~====;~8z8v7o2k0e+^(Z$U"ROMLJJJIGGEDBAA???ABBDEGGHGGEB?<60)"q  m ,9E"R+^4k:w?ADFGR`orkZNLLKKJIGGCA?9y3o/f)]$UMGB>:7410,,++,,0134799:::::::999997999999:::::::::<< <>?BEJ"R(Z1c3n8z@DGPttPDA=9y4l-a#XOIB?<976310...16<DM)X0e7o<|<:9997777799::<>ABGL P$U'[-a/f2k3o6q5s5s6q3n2k/f+`(Z"SMHD?><:99976431.,+++++,.1367:<?BEJO"S)X+^,c/f2k4l3n3n4l2k/h,c,]#X"RLGB?<:97776443100.....011344664410+&"{dD ; z".9E"R,]3h7s;}@BDDFHJIIHIIGHFDDB>8z6q/h+^%SLD <61,)&# {{ "#%&(())))((((&&&&&&(((())))))))))++,.16:AJ"S+^2k8v=AEJ[nrn[JDA=9t3i,]"RG?73.+(&%#" "%)07BL#W,c4l:w=@BBEGFHHGGGHHFEBB@<:w3n0e*["SLD>941.,+))((&&&&&&&(()+,.149>DIO"S)X'[+^+`+`+^'[#X"SMGB<73.,+)(((&%#"  "%&(+.147<AELP"S#W(Z'['[(Z)X$U PLEA:61.+)(&&&%%#"  ""#%%%%#" m@ Du#.9DO)X,c4l8v;}=@BDDDDDDFCBB@=9y6q3i-`#WMD<4,&"vzmU`D3; ; 3D@Ufmdzuvuuuzzzzzzzuuuvvvvvvvvv "&+3:DO(Z/f6q<|=ADDEDDA=<|6q0e(ZMB91)# vzmafUUfm%,6?J$U+^1h7o:w;~>@BBADDDDABB@=<|9t4l0e'["SJB:3.(%"vvuzzzzzzuuv"%).37>BEILMMLIEA<71,&# vvuuzdmfU@D; ; ; ; ; D@Ufmz #(+049>BEGIIHEB?:60+&"vuzdmmffU`@DDDD@`UqfammmmmfUD Du"+6?J"S*[0e4k5s:w<|=>====>=;}9y7t3n/f+^#WOE>4,%va@;                 ; ; ; 3@Um%,6AL#W-a2k7t8z=>=>=8z7s2k-`$UJ?6+#{zUD  ; fv")3 <EO#X+^/f4k6q9t9y8z;};~<<;~<|8z8w5s3n1h-a(Z"RJB93+%vdf`D;      ; D`fz#(,147::::741,("mUD;      ; DUm %),14677763.+&"ua`3;   3z (1:BL"R(Z+`0e3i4l3o6q6q6q7p3n4l3i0e-`(Z%SME>6.& q;  ; U )3<G P(Z-a1h4l7p6q7p4l1h-a(ZPE<1( z`  @z&07?GO"S(Z,]-a0e/f1h3i3i3i3i1h0e-a+^(Z$UOGA91+#zU;  ; Umv"%()++)(%"vm@   Dqdv"#&((&%# {uf@  f{%,4:BHM"R#W(Z'[,],],])](Z)X$U"RMIB<60( vf; ; m%.7AI P#W(Z,]+^,](Z$UPIA7.%{f; ; f#)17>BGLO P"S%S$U$U$U$U"S"ROLGB<60)#{d@  ; @fzvzf@;  ; @fmzuuzmUD  `u%,17<ADGIJJJIGEB?<73,& f;  Uv")19?DILLJID?91)"vU  @z#).369<?AABBBAA><961,&"m@   ; 33;       Uu#(,03467777641.+&#vf3 3m#)0479:9740)#m3 `d #&)+..00100.,+(%"fD  `mv #%&&&&&%#"m`  `z %()))(% d`  3Umuv{ dfD   DUfmzuuuzmaq@3  DfzvvzfD   ; 3D@`UUU`@D;     ; ; ;  allegro-5.0.10/demos/cosmic_protector/data/gfx/ufo1.tga0000644000175000001440000000770212031751243022143 0ustar tjadenusers @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffff͍͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}͍͍}͍}~~}͍͍}͍}̈́}͍͍}͍}͎͂̈́}͍͍}͍}͈͎̓}͍͍}͍}͎͋̈́}͍͍}͍}~͎͌́}͍͍}͍}͎͂͐̀}͍͍}͍}͉͏͆~}͍͍}͍}͎̈́̀}͍͍}͍}͍̓͋͂~}͍͍}͍}͍͊͆̓}͍͍}͍}͍͂͊̓}͍͍}͍}~͋̈́́}͍͍}͍}͈͌̓ͅ~}͍͍}͍}͍͇͂͊̀}͍͍}͍}͉͉̓͌́~}͍͍}͍}~͈͍͉̓́}͍͍}͍}~͍͈͉̈́͂~}͍͍}͍}͉͍̀́ͅ~}͍͍}͍}~͈͍̈́͆̓~}͍͍}͍}~}~͇͉͈́̈́͂͌͆͂ͅ~}͍͍͍}~̀ ͈͇͍͈̓͆͊͋͆͋͑͐̈́ͅ}͍͍͍~͇̀̀́͂͆̓́}͍͍͎͍͎͍}͍͍͍TRUEVISION-XFILE.allegro-5.0.10/demos/cosmic_protector/data/gfx/small_explosion_1.tga0000644000175000001440000000227412031751243024720 0ustar tjadenusers  -,K0` +ہzRR  `d5 ./Ag1| RKs@1{:gA,-, x~Tp R,1\wD3$ R1s9R9sBT1ƜsB!1sB!RJƜsB!RsB!J)sB!B)B!J(B!BB!RB(!R!B)%R !RBRJ)BRJ)J %R))J!RJJ)TJ J)%RJ!J)8A'Ua BCVdR)-E"KFsPZr RͩR $1T2B BuL)-BrKsA3stG DfDBpxP S@bB.TX\]\@.!!A,pox N)*u \adhlptx||$%@DD4s !"#$ OggS!kwY,LPRLMJKECLOPIFHFDEKKOtDMIMPDCL@?JBI,fu{Z;֖ ٶŧ,7Hw=["A^ĆRT_Iv-֩!J XkX}M\m:-BXl ݹ`wUhDU4ٔB̲4`@b>+sb 7v/V{{2T{?{sr*6`gC0Mh,˘tY Z`0.` G ى)@x聶\9Xk(Dۼmz{O|PRЕoc͆f\`s9in>X \miɱ'zPj`p-癔>DOc_O/i. ЮTLS.ת+{h?f7?">@%R'@@ Gѹd5~@,UazHzm@<`  }{s¡*#sMA!u7Y$4޼l= '5 } ڏs>@$:LxVT$Ӛ+,8xu @` C8z;}vi89։as`@? ZݠPhPT4fe.+jMs_䜏_`>&ߢgN)F/1F3>"\Px4_|n;~E[N Y;Sg6mקN0Ù/xqwu%ǭ[v%Y~)4r/8C]9~ ^"\ TTPQ^7Qfݳy׹V|ӈza1y<|+*ҁ<۟u{G}$=L33s5]0=M]i:4Mf{m33ϼܮ>?_fԐkFffy/G//7m*IOnGl`[Xܬ[_>T YowQ_צE}}y?ge R)f' XVJv˟ $݋l/^x1 {s~;21fߋmۖ\Gоr[j4ǚ=ڙi |n $qxg$:{+`kӬ^+nؔ w $}?Ŷ?R5zެ~ M ?hO3y_g??_gFۿ}GZ>wƙ0@Š jNo s)죛;{Yxȣ;!#f]GGC)n?@ **jNd[Ŋ?rmj`hdۼL29H1ٷz^8)zڋ[݌=C:yk<y xWȁ:{O.K>.K@@`_{zlq??_<\%%ͨ0SH>"x,]&,[naM?K!mw y@|_uai/e3ӉmTQE;rGftG)̘2Ww |3y|tjrRzr0,S~i8@O»N[oMsӞZJzz{|Yr3 @.٣W2φ/?o/)d<ͺ72 G@٧uG ,#[ -l @w;"B`Qm  ˊ KԳOq>ZoJ5}jGfAc+u)_g9m_n {ִT'}I$[y|\mx@x|?7dr=d~cLkwHOV}`U!1\+&k٩ yRY/VZwk\y` &|4W}`O+{aN*fYrId>`aYۧG [=Jl¯ZMcO)^:y[+ƜE6SSO$OVOᧉw.`_{o`)_MSJ5i|[K OߘZJ2a~*zPpS޻/?0s|3 k,$(?π&b9aψr?^v?L_9oVm!a{ƘBjEjrɊ%UiJըڕ-䷛Μ'C8>ú__ש+RF|o7oZ7U4q_}jW~٣A]+VWȟ~j(rs۞0P>`͚Fơ=~w|aom׹^A;Y=\Eۚ[B**y6nnF:ڮt^,: 2l}zOggSOkwOd;d7TQNGIEHBIIFIBDDAADJLMCHDBDAKKKBGG?D@?:=6:GEww@z>gvW٭r[o/,Ç1 @*1O(2@FܹoN_U>O>o\~`mH%{>ɯHvs>c&x^ Pg ` 2| X~ INaD8`\󓋩=W_]^-320v!J d,@f,^p~kꋗ"<doo>5>_0Nߘ8fTATfqU}3޿S^/yq ES2\ Әs·Gs׉@EV]|kӜ|6u:V Ƚv̇\@vuC(=չ|h}ofF˽|FFaJK5$Dۓ>,ؕo<(./{ 㶿"3nm`Uyص4դR5h{~?kY#X)+‹_`1 17 Xl6IPWW!X)i<ɬ\N#_>ހH 7o 򔳃r>){.XhYs+ 1>,ޒ&m]P]͝+pp쳫U[o_f 7f(U{-[22|*^Wn)gn⢷9\_*4KiD՟[b@`  7{-qUo@@pv/44 I}4A5@#7 ($מk+}ڧf$˔AQ>VayP51yhNVO1WpZo- /L|5@Ǫ߯NxGްcVk_f|ӗ'G O^X@ukG:H6xh:\ܢEmΪBh {|zG( &v\-a|ߚq"2֏Eu^ReGg {Ω^9/^y۱P˟P}|9jg7{G:zXm?FoȮO B+ iMD4w$/fz wOB_v hŽq gtiqQG>k2ء_UWR= ڵ@vM,GӮߧʮcM, $6vݗf)w7@}ߓٝ=·ћm*^$W]>[IJv `vlNwK/Zla1a\Go2sϗ>v?}@?,cOs?`%;"X0Զ]X^I}&?]*կ@w~4֊x{\ Y!fJ13]k4]ŸiH)j"9?oM@W_, Zs+ f%4o?uIJ7gw?:?zO^QGrRqg v 4m+γ]c[GBL  ʅP8*L/WyQG? @Zq$ӥSOk  b~H7|StGaEӗx}V1? ¸淿K p*IE=Ή  ,_ֿke9 m"S X*%f*`s0uoo?` ^a%ݦ~_4WqP؜_/vx2Um=|m~yl;Z+9Of]<}TU7G_nx )*/ޏYW־֖B]X*$כ~j[Ǖ}0 SǗˣqyegԾ-?ϯՔW|@,chʵ  󳤝k*tiQƬND@@lcko_wR(@pGNv3?2(_S;/zK?<$@~{$lE쟲"Oq61B|7gη1^-?f5Xw_~Zy>%2@mS~+/El\ﯾDe(oJZ c=n)}\1 @O.R \n=9n2<87ép\ Wb^>;ߊ~µT ;5d푯~Lufz ^}~m4rz$-֫p_,:932m[Wm-W^9ns]vE9r7tvd㫃ޜ9{z>~~oy.:{\>Oqbl4bHO̚:]'=qc^͜g6uW9yk`L.SWNOɲ _^gyQtOggSkw12ADIMCKPK9H@>AII??>6879ECB<:89:5OH`Nb(@*IT _wȒq|}P蒌@SԷRG۟P?(f>/vDVXGTi.OwE#ԉuglzQ_:h?H>˺n''Ϯ{7~zt/ /FON8K&}V% ۜ(?s9t;b>~wͷ߼}wOo~4^?]X5d9p~<.gݎif"y3l߸ٺqNp^ێׇ5 1Z2r{aDB{՜ߛ=/$}Yny;@V%MHg͚AWȵ4;{2qĺ( D$߇o8|Ց>,o^"  ^cXPwE Apv wc9OV eaaV P{6|0ùn;`y)rY<u-P˕Eqt'Z ۯ Ų 8Xe`h?s>}_JtƒK h01B LO~ykϋVlײv`fy9r}}@=~ sȝkeV:ޚ3Z}"ZS4 bl^]|~ߴ~)_=0 7FpxX9cy'߻pӟަxӚlE,4j1-p|o^0L7;9% __5v;>Z}RZoӎ_6T毐|WX*_\)>_3Ok8Ky`1;!PS @kkieC<{z4NHZ}9{3˳&f|{(\?;y9Ϸ/ʏsܱm%S ?N~3y)1'PկÀ6$j̤nʪB\L[7^OFR\ @{|ћ̶ W.#08?@P 6 9Ǽpkkڤ?z_[Wod.7Ʀ{o _A-(rbǏy [Y]Xuѕg:nHSw!SOӬX3eI9glIi1旧oWyվ6 y#/,kWWϖ>žx[_`T o3b;L0z{ @W΄ 9L'i.4۹[0Bn|CarUK& K )X,*/+m+ƖF?, \#|Xi/% y/F^6urs=@ /S ۄ}!f&ngi}'PtvS`bʁ_{ԺSSGnSir?lNW.@yaō{?ޣ ɯCo1O,+ wtvw71*><.z.Gۿ~gOFQmRI} ࣷy+O~,|cG5 mͳ6fhV<sW}4@7W ? I/l1p{2}߭U>6ߢGWXg&0/Ol|J)3?'M.z?o$+<ΫUa=ǚ ??;xTcHrp[mV'ʳ~gGGWA W:$PnD!5gm~K:ȳ~<'/"%b&UyY#:xד̑_s" )yȋxv3^ݿ8o |*7|ޭMM?IUPƷB{)?'ԩwX8)y, gS56 x[BePhnSb+#V}_t:n3h'jtPۨuJ*6bWCzͲ198:fH]^u>̳݃x ;WYOBGvs<޿ @J-4o}ѯWpVNVӵׂ2Ϳ2sD` 34)]ʳ}g$a>E=Z8d?NIιm62R"e&Iio }[ 9зYdηv(ZGzsܵgkal2'v9~4 =POggS@kwUPtH(H?A;:8:GJJPLPP .1)#3.-Wb>."1u@13պ뻇9[ËMT;GPjVۄk7֚}*u#M2Ln/dyjOj!w%W銂_&"!k~,ܾ_Uܿ$7SXVU̳7OφLXW٩^_8_FR<۟AԶ-,+ <^ |Ky_3x%|_Y3qrb-+Aa6Zޤ[@!0R*ȷ扜\خ| O\LOOo)/_|5gϕ_lޯM#jԷ-BFLir~/O,up&g]y]56?$| ɾ :k?Fomρj}?k|@3;G]>^/ "\GkS+. jz`"',Oqhq'6\G͗ pt]E{>෎K ۙ/6 >N|ٕrvƭ<ބ}p}kzz=s=__84px ːTVQJ$OM6[== ~ OTo>[G,K^_ϰ ,WGAZ*,#,:dT_Z-պ%c>d{,\w"\X2^o|HLW1X?pkJ 0 "Z` !&aRW&;\rs&ϴ 1ǯ j։`gL~2okg LR{[ON gpFǞ+(6@8Ȕ`; A >,_n`,Yt 0TJ%;﹪4@RIe\UTRuh~~Hfk 5Sb5h8|ss=Xo,g13@xמoNZwB 9x{IJRx? H /_ 7ow-Zg_2n}c7 v ݠ^~|c7}c!X˨n_okAطTïZh`v~g:V1PZ!?i`1,p'  *D|WQkk_OwWo|v:vͅ5sfZRMZn+ocەU٥:_r~\no5$-O$M|Pf~Mq릨DTUUՙ p1F~_}iөߩRea m\+WnԮ`//t|]UsgWm۶U6?RQ^w[~Kl9ȇݾďK"{f/l I>7897R)f8x " Nh@Z;gR;䥗> %Sp*jyt4"ZzFFuP}qxz3ZrIp )I/y1, kY㰫*(5'72y OIkjMXƌC8YثE_ ]O> Xj~v UMF^ $~.Զ74`}F\};?Q_㴱Q: L`@W$X#>O_hYpg3ηs>Z ֗4 y48hRͫ{/?J a>yyzθsLc۬۾S⋞I87`cnvw0^6>YlS\Ӻtnޒ6?EdUSG @OO:g tw2] 0@ޟ9(PGNMlgak 2B@yh˛ z/0:㲤B٤~OG̒MXҶ&ZJSGjp\瓻3zN; ""B潑R9z&Zŭak\^?pmqgRHw*{<};\6pej@Zpc{W[j,xWù~Og Z5:}^ ǒy3q>"_nɒؒ@ |,&%6dKcaaB~5ؾb_Xr?3⟾΋7:NN`"TE<4Wo}~Ɯ4~rZ:pEO~7GB h~Nh,%h2$D&Bޗ߻v$y_[Ǎ.:xt>;z0WVCE;]Qw> ߾sݿvȝ@~6.*{m?=ρ}jIo! `zЉ~ںՐr9-]!I4yM@_{߿Y`̶e ׿R<̋}4<&QU ^ * }:Nn~-uX2;$ v?e$94+X/~ : @ Orꠂja"2}5ܯ=6_㧝-Ɣ+OX}k<ٝ|~whGZG[e¨--e]/}_o:u'P]YYY_@^`X߻׳6H|h\x h" J^~a0 -Y~?%@tn!@ˣn@OggSkw>[.*POK%) %&,)OKI??=?>lDZ]Y^I]e*Yұdzm 3%A3b? Za`A !@A*AsY]8>c@5NOEVBK~Qo#2*o 5dfrWX1?9.ٕrz/@ h24@ ,>_0_`1 `D9NQhf?$\yy./{ ~wnZK"/5S@Zkj bߞ{Tv4;M,ۧ?saUl4BG`X}dH,+_uۖg[[T׷>{?zf4 g/¯-W94F^A5v:Мb ܠ& >O{לWgKS_O_%"wegavg%.}s5f HurÇO'98+{o;ZmyP:]U]a3fk^>Lɘ)zz]=Ҳ< svFc-p>۶=>.e'?>ب RAF4ZVp<`H}p?{9 X,~fd< t_Gv=/BڙGᲐ鵖JpPOәu ^ckχ-3(9f:0hBTQ4l~*  d!6_5/>pS<|oQ\htǘO}OK_!jNwO838FicBIA^u0v0pyyïlY~2vD6\Kd ĄDT)|hV{Ғl*.mJ(O}x]46% EsA 4!@`Ͽ #ZK.m4k!zj>;y}ͮ,|۞}g^xz+G͜qO |60Amcg3>/^H>_3p95: 6__:,@Y|UyQV— JClJ*{ Y>(Uh^2?| %S12o~b X, CunaBMD@(FwШkfL_$o)96!x+OwTX}#S<>}{]V H_os)2N(Lw+T[rk៯>_s^+e6ݷs 򔶢2pqqKd e/MU/a˛d^$YF#G rTGENCu9%o1Iv/cy|t?{9 TƳt_R/n3j罻b<|*Llbg3sQ4(sņd Sc d@`k\rQg @Uw]sE] 4@16gi`Ou-|ŁeK^- '  j^Z%EΙvE ܈L\0΄%CҚgGL}J bg߳(JRUl/>v7=Y)+tXIDaM79{oƘn>h oϟ~˧ 7wW{j^f23g<ӥϷo)u]Ye0baZ% EQ  ؀$|zStP$׿+@HHg($L$(\:M >pmkTX2R5̷~mgKz.XrY8 `H B<=|{K*ʀ>-2mEg\/[{/J{;^FsOJ ASSk.}w< Xi)[P\}l*tH(]`l{ǶP`MqVk5~[b} \70.lcM=.k`}F@9/>@0 9Qߵa Kq|u,ewx/ Ꚏ ^z9gh&2BBڋ?zC[jmV~BW 'L%Ov)>Z\@.|{gqcB{~u{! 3=kiphL(X(pxQm`ǦG}0sٕz6]_?tY1<oȀ34_WE@U}١P Cua>{y=zuODF%[syuWLW7߾@\o\愇5pV #X THdvz;'wS |;6w\2Յfdf^baO 0,A|p8Xp<,@a @ Оm2RrV`h!󃂠v4` }7oNyNmјD$8W+#cY-{pxV6Jq{27lrwo4DWH|@,詃+`g7tS=tbww8@3}[`={h@bAL~aݳźt_7$_Zl`O e$鵠|x3<_?+Jg~{g4FAUh8P/2wm c|Cw ?xzuyOyk~G8hg>JPR9ϓ| .9O<`̿.ng/j3޳w @w:nHrazڵQK;iX t7;AC.WWno{R U)?˧~ڶ8o?RT’ٶ(>>P(=6 ; /vLGFSo?7*Dlwyf.P|aFQ@8]I>b uWn.Nܷ6Pjo/B}taZxm\-Qss/BLS@^]\W\@mӿn~;ȲOggS(kw̫$h :9;EH1DZ71wo@LL0Ȏ` jJ6&흣BWƘܧĜ޲c@bv.bZ @jXL&Sb FJclxzЬՑŻuJ̟ q ozI nȥxټȐ%ի沇}5qw;ϴkי)Noz $_g!1b  hU(́ǦǍ&ϷOPӿmfo/+!Lκk풲cHNɕ5;V4<O7/+W뛫mMt,AShB=x}SA簏7'SEiۊ5r-J)yjGs_=<řzc?9~ QF7(*v~Y;\,z3v^ş9`Qz̼ﻓu]Iݷ ,إyO 2- R W/TW,Aa |x6Ca8L꽅+I #gQ">UQ:G<6F_Jx%@ 3wyhB`]~F O]CVnoKxErnEPyt[KSxUǰ oO79c'u쳹n]{W$h~6U=LxgfNdoy4>QB6Rne }!I ~C/j%#!%k(me7$*đܶmUJta؋wCp+Vzm4y_/]|yoΦz_OI/N؇}&]~g!+O_%4TIm}F5ˊVaMiXSzOy6O>c&_[Uuaοk(S,-F`@TwiFwGQi6^~>e~Klallegro-5.0.10/demos/cosmic_protector/data/sfx/fire_large.ogg0000644000175000001440000007011512031751243023403 0ustar tjadenusersOggSkwvorbisDOggSkw.-vorbisXiph.Org libVorbis I 20070622vorbis%BCV@$s*FsBPBkBL2L[%s!B[(АU@AxA!%=X'=!9xiA!B!B!E9h'A08 8E9X'A B9!$5HP9,(05(0ԃ BI5gAxiA!$AHAFAX9A*9 4d((  @Qqɑɱ  YHHH$Y%Y%Y扪,˲,˲,2 HPQ Eq Yd8Xh爎4CSR,1\wD3$ R1s9R9sBT1ƜsB!1sB!RJƜsB!RsB!J)sB!B)B!J(B!BB!RB(!R!B)%R !RBRJ)BRJ)J %R))J!RJJ)TJ J)%RJ!J)8A'Ua BCVdR)-E"KFsPZr RͩR $1T2B BuL)-BrKsA3stG DfDBpxP S@bB.TX\]\@.!!A,pox N)*u \adhlptx||$%@DD4s !"#$ OggSkwǸ46G^XXWOQMILYbURSYQROP_MQNMMOJGUK[SHMIGDLMDBFB@CDEE=A;8;LS_ںfT"G ~X)7,ZGQB<&Րk1qq<ڼS҅z rh}ľ,On1& :2}igCym%=O]К L!|eHX6q"]b\C,Zx|{ \&ݨٽvLyi4e|vSp>>^ȫ | ^Q33gZUD}cs簍c/?ghjDix]1=ֿ^1s# {|~r Kqw~\7`,`:VoGF^NC"whQ~J{-~BV,F9WQ{ f߃ '8O4,pT~sx}>[04T4Uӄ`~ ЂVPȒ)¶6[+pH_ KжR El{?\> yyZߓP# _qG^)V[jE(A|J?=QZ1 hsme0ЇRz0/{@U_>*KM益f}\_R KsmW{6QD@CBXy{@LĶE],Pj^^h"@~Ud澾 @R5NHtT]P+eYpby{gmmpewfvd |uPHx P?K E&QJW/99 @\v $6uM?.)?ӯڎ]~)_-$CwLyOe=`=VpŪ@8O ȶPp!T\o)XRsj;1[ .)}pKЃCPTDp& @qrMz]T`<JL[|lJb7&;brI` 8'x9@^ v^\9Gt}GDߘKVn'pcw5v#+ Ok{K 1 }!}^TjG @xC&7uq_ }c?/D,9;#ܨ'77 s ||rQcs@o*0Cn DY)|uze`s#D)#_y1e>~"!4 xHoB s!~2 tl\:#oy bѶSC>{9%òvm"!@Tx*n i<:9g~@77t |~zrik5TڮO+]@|Dېf]X}!~p/;ggw[\`Z8YB$YJr9h ؎OZ,0(~\ylaS꬟#Сxt3|^_ @|S4UUW> NmNo;; ٻg[^XxvsCau]wjESJ<L(|W6C_@7P&X޶+ܕߴ)snEwBVѯ 3*: 48#/Gyb>@br?o14t_;WDCß:cYoaZ2 J 4˾u͉< b N) yq FP?hi8JJ O[H^n; &9W` g8~j'O?|{&kpo4]+3eq1Z;'\{ JazxpȑiM 5h> AυDiϸؚxy0E7W.Yj iP gӀƅZrv|)v8jXVA׫ԓhTi+3exݼye߲er^59!_]3cT~27i1 ~0y D囆㎙wކ|XlGˌ~< U DFBvmXY6^%(!>%(^>:L)<o2`ao$wFq ?A~^=XM){dη6AGu%@x<רwmV}v8#?-AoE7m{{Wvzt^iۢo,wNWMPOR@~-ܔ3&]{s5<>g7mVS4W7yLZ3^ak7sz,[o0]U3E>Ij*4Z<%_+|ǡ{~"@VC;|B޻* 'R {ҁ@C Oxv(n[ T监 .^d;k7("H>IOTqrvUF)+1>[-/fh p:\&7L g=ǺU^/cZ@ulA񄁟GvzL@aw z<B,GQ<~_U 3``JϪ$@F,Om P4Oö6G07~ 5ֹzxasyAڿ `go]+j,KDT|> >x)涉 Wa24ۻǛƨ{y߿/`ԝgTU|qhsK~2Db9DOggSGkwJ 9;BE@A69;:67?>*i:TYYNJKJJGQ]\QJMLKJPWTJKHEDDNQXKDE,כQѬW{jd5R]P+]}AѾ Nַ<^:@g▟Rmo[Zwa,? B)o % 9]C7O'$H}g=?% sWtt_C[mF,ms o 3Zkd.X==Iy`myfTUVUtg8˻K'2̑H6fYwC %?+?Mۅir6LN(B޶ms?} TRAtOr<2ߑGjP9َ;e`Z|%@ޟ; r]N"}/7&}}a뙾c@VVr~x[oïroŸ@.4Lk緞vvs.Y,H`Y|f t2x3K-M+8ߒ<.?>E3o&[>=PN p_x9w#Zw^ .xhqNh0!Y~y#ns{Wk`/K yr-䓇^at8Y_ݧ(<;6]urb[f60:uP5>߶5b護~i^<@8ՠ4DQ:nΫBbcxZ#ف`@>_(onԈJPs~o&Erg~,o7@RMV%P_FJ9*|ȭČncڵ:C/S6Wo[ɉ+?* ގ0:LW?K_3jOVx}ͽ EjsqBnQu@EpT.Xn XX~VX<WTGAk`PDఘJ2 <*@H4M'>tkAn+>!>@lJ btp@B˳ Q{F*j5\G g\>Jj;@4O p5˗^ܺ%VO׷HC@M03T~Z ^j~ Ef VA̾ޛq\/j_ l):^s}e?\0y#C&#N]~#XX +7>{r~qD_Upf]v NK$G[)0,l^Ѯ#?obR3>ZD&.6`;zy#.7EE#$Sh;AZ@qz 棂z~B @%_vW}C),@g8s/㿿}> ķXV?@+:? -B|iCX ÷;)u^ӽ̀/~rӽ{\/EֻO`+KHC==DS||d;sVIMUVFKf# P9QP?Q æP 2^ft#E$KX"Ϋ@گ\ 0[S~9 G1:G`QP*'$G7Fvo53YOGI'z ތy 0/ @Viʯ~P6Cy?,K}g}gVp]  7f(pvFH{ ?$ ZVE3o8O޼AL^+x튈r-*N)@Ve_@`ES++LOt@?@dwE\@ |7. @4@?V.$B oZ6Y?]{ƃ l1;O~mNv@Uվo_T_ k %ۏXLת%Q&du/{~عXyvEko@APV_ޥDL^9,YJ}_:`{?,X3 @ ^i o_ {`?$^2 삞U逿T<&S0lW3C P/4@pV@G;qv|bx0жR^,򟱵~5l (KOc p`WI^aj/_m hUT/;;jm>||O<o|@- C 땀@LUm5@92S6\o 7W 4/ֵM ǂĒ] l^V>\i5"wt᣶Ԃyt֙]DUw @W% )<ՠwbkz][~?Pٞb~K?N 3IAi?6>>M k]4٬pM/~EՒ]a~} s`{cϽo'Pm7<⧖ϘP{?e"⎫gd5v6息5V_)@})T!NLY?/ rEISIú/zֆ~}'V<p7~{CD[9q825V 07mjBn5T缼/ |kOOggSxkwn6FHC>DKLCAA@<g{vX{:@> 5WvS6{IcsܘhT>𳁦"Z <ėA @ۀn۵xu_7LSO@@WӁ| }{e91 C.|0:\oI-}8]ΉJo0AzAPv,%,_- 6,@h.E.sI^ ! g65w?ӊk{Nx"a _*M~~~7#{^clMڨ8,/ެ>NV9yh;=8]5^>㟫|usו`'_l?CP2 IPޚ%ݓʼz*~\^5] i8A , b *`-K?d!:Wm8yf \o>,xpVM?kǍܠzXZke*Whv߿aŴE`YXҲZ~}j+򦞪~zkbgH5<כ*vUY~v.vnsxO=n>76 |q 44כ\ҽNaﮩG9 LU(7;O6Jr۟~ryp~WW2Z' ?8ԮށdeMgcrv/>{.n83zp R.3Soϙs^\<@-[+鉟??SXl}}m/(O~63==SY2bgX^siggz|F0 oEQUq Lm6?a!3}wffxiE,$uhV^\2uIkR _mE @lK F6@ WUltqre`؜P:TAsTޣNϿ_$r MH \6/^~'~\m=? '}׃3 -\rQFMe~LXp{k1͋q hg\mT~qz;_a}~xG{zdukG y۔z:ߏ pfK.K^j_0,_n (T*4Y|\<_<,:޾VeF =Ӟfas4L3{{ǚ^˾ײu Y.0bSbF!ִhNh67/~oNԝT͝q/ZZ)>vzM+Kc0Q֝_gm|̈C޾/VYE@{ Ua~b. f:,Wgp'_4 \'ӴDT㌬o~]r mn J~.rJ%2 `ˤO'*b>5RvYNܥm<7NhYPS9 IrŽw;`w@G c?@&u([P@7D<LD+ukH`< ;[B>.^x= 6vpyqUT|q/J)<j{`,>yw=П (n[Tw&`im"=@;DZ ac`ڕXoDG@)eG%1<} ޝS;00VX *@>dn`a W߆BS9@f09_ 63ei!@,:0\owoB E_6M饲jNvo?8>-bs'ry|% ׷ az==P+mMtjr? ʵP@z~[ I`Sz$PY>o{S`+}w("U2ddM:%x%0U<DfHG)Le>v[ U- WϬ*J@_=|]KBYj1?ar!ڿĥw3n4[DU@w@NQ8{xS>nN_`6(`&'AC('l^qQ>gpp5 ;}U9ў ?r@~5 ` $@T©pظo=n jā+QE?xYZZ4?[\aSol@U` Sz|b*@^=M><^&va y'OП C@|)cf6s"'T~_ M_e"R]׮<]ܩ5/n $5AyJx{ M|/Ǻbu3 'K ͻw/zhC0x&<>Izg SP+5݊N$'d+1t^Q?;痺KvC:~yvsd<:;: <.Zlʜ/k 5,36aܙc݌?YG/2ǞKIFeN7(ؠROAiܥ?}KІN6`ߊZ9vDn ^@aw{D7?~zqkFm}[~ 9NHo `7Ms\?`2^hҵ6t'UPzJm ~Cr4,Ƞ}d&M?~C@0d-m_{K.B/f(*T0%|,o-%@L㹗$(W-AnuM,Ww 0-F=Ѷ(= @So! iUAKvv펏&.dՠW^&unlSF£5kI [UǻG}<67^; @{돯Xּ*h/sb3|1@p כ|>c?/7VBmsp %lYaۻz kd~4?`һ[6h`mgWxKXwt̻.yv:,KIPAtлEn^smF#Ky }5_ #MBP >λceD?^lz*_ l'y4ȻǛ@o tͼY8MIM Bn:AȻ?H`yaG+ @5/ s, =@`hguy`N{;-5re꯯*o?~ݰe?UK5n SZ+_Qu޴#&w3~@Ї9}?(9ڋ2j_=~E,s-䕇ycG{ߚunuQa?~4籊_Nm/QP$bBR)|lpCkה6'xumK7۵׬u6h%g$?n1&88'ϣbnǜ_TriS%86 d9sX {a>>shrt~o~h7) Lg߷?+~ x,c"e]RS׿?g#QGD6 c`dšC 6|&ѼyB 96Ӻ^wKW.oIن1JBBw_S"w'Wox^ʣ>l>tu_˭.i}~侊|ۗ7k @o3g>_Sc{>sh̽P 9 zK]erzyP@4dz>vyOsZ> L$?JpmCAp^n$9_0ܮ_1S8pf#2RP.N.ǟ_@RWɳ7|{ԻlC55DY]av`М=:K@}gW/a .Cj.Մվ]PPѧD@(?cX~|i~!rcpw9bTĩ 0{JO9sDDJp! x,Iܾ!%rmRN^t"S"#l=8tDsN?"P{A ~u[)>'Nqʹ^sc(\žX!=Nh/r@αfa)_^{Ѯt\B0 {zn:8I0”Z@.>XA/@7+n}׬'-R}$ mKQdӡ3^xqwA-@.j7Bg5(Se#Yf-Y8E `\-]^I1Qxu@{VՀI[:x1sU5SKד2(kn%8ON"'ݼP?ړl}F A  Y6O>:j Xp5-TToԖhXQj?5mo(xB N }} &o~|\!fT-UxG! @I3VP9EiW_K%50+\'~8>kqsoSЮqA5.P7~FOggS@kwg:$EFFBJSU4& "#CU?;#靁>o=_W>ƀ!&P*E}'|W#ibUCş>>B ċ'۞o圃Oo l` %˦ABqrP Abc?Me A,a@Bn*Ǎ|8Zgj  [/BIG%& 8%/c#wݝ7 &+1MK;Y G8 `v?,h@ł,)qN,,)`v' ֿ~~⇃GQX _ TWkPW[m˪RrM/˥8]~"ȝgn Q=x).4^SO5I{oxw $:Zw&%R%ӫoƎK. X/4@qpua<4!@H u>墷㾏&W]UZmCu%gL4aT?M}dyˡV;'Ҿa{ڦo׳RU'?ݡT-Uԏ{apP9 2l׮R Ɂ_R J[ڇ6*mQo^CY(^gt:E^fAz4B NAE?X#WfSP0M&`J})f{_fV[]$йYkr8sv H}rSܩWxr6LQ@4cr* [YRZLWnkn;s1_8a}8~'or2ϗ=x;xٲ 5Og_z4 m#~/~,)"zk_̟͗P @$r1]ޗ6aGI%zӔora>_+58ɒx@! t>:ɃûYwߞךbf,WK$aL%GoWQo)|m4^o~{srl}u_"`Y[Ǘ޷ed-JIISU ޢo_22 ~$G%-"/-IKxNMw}bFfy.]R pB*A!HE+ؓȘ>OO$LShp (+ˏ۟V&w?~xq>Lm3gBC c6ӵUQO~.?o?.OEV=Mq4Vjg;w Bk21+xx=i2 #FETEZ2uչ{rW am9oxVҼY|Ň<Zr _,-6)r>;CR;zHnz]{{s7L&>f|-5l'L1QϏ{:HZz^Z2Hʗ|n~|T /a`׆@[0EC/d[#CDZfZyP^Tr_0aYd{MϙN߾Ԏv05876w N졙*>I3\^aeqfB7;=]@n9Ɂ1ocJ4_oo5]RR >RI6x ^z+F"r^Z]̝tdȡ ~$aOr݇@$P?~vHr\^=S, ؿv:bYn(0FUUe=[h~~x<-}@#[Zm֝R/zvnLU듙 {3@ԀҦ_}q0>ŋӻ4Ǐ2tL}f;;r$^J==VIcchI59_LՕGə2K9AP0>[Ԍ)4Օc,y[b;5+ =(bP*R XrzDxn=wȩѣq_f}O4@ \,00uiŧ1c s?GS?_wYI;ZO+PX}y]F?,*\,ۛO_RR|^@KO;w*4{ȉ0%F"%3y =uJ+8w ;C40MHBd;~,Aԗ9}qoocmĬR/}y'o~rۨ7獲1av&š7|07[/*}Ҟ߷ElgVroo}每l{.;vjq}כ7g,V/4óP@eql'Z:,e_7?F2իJ!/Km>w(%ʃ[1ͻШ.T1|#KoG. IPk8LxB AA$`])`oMu{箶MRVw҅KC߉= _Lkefmgy1/;9$4'f~F#u{ }^hШ״2>v]f/ȧE T}S'O|%YXRկPKO D}F[J7 8>ԢSaTLwAЗ4xS>d7>ߟEKl[.Gj#rBhBYM!S¸]j>[{jN ħM?MQdxÑ)[K'/62⒃̓ǿ1>OAsfznrj<(΅\[~8{}y}Q~S뗯0~E\ fX~ Qf@T,Ώ19`|9@ fITxFOggS(kw_  &7)MR;,>Jznrm'꒔;̡ƷV7<'K`h0 " eu96u%? G}rϕy)F./Sۛ;-R#oi_WQ 3Tg69ɉ"so`~o QIo8g j߿ûFg.d Pr?[%2锟#%?{+"BP/Fط-)0Q}P-]DU@>> @>Ds9h~mI"3MCS|. cow80  H;7ɸsǵ\^>O;qϦ2C>9f/k mSt]5t 9,0)a$*g}ūo'iȹvh`h}&539L8*MieHIJ,K{q rElT0`}rl0gū鼍樫+mGz[_s?ג߽8^N? e4QFrUU!b7={, L}oO|>tvM~xv5]͵YP L[_f0eƿ>q? <|gc_k Py޾{l'7PEOϟ_'@Ԙ7<>NLTڟX G5Ѐps*ӷW0 W*hięC!5`u U>NWG%qe%[py. Xon"c,.N;^(P*B@-G3?Jvu&!T9j}vk̦w}`,MrO믟m&`_~Pyކ?y_.{Y6/o6vMϧ/{{I.Ŵ+ Z5l6>,_n`,Yt `1W hCU3b$C]@C5U(1N[JǛ=߾o_;{OMK'zj*xDee3LuA304 Tt FR~SY\/aw;+OThmd֕z9 -A*URlЭD ^tb<H,iDo^pgl/eY7pT ."Ƞ 1?S]}ݾTIzz(9OeşbK;"r>DpbNp=e,%2>?:k,:sqw}sv|?Ϯ{b~ y.Sm`Jr{nz,vNT59tl*y nQ/ELTgLLf|lbcU{ulfc̱ˏ>&#zFS @ 9O,Wo췃W^~[?fmV&.?]R,1\wD3$ R1s9R9sBT1ƜsB!1sB!RJƜsB!RsB!J)sB!B)B!J(B!BB!RB(!R!B)%R !RBRJ)BRJ)J %R))J!RJJ)TJ J)%RJ!J)8A'Ua BCVdR)-E"KFsPZr RͩR $1T2B BuL)-BrKsA3stG DfDBpxP S@bB.TX\]\@.!!A,pox N)*u \adhlptx||$%@DD4s !"#$ OggSnwsV6G^XXWOQMILYbURSYQROP_MQNMMOJGUK[SHMIGDLMDBFB@CDEE=A;8;LS_ںfT"G ~X)7,ZGQB<&Րk1qq<ڼS҅z rh}ľ,On1& :2}igCym%=O]К L!|eHX6q"]b\C,Zx|{ \&ݨٽvLyi4e|vSp>>^ȫ | ^Q33gZUD}cs簍c/?ghjDix]1=ֿ^1s# {|~r Kqw~\7`,`:VoGF^NC"whQ~J{-~BV,F9WQ{ f߃ '8O4,pT~sx}>[04T4Uӄ`~ ЂVPȒ)¶6[+pH_ KжR El{?\> yyZߓP# _qG^)V[jE(A|J?=QZ1 hsme0ЇRz0/{@U_>*KM益f}\_R KsmW{6QD@CBXy{@LĶE],Pj^^h"@~Ud澾 @R5NHtT]P+eYpby{gmmpewfvd |uPHx P?K E&QJW/99 @\v $6uM?.)?ӯڎ]~)_-$CwLyOe=`=VpŪ@8O ȶPp!T\o)XRsj;1[ .)}pKЃCPTDp& @qrMz]T`<JL[|lJb7&;brI` 8'x9@^ v^\9Gt}GDߘKVn'pcw5v#+ Ok{K 1 }!}^TjG @xC&7uq_ }c?/D,9;#ܨ'77 s ||rQcs@o*0Cn DY)|uze`s#D)#_y1e>~"!4 xHoB s!~2 tl\:#oy bѶSC>{9%òvm"!@Tx*n i<:9g~@77t |~zrik5TڮO+]@|Dېf]X}!~p/;ggw[\`Z8YB$YJr9h ؎OZ,0(~\ylaS꬟#Сxt3|^_ @|S4UUW> NmNo;; ٻg[^XxvsCau]wjESJ<L(|W6C_@7P&X޶+ܕߴ)snEwBVѯ 3*: 48#/Gyb>@br?o14t_;WDCß:cYoaZ2 J 4˾u͉< b N) yq FP?hi8JJ O[H^n; &9W` g8~j'O?|{&kpo4]+3eq1Z;'\{ JazxpȑiM 5h> AυDiϸؚxy0E7W.Yj iP gӀƅZrv|)v8jXVA׫ԓhTi+3exݼye߲er^59!_]3cT~27i1 ~0y D囆㎙wކ|XlGˌ~< U DFBvmXY6^%(!>%(^>:L)<o2`ao$wFq ?A~^=XM){dη6AGu%@x<רwmV}v8#?-AoE7m{{Wvzt^iۢo,wNWMPOR@~-ܔ3&]{s5<>g7mVS4W7yLZ3^ak7sz,[o0]U3E>Ij*4Z<%_+|ǡ{~"@VC;|B޻* 'R {ҁ@C Oxv(n[ T监 .^d;k7("H>IOTqrvUF)+1>[-/fh p:\&7L g=ǺU^/cZ@ulA񄁟GvzL@aw z<B,GQ<~_U 3``JϪ$@F,Om P4Oö6G07~ 5ֹzxasyAڿ `go]+j,KDT|> >x)涉 Wa24ۻǛƨ{y߿/`ԝgTU|qhsK~2Db9DOggSGnwۏ9;BE@A69;:67?>*i:TYYNJKJJGQ]\QJMLKJPWTJKHEDDNQXKDE,כQѬW{jd5R]P+]}AѾ Nַ<^:@g▟Rmo[Zwa,? B)o % 9]C7O'$H}g=?% sWtt_C[mF,ms o 3Zkd.X==Iy`myfTUVUtg8˻K'2̑H6fYwC %?+?Mۅir6LN(B޶ms?} TRAtOr<2ߑGjP9َ;e`Z|%@ޟ; r]N"}/7&}}a뙾c@VVr~x[oïroŸ@.4Lk緞vvs.Y,H`Y|f t2x3K-M+8ߒ<.?>E3o&[>=PN p_x9w#Zw^ .xhqNh0!Y~y#ns{Wk`/K yr-䓇^at8Y_ݧ(<;6]urb[f60:uP5>߶5b護~i^<@8ՠ4DQ:nΫBbcxZ#ف`@>_(onԈJPs~o&Erg~,o7@RMV%P_FJ9*|ȭČncڵ:C/S6Wo[ɉ+?* ގ0:LW?K_3jOVx}ͽ EjsqBnQu@EpT.Xn XX~VX<WTGAk`PDఘJ2 <*@H4M'>tkAn+>!>@lJ btp@B˳ Q{F*j5\G g\>Jj;@4O p5˗^ܺ%VO׷HC@M03T~Z ^j~ Ef VA̾ޛq\/j_ l):^s}e?\0y#C&#N]~#XX +7>{r~qD_Upf]v NK$G[)0,l^Ѯ#?obR3>ZD&.6`;zy#.7EE#$Sh;AZ@qz 棂z~B @%_vW}C),@g8s/㿿}> ķXV?@+:? -B|iCX ÷;)u^ӽ̀/~rӽ{\/EֻO`+KHC==DS||d;sVIMUVFKf# P9QP?Q æP 2^ft#E$KX"Ϋ@گ\ 0[S~9 G1:G`QP*'$G7Fvo53YOGI'z ތy 0/ @Viʯ~P6Cy?,K}g}gVp]  7f(pvFH{ ?$ ZVE3o8O޼AL^+x튈r-*N)@Ve_@`ES++LOt@?@dwE\@ |7. @4@?V.$B oZ6Y?]{ƃ l1;O~mNv@Uվo_T_ k %ۏXLת%Q&du/{~عXyvEko@APV_ޥDL^9,YJ}_:`{?,X3 @ ^i o_ {`?$^2 삞U逿T<&S0lW3C P/4@pV@G;qv|bx0жR^,򟱵~5l (KOc p`WI^aj/_m hUT/;;jm>||O<o|@- C 땀@LUm5@92S6\o 7W 4/ֵM ǂĒ] l^V>\i5"wt᣶Ԃyt֙]DUw @W% )<ՠwbkz][~?Pٞb~K?N 3IAi?6>>M k]4٬pM/~EՒ]a~} s`{cϽo'Pm7<⧖ϘP{?e"⎫gd5v6息5V_)@})T!NLY?/ rEISIú/zֆ~}'V<p7~{CD[9q825V 07mjBn5T缼/ |kOOggSxnw66FHC>DKLCAA@<g{vX{:@> 5WvS6{IcsܘhT>𳁦"Z <ėA @ۀn۵xu_7LSO@@WӁ| }{e91 C.|0:\oI-}8]ΉJo0AzAPv,%,_- 6,@h.E.sI^ ! g65w?ӊk{Nx"a _*M~~~7#{^clMڨ8,/ެ>NV9yh;=8]5^>㟫|usו`'_l?CP2 IPޚ%ݓʼz*~\^5] i8A , b *`-K?d!:Wm8yf \o>,xpVM?kǍܠzXZke*Whv߿aŴE`YXҲZ~}j+򦞪~zkbgH5<כ*vUY~v.vnsxO=n>76 |q 44כ\ҽNaﮩG9 LU(7;O6Jr۟~ryp~WW2Z' ?8ԮށdeMgcrv/>{.n83zp R.3Soϙs^\<@-[+鉟??SXl}}m/(O~63==SY2bgX^siggz|F0 oEQUq Lm6?a!3}wffxiE,$uhV^\2uIkR _mE @lK F6@ WUltqre`؜P:TAsTޣNϿ_$r MH \6/^~'~\m=? '}׃3 -\rQFMe~LXp{k1͋q hg\mT~qz;_a}~xG{zdukG y۔z:ߏ pfK.K^j_0,_n (T*4Y|\<_<,:޾VeF =Ӟfas4L3{{ǚ^˾ײu Y.0bSbF!ִhNh67/~oNԝT͝q/ZZ)>vzM+Kc0Q֝_gm|̈C޾/VYE@{ Ua~b. f:,Wgp'_4 \'ӴDT㌬o~]r mn J~.rJ%2 `ˤO'*b>5RvYNܥm<7NhYPS9 IrŽw;`w@G c?@&u([P@7D<LD+ukH`< ;[B>.^x= 6vpyqUT|q/J)<j{`,>yw=П (n[Tw&`im"=@;DZ ac`ڕXoDG@)eG%1<} ޝS;00VX *@>dn`a W߆BS9@f09_ 63ei!@,:0\owoB E_6M饲jNvo?8>-bs'ry|% ׷ az==P+mMtjr? ʵP@z~[ I`Sz$PY>o{S`+}w("U2ddM:%x%0U<DfHG)Le>v[ U- WϬ*J@_=|]KBYj1?ar!ڿĥw3n4[DU@w@NQ8{xS>nN_`6(`&'AC('l^qQ>gpp5 ;}U9ў ?r@~5 ` $@T©pظo=n jā+QE?xYZZ4?[\aSol@U` Sz|b*@^=M><^&va y'OП C@|)cf6s"'T~_ M_e"R]׮<]ܩ5/n $5AyJx{ M|/Ǻbu3 'K ͻw/zhC0x&<>Izg SP+5݊N$'d+1t^Q?;痺KvC:~yvsd<:;: <.Zlʜ/k 5,36aܙc݌?YG/2ǞKIFeN7(ؠROAiܥ?}KІN6`ߊZ9vDn ^@aw{D7?~zqkFm}[~ 9NHo `7Ms\?`2^hҵ6t'UPzJm ~Cr4,Ƞ}d&M?~C@0d-m_{K.B/f(*T0%|,o-%@L㹗$(W-AnuM,Ww 0-F=Ѷ(= @So! iUAKvv펏&.dՠW^&unlSF£5kI [UǻG}<67^; @{돯Xּ*h/sb3|1@p כ|>c?/7VBmsp %lYaۻz kd~4?`һ[6h`mgWxKXwt̻.yv:,KIPAtлEn^smF#Ky }5_ #MBP >λceD?^lz*_ l'y4ȻǛ@o tͼY8MIM Bn:AȻ?H`yaG+ @5/ s, =@`hguy`N{;-5re꯯*o?~ݰe?UK5n SZ+_Qu޴#&w3~@Ї9}?(9ڋ2j_=~E,s-䕇ycG{ߚunuQa?~4籊_Nm/QP$bBR)|lpCkה6'xumK7۵׬u6h%g$?n1&88'ϣbnǜ_TriS%86 d9sX {a>>shrt~o~h7) Lg߷?+~ x,c"e]RS׿?g#QGD6 c`dšC 6|&ѼyB 96Ӻ^wKW.oIن1JBBw_S"w'Wox^ʣ>l>tu_˭.i}~侊|ۗ7k @o3g>_Sc{>sh̽P 9 zK]erzyP@4dz>vyOsZ> L$?JpmCAp^n$9_0ܮ_1S8pf#2RP.N.ǟ_@RWɳ7|{ԻlC55DY]av`М=:K@}gW/a .Cj.Մվ]PPѧD@(?cX~|i~!rcpw9bTĩ 0{JO9sDDJp! x,Iܾ!%rmRN^t"S"#l=8tDsN?"P{A ~u[)>'Nqʹ^sc(\žX!=Nh/r@αfa)_^{Ѯt\B0 {zn:8I0”Z@.>XA/@7+n}׬'-R}$ mKQdӡ3^xqwA-@.j7Bg5(Se#Yf-Y8E `\-]^I1Qxu@{VՀI[:x1sU5SKד2(kn%8ON"'ݼP?ړl}F A  Y6O>:j Xp5-TToԖhXQj?5mo(xB N }} &o~|\!fT-UxG! @I3VP9EiW_K%50+\'~8>kqsoSЮqA5.P7~FOggS@nwBc$EFFBJSU4& "#CU?;#靁>o=_W>ƀ!&P*E}'|W#ibUCş>>B ċ'۞o圃Oo l` %˦ABqrP Abc?Me A,a@Bn*Ǎ|8Zgj  [/BIG%& 8%/c#wݝ7 &+1MK;Y G8 `v?,h@ł,)qN,,)`v' ֿ~~⇃GQX _ TWkPW[m˪RrM/˥8]~"ȝgn Q=x).4^SO5I{oxw $:Zw&%R%ӫoƎK. X/4@qpua<4!@H u>墷㾏&W]UZmCu%gL4aT?M}dyˡV;'Ҿa{ڦo׳RU'?ݡT-Uԏ{apP9 2l׮R Ɂ_R J[ڇ6*mQo^CY(^gt:E^fAz4B NAE?X#WfSP0M&`J})f{_fV[]$йYkr8sv H}rSܩWxr6LQ@4cr* [YRZLWnkn;s1_8a}8~'or2ϗ=x;xٲ 5Og_z4 m#~/~,)"zk_̟͗P @$r1]ޗ6aGI%zӔora>_+58ɒx@! t>:ɃûYwߞךbf,WK$aL%GoWQo)|m4^o~{srl}u_"`Y[Ǘ޷ed-JIISU ޢo_22 ~$G%-"/-IKxNMw}bFfy.]R pB*A!HE+ؓȘ>OO$LShp (+ˏ۟V&w?~xq>Lm3gBC c6ӵUQO~.?o?.OEV=Mq4Vjg;w Bk21+xx=i2 #FETEZ2uչ{rW am9oxVҼY|Ň<Zr _,-6)r>;CR;zHnz]{{s7L&>f|-5l'L1QϏ{:HZz^Z2Hʗ|n~|T /a`׆@[0EC/d[#CDZfZyP^Tr_0aYd{MϙN߾Ԏv05876w N졙*>I3\^aeqfB7;=]@n9Ɂ1ocJ4_oo5]RR >RI6x ^z+F"r^Z]̝tdȡ ~$aOr݇@$P?~vHr\^=S, ؿv:bYn(0FUUe=[h~~x<-}@#[Zm֝R/zvnLU듙 {3@ԀҦ_}q0>ŋӻ4Ǐ2tL}f;;r$^J==VIcchI59_LՕGə2K9AP0>[Ԍ)4Օc,y[b;5+ =(bP*R XrzDxn=wȩѣq_f}O4@ \,00uiŧ1c s?GS?_wYI;ZO+PX}y]F?,*\,ۛO_RR|^@KO;w*4{ȉ0%F"%3y =uJ+8w ;C40MHBd;~,Aԗ9}qoocmĬR/}y'o~rۨ7獲1av&š7|07[/*}Ҟ߷ElgVroo}每l{.;vjq}כ7g,V/4óP@eql'Z:,e_7?F2իJ!/Km>w(%ʃ[1ͻШ.T1|#KoG. IPk8LxB AA$`])`oMu{箶MRVw҅KC߉= _Lkefmgy1/;9$4'f~F#u{ }^hШ״2>v]f/ȧE T}S'O|%YXRկPKO D}F[J7 8>ԢSaTLwAЗ4xS>d7>ߟEKl[.Gj#rBhBYM!S¸]j>[{jN ħM?MQdxÑ)[K'/62⒃̓ǿ1>OAsfznrj<(΅\[~8{}y}Q~S뗯0~E\ fX~ Qf@T,Ώ19`|9@ fITxFOggS(nw](  &7)MR;,>Jznrm'꒔;̡ƷV7<'K`h0 " eu96u%? G}rϕy)F./Sۛ;-R#oi_WQ 3Tg69ɉ"so`~o QIo8g j߿ûFg.d Pr?[%2锟#%?{+"BP/Fط-)0Q}P-]DU@>> @>Ds9h~mI"3MCS|. cow80  H;7ɸsǵ\^>O;qϦ2C>9f/k mSt]5t 9,0)a$*g}ūo'iȹvh`h}&539L8*MieHIJ,K{q rElT0`}rl0gū鼍樫+mGz[_s?ג߽8^N? e4QFrUU!b7={, L}oO|>tvM~xv5]͵YP L[_f0eƿ>q? <|gc_k Py޾{l'7PEOϟ_'@Ԙ7<>NLTڟX G5Ѐps*ӷW0 W*hięC!5`u U>NWG%qe%[py. Xon"c,.N;^(P*B@-G3?Jvu&!T9j}vk̦w}`,MrO믟m&`_~Pyކ?y_.{Y6/o6vMϧ/{{I.Ŵ+ Z5l6>,_n`,Yt `1W hCU3b$C]@C5U(1N[JǛ=߾o_;{OMK'zj*xDee3LuA304 Tt FR~SY\/aw;+OThmd֕z9 -A*URlЭD ^tb<H,iDo^pgl/eY7pT ."Ƞ 1?S]}ݾTIzz(9OeşbK;"r>DpbNp=e,%2>?:k,:sqw}sv|?Ϯ{b~ y.Sm`Jr{nz,vNT59tl*y nQ/ELTgLLf|lbcU{ulfc̱ˏ>&#zFS @ 9O,Wo췃W^~[?fmV&.?]k<_-tp&-T)}K}@*Puv\4.wivuqdJfe˭nԵJ`T 5*L0bSA}n9ReV~9.SQ8?]OpM*(Jcƽ]Yܧ.I"ES03B pz䡚rn.r„,GF_Kщ5@ ~^ḁZ fT1ͫB3kwi4h oN0(%-M,Z9/%>_r x_]]]!IsQ182M0NU~H+u]ϡbTQ 8 dRC=D|&t8T͸ S7X*f|{j ,6 &7vW$"5K@{ @QGV)S?^o鹵KS)ޯ+4WZ5r'9dVdd@m 17ꣷXH#r,!ߞIVOL9'^geo ChT?Ntsc/d'vpa\V\PG\$>ޒPrI_GӍU}$ajU"C Թ/<@P(l9=&ԂK׫Q}nuN̔:kϷM[̌^Ua'S%"sm!Rp-`kŨ9VQ$> $;M(Cv볭m_FPO+Kd2j۳[3e"owL@myPu<ҹaS62ǩt)wE"n~7&<ќ^"i~,k۠M!" 6g+f!O&8l*id-"?{Q+a472nE95ڋ<y1w77T8F+g@" )H&+q?*6N3Pyt @yh I͆_ƃW9"AV'1p8xJd|\[ڡF9`༳2w/;{RE v w๤զ1﬽"'\l TSBe>+$ҔЙ:aCM0$\lV3fL?y6T2Op,LfJ!k&TgѺ!+'l]5sdѼžW;T0O@k[-jiD֓]evދ:sΠ/aRc# 32;pԯRX&jh7 έ'&^$rrww,ʵH΂_UcUcPa Q%(|fd) [uE`oruז_WLלV:Yѽ_ckfkPC1萴ʅ4R@pAA/'M7nI+es'y]Za0oNUY#-B ~`5CShaYW k1ngS<U;Ppeh${~: mK,Vp&L`$zA:J*EGC!t0ggB)0E0vD; K(oze<~bZq.A)NcqvA5pw3Ly֡y0K4a1>bjj_QףcCfvrI,J~$W;kC-HM9!-" ׀(G'Iض`܎dGuf)[T0s{}ҌòaI_E;P:U>6 #&*5l˛`; قSD F̏ X*@௎hҋϽW}hr*he21dyb/6m))O5Kc+RQ.1Fq7(ȺYvH4<5>L~~47@bz(Z=+L[>J賔At6{z;-cЗEN-&8n@հf'sZ rF>_Y:*EQ\˺Z_EaF zp,+M"6! w?t`:8TE(1ex*rz4C\בv/<$Ή%{ }@އCHZ&"$clPSVϩNp/nI$/ՆKý {㶬ix >0WF=C@Ҹ6FfJj=+O'rP5`F tb=,ran==7uuuo)"Nk#{PO0 0 @&Ǥ% E/&*OMg xw54AATScw.3jt훜C H?NQ)@Tm8FЍ/%8zd|os9{!Nb6D Ӥfjǝ4pX/>_0`Q?U©.U5ܠq iAVoeaY Εx* ]RlV:i.|TTD)MrwS-w2d0T--;m+C&mvߡf#eWns8~T @tX_~lUFSn E@, (K+.wV ${Z|f4.j2NWBp`,zz d餿{{TO~wAK֜t-:4Sfoɲlv?DVjPypH {ߝK~Vu,R*(YRloB'qӶٺԤ4f/84icg4OggS_nw:2TUMEHJEX\YRLKGZQLGGKMaURRBCY[SJAHCWd\`^]Y]X\aZW^b^v@^<ԜɴﯷJd%!P!E me(F#SHqvTnZ͌- rGAXxtzVX梨{~<v8UzZ0뎫4'NuLi20Y0ˠ2JOӢSYYt /ev`[M(XØ1f+NȬҡ~6JD~+`D\V,Ez`.4 ;8Ě3?dݼ*BOB $|*ؓDwlgxzUS(mSyݥZq Pp&AW!`)Gv~:VP|%;?H^7ìjGuoO 1Kh`-4?6*[?mc孩+B/@?ƭ E?yp%&.iے9ororFx;=΀2;\KrlX&1H++/,۔|u@_dDa15|>4$i?flE5W7$B;6 &㼴X c߄MPF)h.e|u\F WK{J Pi+ bChBdr*k ~>Q:\3P{e;z=> `P TQ!T )$\̤PGQlsV1c#Nz3N@`d|&NSv^f~$4kAE4E(E@N'=$OJ+`?ۄ`Ez#: P,)M#JQKh-0?R=E,T"I @t.)"]d˘ MeX?l\u}>gv{P:h=كP!ًS3k-1w `X4~]6X ON% c+*TLy濴@4g}3 ,aYL`y#@>*Hޔ4FN\u;~&@%sх6䌮 o_/~P0ki@6vtI|Ά6 Zvpy6˹>H@BAzIu7XLlxܔgP@JZcs븾{=E>|U @Z%xil `Il賴ZDmԧ8[` P@WNQbtmK8O x_q]t>siuc6BJ6t?%V fhD`c!,7Srs/bxlJ-`cg7.Vw!rc6j=(oz{)?S` hHqWaUp8xi@&s&U\ #`*Hbk:v QN>7 i? $` R=vEh쾽 c @ @ݳs;*RId0#~OYraozf|k``X_7%rSG0?*૴ wHhQwJ\Hkt0r6\;0rgl!Rі&- B1rk z=c ̡ǔrg4E]4 G(-Yl҃&Y!ϳ$N},R0Ord/=#K8$:TldD S/k bM* bTn_۝g=`&x{A 8ʥds˴) Ll!عDGuXzHΎ}2񛷩atp*թ3D?>HÓ'W%e~Ӗ¾-gA;6e%ɭQ}{?PT\ȱe(Kߪ2h*¹4jTx-G`dZ2H1{h%5CםFA!mx5.Lu)Rɥ^+'U& {G'F7"*8Zu\A %E!W!sVو7Ղ{E(9#]# @TTO(y:p&f B7%%VBJ_^6D5G5_;8s(E ?3xGSY:x{jQ0Y3.0w.$9~(E' *N1lBou.gE 0Q'(#>Ex%f\G1,h<*jz(meY/5 T z2xx=idy .no*9SֈXKsZGa/1,.^̺GB͂B4J|:"ۘt60Q-+ Op_h~1)hт'D0(yHݯw1V|Fk,WQɩ>aO;H< Զ=?w(2W?r޻F%ZjOw$nwx2q=v:;m$z:N"\ _ϛ؛G$Y1S? 4 11e@^Ą0:.a>C [ưQ(X* v:&|Дj  YwɮaAǍIͣ_g q?p0w,8\ *07cq)d ʤ.?L_*Üe}'ɼV\ݝo59 KTw$;:w$ !?#d|Ti\$ ?G;>"3^d=3#j~' d"mb$xA-)\-BvZl)np"#|^ϷDUs*!B]g'6/Вt+}Yq4w'=Ў~8ӱX1۱& ڔyS"zvV鴃+X{1fV C p;~IV%RwkH_B82g<`b5 r} $&Nx:#BByP=O'k;X|6n.S“ivw.^>mnΩL$@~yeEլY:IһZ@KĉOՔZڌD04#ni,[O83X#Gm )}]cBiG{V8'.A ~-SIV2_LjPTƓv|!fуEаQ~ jP(JϾ9CǖW[[TxOe$-G;0S8t_۶S=ȟ"GЦM#Gk`ikns?UPX(+֤%E߿8Yk?N-mVQ4[8&\yi .r`&O8̅)'4? -7Ʃv><  ,bօb{ȥHڔ(cC|Dblӿ߂,C;̛#b8ǬG6Yk/8afq;Űj_O4@*=X{oW^ [ܜol,)` dD_T<^iw_:&G9^σ#4p .yWZI,;2ܚc((T7/ e{ogk6D/zOoiH¥VuFOz%<Ѐ}I}!8oGq%*뉶4[A1؊\~ <\3D2_֎ J( `Z&GH. a#dW \ j/DHׅы#I:p#ra({P@(ӍfS-B1y Tz5:+5*>gD<eo2x$}Ujpe2vmxcR/AUg4nVVIdqae|@M Rڃ&t31xXc)2z@?暧II KR؃8ENo)p7 mz`,uKV5$ߛ_'&s9orGj ]L}okDk[RzgJKhxjʏ9d\s wE+@@Lv ˊTl-vD*sL #,*tE΂egӖM 2ٯ?ʣRh[a SJij{* 5H%mhs!X3pjKh+ca`e^%Vyd_C Z ?Y[“RwGEf=/TL-#'~tP vѥb -joΡ(p.Pfj xA*;=|X')k<:4O=ٺ(cВm(q=P6m7F" )pd>9I4uº.l WzIǕTаL WPӎ_{ TTn]>XWey=mAK4Kn.L漑5vfc4=l( m[ν(Ɓ o2I & %\<Sq>].(2:@+@rd[r@ ]/UA"ֶ01`toXγֆIY:ӎ@ ]fxhNK@@↲`O! Nm qf| a=HdoΫXuz"xdG{r$e }ާ+/p@.RlAyC18JIEtyĺ=-h JTogE8tTM{lk[[=~D*d>,5yp{a|rZ4Hg8(*@<5JX^=6)?ϧX鎑e޳,wn:NcAES R43SԮr ײpnEc5R6 +K@Dad<]҇0@UՆbԂ /{ Dv ;N^c.&TMn%"Oaç3)_nD!Vբ`V:·{Ws֗!v5l7&+kpqJ.pbcq5wK #47d@Pv9Jx%{ξnj-ooD)֪GiĒyA/w)dgMAKsb.,?y6oH"bw 2O!S)ϧ:Q;&Tk 87?+$|2О"{fQJLYHUk/<'(Cy;y>K%W9,^Y" 'C$74nq{啞Ǵ\ff5{׳_s\TpA}kF_7m jawgel Ɋ]rAu5L){1=p,P(OggSnwp3\WSSUbVRJLPYJEB?C\_\MKHP\ULHNKO[WPFGAM^FALEGO]^_d^]F63@-oTڦ?mjZ >{ m;CdDׇ=3G,0A0qNc %ØcCS|F bӺ:j@!ՕT͖,D%8{yBy!hh/5pZaJnHɇ'e@u*5a3cDh J/;H{vr+8𐥟4v7*^HGyďsv#Ccv:*H9t(ϋaXvA}A]T?"E Pf T hHU|ü62 ʸa?#(HBPskT;u"N栯9zzb:.HKX 4呾 cbDq%apk+baбDa+]%&;ĸ!#FiwI'(譍'Fd&T3@`P#n8?=־V T8; %?# f<<խ5js QQO 84Tuܣr^>j`L)EyXj^3AOME 9ﲕNetvX[e\?@2Z/q,jaL&UMQ Rw&oQ$?>tnoFrAEĂ v_SğP 1b1 G1J5g`( 3֯z[yJmrUW36&jOL @2U%3@Sw16&#6"nBBP:6hQ |/ sE"2ygtSɆGknQUƧpeڛWxU$KE'ZtB_8T5H45Trap  MlEM$t?5v'hC5OǽYmk@3Rڕͻtk(b}<:ny&л5Ԭɣ^*@0џ7=>GZ/- CNVh*.i5zY ˧bJ:ɜh f9-1\(Raƪ֮%`P$mxA_hl=i%zO@f #;Y'?z/B4"32>6ZI,?'NJ(6[{KAl=5 6y+@._ABu~8sΟ9iD7"K[   mQ "V@(@ x[R1{'s7j ԅt`wJ*\a|n`X@V@+8Os0j5bJ 瀖LfE !9pM䈨Si/B$X= [ ~aPŲgc[GEG;]wR >ߗ8W@q0!Ho/~ߵ}BE'V]~\ӲGqZ蟟84)HH@.40<qKϧa Tyݣ#$=~i8r@P냍-YP `}k;ީ] @Xa p,Jg#\iuיbԈK a:Lݩ;\>v,?}/,qj<) @gV\ <pF:˕_W^ӉkJ0ࡃʕ RY8b#8OSPH@ cgRakOVT?DT_࿀0xPb Ot `d)ڏ`k\&[}j߿>{!o-FC'Z LN کD`4'8P{x+A쏿N/ol$sg.}IB)@O .mJ LUiFd\GvԮIWxS49~<@AZ\]'-l<$?0d0!T tOa6or"n/@ayd%{ٜPW~9=trK;Y̅]v"'@h'$+絿aV!QPny]f\^ 艘^a_!r") <8BHC֒LM6p_t]mD}J6cn 'sor'y ^FZB$~sY]K TG)}z:zֿN:1 2 ~5e;UI?3oLVYtO:v_w{\@q6Ew#(nd d'cf`z=@EVOK*vWv_7=yhgVC d+;o"pS?/H"y`kd:a{17v_7e pT/_T` ;1Xb=Kc@p+l WÖbƈeVOpbB*LJL={|9MrRd:)dhznqUa(.֙;Kzܖ#9#)^pN">J,U*yo8j @Vc9NٮaS;Er(vyy+=9|<⹄14qIJbFf+QTmCI.j8j.=*K?3AbT{:ݦ3:i[F`ɱaQo?ۃ+Qr̩R;6}XV⵲r]گVmPD,Y+=i%uֱ"\W!s!F]K.~&f\إa䁧!@R}gIq"]+ͬ^>h屧n = F1b8'5xfJ|!>ke/HGkncш4~Z  ZιzMi]Re"ɤ9#%O$x (JI Mh*}ZBS%0bb4e9e䲹~KջXk-fc鎊==to[Ud&OggSnwJy/]]_[_Z_`]S\YXX[T[[YYVYZ\Y\_aSUOQLV]YSTNQc_OPSQX7 L *ԇ YcO6mu'Eu%ͦոs`sKoP*w=UExL3{K{5c#ơ9?@ :.#MW֥%okk/L0Bfa戻TvM-禞'K)jWZ`5vàWJ]lYoc5ntЕX10/ 5Ȥ9uV77NAGMw='RjX̂g 1׷PhJ%YVqvQR|+ҙT [ާq'q5{m06].R!^m۟UeDP{趑!Me!zHib-QnJ)s}Bu) gP%&^Ƀl'Tp]4࡜6#3\. $evX2uO KL68 ˆk2Ƹ+_l-_dqp ֘2[}zۋLL-ɘQOXUR!]2<OP@o Lz/05HSn1Ot+Uޓpsp7nJFE]ls+Od6}F~sqLyiHnv⌠ 5ƿe:rjQNYn:O/hɜV5"tė/0ʮ%tX-Il<N4v M׻O;Hv:x]-"]oYFҽ{DМJpS;(ZEr]Zs >vIdH*`uAzG(,ky]t0 +aB۷ 'mi =,*ڞmY&Yw%( nJ-Ib;*–KZv|C:| }ʹi*T %Y"=Fc,9V;AvizY=*΅ {tpz)Y6=/.oˌX__V!Q2_xcn_]<=?eα984C@1"!8{ΙџY-Z~Te&Es㓷{(cq9wQD&0 hm\(dk{D7+(zgz~h"M=@%nzlߡJqp&9vVEªֻf  ~'m M~vQף34MЗcv튌_?bf[:}SY{qs],SYy$Ufwz QϓmP Ì9F%e-P̨z>fbG͡|*&gO}Ȇ/t+ͷԹ:=6\3]j `IElc;g_U.o|sj)i tMkƱ#v">Mѩo1 p#DCjZ~RyI,\IX "2VH:VٕṆqC5*}dߝW9f.j.,pQ5{L~eӓ,b>IhV'%)pʾ'5ZMNH?sg.&uޚqE 4Rf6ol9!ۨ<9p#(,dؽOm!ˏԩ"'B8 ^FU|3CZUrKFnj,2sJU}|Orӓԑ^GI ث悢CAct*.r0ɠɓHu'j@q\PӘ=ݜ'FgOA9'%NWŽɭL__lH .i)b\CzRR|RӴӌ{?b'Fn*"{W7@: @+doWJI} "5#xdN9 Qý%kU%c Y$6茞k35x,<*Åa e\?,>@4ˌ;ɢִWzBnpt[]-DJvC1)DJ(A V;үo[~ː!.C0h+7$,OeU_ص^eJ Ay!"VC(dü'j8U@St^ۚ&Ҿl_Me +@eQ '~Coz.ˎ󠣡\=ُ}&)~&٥(,騈蹶(¬;/I@ @V߆ 2 v. KT޻V)Qu`1Sy#VA:< FHM0KrOV=!XDTq|+ydqX"E]WMeALGf&95ǐHr|/Dž`Y$ (M,vg;?*rJA3!E)|*5HalPL@4ZQ?Kbb4?/ ?*AIPƪjyULI_JnfG@ SW!`,dLKRy9_ C2ݛ G?PprAl@PR@A3 _8aIuK%'TG*H9;@AqK\73ͺC91梉&(2>Yc'~>hXޓDV3Fl?눑;7 x. ؒ}=FjY `m*NSBՉ~)ohR!/ *AExa^esǽp74|h#`x<ǞgKS/: 8pԣ?T]Zo6R) Yo=d`်< ſ&Ha*ڐ=  ľYI V4-_aƌ,]ߩ1&o$0:\Dÿcy@*u}Pp(== A'S&ua"ZvCԖ`R#00dj𑈵-¶4pORp~Ż7#{w5N@|_ 5|8g\Y_h7 4*C{k )m]ZLOJYx֫xG{k߻PhZv!(B6t[y=[8<OggS"nw:-2UY_]a`]Y]WUVWW\XRQSOWWJCBGVc]RRHJZWECGBKTYXRGHJ\EE+ $C)]/6^?|UYob:,D( zjKQ8^OL0FH֛Goy!bBG+9>k-f>adMϹQu5MiEţ aIHЀ3͐g5MI=^]+ Ql:ZhM4ʅfBy}HhoɪG!?T[~':_>{gIxM e53).,d׹jfǫ+1gw5d>X*^.<7},{1D/דٺb_e1"S[#/#c=(`%k c|;ݹ}{ 3 g#ED PQrVKuu:CCRs IZ3x!9rH&'K$*$+FE(QGWht%\[ojbWˊɛmSa)zB +9SlFy x㨻xg@*݈Bޭ129 T .$hXuxO! [I eR57%ۻqW=#cF6U)d"J7xɒ{+F/@zUA *xuS2SwB}0~I=OH[wGOI'O/8=&g56i<:ũYհR]̧}pALiݞ]HDs{MŽOoב{R<3Ũy˷Rxje %KgţXarF֊%騍hȈ@=:e[d \f[mid.5UHbA-i ${ tFSh񟯙;6@jVW*4YD=@ZVhEz`ߥO . Gϫc:bV?3@E Zy+#殺$( pHb .g;CwqWR;dhǑqTJT gF>cӤ9o0x2<ڽ.@Xmh-0hu9MVDV3|8սc#^7 Ź2?=ǭ\ٓvwxY?_ꛅeSR]] ̺,LֈH=Cj(˓6: .<2W1Ofd2Q ,k)젗-150<R#|(+P@[%qm8u2e>4/T'jʮcdV_Frd2 }DŽ1rR,rH~WSR`u\oHR"S휱JV]ɜ:~Jor"n-14 XZ~~d1d1T* @4FȵosjbgU1jeL\o{dxKm+I ;p]x' HKp  h֌/$>ઙסw3̬:F%je5q ,=x>+Bfіv,xpԫ-VTpM,_4 s6L8m.BffcuP (@p@+N'3P$V 4Q8 P*[63vghlȍ~9wfzH`p 9i\)"bRu4*PN/a~mcÒ}#Xfz*,&>aX#f B=PEP/FeB?g4.Pf>4  [1xD *gt9-(mP׽D 8XR:!݉ j- C0mWKB @)J!ԣ(Ûuh;5G)ʇ=, s3Ta:9Z¬WW#g__egvcy޽H/uOZ) x/-,~6뷛?՜ ׫|.4r T+xzܴ <k `(j6w+t:NVIfio΋%}ZuD6;MvMwC+nVKgV6|G>\tR[+7aC{5.ݾGf^綾שD4 ; 0@ܭKM/{9@}?h} ûۥ"%cs/h)'{H>!!14{ pc!ʑv1Q` '2v J@P s*=b*3"9{HL0BH٫04$ S:dڱmrn|Dێ{-I'0:jhX3UQOՇt 9N =1X_Hbn-,xx~h:;~ ?w?t\ j_lՁQc mDI' 0@^_ t̺+Qt427n_% 45Vz; EP|b` XӍ ^xy<%2w;rB!OggSQnw"/CHDX_Z\\]^_`\YY^[Z\Y_YR\ZZ\WRR\Y[XVU]`Y\UXTYaaUf.=Af$k"MfL+ hATA vK}$;eC.j }FT VfgmEH.@= @zA귪`.58(0~Jxjlu0#57G.*@C8Sp߹$8)xYDl4pq t4W{)k['g<<|>? qZgGjpbW-{4e^h{bH2"3,Pw D_ý'ilII:CĔ@OͤRTڬ'PAZJ?{aw{{c \刳V*Kd@TE___R+OxϺ/* R4Wfq4e\Pyx6vmG9/8nn!ж&vcԤ *${'bUX^5 7AA&l̽7$;rq6(嬄EP sMn;S%p,1vѿ&f2 (@hQRB ݾF?'{ U>`%^&1莞tN/~F*0ydm,S Q0m4͝'D剜}1Ɲs%LU{RVӬRVnڍ5ytu.'G=:@>W?'7.Y4c4ƞJM zyr&A5*Kʲ$y)k8%bPӑdYDwE TJͧ!Ckʭow'I)2:{%QlB%Mcyt[Fmљ-_Y3Cu(0TjujKo۩REba6~2i%~523$HO˛7ٵ[*gqÃ䕢>;1n9;R ID^zINRٵ{EQ4쥠M26+,(|KpĶZ[n'B0nPFr4}/۬_Sr#c>(]LSdc֝ ̫9  D~ԋ,b"+ 4r!.m,m6!XP K&>v9Nx_BR~$ !@[*:YGG, d,ՕE329)Vcd^[(^Z#sH?I7tZp?%Z'AE5g$פPH[\'``*“~g/.qr?XNi4q zmf\,z2f.xࡲY$WvɢuT%贼Š_z,RDG#(Y|hY Bp$3sMTz?1~g9Ar4L"i2}[I*zA}Hfi g KkIwN)B0pj;0oj.CeI~HC8 & ~4sy#UJ[WSO:TաTH{}!c~]}'cqrU!:;[l.0Pͮ˸<50Ff7w5`arӸR󯸚:.Zpĺah<*)ZΓ SboluS$w+>i &NF8:%'5xV2@I$/uxiϬKqlg=T?kmKp_3`}IX>: " ¿"ֶ2;a/EDLVzg8'`RЭIs$'w9!l0 9yPҫY хGGY N#).lߝ.fmT49 v]g^4}6JpE cuv).VDgR OaU *~7)L hׯ89(lYk!Z5RUN7Գ,- 8KE'Ep Q\gIy:.9%[u=R<6rƛFY3L655PDL+#*z F&( gƿg6Cp+eWw< 5|~zao%5l.^ Ptܯf ?a OggSnw 93UMRTWIIIINUY_[^`\\YX[[ZT^[VSVXTTRIHMRZTRMLGWPCA>;L{r'F_svZ矲@<ARlG\3T(> %A km)X4qn:& ADU,9ip! naN~Pj/d([ P)r`S{r)݀AzZ{%~6*fHHREe8i"p[jfe(Dp+w9>ŁѸ_]>8#vi>d0\kjY;IO^u؅t=Oc!eda%:kn q3"Uu&iCDz4p/t`ĨT%#~Uh0}PVeP@nW ,:_͘]]lB?;:r9ؘ5G4Lv2%lՅ؊)e.dpItq3+w WA{﫯cMMoU偍l/0ouj0@d[voBh6`JqFG-+ji0_ jŖ~ҁci|vSb=3̲ AZ8)9pP}(}­qp9Q ݨ,yT"?.8]Lv=,C`OR[uUj+Q?0FITmMC[%'<'K$TDw}wwQq,o0d[ka!'Zr`ޗ` F ueL{ܕϔ72 Ms^Br&MlK%H2oxjGKu9O@j;ۺ3IcAj:7 Xo'/sиkmo_M>z&KU BT"įҾ=>H: 3q{`J#'YgktdJvhE_*>QkNƈU4 ;kօZۙN+[ߨU<'k`y6 Z`LgD\Icm)yKBAh`ҡ\&}ɨKu=WmB]KkUH7;-+_3`(}ePpR ٖ_i3Wwt9.SA}"h\5 .pJQ5Y`y֪~ 'PPԯ演5 d]^ >Kb1j[w$P8hGЖ*KTu>@ݡpRGDQ'|:I2 D@ҕyVDwBXJx&mXX?58+8EI=l*_l  !⡥ǑbO7ЙX=puB\4TF]MW\z)lg=YHXӅ_Y;NsiiR]#@EkpG}rvJp:j"q2\Fikɲ'!@C=z5R9#ѠN#N*OW)o] `eD*i1KR%reS|W=YAmzelf3ۣU'Z~ړV+>@R(rDlS  ᔊ2/m]"G~n ZZV]Q8\{ԯ3{qWbawfJ|^N^| PXK8tJMEY7w7vi:yM۪A`ҘtR5ēwgF ! mio{ԥî$H6~к:9SDǑn5d+vizy\S t}k;3/L!xX8T]tZȝB 3) or]6:yμv~>AP$ 6 @uk}^cc[=@E$0m*Oz`8<:4] NK| PY[Pv3HJGb8sO ; vt~;P !%w%HG{~:YXl",w)1hH>ɕ!9eE2@k1Zg³ `LkrfF f x*n %Y;3ƩG렔pƁ7PLA4nO lC!ڿlϧcإUzi,Vq":ڡy~Z;ԥ¤_I 8,Poy!Opb^kf漬@). L=ƃ(-.vu#9 KP#|Z;2I ʵ/`B߱6H##8(` $}poUٴ2W(` SplT0ωm:Fe40e{Q1P@#7B]oi6WLL% ƿpwrx!΃<h=79#6h$ `xeSqWO.=1Ieܮu&:5ݞYܨŘb?4 BėBglMOJf+C}X  G,+Mk" p!@S{T%p#`Dxq @d7<Ch$`K}uC>+4 p xv ``So]% x  .I@g(P, 9/U\Q^31 7aS)0@v>̀!OggSnw  0N)`VMG?EZNE?FEVYZLHDDYQKFDAGY_\_\[][ZQOIERN1 QPABcjs.ښ$s%,jd$wgQܲo 2Eji99/;ta/Ws`Ar~$=@& PAc۽I!(l!{CZ~G hmV:Y[Au.zgU/l:X{JSo{J*s0e @W7iG>&NzGv[}0vePAxT ;P /U oMz[Mws 윸kʑ $zUir_ `ӁdžyXuNS N z_^k 0O_j%<@\@H@a'*U ( @IS0p=y( Ph+t9f7ـ$TE@nox"A=NQhxk9p# *@%hvvi~1! -/p?Jp8AAVaMiS&:Nb&FJi*XMI0X#Ϊ5L(_=H=g;S †% 6"dAsK# ]iɱuj§Oq?'hGx '0OVus\l@OGH3DGf =Oå,]m£oO4lpX 2iVzUa$ .W ^ M y9|̅-,:  f?WF4Įn̙:$1l ; l'ʷc@ 82!2sw6ĄkΖ\<ظV G$H4 /h>q٤euitMO;' ⏓B=@CwHY-oWCg-`211zQZc|EUyg5 J^"Ty2 XV ЀuӶ=& $80-1&F U4ZbeA@6Pb[ԕ 8$UJe ξ'jb @f,  Q o,V$!~@Ep@?P?Zc`!NL tLZ6LaV|d H6s-L3! +`8T6{b`aCd*;k'uM/8:ur|bRL xrV`rZH߄dR^;E}#NrbW la݄\l8/k6te>z3jx:%yާ-=Ed# B}HvaW mq[=+{%tʬSG1RxcO:w %J:߶fnd#mb9wKLnmɹ&9v'XWQ-kg›!QN*$9cQwUćz\&ҖpjB ٥,Uo.3gr+GghxzC¡ceĬ k ۚx(KNFܺX+ӿ\0 yuzԐXL'hLRY,%d`eoH};e%)BWkcC+>*dF§7N @QSZ[PIauIr!gYHr3Z7 DzAX 3hߪ * hP]BҰheRp.W _ JMkг0} y8 BGޞp![PLYJ'QKTVXn.llĚ2XPA^d+ 7]E7cƍh:IFDȊnHq/IY>H3W8_fy%xR$wt"|lƒ}rdM?j„F33![.}:1V6A*r(0¯"R>q!ʓenN.wa _ J DU۝oBKz*N9VnV#Uhk!fdzp %Qb=Q(xoKL2!*t )$޼ (=M!iw7 sBju'[aLLllŎP|\y R- (Ѐt)rzi>z*H%^ܷMKlLʙkƇ32.}c4x?Fb(*89Ohallegro-5.0.10/demos/cosmic_protector/data/sfx/small_explosion.ogg0000644000175000001440000001120412031751243024506 0ustar tjadenusersOggSnw5vorbis+HqOggSnwf -vorbisXiph.Org libVorbis I 20070622vorbisBCV R!%SJcRR)cP[Gc9F!dSI{O*XJRX)ESLSIR)EcSH!S1esKI %lMtKc1FcZJc1EcRRIs:f%d:Fb|0:B(R-[S-KiasJjc1S(АU@BCV P EQАU@EqqG$BCV@((#IdYeYy/.!I̐SI&)U99dRƘbQΐS 11)N9 "CHd K=b8"A!Ɛs J!rI D9)LJ(I -"眔NJ&RˤB+8XRH)ĔbN1R)ǐR9Řr1 T1H)sN9 d * 2B!+8$iihi(z(y陦zlyiz)k늪j˦ڶ骶ʲn۞ʶnml,ۺyꙦz麪ڲ꺲홦늪+ۦʲʶʲk麢ڮʮmʺʲ۶ 躶ʮ-lBT3MLuU׵mum[3M5]WEueՕu]ue[LuMWeUeYeveWE׵mU}]ue_meY}uu[eWeYe]Y}SU[7]WM}[}am]WUօUu}eu0,뾮00m ëƱ뾮ܾj۾1nƱm+loq,ʾo/ *˺ڲ˺. jںp̲. +ǯ Cնuo 7v@!+8!c* R !T1!cJJI!* dIJhJ(PJKRj-Z JiZj)Rlc2dI(VJi)sLJƠB*JIeIɠ9HRIPJkJJJmJi-ZIRmZ# dAɜRJIZ朔:*J)RA(%JIJ+JJRZk՘RK5ZIPJkS+5PR JiVkj-PBkK*1cmJi[)[XSK5blJ-9ZkJ-R[LXk %JiZJZJ*ZlZ5b))JlX[l5blXR1XsKՔZXK+5kn5R@ eА@` cAhr9)R9'%sB)eA!99B))[(%Z, M Y D ( c*sBcAsA)cA'%B)B( lДXА@` b 1 tR:)LJ'Z )eJ%ZH 2k%bFXb*B(4d%@c9gb9!41*ƜsBc9!9 BsBBA!RJ B)tBR *pQdsBCVy1J9'%F) [cRjb BJX1!b ZvRj-ZCJXk!b5Z{j-ZsιE6' *4d%@ c9b1CJ1Ƙs)s9c9s1s9Ƙs9s9砃9sAs9!t9 *pQdsBCV1RJ)RJRJ)R!RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ)RJ) gXI:+ .4d%9'%1tNJI%5A(sRJ)ZjRJb !Z Vk)R()KJ2$ZK9ZjBJRkuRRIZm-Zk-bl%ZkZL[K-bKb1 npHqBCV!2J9眃B!R1砃B!DJ1會B!1 B1B!R: PJ RJBRJ !B(RJ)!J)RJ)%B(RJ)B(RJ)B(RJ)BRJ)RBRJ)RJ(!RJ)RJ %RJ)RJ)!RJ)RJ)#$"l4LQH h  "$OggS8nwܶ'Z\ZZ[Z[\Y\X]\[\ZZ\]WY\Mʢd -ru7m\u!_|רuwGloiuH@k htBG eZD^yz{N/>15}y >Jd{)@NUZj;$}y>ΥQ}-,L~<s~el *<(DK;8~vD@dda \x,&kk)¼[ڐF#XQ%D8DEEm3`9f2wu5ۑ.VgAqW Wz(rpOxut0xԾ0Do0P475%>QRqЫt.U(_Rnd8S?Do5,K$H?%V:Ҍ2BD.1#eJjE}̜>-Ӡk]:[Vkec}YYd!G{?8)y m:BgsvΐʣMW=_?vcigXFM(K &"!no 7Zf%:SACl B-ϖIb\$@]>C7 ⯪[E)1LHc &zq-bU;V0Ϲ¤"f,20V3zzfgU-!M n<6P;~2/!2{t 'FTo1'Υshsq{yDSs^Ze[I\x~xĒfw95j/y0keToDjۯ/gtkn'b3g$#t`XsҬESdh)ѐ\/<@}޸ܚL ʵy,b`q¾eo Χo *;=S=.&["JG~1{75)mm$沱qv*90Ns=kc~̀dnaB`M9,{n|: 5|^~ȑ qtq{l=j7<ܣR(%f6SCyi/A)FRΥmFHoy(h6u>ub\1H3 } jVQ!V'!fQHs9֍Z]֐fa+NdlH[nQWWg'i{X7/t յݗF;|tgJ!PllO {Ae\5A]"a7k=8{y*;tved L]l_ r/:CTMiqm 2&$o^$!*J.oSOQJ>t]BRJ9K.MP9Xslոi?r23YHp\0 ˮZR_|fz6d*a=Hyy%6Z;"r>촱A]k.#$5|bDJnFNKP:w^yt8IQ %e31?g7&kZj\ i>>q90pallegro-5.0.10/demos/cosmic_protector/data/sfx/big_explosion.ogg0000644000175000001440000001337712031751243024154 0ustar tjadenusersOggSkwwZR'S|B'*Z9xA `請E+CȨ)r\X{jGM-Fm~e:mhU߹Ӿ|y7ִ{9< Fn_k$sQ)!`-cϵOT7QA@R6OzVk-!挱EF;Q}"K|HNo-WIlܫf\ˢk ;|2Ӊ)ȍ&^\y69;lңe5bsi sGeoa91x`~W4r |{BPc K \݆ "="_T mN!cb`?QG^h%[ә2%suna=٪~HGh2yy0dDn!a /uۂ95[^V80@o̊RIDmS>;<ĽK[2T@ni,#F0j`ҋ;`JbnndMbyDƦ@x;Sڮ3?cRs[LS9T3r[t4E-/[[W #*=ZԀd㖷 _5sc/mOߥ_鞅;No3ɷ#eqvwƶ]FKjun_Q'/2>b3%|K}D-^ sA%ܶ5ޥ2n`ۂQߦWΥ%hypIOLk;yUxX)0QA}Y]!T[uO.|RdnnNVcO4uɻΣh `˗e4OF17} X;u;Dg$&.]qz,*Uϓ>ڷ|ۜR/P2ȡҥŀ?XD6&.$MƜ+>_ ޷7/߂ e/tIU"%LѰt'{Jʥeljᩡ{oމF6jdO+^2:SU)Oy|E 3vpRM\zvrnV# I[V(VŠё:uEE]|tyj]&*iU:O͹Mfæ+9'in;je̋Wk|W-rأ<=]jΦqjsڽF~\[MIgsN4j$,J[oR^;]h!4ɇE ѐS}qΖ`ca>Hf]ܾr۳y2޶y`ߎ\ Q012!YE Usz5&LW[8~qo L"m'Q fs5(jOi،W'O8MJWe\,53=+X:ϞQ) ,#Q mSʼ1Yjv*Υg|T%E9-5h-voB;eLeEܡ2!39qCE3ج(ub&Xt.= ܠ{6v+eP Ĩ+?|黳{vnٟ0d0O&N>θwb=f)2hGy,ǡ%&̑vC·,TMh.%:|jPʰjZ! q(8FO %,iڿ`+ŹJO:,dg8 G5)b"!4-Bufie>W&<}www'<{ydJiuoI%N]a]C 8wy5kAlюp]P̱gTۮ$_ So6md[x2+!r5UljSa0/3/.T€Xg;v_h.&lΥgPԖݭ29lsy N4sUu/fsmƉ]Q. ED;53.y7On3yatdl63e7M>6yf[{I|?>#e C2"c7H֍+&v6%UB09X&Ut5p;qs5s+!ƫ94ӤT΢%@ίiS}JT3{> $ sj+nsԩnj,|^_׺—Hz_C9Cx8s#icsE4Z{ZSWF;\"KZnn:50GdF8&{dȗep^(njv~źi]:=~-Wޏ'=Mntߩ>,Rw9i༰:ɪd^FB%9xui9pUF9H`u5Ke>$[O~5]̻?ת\.]%7Q9r -#J"lv7<-D.?1V4J Vyf<nC$U^RMU?'( :gcx;wvg=ҹ<*yJR" Ȝ)allegro-5.0.10/demos/cosmic_protector/data/sfx/collision.ogg0000644000175000001440000001270112031751243023274 0ustar tjadenusersOggSkwvorbisDOggSkw.-vorbisXiph.Org libVorbis I 20070622vorbis%BCV@$s*FsBPBkBL2L[%s!B[(АU@AxA!%=X'=!9xiA!B!B!E9h'A08 8E9X'A B9!$5HP9,(05(0ԃ BI5gAxiA!$AHAFAX9A*9 4d((  @Qqɑɱ  YHHH$Y%Y%Y扪,˲,˲,2 HPQ Eq Yd8Xh爎4CSR,1\wD3$ R1s9R9sBT1ƜsB!1sB!RJƜsB!RsB!J)sB!B)B!J(B!BB!RB(!R!B)%R !RBRJ)BRJ)J %R))J!RJJ)TJ J)%RJ!J)8A'Ua BCVdR)-E"KFsPZr RͩR $1T2B BuL)-BrKsA3stG DfDBpxP S@bB.TX\]\@.!!A,pox N)*u \adhlptx||$%@DD4s !"#$ OggS(kw*M6+tgOJC;8I4)o̦;%JhSmgjT}}OxmvD7>*PR ZZ__5US^*Zlbf{ | ZnFT+v cs"5j 5-vGGGGC|LlLlLl\|L4V_ JKrFPP(p"ES@”e A~:[ƭhc$T`Dq?hv'n|x%~2^LGשDb?N%.& 4DMZ$eYbQD3@pQ?u}%8t 7n\ιRE9 `~k%tpn%hL4 RyXm] !lZW80 0[w4yN h,ҔdBk@3 ]Q ~K_e n˻lt HK t@@ñ~K_^eX' ܒW4f+SS6A0X@ @^;2b j]]lp-bD |JgOpAkY*=I+@(0#TD!ր@(!7q pY>KA?sY B P9ӪRHP ԑb,5b N$՟n6VrZ]"Т\4bn) *Cۊ4e2!C aS+ƒ`~jEx̀k 4mbxXUU0FX4mnlSRQ | )F|nVu*W#&FU$i9 %*:A )BaGaon2vI͗:ѹ0,mgn:LKlG㌂9Gulp p%s&+˕iUCLChTq$$&mN3ݶӴtywuNP~.(bYŹjj y5W(Ǜ(AjڳtneUsy\mE*WrOZL*$Ո;yYKiоTQpꝽ}+lȺ n-~ ҧ:n(@T+)n "$@*[slX5$AL[ q0ฑ$rp:5H~VThe%>Gl]]i%Jgy,C35<PX}AÆu|le\1E9Y*qS*a\ƣdxOa\Mcjydk1qy%Rpx}عιPx[GM)w:B&氀8],P͉/9QrHPϡC"y.\{„q8WZ}ݪߒPDւB7~Q|UdfLuo}fM=j*s|N$EJVn%L7>ͅwL?Vѧr`H` 0eF +s-; 2`,3'E855Hko(O fS,aS& Q@A .]jԵXm n7S?Y=YRESvZ^$ebc ~I\}-}lmInl*X$gd[>3>ﳙ2`j؎-Iw*/a" ܻ3։0eYC`=.~)^#6H@t`oϽ2|Y䂱Ȝp /!WmtQVeʬ!&A%O> !cf~6$JhyW_Χ&;n6FqBwcAM#-<i>qIio uP||[途A v5 ?hG]:yslQ}S| T!)R3QҪi;W$+#]d}ű#F *| fMܵDS'cn<@PΗORyEp6Yx5GSn-:MypX3Tq1C/ tO1ai7 V%gԺx):p_hޅY!6vS~hPhN:sja'@sT+%I)W*h qw>q!פ&hMAǟ:OXg;IV̀[lٓbܦ37cJtE|Fd0ܾh\|O!asͣW|Uu+L}gkEAְ1/i&rg9YYnBk&YD_3Pώ1yfi@(VG4Fg)CzhKҹXEVB葆z#Ɂow ƙ9q9/aNH<|qpGRWccu;r( F6ސS]"dkoF>_q*:`5Û wE8;Ke"xDi0y{ͺr`GUy CRlkۀl'8 ;QhYhfݑYZ, >{>cܷpj!G׺T"191u~NT-$a x}Sz,9̤)--Kθ~)=z;z3JFZ_ 4A)@- PeKϭoh<DpZ݋X>[j?M~Rc+)gJ/ޔʪsa~Yve✕ͷcߝZa.׵N6jM۷]c2%3r2-Fg9masع^Z}x:W\"GnKI 0b{kM6MuhID/pEH9(hf{ǹY_OFe^U'@"k\TJz쮣/emMr&Tl^!(N`N9:*(os6MJ^=-j}̡svT!Xַҿm)ZéQ`r\U?p.^ETjK8<1Wae!$`09u{w4gqt2=LrVF^M@U i .) 8%R8WىmQGG;PJ|r|Y\L&Y{=_͍Zslb Q7QSPDˀtȴHv9bRTYl 8+ kS**}A%:AVp`561}P3YbXl9S `=nYܾ`etV+Zû?*Sv(rR"'?=C')L ٴaTK@$WKo rwogN#n{ai4;CiQoz#/4-RU[F@ۜ/*Ӭ$t @?cvr[Ϭ$^{,p)"P?\_J7:Pg?x(7a =«e{={w&pOggS]nw#X/YTRYIIZ]Y\^Y[XUYa[SUZPGLY\_YWY_]XYZZOGVYRXX][`Xe/A*(Ԫ]z}u7:5VA[ +3S ]¸c'9;|#;F@ux}R#`+`q)M(4F"aGTYvi^xD}AEۈwglhZGĥ'1ۺՃ>Ys(`%+¥ @ewhj6B n[{Q[p8@/E@vxڨO((yı Q<=]>~`__ c%c(ӄ (n@_2x-:Yyp\<zu#Nj1UDu$ "Œ6;~\} 09]1;@*Z;!S4'orV [_ҝ?dV*dM^hri~  K}U2~wL ـ+88IPBJ>PBOT:&awU~i)@cWe6ɶYOόgL4\gkdo:ګюOfgD;)\o G.L7j߷O>5^=TpX-6%xew2\wT$_c#Jiy~ ɍyx|\viZOpK*Ga F_\37: }!|B)HE ?0waTRq]r t)wˬ- SY$z18 ƪ-I T_}lޖؾդf'CM:CG㻎feQo%2"!fH]M$l}1:aqe*2&Gaxt`s~os,HZyJtܻу|^B5SڡQiz_Iձc$g5وlku}%=04EJi&[W3$~ Cͣ$wa;4:$s |y7*vqri=b JR/ʮ4V_rs݋,HhǺt<έD-\N C ~&#VϤ-0n4y@ Q'GdN霼A9=(d/FnGH]cQ)ontt4VĖ} [={`Ev5Ux}[p I1F]jzW@~br.$24Aj`JZ' Q׺{GN$)SSDgo\FH|2D&^}Htj|՛(3j M C@}b}ezB"Q'5ʹ5,}bE=BH/E&1؍ r\ A>j}|>0 - T-j8!11#4)n͘BƟw0f(~|Λڤ/+xX ?p|zBR ^:q+Τ|$L1f[`o(*+vmDoc$4q3;+M]{7iI'{غ֚P^0EuSMK?M:ʤ?Fh`+7cw{Q1Ex > =.;9=)nwv38rd=YA@ntjӹ3DJkMWi3Ρ}H@00f?׫{BWdjYNe!{" p ( o}^$hp!v3m?Eœ?X$0tOnN{X%-a{U!{UUOKc67[ Nvr3vϷcoT¡ LǏwGfZi FtbEph cpoAe'y@PgVyrV/)QO8ʦ0 PǙ׾|}c=h05HNChdN+D*zwUSZXTJe&;D!&Xnj ! U'Wƥ}jKi|e~r޿3bgOgh(6zihZz;$Dզ[:(IBrֽr+ foAn=yQ&bbFH*'_=>kOez2Ҡb,X DY!0πZ%]~%crϻ.6\:i| ! Nj+qDirtg&Kb%Dj*3K3j5%zTO9`Ϧ)\K$w=j"(@u+_ʑz o4_s=S& Gb{NϘ 3%JEd|,sH).N}P 7YroM"` :} w:QpȽvFh$tO؋!>E:: C5mp}czF$ :l 8(yel==G{;Jv~\)r@pu VGk,3k]yX.+- ߂ʻRiHry<ԩAm\e ,$ˮT@\Ao6e("VC̢\@.B\)ϰo6k.ooV&$KΪPN7^oL|bb~6LԺOȺiCi4Mmm!:g6 F+sCtn? )@E\I;y~pScڟ:ϥ{ioaQOw$R:~')sH2yjk5TCw'Jc;QUBV4 ˶뇇s;;0t^VV!SjMµ1C>`=2桾I9یƞ+ QDGyZ̪SmR:;u$nj)Ulչ/驀 Ihػ¼c(wu $- e/Ν5&"KpT_[̊mP(&A. c{~*4Si`BHtF 7¿-w'(^W6A4cPur!\J3dK[ӧ7;{'s̱=~P@>-PW 闱0iv9 0flF$ $cR_ WP[iR4{?JT[`l,/=8-W]M$`qzᳵ)fam)F`P8b)Sۨ<,Tp\!^ VWi#z=F=J-%WRx?ORJ )g1(_➛Gq?dQi Nf޴\l[/i(eOa7Tj quؘHՂ) D+1Bjj`M7|OfE6a1& + (ua~cq>ݼ+Ux Q%7MKkUcd$ł}6r0pcX5%֔q:}@@&0 pnZ;}V"# =-৸ ϏoD0fikacC9=3 J\Sp2[m!%r,) 6Ǖ@M#=4y#bg=O[{- Xt8_NZjH2L]yG ~@\'`+zRgVLrwǮ讕$l؄@|LN4*gUW?{qg/usbˆ AN;! R* ]`=wxz/K,<# ڪ\4-w~hBÖW7̨nhs3`C&Ga:e=r/ѭ+LJ53غUIpֲ>Χqe"&GcNy[~G2el$-葍HU[[ إQ'rM~~W3%A[UZ© vks C5F=ٿL]sʏiLJ{Ox?#r##/ꨣ~5'Ksfzɲ!k'_I>`}-ufV3k}HkX,~L˼ocKVI9|AEn)Me'\;&70lDBdimIh~nFQȾS Xed .-ƌ5yɰRΧ"^҆Юג{ OC]rcrlga|2.#,vtNVTJhIњ';~^ɵRêB j5E6OqfW92 F'Pй8z^xsx9e;oi#0W<͞ٱ @;Tzȶ((m'2؛*g:V,>; q#L=1~ewՕra{)>5~ǚ4*Y"6vPAN+2=F3B%gPhNX_mѮ^G)qfU~b%)Q$36Ͽ@U$dlMJUhl` sGm~#ƆRp%ԺF`֏ܚ:YS)sޟy6wf49$UyYtFhXM@a}Cې׏>j!g:\3X'fVj%ͿH4pS.Mq!j޼z\:<_)*~;^)Z;|FwM{ G@)9 c "aHG h` \xz&u>UʲF-h:J-OO^9x8`F U?($&ȷ]Yg8.)G[Bnj3 (c3iQnbN pK )A*;HsДbgu4Uf΅C~OggSnw1NRZYQFTQHKV^XWP[YSLUY`Y]Z[\ZZg\ZZZ\SY[VUD?HDH@VZUZhhLjs]mm!U@\\(fRÀ(Y$0WZIAǿ(յ.$E=ӶNN-!u~xz}D">4BZ'Zq33#/qsF4[;bzCBN()@o_szict0w K ~t?{234>n)qUF%{V ,˼v2kUtH7`8,jS'?w)}2HA|NJ4"J,j+JBvf鋨ebX`ʞ?0 (=+3/ʆ;$|Q-F@)MBA ģ0K\醮q@'ʟ@$0ş%gp(D c{慢RD?= :8'*#0P? sGH9L0ġ#m)pa{@Jo҄:"dUAK^{(r1Qcfѱt<w FSRk?<@BVTRpxbRR^0[L5\P!0 IOA}ݐ) HPz鲥/% DX^gA4TIw :k}P]1 X'MH<m<_h@U(`S(S[S@ hYqy7Cz9m(N6}u3r\&$@[=2=hH2Dx^HF&Pb cF@wHpgù6ЀJo[-wFOSæq@A#q6b$ԁ2+h\&9uX6p2HKe]7$Ғi MQ¦jƋ!H`0aW嗚vkʉVUIaTU7@zP\'<>r]Vx9&#C@@F ˼ؼm"ODG*Ek' )kޏD2CrAJ=U]( 9"c?80*@'߱?*pHq6bbYC5Ŋt-bf*jMJÊ|oij$MRŹψw*gK1=ϱbb:qT OLo }3Ni o%2Iօ iEJrr“.2ћ+~aC!}.]`ś bF2 e;ݡwms9_қZFӏKQ1/cݟu ޗmpm>&NJ0QLY -$$(,3Euܱte>;a㾘 &K"1.$ܲ|Ue^a*{y8`YdH%<gtyńsc{hЬ ְX@c8>X4rgfT+qTn4&MEg$ 0(Iacti8?y KVuK S)xjqXȑBGbRfNFqt..F^e!LY^[A+I)j9tlF@vp>f3̐oLJálfDŽ[=n[pL(lPY/Hө{&9μ3s3y||91y3˭t ?#*t@ݍ*Nң{P!nnDVۨ$LqU{6x]V*ȯ;Zx\wӣw;,Jl{ܣ3ʢlk`(ߑǛϛq󟔷,Ih@t ݀U@[@k>1٧@$}`^CP0_/.nvI5>tť3UyDAyF0rZ9gL_] aT[oKCAWɏ1⊃Dz+pN_W`Ps4pT [>Łh8B'E"P۠qpa.t6 ƞ;a@ [v]B2i^.P*jQ* lоlMB]ʟ'`xyˌvgD5MFצ}`h蘠(P:=!)($,?q0QVonl^;]__X_X_?\AֹaAnKc1[u)2DEOG_'^t: ;7YryTMӜQUJ&h0-Qnufث\4O?n'cSLogWl'([B";& 8NJB/8JfMK9 BEn6@dJR OggSnw|\0OP[KIFZZ]ZZXZWUYaW[OVVQQZWOKJXXRLX]YYWVUULSZf]Z`7&$XDeKc<b!T1 $@ib}OylOU`9"߮gp_|W5L$앗$@54 tu6GI1ʺwii';;4#rH&D˫o]޿<}xmų *H֪ _drMb8F۴Mi5ĺ;;?))~R+`ۮ.$'rO_{(z}Af7VKp'. x\i5Igg[qmDa]&y6yeUfx.e~TOrjy-d+m"Nu.;JTKOA$y! }PvsbWxG>s3c덻N$G 6°zR[P"ec㼲9DdzO )|(vY䱺*BОlX743TcW (P8??Mb"㣩dC9tc=Hw7eLҵڸΎyƐ}?iLp)+ڎl2a^5Ƣ֌8C7?-}\mMhYR.Z[%1b,H.BP֐8M:b9!msơ֌74c:E5&.fX7&;a9:'$.#-W!X,fX[OU22 m6x4d5 [6H p3teZv`9=a~-k诮P5ٌS;+pN\Tyl 1*+< aBl>9]&61.SKs|֕D*Ui˓-BN66O˂gv$@PP񁝉VqLpn (+Q_@~kR$j#C  4޸:u+z1DTwak}<)k!2;!tk# 5G|G#KSds,VE{nŐ PȎq4K?  G9{j)S^D)k**Y%T{ aB o^Sec-kyߍ]ʡy~tʟ $0z)zS?֮m)PŖHJ 3%9eGP4ˇa. >;+#w1\ X_98;%M?Mv-"Ԗ#RpgZ ܷ#C=<TN^.Z6.:*0pSӔH?QHKijvfBYE 5{.Bɛk@}5~vu%{b]D؜ Mh'G9+!ZFo"M ɸ(#(-l$J>r:6vF'!8ֹ,uQ!;eq{sٔuE xv59 SZc`sqZ4&L39JBB7 (_^NIp+CN.t:; !kIDƛFK@7Ywy3ajTE)iPP/Hn'oL/%ߦ .ߺz #GO,@DŷW{ Vv1먱J6V:kW43z]O d'؆b@SfN;p7@T?ݵ>imzz%1]UhP+%P^Tm] F:eQԽTSbI)rlC~HY cdϢWRw~wkffpBa_Ya!\ fWӑLX  zrxe}ڴF)x|uom cmg 0ԧ;}݌=$.GݏM=fQCHtgI A\-Ris8Y"hjN"甍@R9~:;?(#ɤ'MCvlu@/jb# g>xWޜ2Egl gG?W#JPYX523Jd} ޵;sr:[;p[|( =ge [ όbHgGcK$-{ӽ={LÜѕG-JJ**^z_~ڛ+WP (-$w9t\|"Ϣ\Gwh5yR[S&nKw, @o1+ޣ>= L oAd"j1 Pzp1m6CG:#d(tȨ. 6zM ec̲lf/'h+u};gLO&ҭnsm)- 5{G,2qc~ ys>qWӦ rZ}_9\ÄarF gOozʫ<א 4@(oUͺ8rٸ4|XfZKh[} !wWl$RGjƾkޗmmM.Q%T(xF]<[y(GN j1Ecj0.7ӵdԂbʽE𠭷Pk0oۍh]^brرq 4BP6(2W5hV2K~j]eȜHD n^1Y.xL=M}nxI)sO7g_Н^¤wGKBOw4耷qY64ѹ!R%2Y)6Hq٦8"W)oi(a5X}JOggSnw70[\\Z^\\[XSSLS`RMKUVMQYaTPUWVRPX]OIFVTPHW_]]\aUMP$GW0k7;'xDuGdv%_nX{>20yĩsroī~hg>r(f#g~$Pk z:rlj7qњ:+GʍdEKJ!ƃ#5_4) 48!j@F'&~j_+_iSF?=X$EtV@BOUnf٭ݹci[aG+( Hn ~H2V]VC)UQCr?ܨ{1lrJIGʸ72F1%}$ LVJKaL| Lk `ǻV9´ RG 4@(T'K(ԗ#" ۙk冹k@ɩ tM}kYLǯV+W] EάP em~NA+3t귴TV&y]u[Ď`z)~ހ Yx.vKv+KbkCc2@PO'j _[%%b8g:FBF/Oƻz\>b_2ŨRLu|VQ_hpY^{T]ԵLըOzyI?(*LQKqq_|OAgt77/[֧i}Odd 4׾<ʿnhG| 'cf_mrgfMtVP(7q'ubs6@ `3W:} 5҅%o .}:zQޏYoT[rd}7Iٗ(vj1ip $3I@{ O9RX9QzDqJ|ş`Z fK?+2ߧkfZ`xN®q؞9i'L0W *J '{}]_ H|}{_X^Wdu!FhMo F83l P9:7P/ɂ^. ƦƆx PYۏ|cx2)+6zL;2BUw\K u4MQ2C8t:pn^B*}x ʣ[AJi珶߶%fP_&\OI@kA"s ș(84%q.dw)X4'^s%Ơ[0 !?/wVhZL3E))v gwPBlI]O%7gžF$o) 0 9pܡlJ*OX(0vU)*Exnc?^DYײ:|l1BުgkA EƂEcpdb Q 0R=^Kn]!EfYmp/!z>'&G)gyE1JEE!*B(8ދuv-oYM϶UB8w5ܢcS"A2{DuS8z orT ()Q).־QjCcC{  CopPꛄL4170E@Mj9q?ؘƧ^9d cql? PeGQAȂ`WsT/bm#`i@{hhR=rqet\ϧZx)@I 8=rutX YVi+[(ʑg=}ݬ_^y߳sdnaeN=7 0# ;!2qJJ;'%SI@E崆-x4Hbk%aצͤ.il( Rſ[Ϡi'ۺd?.)SK$Kpe< IYOvgi'+%K2.' 89'GՉɡ V\7k&>&ek' `dybFgAp Rukr~3%5IqulLqч$kuDH'мZd;$,%E2>>Vόo A BÜiR gvn1t> ">}5@O@pt|1iϭώѓ~IJQEh6MU#>%l\"Q|G!ƯCeC[K|OggSNnw l0[WWRPPRSJY\TQRPSKMX_Xa\[^\`XcYZZYZ\[U^VQOXRNN\[X)uP4Zz//4(4*D}Z?S&L7m_!dέ;>{/x¢ ˕D(|‰O&VE)+QQU ŹmӴl+ҩd8[Ua!E|CVhU.@alN4[M(O2}vhEXQ[G )( hGwU_Ab;S) fmq̩a,4` {6Gv?+K#egbN+>\0e5 Ά<#S'3!^>f8!$`dli'vd%}mQ1Seϫ. ,q*wɠ, 8l9 ŬŸA !H~ =3eӯG EipO%Vy#qZ\cRm Ɵcۜ( mrO9nQo٥R-x =Phs[1&<2Y'^6$`w{J - @ +&LuҘ>nL$[M{1!SVwۺجj+P{K(., EBx-sfZgkU=rr隡kj̳}ļP{`@va*P 6_+u4DĆZQx~}gƙSo]*f_!;i~uLdQ &:S57CIcV-z~dPy6H4:3EѸ6 QS(s&v5ly֎><7U+))DkS EnS ª涳+2Ǖ;iv-.ik:dH퉉ݩcf&| ?gx|G8)M[pCbnP2&gT2=Vd:3.~ŏ/ Ԭ~0 :G墼4{Z%Ԁ$1mn%,¼vpFoRus`K*uml7Q+ =ҁ^3YCI9\MF%S /G !'kLbw/'ӧH%GM6*GUb+\_mm3$(K%hz- o^yLآVTf$.)Sc#SkCiwO_l)18P#AaȻ}}C6|Vc =n--c2y 7#Cq`[m?Ofwo=[泌:KWE?},x &E'dQ"0pD-?4Kvkaq T !9z0]~" .qx78w]f O lHD%g:.W|w' ۺzS۪#."p *qWW$Җy044Q&bP&HEޒj"Ckv Ǯ0_H` 2/&‹#oH_1Sg^\4)?L@T+RҲE-8yYrTa]`btNP78lOJ}g**"HXτ^ApBӆ]DwSA(fC> S^j̒`<cgl 4CNeu+5Hl39a5g^SrqУfN.V`y }nnIvs\>]wҦE.+|#r̯^Z3{ in]eb^CU`e9cW5ힳٌ].vF\T$ `e`4P? VpR.c*xI.nE y:r!}(STCYBn*&V^+MmYCw8 ˦2f@)ݳ16 H%=h *dԭzsbOefEt_W%N<)@1P~>0f;2Fw_l0^3]xqNZcժU;ccc捱˧cC3&׶;BwlI9k'6YH6aZTԣRw *\/T%U.h([Q)YϥWW+,o#gv%0Ko}H9Y_}%EE0j[׹Ȁ `(*~}8SXs$#0a.d(?h `t@i/Y '31$+QuY2Lht>RtD!zܺozu[U$H ӥmXHFV)D6^yz5@T)ϳpT}(fW;N\ mO\ <۴V0(?yޞ')`̛`#f) “-8 ^ {o(ֲ)5oz0}Sno!\UnZ?5 @8졟ymFwBVn@@Q )Nmy&Ø#^-T[EM[6X=` Ó{{i,g3X~6Kg\2su Aw S4zI%N#VMKwyg__Hc^A]!L-HXL!\;8H192£4<5j JkO^'c¦0L:z@ % ծR=5]脿a[H;0*S V) ZfnTr+#;+59,]upCT*ϑ)2B_˟BF=w&wE%O+Ӎ{LWeK%50 OX~WY N#ޤv$vDݱVvwŽ uoylk񢥒eGm5OggS}nw {p/UUQPGGT]__Z\[WV^]UVXQJKT^`\]Z[[VXYVSKT[UV\\]f[_`X*Hc:8~9)RIt ) oip7Dq)z8YJ FzDζ}ԫ.r 1`ǽ`ll9엸r^$-/>K=~'6 v}uQ(vza?^xY,Cxb~^Z,GᷔS(g@ugbKn=e`g'ygePߙ,l^zi\}xT[a#E6i.o]H l(V@WÉR+Ftvj5Ivx~@{]ͺ88N(鯔tFb5(c`ˀ+Esm#z~ 0 [\ٖ HZ\3-J[;@L.U ;5@ޔ-: v$?SQ[aGzZbNL;,^gSPt^dZ"_nK+cgЁVγ~Ʃ:y|X/Sd fU[ܧ?T ۑ2?|R-֠%WA\ ɽ-m^Hi4{HjʩL jN﵃411iuG4OXCmsb A?P.ӵσ֜Ij"]6&6C֑P-DT 3KA,lZwmN> 9_(T+ǀĕ kRSs MV#⛝#g[c&@ %  Qi;ɼvׅ:04*ѓC;u/`ʼJԨ? 9FgDqc}AxKhPrc0 ]_߽5?;Dr 1WlHs4 GPW7rG.d}=~r3.E$¢.(`(ڠPkvzD9S6${|H= Z(ơ:{`IWs+Oq` D.@ȃJ1ӌ#ܿc_rfMdVH)3F'_@$P215R7Cdx\< s-YkP{8(D|yWu]ľ8`-- @'Zl  @k>nl.&BkrS.-J7C)NLly[rF#߆%@‘ R{.f>VYL` )ԯ]Xv}w  QqTSB+ߴtPo:" 8; "gx3q27btIvl_|oݝYϟ*,Rͅᎇp#C/vgy< s} T u?E%5b¦֙65P)@^elE/s2&;CW RwՁA4 U2WUM (gubJ/ʍ۵n"w¥I׀wc_:DQ6O уW)U6y>,2NsB gΖlVFmF_K-_[tg1,ΕrlJ!1hG[.:YwޑgwHD|]4GbjcNe4z[z{t7#h<ΠM7 tTʗ36k;'Ϯ%:=^C d)/l{4x˃7ն-y{I;ZD6VDYOh b),8@[}}}˽ ݘ^KՈ'r>LՇ̐cg^尓#LjcE= c#cS,ՀD_۶^ s틙)l%)H^a B'f.JZ""Aw/5ĵ~>lnhEISIVX힤4؁TTHNbs~z_;bꆍ7WtN !zZ [ %dy-k*߼/ 0"!+'ѩUk\qQn`%U6Q Z+TV^O6aNY/ @.JqS}ٺI9r&cQ%혿+=xuKm#ל=;G_A_1AwIGkoS k{u5n-rTOggSnw b=0_^W]]^XRQUTLXVTTJJHHIK[VOMUPHK^]e[[X]b^^[`[ZWUQKƝϪbohDzѬRntL-{h$Djoq̘]K^ 娋8obCLkkZ&Oƾ1X|@^.KY;8Q\ЗNg057c+ƙvCX3%")kgkXP#{}O @+/ږSHn+jxGD#e(ü‹`3W+vs C*B]`cUg6]C(FUmå r~bjf_iSҲ=WFkcgFo.9Ёa?h>*4:Y:df|ѨQ"tvqj26fȿIJ"jy]W-f WQf60 p"6u)1Y&Ĉ -.9wnɨ*A7ZB;ɆЇ9C=o<ʤ֌. 0zwov-/ >F # (GC!][x|s#W> \Ep#Ǿ%ڶ[HTE7քWgY*# *70_M}63ĥP'ˉ:-q 4aF[H k |gSvD^Uݫ:u8@ޮ S@M2Ad4%W;qc^?&_m@0?ǔaKwG[c* )TYOyyexډg# "n SIuȞG KXZ1}RuDjBk%8A9iM+#&nDظqIuFK@t8Qʕm'S͚D30 @|mlCZY@-l Կj;XXIK!}@ @}g/+;OBEiR"?2ڑE`:~9CCQL% #^Fh ޘ)b(JrC''=c{Rd{Gl)քXuRw.Ƥ+NF΄"OAg^d60 MNye2r$T:Y[o񈸖I=Fٮ2&Ybcxt=[IRTODž쏯p^KY;7c2!Z /LB0} .ņ?63Gp}=e2uƟ$t\:8w}]0r?Twh:-qe%zr@\M>HA`NDg4 ] c7W7NCTg*u`b(.be_ ׼vV<5 &&Nd˛یgN?P N,.h˘E42j|, ߯FX tv=>ܟ߫lm;_?u 8@ p5ЧрN>:$ x`ݍ)97xP-06mglp/ӭwœFV _p4}iOVv5ߝ)@.0R }nŶmb{(?x9\+6M;6WkCA{(9#oh+j(ڂև}H M(*ukB +ޓAJ1d /l0`UV}C8n)Z|ݽl8?CT"da J `'s"N܃3Q3sNޕ@ Y)]U%[zxHr ""i$BW[ERp{!AYK} @0ԘKXbC:I w*XOj@gx0N9*^?5{l(`C}C֝Nk_@U ]nI #rrX~=Ɔ:S0Dٗ 2x{*a/v4 +p ^o>ݹҴݽU^" T"x(Z& iMKN=#4n1D4J4dS51 Pὑd>b K~7t  ҥn,nM1f/?!Q (9WхW1P3Hӑt$,Ө٨٨٨VkZS֦ ;Ŏ[^{ m_.ukYQiosO&ՙv4NR1DJ7+r'&繚PSZ,c?FQwJ*$;Z@P~.DͳzѥuisUq7;mБfȥuwhP9M’ZWcr|]XYTs^ {͐RTi]ionUoYzk)GN]FjknNj8JʩK*-*WeDABRJ2^rt옾'GvWʱ-OLJl&C M17)t֯sDTdЪ 2'\8̌oSMae>nkpwU*̨^ͽ} ;&JoO<{2ڄ?d{!OXy$i_ԛFfpF[$Jba a*/YΝ 8|pt?u&ϣCjQԎ>5ęmDo1JVPI m|1# 1H٧d'Xr\*G۟C Fes#>f؈9"[ć:"F `ܳ?d߳l5jNX@! 7ZzK9g~s@I[Hn0ݛ2mOggSnw Bf1\VXPGNQMJSb]TUUVUKS^[]a`YZ[^aaZZZYWW[ZNEBJCJARYRT%GNԊ鿿O{ c"h /ȷ Ք}qeixWWH{bK =+77/ *@L~yp1\ڜ5 {oDcvxK?$ِKr攌.?{l?`7ؖ0Nkr}^NIOHH E:+HEs.8foAIsc_.Mi + .ʟr@F0HZȨ<"l|rUo{ p 7B: }jk8Ep2ChU0Ο.V :@нA]K2 SD{34A}  Nb@N@ :o"9'  `R!D?+bo8GADVPgF%?3-뿹r[CLM +V]6]ױ A(c(iJ-" 3@A+5E}P嚺+Vs>5yJW IŝDn+5 J]`f-< d(v$gĻ |!q[h`Qz_gd+cB p",$}NQѱD]BC`kxS:Ʃ V @0x۷I;`yvZb:C]#-y'KblҴ%2L_[M,Dt%>Gg-{KDƦ Ip٧󭞒lrm X@4lrzŸFŽr=!6F֦o'c#qBE]+8$C? __YwѠ O * @vORĆF f~nVo.*"g;0*2jɍԞsUȞl+O52Ι"Z"@: . 6'hBR"CY$0y`( ۯ5!:^$zPftau WC];u|fԇIB흉!Cm8$0@]zcؤ҆q>y^hIexޯ@OQJ _+!Nh&8Krx?d+0O[b0 hֽ̓իÚM:nl<&"Ujlϐ@xPpoe=gxwZ? @0N-ZV;h]2ڦ.+ݢcR/TvY]wP;ݙKʃ.r(iտgbu Yylf푫whzhX{JXz  -<3;. P"ݑ>?n]c;;=9$k <0gTɁKNN]W%|3D$=8%Y8_Tr|4ƧIβ*`>dW._zQdNX@ +~ls'b35ߤC+1+wUe ::_X?oAϥE gaYV;nwʺ!$(_q&vm߂jU9M ꔖ]Sm+ (:?|3{woŪ+U)X/G,@b nR/[٨+ԟ4'if%*cgU1f+ QW˲smWE:^;mscYK& @QW><7mMK#9{uSLMj}Wvfвֹ?VagåŔ?x1[cu:N,#~?(@ u{Ҟv&͵d9 w?&e睏d{LfW|:a4U˼+єp3i.c=@ dtOtNrJxRw͸%Dl(kdkX@2?L%j͞p9/c ƢL`*1WWzH5B4)܊x@#? rF9P~ `V$` FE̍F1ߞ}SXEw~4`P`<;@@$^] a4c[ww>ͱhI3kLA'Bi^u"x4ƷTګf5_6 ao|Φ߂xi8Iҭr-Gp@E)AWlʞ30tV_{e_~)@'t +KF& 就VB4wkPJA:酡 /IB'2 h@:R46DXi&)aG9Vc-P4ZpBB? ɭ ,w©_&YcW;1^m;SVg}vv` +zXNx?01q1, *J׾<%ZVafcmM8q]ÿ´YGFݍ8չ`U > WfѤENxTF'8إ ,, &|+=ڵBcE5FxՖG?HCKEҹ3Fl =k:k]~3PtdaFQj)J0~2#EhÝ~3գǎnU΅o$F1N"ޙԂʭ򅑓>t-A9'H(eڥCyJn8i"(mƦmdX?ZyM|z+3}>xkIUEJteqً$T&S$g"weqFu4<\1?\W Ci f$&oQ{ c;7R{92i4hݧFo gWz\`W1*TRf5rȺ 6q1£_4p^}ӻ$yP?L/G$5uע0 %_R>na"Bhƣ @rȧ>bZsk k,T,9F$3Rh73&<&dérQ2\ݬɅ`  Р(GwZ4CTmƗq ͣY]9Z1K% /j!?:ep_T3),%5ʊU\LZ 876 dǔ 0µ8Z |"~"fi@wԟ`\FѾss.WB\w:2fKop6&T`>1>cN_Fǟk9jEhfx i:D4I':PP3t ڦuXGFC&PZ6NH_`@p$7z뒮vYnurUU@Y+ xV"Mgh*2G Ʃb?@QQ?WM헝.;6[L$Aִj_LY66>•4xn}ᄈuvp1"ƪ V ("?97d|0rY[UXU3S~=.i++L)- EUUgU|x<.p[kǩr Ƣ@+ `;Ѭ6` H1(š+$x\Msx%Ql#qx<r R@-Ӆhh5̂P@M`Z:h,o.pm j (,Yffœ4M(a}lW];^%H/(@e=NzAREsn|3dxi3ơ9_t @W]^䋑f?vᮀ('@[]~J4ll%Zy̦~O{׆lsU> ƤJE ^Gd@B/ENP(#_%zSl}:G.\O$oBHg XZ{ 6,mgT䣻݄ԸבFқHԴ*z!Aݰ)Vصɱ?!lw/f^VGc7.m3q8qyU^ݻЍQP:e*>R^[!T ]iE^E,DWZ t$H?ڜe';gSW]$7C3q v _2#wœ-1߂;Y݉l9SȃjzM(XW94Eb_C-K#Q?Vч[CH\~f뺿0,>dK xnUz5lÇ$,17c\9ŒҺNЍ❉9fȑNd y}v$`1<)cfq+PJ+?J/ƜaT:E0.Q6'X 5,{7RJZs( CEvVW4}Q/©S@D_5#>;Ū:;;ÄQق,Tڐy/L׵=B|"-_# =Rt4TJ (g{ +Ųrq(T,+ :e?-ٛ-:}n,xVN4@I;r-8dl\ر#s) QAqVD>ʤֺ Xt̲߹ﭼyD*:]Th.eE ĉY!N"`@9Zq?9xź;S $&| (=5klbm;8 HcUSnRuy|Z8ϟ`(TE*OggS?nw c1[YZ[Y[YYRRUW\PTGUTQMW]RRQXSVPSZQJHYTOLS\[\Z`RIRZZ£F6؋@,n[g*rtO;]B~JbGcB/yE"GJ]:\ĭYSoNt.=C,E No$:\nؙ1OJ)gEwgd[d#>y|(Vᓫ6:ZUs/Ϯ9LyL,a#%fZi%Sj~)\ J~%AQD͊. >;MBL S~I> v,X׷lW4? o}G) s͞828Jyϟ'=^ `k^zI?&!'BRcv긂YDB&],M!IP(cؤS+ʭQ߭}.q( u(gvysxQ/?o{{{8qѿFgǸ]mw⿁3Έ}7zlrl2' }?==z+.o9Od2V^2 9VNߪ&UIX "?/IqO?s*baaV, ` Gu*d]C끕KEW'TA. G)f*P(Y !JOYlfTX؄܊LIaܻ 4 cyFpSZŽ pch (wzDd_5 d1ht8 :- 2L@@+k(#Y"O:͊5c)̝o#2R[.H ƨ48.`}h 3WZݧK0=k.HG}=.gM}ږ:"j<44 aMMLBm TSezbBNj~jF5_#n\=Ƨƞ\d>G/M>2ѽ f"u=Ŀ2^׍_Ԧ F*IXO@dJ9m[ #[a¢諣;SYH%Cu)g@áM:X<9vF<7ȖD3r 8gzf!G` ! l\z{w蜚0nWu' ̻ԸEc@d?B!upvf Cg}`sMðu\r~Y=P -:<^fNvF˵I6+ f$0*M!"{SLڅdgB -PvVp#d?*q# xP%MDZ=]等|l; W"Y׆Mhij1%G%@Hz՗t~90Xǯ 1Bei>cO-'p3ݫCFh bH$sP/L~HM?Z;1uC+ppX Sȱ+T!HW#qBl|t{E!g%"LZzz=!`bvS`B=SFFczj˶5w' RP?l;F7l .]щҪF6srN-7378:+\d<>lnTM@lԌίkDCH۟澦 'X4~k'&'jAʒ;,QgHKa"%8&:t7n|yZqቤ6S.r9MK`lT4 nݍg'#?ߺD109ѳuRౄtS~xjK7crc ߠ9>e0 0݊ysDShl޹OZ+-VxMGDukp`sReY9-MRYơ;q  GH諎*ʏ\厴XT $c$e E: @ p*/1̔LWA$;f̎_b5j!m: 2h_N!7(ǒu1ՎA368}T')4 (T$D/I#<!FA9ߠ)bl++bx\|>nfa+olx_LzpԞrK*GF"D O~H7Xoѝ4Oߟd=Mލ"gdQ4Ap7%xqoqDi5 v 8DbƦNB:Nٙژ2F?a.ۑ{: $Ȼ*?rZŔ W9R!؍Aa=,Hb>*ԁS9%v{lg|nSdG8ˢs'ܿ' )ʪ6^- 8Զ>)4YK{1&ENaUhl> ( +[Ǩ3Nnk*8ZN&Edv/NhŘZL je/?BG&gB'Ku8V?$RHc*8@_T/D!)rD0w yF c~x< ">}{WV=^׷rUJLy}MTZ@"@ܦbw-kҹBOG МCu4*(|H8}X5¡/j!'y˭|?[ 81э`kvy֦?ϓѼB;Pt^gq|4B(5e; UAwV!%6eS>s/6U`@o?,^ $~EսZkB+|Z!w'F,ހ|8Q6' : !R#f z͆|^T!ޖړ%9*PAJQFPF;kYyfbg4ݳMWu# ev#p5`ે̓cچ;j~@5Yqz, V(@yASpy&*1ӻ;f!gfcfEpc@$`O4EH)y"F0;6 ukGAYM/+%.XW!{G!k tlqVd iwf\lN$jΧO/ᙲ VrCO@T1{A౶ " )rUk{{Ym*6|:t ~Xq'n}W" Ԭc긘ko$%Z8 H0ﯺz \Bb'h@>K9vpgu;JwhaӤ)$8߽@ @)O/YN-\bmnH}?6:[cН~/O{F>kxM)v%mGzK Bwl{G}wW)'vƏ M)o|#!g "ͣTFbSBpAb%@4){ʫQu4_Cfo GK-9V@%="JG^~K]?5Sۚ AōXDd(pK1WɎQ`RvEhOZ\emuko{ch@Oŕq{Nњ5*fg-bڼpqHGն.tls=r|UOAmqz&g\sZ#Lo|*g1R5g=C YҿKړ՝l >1+ ۬&r|KNC`<[x_bu^#SA~<|Y %"hp-By L(F˜Af f4wg?)D.W34v$b^M"67<NN~ww{6VV(<9V>6,b"1]5VPIl_OzA܎p?UĂzo5+yt%"c. Ҁѻ%y:G4/OjVRӑSE*Z~iexʤȀ̇@ *WtagQ;6*kq^8Ȁ676z!Re4]|(.@nY٬k)+~1W8{ TbAP 츦0gȫYuJ\n^KWx:o&Ժ0pXTl]')S8w7FP \hʺ ÐzQ@q3>9FKٚX+EZZc#ה:܁Q/}7Oq%ym Aǯ+ײsfP%bsc9Hh d$o9燨 "w%IvNw^ hkG*efj2Bʹ ;<1HS|8bxOgEJyd k F v{k`S탢I +}}kgSDYM.S+Onu 5󸺤>)\<CKGf 0K=ꐼf;t Vy呙̼92wdTzDx6J7S2];Ȯ9x͏jEcd%ֺ5[qAX.P:n6f ]^oZ4q`z Wr9Y`c|֛ubl$B xPpEeackoBA48_ZjY42S+=. Cg88x?qi_9ǜOv71vn;=)4sY֣5( S˽/\7ѬvTėDV_SZUYMGZC>o %d&w dwU:ͫ_KTѤkbUf\.]Ác鷂|5Gnt>vlnAsuvZK,R_-b~}cHa"G-`ы;#h8]hћK# Bp4(q@*ͷ$yvzBd8zEmc%&{Wo @` P9u6`Nk--%ɈRY Pc)xz)vg;9P4P wAX!#)W h=kG$-2c3)եR%Yl `9,mͿO9ͭfǛr.:rL[0&B p6)\K6@\-i=OO^GW>Ǩ5^=CP>vG~~s`T^'{&>  q8f;K}$<*`=3Kq#@dw-"$l?v^3b?@G/uVxjA ]}R_;^ra02p"uߤe'G,0cl_݄DuD ts#Z}AX]9:_".WFk`,E&=<3ŽEWutJ-Q` %{)1O+SYflg6`_K@s~weu$yHQ:Vy/&~n/6G]=a)TJ̭dh/]OggSnwk!/ZTJFXbZ_[ZXVT[_VVWSOKG\\]VZZ^YX\ZOJT\ZXYWZbZ\X]~aWD@*#h8R4<#ɕXQ+tpţ# k%:>H+N:RW蹍<_1$v\T*YRu6%C0L`My1ڦMEe9?N6W.[EøB/+l'ۭv騼i"@/ kBh@ցo}Bj\_ P @~H=ՉA+] z0vջD$v[WQ|wށ-(1d[tTՈS"3><.Ly;3ȸX] r^\% y-qVtFSIGZ^,YmM^Fz+ó]t~?sƧy'/rlMdx"sc2|'ƸH k8itP9=}OһAy*yWH<* +w?.gNҦ,T'?|P Cy^/rVqv1gKkp͸̮97'ó0LoY$NVbb%ͼ~k]YD9s;9vD<@V`"Y [01uujEƥ断&CPC<~a7vvɾ?>fJBd^PpXU-4]zNh4*i  C+~_݄m@HygqXR;?gQrEP kY ZP:aϢ8d)rc~LTօ #C snܝ[OTN@!Tu§شZ+*E#Y-ZE8D^rXJe!rӊPrg q:VkCT@*.X|WFdsQrW?8I $U'׌yTQE yEw]cU9כ,Qn)>1> NZ $*e7@ϮD%v׊ӎU$(W)`G N5:A*c%'ȿ.% dM(6'φfFl52!y$EUq5qDsO3̉Mxؾҍ![ՠP-aē9Q@T%r|us%}}4gxxAX|f\YI(@؜\] ~i4K>{{c#*asޣ"$c[_v $I6@fݝ. Z<-HO"P!r(b)X(Un9[)/?\xb Q:ukz}}"!ˤrswjLP!w)# mZS}@/1taVPy_Gd@P@?;cشjΛtbJ}nIwA hk;ClD:Π|ЀcĽ7O=Nj#ѝWxr>{rELJk0 !ȞHO-XYcUU(OoE#Iej6:XЈ^!u< % &[ A_IӽԔK_]x6EU*qˎj@V8W㵠^yvUG`_ň '(u(ʴط回s06;M凢 ZʹjժW}jժU]lm;~dPq\u SscO=zo d n0}GOL$y;&7b/ǒQ8xHuc (saɴ5q ~5 ~1 X@J KYd/8]Cu Gsg=vn"e"Di:@o_E 2ZllN_,.9IPl:'G,cYfʎMM(Z5]4X ()·jYjXmIT\LYE[9r HeE5EՇ;<$;M]RcY'QJ$RJutL=8t="X(r-ʇCVOM^d\X .{Sjq/)-B)";@6~GV;^q E*fK͇P0=^ȩ\_w$`XX{vKjǷL-h^^^^qg^ǥd)T`CztdlcXgvqV'Ne,,EݰۧjצP&4esb-Җ+Jb`X5ST "ʟW˦C,F*ROv2> ,Q|5>x0/92 MɉxhÏeWEݙ)_WH:V=_uI'=D)wV@ & xicϠҝ?Ֆ߭5b {&BX;zғ:NHRΫV*k3,h`wIE,sƞ> hAw EYu~u"7-kr$fTM̨vT.) Y%.W/B1q%9W}9&CE+EM\^##^4'9qӥde܃`Yux)S gRW(jX웊\fG:Sg` 'ZU`b1ܲ>Z:c8F eh`v"OCƜ%~a}Y{("79SEANϨi2,%͓iȽȜi>;.P ozRee NY|OƩ6+桋z´G*6.wiࢎ,^&!Xbߤ 3htruW9Ĕق[l(yVl@5t^!=Ʀ֬3;^ `]ݾг&CRc[ HsyDC/ `]}? Ǝqޙsע@irΥnLEu?ATWH#2m"Z4J?R@9j޺Gl E˹Yuj5ń/o[5kc"G(X^OCqdX,F#"kIM(ؐcz"e7݈x9K[hDUt*Lj!v7H +P;v݇9v1hS%(_. [6RwS\݈#^+6`ܾ7$`,fl}wnCDŽkNhloBR,nd "6FNsIm H K[,$`pוm{clgu]h*͝ P(O " clRbt^z3c_yK.[gw.M$;{V& XG@ (kfqB;GmO~7@7ƱWn_gr>5˛x @P'>"3%W(;ze;~/EV7mih)@(Z;=e줒pMZf붸>;`zʾzѸݛ~Ɏ3K'y6b%ŏѺ d >GXE^u])ou%nd2x,e~g"yޞ{'L=^33 dQCg+ ^GY4@k V2j?R1N&0* '<0 l=&-<gP#Ng*!mƟ$? utQkbm5_* ;KH nY(dmܹ~>2 ˼N $:Mo[YT3rU!B (pyv)?QG  \ LLwDy(9P)4?H.cIMZߝ'H歆e$'G9F,3H@ i{2+Q )"*zy|yFmu<,&(1r;Ux>k4ѹ'ߐRH!3-\B4vEx㑎:{C}W1c _p4l充99$VN;SB @?]`pJcjF^ (7laA^!V1?g{ .׊2:sj9HJ_T0&Ԛ-1w&4(8 yGSG_Y^.mV1_[ P(|Kݐ23.[#^P(j 堔3)VJGy:_e`q:t@$njJS+~D '<`\ PHML (0|l@ɧ*V݇y1:Iq 9@X,5Ɏiw:cVHP|SPLvtK?%9 rBBd %4Nt~?or)-9/|V+bɞ뤍͞Xc8<+kzѣ(d ncf2ԲYDy1bCTęb#YGw99j(kQԅA{(Z*8]ۇr)EE&o yˌ|th_JatTvΦ|yo@m`4B6ijʊ޷ZJ0EW%1Qv/1Rn ]036O*bΔH6!p !;A?9Lc P50/E6] 7h(-3@G=9Ƃ}>;c )gF <~Oϟ=iYstE|ސ]`ɖ[WFr޳lw Sr(qFH%wlyD"$/ !r jyvS+gϪsX𪸓h;NϞѱ>1/R_F8ub%c z|ߌ,O^ LPjsz ֠M"8 LT$0II,u>EM/HHP@@/2- "c[f61* @'31Ԯ=EMDC΂(qrbM|_ٓ?Afѹ Su!g&u! 3޸qrf߽KsP3{z%th0I(XsMmu}ii%VwdedЮ:%#@d(;o6q:r^K\D5+P:HlXā15㓜/A|e>J`ܵ\BÖ`)~o?O_:vZU>;@:h~;Lر\$#0ӂ;=CP d]aVM+|S/~L; Vh@%{fj~\<۝FIv `+ ]pWY`b;k"&tZ υU#a19H¦jƪ ( {טN{vn{DĝMHi %GsAEV,Njv^G',fi :Ƥʓ-, `4ݸޮ,q.ȼ,' 㦸k6vUqrD#i_ٖNfC\Rr7~z+"cm1$ h w:d>);cVtNաYlD)pG3&-!; 59?Ks0#g:"gdC @Rm7zkI]ew_3CK 'P7|τF)0O݁L <Kc'!MW8!g6>H`@Sꯚd#\LkDu,='@@r@Y#q9}wU9d'Bj-=դmͽd![QBָ8C*׼v̾+ &0j:;8~ͣ@ws7(R*'B 52!qY"Y`/z~^$]_s[sɵ}CȭSD\%ŏYu`~:y{oϔİJ`̐\OA #Nc/=b3er4t-g"G[+}F"КNG)gрPvQ?|ìŗ -:jM? 9#\Ӫ)=4mgSI.e5Me|>%gV4@8o=z濅P/o9h|os0Q9Dِ+O<9.8I3cʹ)V1PkܤPEqw~SHzG_w|d8kh%`l0 0V|VNmwquk2c$F]%EQ b9$V>} &Oj_ijr~}$Kc"쏏QNѦ&_6)P HսDh:<{eǍt0[\>D.}7͐⟊?iemJGP-ccwlH@ ` >it,յ_!u"%5i/mQ`(t>2 ɤƉp\lu.OÃƢ^0HtRSN lJR M)c`p*HgΌmhB!f5 C1sשׂ_tﯟZz}8_ (_E_.7;&Kd X}K}Jӳ䷤Ot._mՍ#YքWoWjjFݬf٭[FHߙLJo w*@cqMiZ]^sBy k.6,>^QCLRldk͐֍sJ'?J1.Jwf~~Ƥ. {nаYOPb{//p2xp-Er]ks<][,d($˕ @L&MfdCI^2t tO:OW"V,{Ɓ[,1"^Hl.x+bu/:0 hL_UZ b׎x49ѣm..in7[I zPƆŜ0P3栳*rX vH<;R^DB!{d!em'ltEWnÇ؁_ |76`N{ p@@Hqk gt O@q\_6SH` e:YS׮:6?:T@O4vl޽4S}cmwZo>u%B3Z&mF݇63!c8͈1v\ZL,P)癇vvpxZ8yeXGo<$ᏸG!96v uf# 4[]j"7:l5y?*gnT&Сө=Pxvb*zͨ+Fg0us! tW r bBFiꯖ$J(g-:ڿ?umgY&*n}3=ߙ]#sW3VTB>*lH˥y(P3TM-g.qAb gD\-fkk}?+;5anjK2`zT"bdb6,:@`UU[1&LW$GFuVr5woyUEv줨)rZ=O;Ud;V(JW63/53rN\h9Q Q$R T2|v*?SsXMޙTƣ֌7j (`rl_;6GvnQ;=MDB;ruu x$ƚO+ YMJanO4e,b0  bhʰTWwİju[rb﨏ybۑ0"Jh0WVMGKj$Ni;.)-qn1NcEAC @)~i7LLwݪtj(N`' ,unrUfL/<>N6^Y! dfzMeF5g|PJ7s¢c$(~u1ynB(vu/#G|y`CԁxXGeO!ݮ>rE00GTžOɄ3Rձpj̋P^G*/4hQc&*6P:‚D}aJuFADKYMMո Q@(AhAWm^Q1-k!GF` z5h6۵8+ vD].`^',:Z6G>&^cEƠN7d:6Ï6dO:4ĿHSQhN+AЅ󲈂VR6\hnIl.9Ky/׹ ˽d}?},i^Oc J mBx -|~)_ńu/:#`R0MUKƪ[hn<p7c܈ +mjHPA<"^ffЍkɯh K?!&[X $(?W-͋ߺ|:ƪ̀XbVN1  y4FO.m%!&4|l?<٩O^x3V0aM#<ހl0c‚~s/nh{ǾNhbb 0T^/龏dNݭ' [E#C*4 Р b-7Rڝ"/zv q"_&dLXWN>I9?$mgU2M[|֬AJ3>^P P- ( x#.Y;Έ9dIg [b硧S}Β4q]N? oC8,29Q4%K^cT{L5ƨ=t*DZ6k4 ^=OڔS7O&;7Л44f4@;jy3+yP턷:cч: P|塗m|^n vf,v9xt{f,XNa.7Y,kjoKY O^%:'q-8(+T)r)jN,$a/N D0skzTwΟw+d |W?zBvbIXTp$?lVYىl_d>wQ w"nK6,Tb3w,ZizlN V'~V]䋡yi~-Vf97f ֠F#9o_m#­}NQ<^6ePu(Ó}% ^k6-|0}<L%|?ε GL;v3+L..G}ؑcwʼn|{JO$L7 ƥRH_uL2ahDVR``ִ !DgIT6P̣B2GUs.m oWnu|2c$óu߿s2=O>j.=VZ ^H; 1zH~f=-i#f6m`+};GrH#d8Wݞ|>gI/f"-QvjmT,UfAP頸>_4F3 ]~>Dr:)N=M~O $C8 5{1;J-9mZ옸 >Xa{~7bv'NxYU|6&_ aD{b`Aw?jYm q_D߄AZq mV&FuaQYusB)A m u: 5!Ckfҭ,S 60o缞["Րy Dh߻\ G!xbG;9c K2~lxVأs}c{.n}vJg\-)Ca {B}N5t6f==~E> :vHZwȽR]T& K5@]n7{&=\1uLyK)b=bz\l`˱g6"T^S{}$_(v.#FK3@^Q;,[E{^ۇigqU3#@53g]ә݇p8B|c1[%?l1b1 (ԥM~͗ن̜l2p[.ˣr\.[-U*Ēg`|˰\+zOf`kWG"JS4aÝ7+A>3g65>ӖI)"P?oLӶ(:o׳3VHEZ>)ƞV` ܪŊ#5˴9filO#Ze Y\=꿇ם`fKc H``#;fb-]DZQ8TC,w*W ҝ(-]XteK] X4U*[Ӈ /@s{A"0cھU,VFϷz0RG[hulfm%x@VG]O?feUghh,wR^ZC}aLPEa;^t:K4Pꏜ]Q>dd5kQ(EmIf}Ў S T`n'@w.7.I{9۳.zޕ'31k1ߟ$ )_UU8|'Xp\Aıg)ڬ3>oG\ꝥ9ˌo>~neM{_//_|]C  vndLlәgff-8 =~ƨƖ-A*~^nWvT0~gSZ7ScC`I9&oѽMQ߫}(Cnwynʤ۾O hSkitg;8PqT>@Xɕ  i.y:.χiy4`WXBvȼB*ϊMk%>ƞF]/Z0 !pw!lhyɥ|huro:1]0vz"S)'v"AT ¦ CHZ906{\8Z7γD=h.U 2`vM b`GrSG:P.3?cGF%@&G-9 %ݫ;_YR_-QN{:9 aщ@ZQl-e.XIT `#۷ `'"?^dV))xw133suُ0FfWmN_\۬ +0 \Y#sR#h)mHX| + Y3ziu8 9; q=щE8d쨲Ǧ=2ooɴqsdѓW%/jrخV F3"3w/S5M-t,TAh5VsըJЀe31"~3'S FBmɲ9rϕ@BUd2ߑ$" Q$ /RЈD-Zn[l [ e/m\Q< c l `^%V ཛE4``e0)Ea.-G+lP{!.D/uWO=6ԇNSG~~x gjz72ăgt ĝͧP+ʭ/_P/mw!jP@l:1dZGcBD%F8 %hga6$+ |:vm3ޝ>|_epiοV08d:ɒatory)}g* $&(ֹr~`˝Fa@k'Kqfꂺ&5&/Ԟ|E6Y{i-T(r;a¦)xw'#LT*b*#j+D>.H$]cDj;7X¥V8C=*jܧyYȨ5\ŃҺz/. 8- G996wL"? ] `}AgrN\ihl ㊮wĺw3c&f5ܺX+m>OgՉ aK8D֫ƚʆ5Ջ}ꍓ cEcͽ1 /&H%yPt@pu=OcHu|B("hzDKsN{FЌWUJ]'cltN@?as2&4`D]} ZZYf}ܙ j(GͺP4BEI9x{{yUiIz y63\p6 WH2gs'u@bGsqi||}Yɪd܄p$Z,q.DP?I1rȕn &7?L홿*i3#{݄$UPΘ-DEK0O\T[ W0v81Ȧ п2dwAc#.:M$G+7a(lBcMk :U͇i}Atpj|g8 8?Q맳<"+e3FnOggSnwuި0MTQTQT]XRUQNOOX[]Z^[Z^dV^XYYYZWXR_UPNYQNNWZZVUTUa X `_golcJq\{SA)5^Mwf[*몃Xx۪ 4\+jfؼu ԩơP;L[6/nv'OeTULf8ӺyW.H=*s4`F/0]5v ʟ$7` InaR8\wO)@8x+@s[ l!]dD|ЩŸ?7 5d)-;5}[Hw_* Vʬ戊v86+ErXس,o\8MZ=8pb?D^m$:8Gv~k㞱/m"F<YgfRӁ,u+8'@0c@\ɬy_vg90K:|ָ_CRD@|]C 2h8Tꊹ'42&sm8;rn^˔ *]d##:s<"Y̡1C9U1-8+gQWA4f/m5` ~WwӒ}T& 6ـ NHF9Q XsUW7"TZ9LPGUʷ=r\cmI`N=-ˆi|Q H~; ԭ 3~Bb*f0K;{]x%Æ!IWrd{h].<L?&B[(={-p{X;t[޻|YWu̗AFe%3E dY@@@4q&͑4vl&ތaw[]F,{5pTi T N ż[[=ush\BbPV(-;.rn{%tζ?rE K9QA%|[%mo!#\hs Ɋ̝8mhRj4yV[D@f;q@o@a鑛fS$@hgF(\֣;wyK(!EV+ ȁwcN.}}4X1x@}ͶZ/7|h뛋՛<-1Qlɂc"co?|qh3N 6 n֝&Pm[x;dKw+Q6S?iFN&sg`3XrBH[ubBݽﺄ3 H'%ƸJd$6 ٻzo7G+vITO=TPfhiwLjT&֑(ɝpƒ8MGtN+$ܱB֎\"c$m~a^ }gnb8͞.& :kXVLo:tȭF`.n*HTR44 s!c.* Txľoy%iM--agI,eu%;m;}ߦlZIIĹ@;+4>A} [lh'S7 |'3p*gCjuĚn21DR’ÕJPGx҇&町@SҼ臃ޖ#V.*;rp% zo8PW4$2P ) 2e.Cta`d}M~ܸ//C"Rr)R[`b $F5cMF~69ov8O"Rd꾉v E8'qb_`Bj 2߼4qwuETڿ~ȝj(U>c:IzBN"5΅j5ݛJ>lq΄:M^BRC`|?5wp: 9%{n}HTU/e͑ǫ~!o)]aO,؞MTE}yL9@' Gӭ/tXef;7y̸JpZlCnY[x| (: SؿimޫOoaVh:ҩ[֘0&ihG 449/'fH߽}+z1jGy&5籕t-3ୄ ]H_9V &xK͗f>sp MRzj'm#\*#hH X-|wyj"^ "SܢTAVLTLi-::m?5϶e)Lܳ +3 :1߽3|Q)P8Rfݙ+N=E\tWAt7cئ6KsĚ 5@@ۭphBu#EVzncP>Ҝ _plSwt/FG+ h8X(g|, Ka[&0|>n&`zp$+>/ףwZZH͞=oTͥdT[ܜߒ L@*v2jß[S.:cӐK,?p;A: 8QnInMӮNA_XljE` 0z柱Jw]'y'p4pS2WHWwL %eWAV~VH9w'UK@^ ~.=l=iG^.AjFQ߈C* i,"*`Nr;sxٮdSNSI3?}WYk B !̔=~?r0ur+f,=\Q _hnT`e;mLn,@z wHS鉐BA "+^ƥΘ#gӌ<&~a̪Δye/Am>*+ ׽ ӝ]⶝880)^QPŞc:>2bm@!Q^?Zx62x`sbG%0ݫY% Livv1t|nLο)P4 NKSԙ'H_ɫwd~`_K.`uunn;Ճ+ To({= .y[X Wڗu\fTH׽M۾^n<~aWJ@I _IIGҌڳ!GG &cJ[Yv89#rPչ+Ni Qfo |ϴ+W ơm  >}Ov1r %%yv\!reb饰Ҝ:^w+ʠ$ }K;̖R(ɋ<>Kh ^D (i,t}gv>ë1j9lkh> ̧G|P+KwP٪Dp< 赺>y޶T9Qobh^¤ݝ3 T"$(?]ڐŎBu I@Ĥҁɹsޖ`oK FDt c4 -BR9#v3B$#6@ {"泚;̣ ~ $`-}~W[ q { E>v;$pPE4)=6'ʠ7H:cmtY]wT { ߺ2 βA*~CL[Xu*@HOgsU;RvyUU4V4V4eeowBkE~ȃk#ު}nZ؞5U;*<&c:h x秓i[x)+_hI̡:y5yگHFz;Ti{ hKej +){0̫ƢmX VVu0&+ډ^iAuBW}N@qAv~_v.@|uYe6J~ƞ o@ ~pwif'LĽ2:: NM7M8{Es:z:xG-ᪧ%HB œ涷$$tY7Nnߟ6^۴,  ?đkrY$cnsVziLA:ܿ>ä\嗧\UEĀrEWTF+ƥI7 m՗OOllz:>;o-YxWl3 c'S0 Sf$Fc2+b{qtVBw]M}{lH%?txe5<81υR/]0-D#T>bm ) g ,}oˇn1UIRƕܜ&_Ɓ"oYurA=Y{p<{B:յ_1;8>\>O"('(u(эn"[3[geVq>5miڬ?~i$vij'RY$K&P}1rdI>|pm+=0HRQD43c@5szqlPD7ӹB(#o I& w08'G  5[tAڊw p^PpJבpbwfǽmO?wM&R"cǥ)T? B5+(T" P_[ \Q${ =3Qr6@ H`), :BDT&v KAD 3H(!R./#؄O2rQur§FP @8i8|?Vָ%΃VX pťkHUU> */HIV J$Xy^aSeݎ6GEwaW-϶jUHT $d@2dr_wYdfR W>} "Mʾ du P}>gG}SyPAh"azKTpa$R^> vPFՀցUR y`Z + PNIyx=N8^*%ZR\RP qT*1חſrWyЃ7TuĘO3 +6 %~O7/V~r m5Dr[|o6Qy3?.# [J7AF`g,b_]?>ڟoXZ7dr| @i^962jצ$ svy|qx R,y"}Uui*K D_QǒQ\T~2akr븭 ~"MTZ*&kЗwy#[iF`d?wMsU$tEiA/;_7!uJeJ$'$HQשr&$5#tm>zX%GW?-9'G10_QW-u8ؗOd8:]ijcsȜ]࡞ey!Gr` *טۇEl6E0$ƊH"oAe; L Sg'!,p +'s*ȸė:PqFJKQlZ?/tBWs lBN1vCL9;dObT{wD_̢,єv!"u+RV}ċ] EpL}? 6.N,#{}G&Bko)V!OiKtZE+ -;'#[Ud~Δ-qRAd*vd [OT^Uuq'paY&aȪCU_uwB^/XjϛR*$i biVZDL.eBsV*\(qe ΌOggSnw1YY[VWTPLT\XQKFJIHK\YUQONGMMYW^]]YW\Z^_\SXXTNX\TQI©z :1_Cg{=֔XQ2rMXc*@SvT?bZȽuSy 1yig-6t:2Tגqw+qD%BiN(Ὡ8g˼CTM&.b/_}D9]عPf>Τw6V[,O}D֤ɸpA+kQA_ Qqٳf)i5ZٗVR8_ʣ֜nx%'?}ù5ٖL_CLDd;R  2P(c#pNC;yuLGgngl v7b/z3-jUUT uuN,LŠCkKzŝ$v`h{n;=Puy2Pz3j^ j|R4gi܍xc8u@DO=)` h~^ekE@{J~@2;ѭ@cid M.F!FB%K.[@:@y}sIj;FKx @:PN:?EX kƜFMm .F ?߷NnɊ+EC8H<P!N- /9uA7v<);(w_vz`lqy;alO lV5׏'^xs9l\rʗ*E0r|C؋>]d6\,#֓>ZoKA+84*eB12@zl~pV F|tOJ!9n_w`EXGcq'WF07RP8 %D UL~!5];,SƟ[Fq X:?|\8h4_jrԪ9.@9Vqly-L[7^fFа)K!]4@3jiyBU%Qbݑ/)ڢ`uښ=HbZ脷C@rd1!01^H~λx G;{t $,0w^ZsoFwv t?[W,qBhH' EN?-zw]P>cTƜ-,@/YC%|`Qx{"O{~kUÆL6{ʔIa4|9D8g昣ogxy9yAK׺H Eq^ PIr^Z>da׿3=|j(jToEavoB߷(R<жQ==/9n-ͧ[:RB9O%Q`'~_7  Nեd2% uwlUn%dЂPudO]NLw同-x!2O1>yGN(ijԦef%'h./G`@`&O:EVmʢfWO{;]טEkA|k $` 0}6jd+'S@;x] i/pјc ^']ܸ88. ;tcCG_&!,T׭0E|xG1s IKjbhKc%i* K~6GR@u\j?IUkC\$rU@+Z:d,G&1멛Sp]b`2TKNh]?p$}2pFp)*zQ / Xk tsvXX\A{֧ ÒR{BP($nm*p:{+ 4yCShΛFMw @TxvK}.CNBQ{! ?r:NkBWL @c9bb­} ,tM ޖt˂|,'D$ 1ED9 ]X1ȀߨD3]}?BƉ&tc+ƌ4+3^>0}hO ׾X:)sr0גT9Et K/ӦJ?S4AOLmc`0s.>Y tT k4Eʸ wno&QJ;Ie76 8)9 k9Yꮚ6P>Cr_~WZX44p #$.kOݤH2A&!~QQ_\#2,YCLd)sbн\6)yyނ{&'qS9}߀ `EE/I?j\0wbt7I55 5PvؚpE[YVy':sD=t֛> f|JR`ҧj:)A*" Lg$-[&-ͮQ|"NʒHJ\ ##la~ٻ& λT¬$B}T@e* $G+ >/ mCͧ{N`VW#X)gN>Kl=vl-ݻv',yfa6N7۵Ԩmd'|(Qh84KrT¬ :7c`JN\h["&ϟ@a `,ֳeܕ?g]wj x7;=Z9RnS8=OGͫ_ ׈%Ժqh`*<LJ~&YG{ ޡCVA+ %Ƽ'u4iKC˔[ {"5fTxl0җ9N6QB{,iQP>/OАd^mmA K\f6@2y TQ=?U5g*~YF(4d@9gtОjNFjU;{h$,>V4:=[d.݈~QB#h*=(;ldڵz5N_j'N @(Lfa\B.<׭?oSa}4 V#)PpXYFOK$AVWbF// fS.ވ&7RE -ZLuh0[&^ѵIedo~m)v{;P:P*OĂ )eQlؚ\Qeҗ&Ν:Q@dX)[|͵*D Ea^I\Û*`6KG9`,P%J3*@ni@߭nzMgޥɞ0N6cDbG-'I۱QTgU@hDPϦݸ4=1d"Fwm}lٳ]s_ *(N3]$?2 C=3!E{J0gE}f.>(<ߠ5xj( tr'v\8he'N,P] T`Κ hޫHzD.}. 0<QP[?h]!b[ P$ )UrKPx;9ס[l/ݒ \$Ѐ&@|LλSa\ۇ"d&ƬFf}(9ΣY-:V4xy8JF؇,M rЅfƧdž L@/N^,wsrJWUCuRnW2yɈ8t8%Z:! Nݔ6tag:?KɡƤjFli1b}ݷvouk;,wQ`UHTep?n2hGvqyHKw"g HH5Pppcgw2-VGs({[% 祾 ,qђyNj4̧9XW)v$W\ddž\(`jZgl{vᮇ1< HptB5 ~@D/ 䀃s\긠)pY[bMxF`_']:>N%xݖkY!XTȝT1W\ Ep$f+8h8(M _c՛WG q؈[דCy:ynE M햆*}n^-\lɖ 0\vkIlڑoZeYV .L0*3g;^+6ɚXf3tGwvn}3AmV%QMGB/I"v-.aҫ] V_qgKNIg[FiMuF7Er1v_ŝ͍L)V8Z k791|dH[,@i97~5a ުCP6TCS/g81Q\sI[^u3R"{K?Ϥ5_#p+\ր V|Jƒ:¨W [&}}{G4GG C_1ACğM,71w0z'P E(]W^yf/BLeGj;Y"'h!XTtsل8jW1P+HM#M><؟Z̸|O`NƮDvk""id/Y9@鰡Q;&oB ;*VsE'2d-ߪ)_.'ML 2t>|q'ObE 9_9El9REq3-Pu%t3mlb*[LC~%#>]s[c2?j|[~We|"/%F*CQ%]*\9(R[9oPr$ƜYٗ m, ;w%lU.M)@HWb4|ϐ*q sGqena|׉y]IMȟ.d;Ԩ)g?,!WOa.DHrY~bdTp1b/RIE.ԍY~} (/I1X݉{Ƽ6% XL\~nw vgseDROAZG$kCl53zJ`G)?!Tr告%Nt# 4eb1 PTGT˭ ;զ(p-f*7rELUDɺ=|9'C;yѭEvNt]bFu (`,6̓ɥf4iB؏4<]&K+Mhg?CC=m59Ң[1~W/}bHt8`j|0/;J+atC7t6nZ?%֗=O-gB!̭_/7.3,ĈQurQe0qO-u2 4:R,5wW5!Jy`60?]PǚUsNWzMRZ _3TkUЛJ^]ϊmЁ LY\]X&7Tid8 gdz挫)]CY%K)^}F B @G =0B!ƟC$]xAk|aqJN/d䶀 ny:Uh:¤̶H+>=EA˕Lm*ysiyti:6[ulYjijhl~i}iw=D7MޣM~*@/d?_|0?8{:zi/ Noi0 :IzH-{} tL(AJx7VY:_'fic= ̀-4t, wOfFT/pbBS u z[_GMT_m](׻P5QFS$r=tL`40[M()iok>,7F o2( (? wQԹ;m+wRO-bŸ"'BFPaؾWA<Υ|`HQ~*<[]ٴ[l/, )97&dߦ(Մ}>_?v oSotFL&z0 m+ȷ}4z4QBSBè@@;E&ơk,(L5OxߕK.]dArgt?5\%ƑEJDN}ڨ>Bo=rfatvP߀>\ ЀHۯ}A ~ܛ!!Nq`wJ fG6X&`k   @TDn\%oW|C!X ˘0.DmYQl 4 C54Ol4p5R+n"D2~q@S,b1V7˃[&_YFɕxXyRWKl$5.cMA="-.GJAW'>;#:+G&:+~^a?YyaǛٲ#ޓ%HI{@{K/0r? E#/gFK)gmX zn^׶x}fx% J/YʨQB{:sV7#;z] ,.P@1Ӗ'G(U^F%f13vbk&9tJz@PL~餯>&sPJ;\Jɺ_֔#< =q¤?eO_;v6iJkN>ۑ.`^Σ݅Ԇ:>u!{@oS*CSOɰ^:*(U;773(RR"$>m1 S֌ވ(;Oj} 5R__:#Bp)Y&&a(ԏ,4$ر%C샌4&+njzѲ4Bw\EzLqz?p-$0C)4Ss"9sO4-٪j<{ދ3eO+Ψ2IFLO]c[3$ `tFOXuu]C^*ERqYԥVRǗ"TdZup/ظ&]v Ƣ P@5?Ө_mqdtE}yL1y%'z^dvN"dήER_KϞܸLJ]ķ]66  ~yqI߲wd,ո4@P\Y\qVgYiGqC^e:0T=2]Zݬ  ̟K=g'SE:Z]APw)}ǠGaJIi(c@yhۜJΦ3ѣi8/Af:Ĝ"$vb̻fH-Qb٬n5YeQ;Pgqa|Ŧ'*Pd;oOF/@{y'LK䓔TdgnbѲԜGJvNRt=Rۣ{:$20?;զDfT0* I/v 2jt47 L!oǓπVYž,?pP_ pfl:fPbz + Go&ݒݩ5ϻ+rR2|œ4} @tɑDWk/IޞŢHax`*@ UD@ǓڨgMh9g`0nuh=P.! %ޛ0{PMDq_CA򀋙0?ی )-HơN7`,W&=an댋3ϼcI"k!:2JC-k71Ve-Yp^١$?K0cw۞kѹ AJ2iM P=8 >+oQ/Sc>Hqˆ ˾ \ txr_?CFO4/.V&q' Yf'N/ӡAo<)3Fym2&[H__T>?Or_a䆪 u*Y+ @ہs='M.4f4 Ju6WZ g↍@FDf5c4fmaJҭS86-0)ؤ1Sy-m,s\(-ehmM?'a sT{9w&gԍ@F,>5ӓqoMy+S9Iq_Bҹn}tbW=zO[s_)Zf{9*Qed\b;/~o[τӰ,07|W ڥ.T+C,M|MD~ػnap3wH)"&;p|?ܘek/uy3)QXMKı9 ~C"y6e: ̅βI\>S!g ;/Ɏ2FniQVRY˦O~I6z4tEI%ͽE,~V%;d ʩ- ҝwW3+gH`&Lc[c'$rj\?-/W#{:w JQٔUy,i(G H+cgg `;]ju0~2rZtvS WY\0*؋1L% "ic@ Y>˦'0(GeYƥNZI[ |\U}4]h1^zȍ\ܤ9E\ǓB'l)0rgPRH#Nǣ_¤-ۻ Wz_<7}^1U崳KxhfM]auPDKWD=jtsQCƦk)׫aF/-aM#-X |m)vliy;ǨJh{Ru| AoȄ 'l0ȉG :zۻUYw"GJn2tɻwc]WTviw@7; SJ!J\eq&ZEb%*G)Å( 46"Gf ]穥_iFgᦧWjw# =ѩ߬L$ @1[j!> ()tX}9oÆy0 1ˈRɏ'v>4f86r!;wF_~"A0%AY\'&҉#$OggSnwCEU1_ZYVXPNQUSSMSVQJX^UUOUUWMW\RMG]VNGW\]]^a[SSY]RQNM&S%JRTt ]lIMJ;n&ud*]^Sq7D̘kTF Ky{ڥtAXt;qSeB;bD2ա' l%>,JNΈx H/,eԁ}S>9g|qRd1S)bvbXt,;HOj_{/w |Z絀p.cŋðc?qX{x(#[-勵$!czjL XTtj>"sUKz5@B<=(`.G5KQԖʊk\Ľ#VPϮL/1xHj;7:HSoۊA*:;# .HLkH˱nwh*Ԯ= .rr"^LHg |\_8aWɄ!$ "ToZ$ѕŴcv1j7 n~f*ȡn; ݾzI/:\k>o#0$*__k6Bǔ1[#̂10e[_+3!5-G~&(|ei#O~8v뇿8/v}b*m/:1u vbvŗC(@]e~^>t2S I~CmNsZ75ks-s g_rN8s 1IʃGG'.%ײb=;hlglGqXf YĊhUt BeP {bifoVy輤1ο'ƝƆ"C0p@ZtM7O,($f)J*QP4Jv̠9u#lK +rhv'^;f,a [I&}5Ev (8EAT_c{e:&@QNɇ֕sL].<Sh U mN|-0y+H,v/i0X`cfm t Lſ;GFFcMQ[FJ~ggƤ~v O8gFn=2uAl9!Kx`/% 1Q8n0mDD8n$ @y"f=)4߹]@1~xҀ1΍lga|mYl,Ѳ2s<:IK?TuWbS7ǒ1AԅRfB 14pll`2 Fǭ=۵/m֛{%e ##^ Qм&G<`]b~-6/;Yባ,aGԡ1̈#Rf}Dk^/#;#$gY3~yj群a[riM%!c48bm[J^S8h=IFV _j@MG<$aÌix9kw4l2mLQƮN"K(pkqs N^FKKg]2Z|&>d a+aY"9fN^{W {UX Al-@ /,vq?TX,X,`e+ڣ"t;ߐi.di>>er?ь4zиss;?Թ<}^]x貧 ^&39x@ `ß: )Kc{ê9KQ0,'8 P(fd3KTƻ'g* ߠ9ԀQ1sac,R &iND(V=(S%B"w\ND}-Ơ@::nrG8%VNܝb>8h@B 2Xmt%vj)aW%A`5 [i/`c;޳C"sm]<,ŏ3VC9K6%k_:=ō)wtdkNOk\ƥ^#iZ*O:ݫ_B-T&"zR?Ā EA>: ,e(-~qhHx`.veV<}o&  V7(c+YjމGfz33uR \;]ウqRS;} =1Eٮd >"&<'oha'1Z=bөLW5|(dT @ש1]o'`;AjVIJ4<*u"-{xw%[i8g714-ud&tD*q@1Ȟ?aSw` yE;ǚc 9+sW ">k@^-/g}Xi;dȇRԒP+C-CP g&{ɵ(7lWc\a؂>n(@㶻wW7utg֝(1B D"uvXl~N<όDzeDc&6v ) M-{0c|ᤣe-2<nKSUU L>TUUؠ=FO~^:9g]v+Ip 5:Xk~n%RWZߊBY4$)0vTDO '_) ۶Pa_LS?c', |;NjO 0l@ }4,X]g}{s?U*;#aێMH* h\>6ڽ?IjfO}ϩ:N.U;T@A$o(`W*@aV3aK&$`cxڃi:d>K+m,׍t Ts4 F I/_";OggSnw׈0ORMZ_UWUPQQOQZ_c_]\]Z[cZ\VWXZYU\[SOXQQMX[WUYTTKEƟĶ]Ski1rWE)[UVN+PK6V}u-v}}Ÿ_` Ey9 'Ӟ~ RT:h s!+.δU^& ApG|>sTv."2Nk*Udձ=2pB[*i !?9o)_Vg[^2>ǗTdV[k j V R Bma2Wh<F&YmGcqW (חg;9_lz7T \d#;AiUq]s&Ɗ6\.ŴPkM6ݻ݊I?/ ׀&+ߌGeƼY'ʹISrp @-hB︓vEIy.㒊c48UW$QjB7_7J$PF;y$"?ވcf莃"&-=a6:%|a}xe_!rUPv@bqBQrZAXGt}svi1?!&gP,1lܶ}XUnőQ呴 *szAAfMFN`ꒋ:hkNZûdII|/Zu-9Ż/~5S}{ۿ(bHa-[㏑ 8_!}D1(VqnnA4ut l_NbP8K6?Tfó0 ˿R%o  m>صƆFumtO &O*=Q[X(w.ƩC$W'z6yC0lfftvb1_<c=Y97'{-f4BZ.Kw%uձ!}s^64ˢC,#>w6bhOdK*k>(tWNJL'&[HwƠ+dKuXԸx=7{1@*O;nĤw (N+ `#͐UJCwE!c%uʼny8?z2"( V$<扅i'Ejol26AW2&§zgw V#Yd`?81lдݽֻw9Ԧx~%Y rܼ}aFL#gԺP X~\y|͗?fCޔLUlmT{vD&fX뛗1ݱ!d;gW>Ͳ0!g 4ã)o!]2I)E\Jw:6]¯zFQ^\.WCVn`z^uɟxf>LH{ /{4sm#7x~ vkkˍ[tA H%_kÅk2ԇ2&dr_{)mZ 7K0zWH DplY&юe eg㱣zUT!kK(KG{BFg Ĕe9h i`$VƜoy7E@ ǐVd_NsGe@!}y*S16)xP)W6rh_{!C͊BUeV}<> ˦VZL:8tgs[x*doX `e877=AaX ؁*tF]_݊HLRŐ}LE_^u((Yb}Fwwp;d٩G}H\L;#Vކo\ .X}Wo]c" m%nT'2ҍׇfKlh>-۲Ls= :'LsF:%}QU;&E 'Ɠ<"sJBM7=9$#?/˪OEA,gu'fSqPs..:U~("_28k/LjrsƏ)|GNmpwK3 _4=:`g2<°xhֿisL=5KB[ޕ@|$=W鵰R6]O{c7)@"+pi\iz(^ω@[jowL"~5KmxI$m!%`Mp>2mToK||:q,eM|((V6c@"-eVO:D^vS[D7`H2~w)nw&Fj'wt$}ٲ!m̜DT]$u\6Xs+_~$%>ɒU(7P\c; W8BJBR=WJ{K6wIhnh{,ڥO(>8#55K" ~5 +U )#1ULB#%KdG:qg{{gWJ(#[.`'@# n3Bvl)l6Y]8"HJ?ufsj1kHO 6w~vt\1c[Ate* Hg(*M`POY#; F [j=k%,6))2J6)~  ˊbV cHg?Iu3VԔ^2L=Qlpk̀lEbzN>[3LbA < vfri8~f&`o'Pn8"/*`w渙Ǹnns1{ZY~aWJ2YXSL?f8d}~5{=d~L .w,sG3bztĿ)ȗ,l&y{nz|~ g':{KR8AZZgS! ( Q:tviHRWx]OggSnw_./Z\W[]_ZWYW^RVTWHMHZZ[STY`[VU^JNR[\XWX[a`ZZ_^Y`[qF>?{nʅիC!ҙ?geJ:㭗,;_"#m?-A5c6`YvtE,Y݇^{LW<!I''_4*ЫW69'4gtp\תV2׮LEÏ?X7Ռ+ġ@9F:czyB\6q|5Gx.m_ˠ :}p}Ym~6BG(t&<p,-<É(G a$-uy6tˁH'nZ cT;`2=ઢY]=8z$A@# 0qBޠo &y a @CQUoV8zl4ݶXҹO^o ";|#HjkU,*MYr} j%Je6Wu̓ŞE?-R‚P7-->'4xQ IVV+֊]6hHt3JuOޕil=zb.UA`P4£k`<;}mbVcڠ Hա4JGKF]hklu/oGtqJ{MhWEH ¢,[A`Q϶}Jߵvd&IpIqU_͹dz\\̳醜kutO=к$ArK'*#HaWǸL{`UDEg}A9<6LH2>KC8T0(9E,2=8"6i*uk4 y/ Xj(&a2k_*dto£^ $Hljgжo?'v;O/,hq X̒kりn%C |,*lؐA'Yo{_iV{Ѡ̳NQ=/ZBy__`MO썟-_64h[^nv4KgV5MuP>&/t:)䘊p'Π|oA]0q{IcW3=hU䡋ho}nRU58] Tloh*($|CibD8wwjQb;x:Ynȍ nځiccX֦}k#G &d6,VmsKW'k:Ϟypr)mN$M0;lMP^1)RIPBeJoʢc KLɦtѹmѕFfDR@)o -Y<pQt& [}ޠH`V>x+_v{b%ܫbeF9a:,r̰N9K CtU1U1pL lt$tL`swfux9Ip25@>c)C6%^sI)p Yq*EPml6Xj'7o}:mldν$*w% ;.+7>HĻC Ŝ)d2$iUWzlKlu5}?jv4b%B>n(Zʑ[@\bwIZר/&x!gԍH`QRN׌D:}Vs|c5vW+h UM%6瀜)&W3w&&u{Tlَ=N6D$'ُL9^ _.͛μXo.nFF=^h9$}y дio3}}2݌܊l*?.&Cm#Z'LVٸ~z.DduD+}&hf22ΥFzM,.J܄驃~ M:@r&^i9,-Pf P'%8ypLO`>L尴^K  PDy320G@C*PcT#"%R\^la^C|2Rjv3%Ϩ9{'2}bKw.П^7 N/,:z:3H4>Ln#qҤɌRⷹ2q1D!Hrr tXDž71vM2HeC^ *{XLb~?!'U=TcInZ|5L\,Z29`ma+/qHGRhI }X.4gBǫ:P<EC]pgWW&{_QQq-(cT4segZ]n L0匚<>.2l|bO co(@ ԈFUjGZ-m"J"'_~gehwk/2xZ1pSi|ưi%Ѻ7gH@7G,|r ^2]YsGSS3#"iHv;)hu $E%=HiC9;d cVfMs{Oj~KUi}KhMW)b/d1[n69OpWmqol}^Fi}]FcgJgoi/c\#t%&(ϟu8SV1֌j{shY&?' + ;/!.]ftL+nkB\-(uvh[ꗼk82C[<- %\/?{ߵf(_U$7uҐ0@1l^[y:gg234^~8Dz_g3N1G7g8"i؍nr$E N2oR 4Aˢt2HIxv7{Q74I=Wr0fWOggSnwf.1WSTXRMTX]TIGRLIP\[QTRSJLLY\\^bYU[[_^\RXTWPK[VNEROΥْ%5@XTvjJk_oLǣ<;$sgH@x( uSϲy˙9Y$ $Vʤ֜ցX:@Ҳ_Ϗ}>Msr"|m t2@a@FoZ7R&Ex½l)VJD)U3A&tS vq X< ?P|KO}ג09@&-h8 AT2Q(؂&v?E8x1Ȱl`lf%jgCQJ2,o=xi <&[GJQ9w1#k_cOV9-[%SV[H 8z{wԞ^dZTe>h>Q#5YJGͩMrjUUy&ߥX$` pьumZm"Fi (p,Q Ykv "_Eh^zi_1=ҷ@7F_[Km:gd?  4wz6nd~.Os3#ÇJzj%):WwW͏_*Vq7UlG?7V7_5O?P.RZjg d k}jhp޵/;xis˳1V0ѭ)ɼ"d+`\R\2E23'Hd]oǽ]NC ʠ֌K:LP}_7ywr>Xbl;)#* ȑER@ hA?w|щ;Y.sqXU(sC%8@P`x'lGiK& J x+Hh[7|8;86g ɠRKZ4#(ˉyIKDZ^ѹ:ݥws9 ƝFFԐQ:Wq}$\{bc j~=XL!=W!_V/ߪ1A 0<qcl* :@PVwyYhHO JM6z}v;1Oϳ:uyI|Fω@Ve(4YG&C'S; [qh 'Rnn0b7Yn N@X6OsUҊ딢 Y`GH L'p~hCgQ6zi'ie͒ <) .q֭))0s]肂PL 1 ļYQF&&/mIKF $`ܱO޺ۍ7)jDE [Y[4Jn֖1tK&[zA'?j?Ŷ81_ӥJ@ TfP|K^Qod`&ΚFM6C 4sJ1;Cl P1k&:PQ^A|~=TvyBL2;!_7t -~`A(] m_+}vKgOEGLE.,szU[S5Xj_4[̶2jBl꩞ffXݔژeX{Ϊ;WȻÈv{1\a.V0R}S`ObM_^N`i#;RTFRoG _1;8mvgnAib9$PJڽu5'BQ N3n.|d gM@>Iw"5u3_{<}!tHTcL"Bv9}Dh_>$ϡ`3Q?DDfY@PJ%GH@mw6S5g1,#5*~el#qMhTc-11R9l-#S X/UIqM9L[kD, RP1-+\9YK=Fh]2;r-QM^{*6`b'glDQx/]9] :UQlF0h82+#C5ak6U#%ɤZX|V$ڂXKJmƌ#qf>u \Q%,`}z;&(;zZѳh~]qo9}sP+ڻTh;c &_D4h 8ʌd.b ύQA ٻ1uVNǨbl9LH @~}vfgTU8vq.֛ݫNܙ|8nP`)gV^ @,8b{l<5esAa4Xʋ i+O<;xlG Gk파,T 7q$moo3f,kdJVhդ'ZKseY'OSj#J,;ACmXʦJF[e.v לzZYXfsZ% `40(T}rDGF?N'k lDzd5<**24~$Ye>B{`(7I2Q=#c:d@h*@WꢪYZTc$F TL.[-. ?a:HvyAW hj(xhx<]ʙE:)gU4iZluħQ@}Ə%ΧX_y-u#H?5.EL+@7;Bkg$jpK*@r@)u6קc6}w.ߚN&!߇m.>CJdavfƋ rΚ99r0yec@L+=^0vWzteYcdD%b-*Z:/'愑STnWۃWhߠ5>PFh3\k\S˄; 9*H&8QT `h@o@ IPT-2kzz"KX ʟzo9FAk8'MgxNڟ Ab)/ڱ>L`"z=[oc*8w9wkZP |2d1 ` +",/´g@[m_ P@]‘Q+(X qP " He1+J!E0XLOggSBnwgd1JIG`d[MP[UML]e\Z_^ZW__^ZZVVXYWZWIAIFGDSXYSOY]HGW[5 FϮ# -}p`@ T!𳟊@JvSg&l4P|O+ #&lFa-?)*jG@@+PDB7)!{ tC@ FB%P[$ \'d3xB6!4it  3?nCϬtN-G{ c¨-[k@HOoMc+^<* 45 Ҟ_"0rS%^"dpDFQ0ptl§jg (* #ZnƖa[5\6tF񣽈vNXq%Z %*lY^{l|'=ufd6Ƥj60zvϝ־hxc+: j`+*ֻw{>_˫ ͗*WW]l7Kε#ߍFOp(%?X~$%ҩfXUqgKx?M8DPb@|x:UlٽqEo!l F,.GM#d給ZeEP׎57izr7pOv5Gq"-F 4@_ox>y~3Ƽ:fJrY4Ck5ld+ hYfm㳻֫Nf&)M\M2L NL~2LoA9sCsqRS' }803Lٷ~@D㿥Ts@㑩涙Wjy'qZ'fڔ cjr^'pTK9(g Л=|*꺴l>-BY?tm5RfSAŶ8X :x&cϢ$(~xZB~c52)Y5ގS&PV%D-QȃSValٛ2~leSf :W|AjދGvR/w"򫑁U^*(dDPvNSOs:\޲.T9Vdl$ukL7G b8Rŷ֑boDi뙺7Z=ZӤd$qQM̫.veRq'mjW+SUO"& |;MRbdG,@Tn%W1oT׶u uffd[6YOWp"up'z-i{&OOWG&kOjJS;n,zÑ*'*bts"JX_hrRm눙ccg $H (WI$]GR/atvghF ɺ}w9w(AUEѡR%-KHqz{ӖN.Y($g*JU):ϰ9~zzk=mZ"/k5w~g&#~R4Wĥ?n,n=`8&`d֗Ѐahou|j/[ԞƭO!8NL{v! cN?$ %Dӧw0MqCƢV^9;`( :kbYk*p >_jEȎ'= t3'"@D\My#%fuLaG!~#\ޜrBgM!4Y"8Nf*CEƮjϓ^CP%`c'zR[Fiׇ V@d{mMNC_6 C7W3XYZx? 4@ e, EK4JQ͜q ƞ6a@bg]t6l@sqIQDauwZN(ۀuJ1JY3kŸƶ7t:0LA5m_=e]K e[(A|h8_(u(`wU_6"&C?޻st}w8Co$zfdRpvL!$뗴.چ/ [{D[}*@-ug/\̧{l{)(64Ź]G[71aP]eߔvN A kiζC&Mb&%] @R|9Z03E!3-'qЙßA tkO-CU JsG:{x&0ź2tB~xX*UA:USn`~Ti4גw^ /6_6Wسn _QQtSR4.P'IEOXv e gqV}7>Ύُ8&|VPח&7;7u7_1zф6;,h=w~2NW-+ĭK7љ#Fh$P/iw3sʥ5c-mtJa:9L<[+sΜɯ[#4Hn8Ρ_Mv}%<5@O\6h8a#,y;d R@(O++-Cd ~( `~?P =uYX6T[@ X p'ߧ t+p'¢Ue<@1 `mFRIԫ!%T]-Aj{c+6R/KkzvlK=k^X?,*Zw{Y i׆lX-.+ݠɳirlrг?ڃ=DNJQsJiK JnOggSqnw:wD/_Y[YY[\S]ZSOMWSQX\YONRZXKQZ]]UUZ]SWXc\b[]`YW[\Y+GzchYv= ?mbLㄦD]\~C\}`0]4m?1r7s D#}E{Pl%$Dib1~L[oi^k8Wrn=|͗ ~4-Pڕ*h؅  JTJ y"UrL=͐fbW|&ۻnYl9Lw҄vq{My VV`(mNLR?jW,~rd/E Ƥƿ oUW^ws;DZbٚ:rqJq#MF3gc:Ts9cF8e;~njc ^Li\QAJoUÐ訏X$wky)%\Ӯ{0pѷ i";cypVv;fFK/l# \t 毟-iܦUܮȨخZD8|ғfhu~qs4R,dzee>DӜvg ` oR_ϳaZlfwi,@keإ};hyڱyy{1B-LR{GM3~=qђH`89UB,f%f_m<utu忉Wi:#W h6 @oqʻ q^/w9ZiKDzD!mHBm}QkfSAv@]0KĤtrmx;1N1NJ1>fstF`awb&ӕ㗱Gǁ7"Y21;|ޠ?wj>Sx l}) s?usd>O@ HV߻yim?n}]Ş" Q@ N@Hı]soq;M컳ɺjY8iAkqz$0$ʻ/:CEC XR5`(޲M",yἯkQ!f1G_]8`4A0y͜JzW$YxIʇB`Iz ԕ.Q={(?NwoĻC<ơ0 @Kh]]*[lGFWTGUs"'V^E4 諔}]m6=rc!bqfŘ ]-H m??'QT]7 ",.Yۛ{3Uu(#i)(7͕uF[g `5:ϿGg& 3~95meDbZ!\R'*)2,QJ[AkL}Clʤ8 @޽<Чİg vrE@CfxhnrFsYKPcqPlզ5O`h7QGڗ*FU/SpSԵpkdvq[gߛKr]nzBn8e҇Ioe HkcމR\H&`#L@@rϓKE:+wK];C-RCDq xIHc*d瘯ՌVELv:ž?Z>t潈mܪ r JV x"fvpV*]|ݎofSlB37.['g5+IMDá#&ꁌ Oa5@aƟ 1 V'N|Ht]fYw4.Fi$(kl"%MV5Βᮬn+k>K,p}Wu EշFP60Y7@k^i*+gsGy;ru^ϽEKFv ]5+`WMH:AIC4Y0ir8\N7|ެdKKƶـt81K>=珓irVpG d wAwz!>^R8vetD{SdGPׅ g lP4UӅantXcWn٨WZsso\{qԚl>fW)3i&cUdS^a:mߧ'=<|qcH 239K \:.)T͢cTcg0B{:e[XU@T}olk˅츻n Mڏ( \">uA\Q!6BʀⷲD>l7¶#"m1-׬o;/vrb҆P0)0Z@̄~PT#&,ż32wsb.tni!tuH&m{w{i̾|#iV^(oRu]҃=O9F\-3:)=J ה Y?>_n\1kb΍L~x6G!R>׉ҊK{ZV@( ֜#6#$@Q1}V7db3|U"aM9]j)GvOB)+9=%GE. Kb}TV)Vv8ˑPSrxLGZZOn)?n'votCf/'A*vE&ϳXjYe8U;u#K\2kBW]rm@i2ޫ9D9b˗$N 4e&6͋i~9Yګ #Gʶ `@qˬ)ߧ:xouZVwuS想xO@XWPIW('WLɩړrN#\"GmAA:tןNwm~ }v{OJU Df @TuDtܠ'ƹ(xRcm"<ʓ n_ٯ *o'rb89C2Ic]T)ֲOggSnw)2TXXNOZRRNHPUOPP]SNRTQQSVYUHIZVPLUZ]]\\XRPYTQTEPQMM":69 @E177xVl y󞁏J@@R1`z-mQ9j:;7p_S&b4p%ޭdQ G{]tg!VO|ٝyi~jkG0L, \5jCm881\iiTmz9)2LFFFt8K]{iݳC)[H]e D"g2%%=zrÊu3޺JQэ`o퉂_G` iٶ!霩}yq<wtA xɥN=x y/ un<<?w ωv)~o %x4a qr~OqJ ~ M)}AwŶ1X r;ecת "QߧGNN|r7^nWiXҏܴo(  =c"m!e<>$)t뷞[Oroo0%9.tIW9z/3nHnGr@9.=*=S8jNcûގ `,JҎ-FFc'u˽3^ <-4]C `P*N* 8R/0r1!9CѪʜƎ0=tǢaOgvAp o QP0Fm=YA7 Yz,5Ydܾ +v1v</HE7( %zB~dP'ւ\k#K;g~:*FK!W\Su2 6 _B݋QhG7q쫭MԵwAEde̽_N,@:NjG"TDiaV+J5qy RVbcgBw[{7/Hw `iTFN з .(Yq}{[NPgK#p$@VO ۿyۇN;1%]9-@`jݪ] hU٬{sQa7񑀖,w{#j)ʨlP?6_nz1 Ջ-XH84mЧ#wsxH5 =c;9ۃTƤƳXS3޻}~l;O&>ypR4× h c@ >5f6SIUxi=MR AdA0" "ߗA؀h0_IMUx[f\~T |(=vT23"™LdeVq|q{:;*v)ɕ%3h}ɵ4):Ax zꞅ2!\!*E^nje` X'Ӈg!5Vy!Հ.I*OvRM6Z*ܲ1mކ1zЙ&v0%~|\FC\uf[Gk:%2oDgO92<;BT+0ڮ>%G;[Ra LOGoej6RXh~8w!d `5ҜAp`I0kw8Y-պvnabY ȁӁjw>4;LQֆDZic2[{R$0,V;a|L/cUJ&W='K&ࠃ̣kon+b}X32%n ~ɝ6jJyY(m|cc Wdl#+z@(~2J8l-܄P~.7L~ 0Ź*UooJLlmϤdB,\#iWSѰvnHORt8\9nTH:V t@zxH- P [@@v`Jy6:5"?XScc[v*p{q)@c(4@Sh} mC̡?D>& V+_<28zyhBNR ,HkLc"C4V]_86^yɗ٪c1vqY+@]D_}{KL߲LNq#ga낟B-9'reU6Eɕ%pZ]mֵ25Ԝ'F:v>*%hNDr:Gk-Y݋1ռtU2GyZ &r,!W"I(EPTL&@& p1u?m˻xLlF2Y)H]G8fyHbӘ_jc茏ut,tUZ@jnJɢẹYW%>uID 8vh󮽷=X8@^ʮ9#ҳu2raME'5;B֝zc7cl= ,Mzv&xlB+([ H %})3@Ρ9mqb_iQ4@FKcuTwlhbb\@kAn<3BwY̌f83#l2bK)@]hއ/[/!QXpXdfRv9íd{t¸;¥FVV`a>uǭ=?qQ*0p(`Pt&ȁO1W »sRQ/!d"@?Rd2Ϲx'ᦪ0 ԇ~&'Pt}jgvfz0fNiC a;.h@QKbsz}`mmJ8A\wdT|  4^#CA }>@6bhR, &Nkxu4f%u=GD9nMJ8|LMUN:vF4D `} Vm.];W2igA*$ 7-Zw lR' '/ `7ӿJ^ZY4ΫEl'n!!TxK X$WnS*Q-O8uH!<%^+ 0 jMv.aBs\dɨ_9(zb[c;%}/Q uNWPZ\^OggSnw uz0W\VXUHNRPUT^]ZYX\Za_`Y`XWVXU`[QRTTNQZ\ZVSUUICXWa9*>|Xz̙ckY]A|xKS؈JA`iyc.C=G1@B;1qW tT%JiXn1ڔ F!*GBK4Wi+z%zC맵^Ws5&e{J ~7Rޭ£I>] kK!BSbɂQ+`G\>3ӌ^S3!WU[mJzERx.&dDggNA&Jښ89 @_$K]o[=w1{a-$YMz0߀ZLFqTG'a_A&@' v^KyΒ5H7a$O?)UiXP -H: -8kJdrc;WTiD> 9;gpqgLwnךm̔U|H*  /EY`I[BbK' `>t}I֢`26,|uH2uͱp#|k%hwڸf栱 =~ 4,ilLuU[7ͪ¨滳,x [_ӣz ^@j&h;q1%cʹA$~r떡+-3.~ʧP=SבBd Ųb]'U s-?ÄLYPث_\8fcge*yspwMr* e+a,G郭uuO|*;}4rZx>H'T3!V%F>=.Wʄ*"/K%D]<"W$gt }ubztd$ew »n+]6n@8/HRfu`M'Tf3ƏbZ:I&v#Ce*zǿv~Ntw-jd: s wiq$F qw&?9I'NUwhs 4 @{]bM#@ ^kd.S>^fbB9$cgKR~{r8 ?Goaw7,;x5mB Ͱ=ni`HbHCQte)gn*ӧnn@%A:>͇sE}:#ޝ!e}-Y~f 1_(]7%FĽNtƂ3u]VJ=8v(*&ƖC<ɬO>?N,;vnE*doCGjX3,b,dU[i{OhNs0ZL&[- #u{@_I~jzJj !LdGk d>C598϶Y,[|Yݐ|PA f}c4O>_Ɨ{'hqAR5g]Z -,+096 iQgxEUԀijl7Jw!D`d:@Qöo_$'v T_|L"EsrI|Q9˷4jÀ@gRK'x/'Fe@(%ץiCek3kv(mj|>Pa+rkWlDc 5[A98ֻ#ʨ. Dw&pɆƅCVc<ޙD{_!32Bo"V;K=Gv ]W!]Pwy/Z% e0--Sk(;\Tv :I a# a+Bm:SEĴL_y%uEwb:.zq]3of63oKcX:^Oub? !n]?(ej3O⟝STmUU˵wM`j+p1*:yWəz&$`!+rֵZ*ϷFjeZ;G._G"T.P_EΪg4I$Wc0N;#΃O8"!G;`wz̴NؿwDg5]*ixr2" xzc $Wnanq}&Bcq u;4Ov}qi_@K(ޥ\P vEityF]ܺL~Dzt@(w=iܿdТluױh*͂&: %6E[͔Yƃ=A_c)[cxBX@@Vibof4_{Zf{HdxODkb>@_U@2EzF(Թ[_/(8+Xl$@hg)Wsg%ap^{y)fnXQUf-EBd'[,~NvH@@wIOɪ&Z_O# {UfFN8:b3z=$dK&AT:~ٶӷ'=ԧ>mgB<v _=އ㈁10C7B Ŝ{ SqҫkD0L;=2-8E$-hQHՒސ]3IEIo2*C&龸Hmh $RnAIBZ@=`ić{݀kV&H\xd'*RJy)͎ǼDv~Jn$WO$c˯<qU)$DAuu{˩xj0vw(^,ږA9YB1\lFQ{w5U`K% @ O,UQtĄO->m\*y\π>mSGǚ9st˽tD aKoS d̖e8% G8*y?ho~_I&0xqAQu+S{Rz^?. }(No*I"6U\0Ɵ92%iO2uuziM? O2t hi%/? ml)61-vy~`kg@cbe`b:~' xs'7?Vb Ԋ⩹2+= x޽M 0px{n' q{Pa߆֣l̄C?UCc(QxQv7,Y(ÿ͡},%SW5Go{W'P+ȓY-jcEZ?8+Ez>&}x5[V;V>aX03ErN Se&mLɨf[,a Tcw[5=kN 7BBOggSnw!:[/][[[TX]]RVSYKLH\VYVSYX]UU]ONK[ZWWSY\]]Z`^]U^Z[Q(g $mog+cݝHeuHFE섘 NN;:]Y9/ e욜#<Ƭz,㝧Χ& %<^)&g@Q|wvTvF[m9;)2nk^hR5Dg.qvOpfxe'4RC7@R[9eGMƥ6I )vsv 6>YvJsU]ɬ4$Y%EZ'ZidŒĕV^WR{JW £&0_]V vQWdG$DU ^WfY Wu\DQ"(+v Vy:9fgTj#` &B¢朿zhH*핓5gCd帛RHg[pBq!z\Z&Og{JJN9D2 uTb6|CN%CmD19ΰ1 @Rҿ2xD[ʇ$4\P߮ R]*m0 !T-vK$o,<;?AC+l-4ԁaPC53:_{['RAMYYա≑ %2wS͹Rp]0$~;^6q:p2;z;><}=(LpTl Zq+0iQ(PtA5abSHKo(|uk`E9O|`INGr64B]#iP!UօQ2Ii^LH58s\kl1=9|  @Gsq=R:^j|*aO5P4~3 YbX9) CE{)Ma6p6 A'ݼ;h[3ofEN4S R'%]\\wbz*7_`H mFps7h^Z;ES("gB9J @:*YR ٓa'ʟ썚(@wo7I 6 g=q8|Νnk༅ *+'F21،t{njvqy]}4hQ] {:f5fЇD ''~arlsBdFo 6(6ſ9A=tҥھsk$us7Q~>3y IxR7s3s#ZYYt nrl=u$}b}h`a(\gN;;ZvB9kcQlǪ>@U| e+;$3ñmURQu`Pޠ9F& `H׏KDlnKX2l-f+]^"l C8q<uM΂[RKЦ5AR۠9("rc}e7$R?2 W4o1:~o]p6`+?I((ezO+Σ'%J߰4?*`ozmK&Ŋfr(UN?ShҢܑ0TvSD ] _WnVQ;{¦꧵@ӀڟՎk/[H|ܾEVw%,8W|wl*&!hEQ'z޽{z8ә!DD+voΈ}F'~a`_  y\/&lsh їW8:>x4x^2XlHZ=d PBQU! T&[buoxa§nXDYzG֡ ŵDpз (мcƪC (Y_$/|yYw=fyh֙}2G?&t!P +lè9-3% L][|Ӛ y:F's2#'AیkN\*_̍4_wqpH+Q0|Vs Bl\N96(cnW|zbvn4oƚQjjΔcy?!SOF3E-E`uV$OH:h:;'oSUĞ\,wKF['L~4 dZŜb`8}KǕG=%]+{S2>*U'8T ա@ܬ]jmBZ6GRtk֤PYt:jӍ\}P)z%$.jnF>U ]xK %Ԋzvί:j5T33{rRJӅu@p>r]V?$MQ uE9F=ٿC\N ZqzgZHԒ =@ "<0[-&yفKten }FA*kuȃuZ)&BՀ  ;7?*jo^mK:vmc9"[IsWRA# 9 Y:GNcp+ Vw~DqC6qEV3[ dTm `gX8m޼37f̀L _6Ʃ@@[֮MsuY̑mE9gBr #:#l+CdD+rDPT<(~'Gf=ʥ}/3yzC.k^/^D5 cor(",B63iTd]瘜ܨγcmh@`)ҍ?,#͇M.Ǘ()XD\F-/{bM_%4k)&dDYn!G?,w/t]읚ZfW\f; ʖslpy3&)˲mʧcCUOggS4nw"-Gg2RTNUWYUQFLIJNTWQQROJQK[`\YZ[^_Z\^[WYZXMOVVQHLTKJL[`2:@wVg?Դ''V9B 8@T0:Rs=:blg}P.Dbͨ$k}{ {)uc5@b->xOPΎ g5#""} j4̍9 2 57Csv2ɿn˞X.2]z_?f?^5iP -H(UfWcm99F rK.dj  ` PTٳԶܰ> )t] (Rd!(%8'((Av+=c6SMf( u$@(^'}u$܊C<7ohhoZ{T_?<^|ih~};5&c5@(^yF':yy<$ۼ\|bu!'o ΍4vR4o!)&Π֝J:0 g G7LKa N^^aEBʉ 3@}ayy66- 2OYƟFO:4`Mn"9^KPIXmB헨M db mR~R0+?t~}LX<@iHⓍ6)X1kZ3]\M @P`BK,` ch_e0!01+couJjwɢŝ**|gEPr[U"&9R]Nc$zY"ƝFF~.YH@ a}d6m66|ȯρ =gP _6.7K|WɄ3MsN8{=Ø7Q7iT|> C@Ȏ]^;}F\hF_2[cF1ɧ?pJSk&0_@ -Qĸem`E}+:0{<9ZO=y<4H @~wW^ŚEONx-eL̀h Mn\ ~[ MU)\TmSM&iuAK}"@,'n澃s#†^LKե:${&AԖq:> ] |t+bpԠGLY! 8|D!yhFw,W9p+Cįܝ;K 3珒 \ >`TjZN]5>o#-lyU}#rE2Zrvާl@-`.mHA`%ap\т@!J7 { K 4HQC|JjY|Og{H`i@py.]jL5q]Y =7FJ`oYˑu!ﳱ>spew+Psכ~`&E7 --q)wccd #&@l<;Iwiήmu+ےGG4,P䦿 7k_I Kytq1*Sj!J&( @{?ZfϡfPWҸİ\DVKTPZ^S9wal]TQ Z<ʡ m[9_o T'42o7sI때,l),!pd#UfŽv DC1YL'C3n]f-9$ZIZiiRpC^rq2R{ DQ!Hj\c:Y߿:u:ML^!(]` fB: uAfsXzc,/};FY[+ S y`.`T'@)HDv6\N}7>OVQW汗>= /qJKHVk~L)7 ;) >|I,zAR-39m칸iM|#8I9fZ+V* %&u(5@XTG=e~7QK2ej5laO]-S1xJiKL+=]b Yy6lg$Cg\͒AI.J "WG"ZrdԲP\LἜYndYX#b3gnb$hzMړK4N3sX pM_.4vҕl_55Z(W_givwW^6pf9 CG0XdzOMHLNl3P-E՛ x|4}`"ڗWTY_`5 GqB(`2>io'^V cYHoDV8 BJ@OHrp5ETJbN"5[ć'4&T.UDًYp\xg ~ꢊWۈvN|&藒eȨRQZ,2(` 0sddϸ Ev5]Ae"?9q1og{X**@Pdʲ//T]CKt| sMPEk{P#9ңnSS+ys@_X"ޅ'}0"M_~raf&9MB@k0k-jj:2Ѿ.~ЌǚmfDhFJvfOggSdnw#$i0bWQTWVRK[d\ac\[][\]\^[\YVTV]JAGILB?]]TOWZFCIX`ZUʨ $0 htJC)V3Wwg`#lTHkVш47^¸Exr3X+Nw3( N|ӝ Gi=85]eDmFiF')]7**[UU#|ML#,F )pYr*>v=+P,5@+v&,?۠n7>8k!óE8?u7$'t~z-'>:o`U1;v$?zxj J]xXPdǒf^l"co5 iFNNzhu9}VR/ǂ5{wc{59@^1t%g++|^\b & @m3:쓺w3}4 FjWQGqvR :Pj(PĊAg9,M [b:!wc,dh A 8ԛ,D+{l 4uQv>:fZB(Y{s<.o"ƽ\Gc$ }-gPI? %$6/%z3Z.d P<w?ok77,C7,.'g5mI\> B/AZHdbKFԊ}ªh j_αҲzt 5hh&kuz=ߢg#>:;Μ7n}9F W>&{ |u `Q]y"!-t5y|!U|b.Pl+EbƜh^`Xz$ SGO?0w.İf%4T'3!eȓqBTHM?E%<͋WG7 zHh KBn6^qH|r(gVo0q@|u"1# =h؄:OJ*VPƚN1_bc0]9/dMX z"(w&:}ג*I䣴-hʞŎ!UDsǞ+-R OIũw(GߖS-Cg;k c2$F,BW*m'?YX<;C-YGbGsvl "2gkle &GFQ$@eX۠go)o]fHp(=N k-w>[y[=vGrztxDʕ C]|5Ptȟebm"0շ?][Om͟KK|e?hA"Aш٢8V5[0mnpCq Ok g'd bb:ꖆ4 }}$'oO[9UߡWR-gB3ss22W 8 o,0O޹x/|8iaSS6B5<46ݞ^ԓk|K" 351Ýzʙ3zm{k9hlͮOw"-:csf>SOX2,D6s.让0gMe"qdc){V{ zϫ,+5&GpPCѷTr+692b> ĉr^-f2\/KwE-УESrP\Agtx`40HUMwӷxQRMT*t/ zg[YĆv]n+& P0=6 Ó}K (gK+]I*XwCU~M,(pk["euym#QN.HO,eoC)(տr#)μw5ܟ}\P"1lmU^֚zlGJ*^xADž|Ay.j:f\/h.hde?s",CybꢬԀ LyBcR#P©㽉ZյSa o=A9! G=:I" %Ƣ6? CPǐ2;Ǔ=Dc.p@YԺ!:"`A#BQjxOZ, BQ: 9"HŸ9ct`( ! ʩR QQnS(E 6 ^>60⿛s}c$ib %0[;`d@&(K 4*@|EyåY/Ϲ)?>6m6ޕ_Sr~~>qxf1؋j 5dg]t|2GL'&׌Yܪ_>:7b1d%3"zd匔P|vb!'s94\Ȍe ;Et A~i %4H,˖c*Dv*J{ @}=3SB8o#-7B|G;{ԜJ8` t"JliQ-"(Czslb"?* E|Vw>E-I+Vg85656Cp8vn ]o,fF@wwC 'vawBXljd) @%*?O{ë ӷZg>?o٘[Le24>eF3tn[9e s08rUE_Mwp-@Tc>t,W4pISqcDj{ I~ʼnfAh} pN p zp J Qt 8$Jp`NO۴|Jewgbb=0p,EQ^7y͑aEs;w%FWDC3g@DoXq fdݟf`6Fxk#EP\<+g(&@meph$=ع5NߪrʄբnG!HEwLCx 'Qt<)5$t5)w lRF=ͬ ZK4QcӋ'R:,<$ⵂ O}'kIjOsLo`e}BrBIN(.L}Iwئ=VlD֐668՘KX6wg7/㥂J%/m+kR1I"˳:m'k?'rTs#H fB *zfb'IY8LZHQoO|/F,Y2VrXlQ>F9XtvpFo>Dq.d@ 5`h`aȆ<)փ Ʈ9 ?=!@Qiə%FxaӤڦQ^0ve]b< %$pH(2Xu;)٪K hN3xE)_Yl΄ s{Q$R(83s*X+Abmx`4:/X䒄8l5VGy-Z S㺽5`[uTGƣc B( ճ3~ܩ4j-Tb.fA{"q-ʓ^@A!աR.k9uFGtʞ[5 0Iޟ7ƓD Rk 4g*p\iUTSR$AuQngw[64@UtF}&^av펺}XBWL,{&H\- oU>RއK7ͽ] ( ,|2zciAUJYqk bB8NAwU {ӵ=&7*[nVӝځp2f'995eP(n*6e^I F\xQ4.m_c_z H``a5+66vڊ2 9/Z\2`4z+e$e.f2pSŸwi` P?W )u2ӠW%s -`sHZ.B{ 2U&?œ4߿UꝞhNAUKF%p*"sGpJ<BxZ7,G%߀.& PnN7),f} N E03T҂4Q`).m526iċ۞(¡-5@XR3Ewg1 u pYZw$znR($e2[/K֜imVvt.d|W˾] Xt@Xru^?COwRŴ IАAÕ$zHA1=b#(JB5#U1#yKlM6-[6,bc֍%JWNX Ip  Hf Y+ItYϵCGʚFx `xi}j _u5@A|fe}UG2- YDyq{+1 f)QFw\%gȶ%z %DM.޼HZדJɑR;N- r$L<[t' dN߼i>aza~l,E}GqҠdSacfPzʒ5KN9geb- կ|c}j}F!j"'! ,EEul*ZF\qe|z71fC0pd"甍 ,3EIww"Ļ;MS>/Kcd8l,mlELRcUNJ-4 h gXUco|GN{-[o2iTC8Jݧ@ i3lf-i w/D F[ !-4>.)nΌ>MQ d ?̷zz2DG$!lM+7 njR;}.M?dgC.t˥ǽq'c5ho&Ø!Dp*`Drnbo)uɕ,y6-GmD1&@3h>IgY۶Z٘x4w%` NЦW*'rOf @Șg_cL4j\2kmz~KPAVGBXtY4J#vbd]ԎvV "Gn4C7#A`.̣,P_ֳq8jM1iI{g٣6 {H<+HԬkčcBMPB</n+d@ml^qBXjX*ƳwJhʛL4~ɀғv0|W|2I[P![h'ƪm`XoȬ˿~GѸuH>BmyGnq܀iאo)Pt8`k:GO-sY46ѻ&¨7A @jDuyL'LX6]ܕP6-FyY,P;59nH %6UkYZؾ kLR&͊ rPu-ժ#gE,7WΗqceêz)>`m>x8'DPtlPS8AlYT/yz'&!̄tnuc9t^>!jE1Hk՚M`ȓ-{VKş~y57< =4yp-7 t{o)@}|_:i4S6ӗZp6x4A\ 'l3HM\Rsb cgnD3%-z4!;cxhp Xtnalt~A2iczt7W Y4Rz:Y\khΧbEwc~x+2vdoٮNOh ʟyՙ۟M xXGIs!%/¿_duJL9uvANQC9]˾7E` wanzKFkHx+\KY + ;?m\_/ d]B5T2}j|6˚W4/+E3.8@=W@B8u]ӕ}+'c5D4@f\oU X4%`7?+iKQ2:$. |؞ =n.p[vp_s64)>C- eO,@t yA4F㐐/b(1/cchǁ*JpopB[͘'3 @P?%DHo  ģz~.?WtKNF$ ,ΒS'giR e\@`#['}%sM~b{2Kq¨F'! o@1n;؝'= aTq*y(u.t51 Q+L35'{G RP@K:*Q>X%-$`t`v Dv %c} "S*~a94u9U:8`G H ?n8s(&G"t Ң,Wdp&_RK8Pqɠ fEU^ܥۉX"J5"Xm˜* %G;[:!dS;7_MB-}Y8&\D89 0zIwʌ:cMkFܓ@T a:Lȁj~I>4 [Q_AHH6/+?BP@S9[jP"! հ_hklcc[Ԇ٘lE*sv7qt PLZLgzj<:Rxa.LR(4%nVN֡L[VNwBX5vASp覍q/Y-͸hh轜•m޲ab n" +(tFcɻ3el $.mz.߱LRƨݤ])dpx0]xƂcX΁47RM*y і_<=-R;V}0Y?8{:$;,0g/{=]:u\][m\ϫbǾl ,hǰƦ7(tEotOi=YOpQ) Obe]ޮ:7)D3,9l5CkiqI+͹6ʥ]"cO@ ߽/{fc==Mu6O~Alv duw/Α ;%2-UciH|N濎̻I<(KgK$ޕ>~UʎL?UYY'G]쑨e{7w ,UhuE\ Ra4# hl)xv[vlw򩒬W^a;% >eoz"=(NRwwi趈R'BJnTcU%>u /׻oa$t{?]Fоtav@T)kJg쥏Eo΍.,ctn"oI pU7ZӘY>q_E4!2z h Z&iRѠDB,d1.gQQA;%~m,~%Ӝ~oV`U&[ Rh G#mlٟˈnPGqvvp0̐OQ)@]*oQZR6^{dwrx9huis^S _K x󮤿et3Gby^rt"ʻ$BfCtV!*(A~C1+', ½QY<(KZ4@QNWGkOts{me ,"3쾜6ըC&* v[١2T<в:Vd40l8i8G} 5#J,]G/1>)7#hF 68DQ H8UJUe9f( "qN)w- 4}xI$ۣ`]*Y@&c bA')͵@0 i@ժ؞ewڀԩX2YOC=1)H^Y A5w[x ^;ܘgV7$]F ϡ %5zMkm.6c!L&-g6@y`𩗑z9x運M!Bޣy%hN1@A&fv^ɠi%sLmJ(v4@+@gb%JyF%"]@6\TH S_䬓0zZ2hݶ=Ԑ qrQ[ i> Qy})GE8YXɊmNpP6{<+gKv~A\hd H `pU57R x 0N=AEͅJPovsE\.76EM S%7}) `gKoWdUԙUb狮OO$j!hw]𭫦v_ZΗ<؃O4hTOt/o,i_7+#nv%k>bٻ߲'#r~}Q4ύ!;ań_s:.DL*dk뽇_1)Byٱv.L'=KJG%F6n5$5݁V)KO/KHMvrXSk.'q!)hW $`Y * |{2̎J!ZVXԽQw7E:cq'H("&ѝs'2>mbu+w]lN1ڟM  @2(s*Tl#VwF5|j>aDS Ww,-r \1SP92\O6v3dMS(KL@HTjeʼnau6N~/ J  #+yzMX/#): [O~PѰoos ?-7@6/ lLkjp]y¹RFNS5ݲDwIa;F6נk^ѿ:\M uq@a-q%bdh1lp]sГt@Tء?GfR/ɐ~PMkĞl ٦hM|) l:x 8Vse'U̡fJ%'E2G@'4QVG+ZWX|,[go8P QC?^!aԎ#qښz ҍ,q7|f+,rEh/\ q ![z|)v*{oj:WUmZΛIܛ_r$ښ}J}<`~Uj 6'34_6@Nw=-|)Wm/6)uk\N6ARg9RmeU @xʦqfvπ)mBƷ߹4P wT&UbF /rp]̂j\@M v ځr,F\F4j7,mLVھ Ld©4at-CP ʞ++ (@{$z@*|($|6]ηYb(Y${OG)gΏor!bd/g"1SKDb^ iWTXEvX0:WP@\sL\i[Sg@Qp>R湓8*XRA"S P@/шbAb"jmSj\deOyWLN&QAKO aکCyEi'n0 'x4fdX3\<Nf#[2? Cj9kWw)gQ([t)׫|z<ߎ[ [ 33BåX>lu7,viv+@}+E۟$cJx_qy+O'Tc#EU[U2h@JPN؂)Nt ?VlCRq$D3 '=3]mz[⡶+ql}uZi|#A4\<@Ht 2Hz+dpYD[N Zf p-ୀ?kt h[-J@ #@lSO+ [D@F UuZFJXk }keF_ :KiOɧ{c~|r21+uLK{f ]U.d'jP4*MXVB[:`՟P'(|?sT\ /Wyfr}|*re4AHmIb[{tǶa Q\I-<_pu8PϽ$Ueb;" _q$;A,/?vrg_*X*\6W&*ݕ g(˨tlܧsQ -U)YbǶAUȈ5Rs5{d'f(l$)$_zux*QlΨQŭWiϮR7rb % 6@`TcmϷӴ f'g5wN:mPN1.*Pō>*,NV2 xLKOGrb7<‚$$E;~-%<>PXf1aB6 Kl@n~`3va=U؀ :Mؠ Fg_4@@lr0p퐑yhH)(ff½(PTʼn{[{Sα# v]o}8PL|6ǑY;IM#-ޏFTĎZE%ƪ~ϫԉPGy JBC|`iz^H.ݮ Tƪ_ZI!bb5뙠7‰p-z])Y!] DRË{0 Y{%);_~JHj3SoMk@}nɄ0{L/s ܁ 8yTFO#:tQl@O3(קĖMV+۳J(HY鈱Xt.-XJJY3T9?Su k*RQeMnM*TzT (X n+ 5{(W:<%O{KTeMJвguWVYd7bLFJ1-s$ne$<rbКPr ug (ſ 'N(gqWO]?ݥv 1?\uf U? @=U ͻd. f@ ! @E@|W,_cJC.DFWn%zMW\@˫Qlg=8ҭ.il^,3RG\9bp졚4eJ plNI>\Mh׏97Wzh_doK9@B&()F=kV8ټjd7*G&II'ݦ4 0ź"KݱҲzh_CRuNgMJ_lٺ) :H{^B䙿kM)B ıtP$qOruLjJA1rlh~i:5McŹҶn5wJnۉa Њڱ6ĥ<55\ETGI}[)& LTӵ{Yͷw=ؽ841?Dөw5I4!3k+\Rױ6Ȼu)A 6f]8>)RhBwj`+=1F+YTk+"O$΄~FxgR(3 v>G>c Ƨ6ql8gstcWUBƂ8ح֛9}/*vBI ,]橣4ai-ƧV4РаZ{y[^n5%a25\K!yk¦_W$d3$]{gvynCJtZ“4 ~;UpR@}j[I]-:V ¨FO Et3 l 5:b]y' nK(T6 呔gOK!hN q,Mhm&$ }ߧkϨ\WA4\VQWe7Aa XWT 7?^Cjv#J[ݝ K YO&lWZۨaW˕ަb^Yŵ.!|E)$BC['rRGqLm?{ǿhs~U-H6<;Ki2P}C eoea4c1?^ĶNe']3 Sioey̝ݻd"F2Ivqnj倶z~ p1&-(d|z*Kt>]AU]Vs׷yX7r\!yK|4d%`k:=Tp 5g;v"P]U@WbPi2{(mApɎ:EO2'Xi|`Ӭ{A"Dk73+7*`Z\PI& rk+$$ ޘ18iMSfR4a4(b46'zoV{R8 Hh9O 0uDZ"/ (4},EX8sŽ3Ű뤸f;51l~@aUӮa"+ߪ)w|0Q!`JDP'B|{ϻ}'$pP"]n[@ m 崵.ދ躂͑i:x>F(}GnNEiyxs,JV 9QRE>fƌ~,yS@" |y͐庛pƝcV坏ɬz;q4cV Nkr),e}&L\v?!{Hn=s+u|N } $T_)51{;pZj:E\,uXza'Z10wj-8wS;gEېy<Hy7C¨dwdJnzI)9uʯm A Ŧzo2Ӵ]4)\8n^ylQ'q6# iKO\*9]Q( .-"즮R*/H em%!H]1vơzh(S;  z3hsJFA9?V$4t!;;5= e)&2OcV$9v rnZ(j* ~o KuQE6'6^ !*}'. 8w* yDEJ"vZO4~?] GU[tU[yjo^)NYO@ y2Nww-%2T*uu"Et] mI#!nUێG<Y-٣:@:mSHzr]i*+xx\}wR6o>4zh&ƣ#foQ(z=!B_kGT *vW {?o8|LͲEiajKo5aDI.j*"#Al(7{s[_qՒՔS,H< -tm4j,eTgP5(TKF֋^>o(뛳6fck Й5m!ʛJ&ҏJ*(Ѧho r2gSH&YZߑ}UJP{T_ihUPlK!{ ˔Qڏc }%"Ҫju&oqlԋU_TԸ<Ԣw}?-s)>+ h|(z^ Vrp%}O\ ;@Dx_S 8jx%tS|_2F_I^.(J @z{8ō\i~W@P;RCN=U)O} с큂-cq_GP]P8@PL](88h` ̄;RuZ Pt HhGOggSUnw(00[^B?G^UKQ\YJMVZXYJV^^QWV[XRX^[YaaZW[\_YQ\Z^UWZa]+ME ~;:8r%juyFҧ5Fut1[蚱o3X3F-a B)X0VB '2 tnҥKkk9퉓GKMk(E%?2w#s'9 G&r|ǸzTSy) >U& C;D!pL SD>ͧ- 2XϋoA7庿Q*'t _]f{۪kF.O ,`\7) ʭ20cG3bIԲ1nGgX]lu|"FD P_| )K}KY0=h䫉mlǎzjjjcHaނ8Ti˝=bI9qWu8lLWi d{j>zTp`![JϮW:Zr>Y»dĕRׁF\.K'N?"*EQ(s$Vrvx\f3ͩH/x@Q]n \eho'(oz;E>+uWj/| 1@a3q$µ'@Wh4zPqxs3` DGa PS*݌iŒa nciג]jNNHu׻M{(ZO_ЀnAz"9ȝXuqT8YQvNR!0-_HZʦwUB!>N)*c.p C'od5;KW`4TBW>KK(JHCQґtܣr\ <`  o [@]ZuL8l (Z M CLiSg]*(-7қ k@ΛEal!OvK~Prj2CB:_QB\')OW?!]"khAwS (=RFa(f)O:z٨Mly=`5-ltl:J\俩V;֫Vr znabb>Lގ3|H~hg l4z|beꠡjbqR-b1Tf1P ?"G (KVr 7t-kbZ-Bq%~iWO0fc0Aُ{o\7} (M:rhRHը;ث(\Bd? 0Hm3~eX?z)it9Bt15 ?(E%c\ AZGRDq;YRW}&,>1>oCw"bzJE=oa7{3h6/ۆ),e?vDK=nobֱIʹMGD'9]MbeeeNX=^Aځ/: `U暪G/|^1ԼojB8&k`P-j>hsqIDiZ;AGx6}Ӟj]nZxضSoN6¨0ܞ؊?-<ҷm7=ZOrƥ*t)Pb )۸1ykr2|˃k;(=6,X5(Ε%SJ5y;=dgs45\勹kr,H3sbJNI~4CS$+ RBY#nc NMϞWӜ+< gwJ%l8dswQq*wFq)gMF>u6p- i˹mY Cp7"cfیW'f#F`lؗ)9cX}1-}#E<&~ߞS:Q"7r.YJPXk'47#(+PrGIJP>]xxHcއtc+WYogS)ssC`#>hO4 @#yL&sKQ\۱#4(5Bl}$".>UPYn8'IH*نϲNziWQOn 4hL3i7kј*XN|`wXR$(Æ1ܶq!+DP&j&S$ˊzg7“  h [ʯaoTJZۧSU`uѽYE;+ pє4IA*0^( ۥ;.GxK)3 X6׬scJ}ec4sƲCYƻNsJy(sMu2>=GM ;G=Yac޷Mh Q4@y\g!SSlڙ{-TĭC~hQ=ST(.-ŷN!(4?Oޠ;( {uQzȎ ?(RR1;d^sQX)\P}H+_8wpWo=6*fxQ}t;*FjJ+Ƈ=r, 9E=E&FsC@?eW^\cXQB蓭ZPO7nDD3cĝ62e4+m}E,,IW`/װV@X1F.%6[b"|{$| h:g`>ߎk`庲2gmw|?Rݺ/eK4 rυvQ哗)jtuOZ#EN2dpcTd HЭ\E i`f p/\{0;hu\zndvvNuL&7 8DܽUtۄbvpqeAͩ j#"]^x#g[$:ckC0'\'Ox+89O7YA2Ր}\Mm&kr;YL*;/ơ/Jh5Eڿ:(' 1$~;橍XlizRJ}f?\/&@I=\p gfځ <.eE(TpXA *J&/:z"IаuHn+4v`Q~A0@*$w(2( *{HgA''0 7,` @b:KtH_ A@ 8&(4¾)_AMD\J-Wbf -m]H?oyw2m-jٚ=,R0SgK[cضD[MmVSˏÁG3Q,r@ |q8:}c&YNIE7N,-BdU!,ʐ*D@N f{gΫr7 3dN8tˣTkMK`3?ݩ"<ɵ&͐[tM yTrO+k'+誁ͳqC2XsG˄(o4`QyTeH/~]q>u(]%N3ĿѪEuwZ0yη˲:7\I(wՁՔOo._hn_mD|+3*T+.ze.Ń g+^6/o갽fUh1VƂfH!A>;N@g ةq/pb=$GN/i L7$$Qm K%!TEAzJdZRkyh @[or'ؙc߱tGkB-Y ;*qTZC4U;~B5-nq^ Km1-}9F+^K$@jgXEX})R~WK.Eû&>qLwˁ'!\1Y7v7gw}\x hܭWV/P85{,Xw}m"qԯ<u4#4}N,rXW6O'd3XZűit! .6J&~miGs w:]HV鳫!,uSiU?9x+W]aAC@4\[!Thl  QcQ0ܖT%fM*%drc_" ~YNu:О]igy8}4V*!֥hsy(غʪՏF 6Q!eh*+g%ࠓgdzso2:lpɡc2-.IcQɿΥ_n)v-86PC; )U21˟4c Ch<HNbK$Q &"!RwHY-XC򾧳I lUV"bN H} {7Y t'Ծ+ +ʱzޑ;GNN g s *zIƊ#YQk|Cڦ"4x6G7qN iσgn9@^D3;9eC. [ːtx nw ^%.Ҍ›^ rॺ/A/(TNYLvr4r lmښߠa8 hc/yɼ=iԁJ®>4D=|&T8B *gS͚ -*7:P$-\Eڗ~ LP40uD12mU"I,4Yz,-JєEٯ"tQsbʼnDryf;e4n.gY b8ӱ*Rj5i:hG@׷O6 t[qft:P( su5{Dkg𺶺H~(Dt&vud:DjoGbx<ԁ=ݾ9u~4ťQҥ7VeMFaѦ5H;)sIwʐ`f烩dpϝ ~nmY$X|ZXL5D`ЈBc\Z @ bݸd9*Q."M t<}CC&6$W *?Ugp{WWX;f߾pv1fRbV\V}î@34`ʅL(1 e',%Ú(L[s-m4pz9AJBuB~nGhM;n\PDž췌RRFOJ45tTJ`=W9-`9>7BF)́ݡBZtX 'g;e X,xn#UAJ&)[S"A҅M&}Cí1l?R)Ae<Œ(K7y| hJ81/!$Y@-*&z$Wp">hloۂ@EPèE%.-=8Β! ΀x}jD"(>>`P]M2mE79Ѻab"# Zk(\lf63'qh1ξA+ /g "&K` 8w ;2 ?*3Ǫg@griL RVeNZj{؝= ="&{`I 6aP8)aRBmܬdZez:m~&'UJ%֠`Ar鈺²qW ޮ@}D3we @٫fc'_'h0+ l4h M//ok.8{o v N+a5vGROe?VP0|f{(Nw7wRp&ffD$k7(R< #=6[lTת~5cuM+b_`(_bkZy.bHB>H~0isD |DLZT(>G6H%.meeuQJHPY1> :N`# cs+fJ[ :1Rfh]аM˼;gmXњD :&dWĠ2{© _IPp ZdIm&[L%y!t׌h."oYxʦ%[^)>xC"*̮x-0H]h.q¨;X0 J^;W`6f%!$vU4-͋z#ZT:cwLIKb._L䴺zT b)F[@SA @|wE w"Daro<8nRfMFW&TnJԱAע|/7꾗h]\pr"dP-LCrLA8rlOggSnw*&Hr0WVVVYSKS\a[bYRLDX^cZZ\ZRJ]YNLL[`_`efVSS^TKGS]Y^c)J Q2Y-hk˞g%qV"TNM/RQPVkVDtڻO\rONy}Ky"Uh94(`7RveZ{)@{N}œ&dp&AmnZ33b l5` `c,cW*[7c#P9G_[G^"Rw~ڊTR2X k 6f }= -^AU]l߾[" Kژa=5./׋Rػ` Ss c.ܘAFЃ݌> A?M!F8ê@S%sDZ"󇐊%w L潦w6 yrz :pٓ^T5H@>d,o[4_kmu- WekytO-vu`߉F&\>NG(r@|T4v1|HdGSwy,sKz~iT&ţ[.pH<ޓѾ>N@Ab1yBG0!n=hm QHЖ[CcV! ~Wol)^{x#f]nta3,?9|LmA7P54Kz`p05p\|~惌+Wb\5åz; ?_ʬGJG1A鈡*ؑ}xo,{ /Mk焥9Y. hW@>N͌Nr};"^m)JcOJ*&'<(LUu{^ChW8G12`)@:@w9iggaD-d;}\o%jsmX]Tsk`qJ~kzЦF%kEn."z<b+@}X|C{׶ϭ)dz}Iym[vh{{jîmL66uu@6.^'GWN@bK)_ۯWʗaBZ<XHF@)D ML*>J'0rNԊn_eʧ>P"s)} fJ{sjQ/U P I9_iZ#aX§w%hh$h{Pu|j M8X]TQ.x-x_ " J @Hzg=~ &*+8P)7upESc88 }|ɐt:=cAZGgh+22ر=iRbg5I9:y<5ֽ(::5)D? D34pB<Ɏxہu$Kv|eF(ԣ^n.((D#*耙=A&tPLDP岶Ȅ^z<x;%-!RrRN +/Pw 堮c?$";9߲]u=x]B,zoZ#(T"gozhUvd!bpH8gc, C6ћ[Uey8z8k-'GeۃQ %VKytt$\܂3b(a eMx`L .Я @\||72a}Uݱ&#seO#^,@4O}H!EhFoL .?#; PP|[ PwZa"~sT-pE!8݅nbnGV&'G _5h׋otʍ9o=5nywS(3Ig0kxcF1P=(^|qG̎}h_ L7s|҃rKv֌% 6 c iL/ΛetTS!VmQGfcR49Iƫ/,PA!*N_ ?Dg_852vAvSUWf/ujN> f|LWSTu/vˠ%y̼ kA©/NN(h,Ϳ>햱Kѵ0;nZbEd2R< [V#ՑE9oy/b!ѝ;H;(Ey$  &~4#c !hWAPʇef(}[)!k=9x4|{d^l#g;ؚהYy_, u+Mp7d`A۱AIZc6v ;K,k$e5cQh04ZQ5oȕ6 zJ8}ɮ؉9[dw h MG)nV퉌J{Cm@mBFtIh} ,+_h:6ٮ.+ =4$0v~jୈq)XY{E\ۙLҮ~Wڿζy U9c[脃Qa" o6hv B@(}\<9bF"}f\c*9lq(}'Ƿ*hjfAZK& ֞ݣ9,K$!KDgNk8E,E=፞W4> ȱc|e'ǯy%@{=]٫55q= kI\)UnsP~H~>v}/% 0ϣɿCoȘ"&g7yr5@X9e5-[4XIt /eBu{]ƌ*(X* t %7׵H@7;Q$X{q !C%Ku;"I'l4.v Gf8#VEtC0f3М5?"wK;XOCD6L)KY8:I2+hrظ$ʹQ Ϣy.\ xDMFB0CAE&\N:r3Q" ޏ V6@}9αR$Ż _״!xҠU.{ =Z%*D_][s=($S,OO"<L+`t`ءqؖ{X.bIh+ljViE;>JJQv@{,ܴƃX~"MhޗH x@6tNkYo.;J\"v?؞wWg:c@QӟBR5qFn+vȢ h^OggSnw+AH<0U_WK[QFJTWZ_Z[RFAO_TKN`ZJOUXcdXa_UOaUaSS]UJOT_US*@(s{;g;nk~{r;}R-)9K2ȇyk񶸧x'ΧcLE5$db^}RP?_+rrGQ>8و P&Sz. vQ51v[pl=Vt!=a‹7>BoG^}")!L)QZ% 4M o5[#ô9u aOkcCabb` L=)h$Wt;R E9-|kgH>;3܊b5ZWaBכXoWo2$Ǧ?Wh7֟M̸3G44lPC}2c`s-z|YKJ;oD@7^Qv]Qg;Al]k1[m]36*8.FM*H4/bé%[H6`PN +=5<ŽR{s~5F>gIpI`ٌ;PSZ*|)u+`}r.86ɻ@6^~($>+aZ滼2 `mHo^͓Pa ҚF҂o.)2b®I1 +jbpU'׿aF"~(N *&,I&%&;-d]e>[/ +Ouթǘg,ö8 3E9vQ`7C܆]vFX{p|VwbKPFgdl{}dEM꧱aȭk$Zq$)fLΆ_w4ګ[#Tg$!Y5N'8Rp#[30to zz n|O5t G`3HfJzi+ 44Sq{ Jz#^P2^3thJ W'9+P|DT)rĞ) h4aVL6LOUUl3RSV[=n5к]_VEwTm+@]N-ԿV;Ա_Ӷ6)/ڎzZc~h>o*T9 $Rw[[+8P@<!8J~Rwȍ'9Ҝ\ dƟm-h/.G F0!DΚm7@>s$'*hzTlPpRΨ׿ Xp P%r{sSHCG7 DDgUAS1p/ұ m/B~ (_JgAPfsJ@@ FE`R)5¨F+bd680(9I:oy,i f ' gGpdz *? 4'{[$ԭp6O &wUʫcלP B|@g/ݑΓx$NڝQ#C_;#=N@s$[]H(Egވ1V#kPkʢQf(巋YRyVf6aFF.H%¤W0ip9066ɋqCB4PL$Mblnߩ~ hhro>-[NC@?N@'pa5[aF5Sv.b=PwM&KNb~ YӴB:IfXlyDkQA^f8e-Ͷkb,d HՌ<=~`H|NMRNM?{{~5s;LuZJg-8 eұ(ʫֈlA&߾\_4[O˴btYY轙vRIm2Kļ{+&Ga/^J=©./ T@p=r%eթNIC8طPlYR jgCJ\K< el>KXp_=`E%S> x3_©~/Pipzt˜oswfruQ]EU% cz2v'b6ƒȕGDfF9e 3WF_XԀ ;EP&C@֩ك;rhĥw7YW&>ĉ8.ZL숿w1Ɵ %F1MV͌3)7@'΄6<-Wo5"Tmë%YKMfP U饰n]ۚ^wQfK%¨Fb 6_&Vъ{) m*viraA鼗CKD`6KM}(5v`~)]eO~H ¨V5L@l?Ih͝.kQ6Kjl_!KϿWǹ RO{,р"D]A@ [VWPRn(ju*C2OggSnw,hu0LXZVQ]ZbXXZ]Z]\c\VY`J?B[]ZKP\UPQ[aIH@WQNKVZ`a]XK`lmpM `ac=)jޅ%;,=  o+$Vß,m> ' :@qdaS͆iD 3ˏ73>W!>c\6##z;μq)Z!t (|Nd ։ ~D!lq,.Q뷀 ~&u >P݌ֻ(#ǜI}dgc TѺhl}*   4` uUehTVܘ?Pbn!dLǻ hlj \0WFv\8 (JnQ t &P@Q|LLՐqz HD)< t a*Sܩr"cӚ|]5k2T 2#j^ڔllzW>Rϸw1Q* ɸz8.Lf/^|c$uaY&5~^R&iJ`Qn_0d]]v/}W&+jm@')Q"tJ V-wGkgskR @A%8O9cmYr/H ixY%z^*=zΤI篳7[@#ս0J?L5%*j'3ü1OJΜ#2[D_ef~^j"6fsZ-VZ\pc{\|]KHL 4sBs3yYA@+LbiFTP!pb7W }IP@k}lRnK*<hP̀$!8HLV~W2k-B^ݭVK +$ Z*@t}3MSV* qxj{jD}5{z~U+!hc7ࠢ@_FYpIlLʩ>#yĥ&vaѫ3E i_3  D } vDE5 W4$΢ƼlJIHk\kb-1'KW&0:i]1@@o͍F*Ԑܪ.CQfvi;mQ䷈ 7۽[NuF ƛcc/$e vzh4h)aў(*TWs"蝤}QPD!u 6J!? 8'Y>@(> D?޹Fd+:6&5pBRt{3C8z(--U)e t#C#lg??,glU<4kD fMMuWk '"ӯT /#X(K۾ώ @0Hsl6_﨔zA/Z@]$n%G8p?(Q@ qbV{%u1W3Ci )|@K'ΠpQ`~M%~t|k r˭f}\slOJGB6Y-nm\-|'#u혬#(vY qO06S/9ir#A7-$ 1=ֺGeN<ӊS) TOB( PcOG7ljBH Cw\rB]qCp-X $>!MO9=S){Y|W'_`@{v&R O(5ػf oCh, g{n! z"L({/@A#1yD!'BM@P2,Uг"AQ ~S# 0Da?3ߪ9+:rɀhOI0 !zlﯫ6 B5!Wq @k~jBj;Zꍦ_dQ]Z5;g56h.9' O@B{6[VG؇W?7" A^"yzJ5O3쥝 :8Ukڗla_J徝_}^g;@?dw ,a41K纇 gU6A݋uפ >ReszBpw ur`DGqIv)vcp!&z9]xA,c~vJyͼy~6?ӊx,<\٦7yp+9b'¹eO.ςt<ESng'WY =U@oZˎe{%J=8R${KΕ\1T2pDZ{`ȇ r Y_|+ǔԩ /z D":GJCF ;kBծ3)_">)^_f)Pz@:ר24瘢ve}=Ye)?lU@btQ@5&DCt(@/ؽo?!ka-/S0Rx#"0ῃքqL< Оǯhd bSB ` 7kH(>6A@g )}8#_S {+%w=4M!! 腰KKR~buObҺJAF%Fvᤎϓ.h)31Iu^\X.wqueMY._pP  I͘QlM}>ܽs6}>a=DOb˗-L1V߳w^Ο],:O.#)0857yQW"on{N`Aֱ7'3u&0 S,wL @WcJuŝ!O|k'=K^qaNL_rկ-a{ZFnyP¨w} *e-b6}{=1Od"zL^ `GYt2]'wƅ()Y`?♺-ƻ5 1Ex"b <3DATM7ja s$o^ D3/Q迃\8F9(" 9🕀)F?W%4Tz9ۮҔ_2#M ܻeY°: 4vle@z5_e6YT,ő`Hzh'e3$F AFw  >LAP лى?L2o$:Y nu(Rgn+ϕxYfd/6hwL,DQCIMHּ$Nx&E&{h3晀Jq`,ZG]bՀTd4@uᾇFIeBvWuWR@/7<4[+Z~T4Fdn%ɧ=Y5 0ϛ|JM$B0:/=Teu5R AqF #Df[N -Ԡ= mŔ.iի Xt"A"^ug沱0Z# ?cIb IX wр6KNX`yV?Wt (s9h(g`]a2ܐavr:;i92sISr"r j]DF0I583hbts}qJ&b#::n8&KfcDѦNC:BFʸ|tM=`X%8z1݄]. i×N5<\ZYGA;1<̌r& iKOHD'& |n!튗 R7>1K;tWE)Ko9^ 6^Ekx)?'hc$sOG_c$$B3wyh ݑZ<6cvk-7`96P ޗӷmIā夠\Tc].{?%j-6Mdr0_g:=CA6j)wg06`{@~/s0^f H(T)"} cлkȅp &))yeaf5Av4Z_jfl-fXߘo[ PqdF}&Y Vq62OggSunw.X0jCsܧt7PXܖː67smH`4 b(CW& @"ׅ#Qv< U53fFcFsL`PQ]5;B ZMX$` Jxz^/s04ٕ\q̓[J*YKV M[N`'`=^ 'y5/o&qvyn@R.YݢDNPN^a=+TSBu Tk_ Nh#-\3*l^Ᾰ,%" W2f{Qi_UJ!6|&Ґ?>iK993dE  %#пe?7 aL>,gy~09$4EBV Iu@p#+Vj @D_]hQAdL[weTy> hNfR4{dvF0ܲQz@Ka N7^N| yJ#8@HWֺw[w%)5)[_H;@rV 8eڃAh} eWazE{SWp[$۬F,y#sx 9ɟ"J'fd\(Zk؆/ϥGTu׾zh_*!I``@W("e*$BRpj[j?F 69 UveP4) %\r9՘Ü? J)[~>X$FQ_fŽEW%prIQ|xA坒)=wБp&cW{""~iO@IBltpA܋UFA>B&tp+;(uKeڋ sJey6i\+#~*!^._ġ>}ڑф._|U.`/?y(l&X: qkFOfiC,X.~O[w6T~3nӧ֌,.M%Gd)(%=r [kQݻ|/D-lnM1RVsgL;׋(&,jw+3>ru ډDg.2*Yo}K9T"\+vwbyst3ir §Ʒ_uA1$Рs}Gg=Fgw-^DϸYPx㫊7r/bkإ߮[FGL1Rr1ٱq&w )6YVNB@9Dݺݺ&T>ƚLjl,nja7*߫ɢtw&ws16x'*&h`RtiD>(lDIHhSvU QG/P[vo=ٳ;aOJ4Ōp=bBg)R]yag24ͣHYA鬍cSw+e 7rXPp9U L H.ibֵ؎hF Sth <˓ WT"L3sUz|w'bAVzhWQ-PЀ}.f{;2KZTK;?.!Poy5j/MP#Sa.>HȰ<}(MGbzlw=*sb5xz}ynt{nac|bQsag%&#u#]O'1ɛ18Rv*LIB>ashQ5N쑃Nwp@d-4gQG0< DV%93>~'ܶ3V ;w=YP@Juwbtd`5> 28K@2l ~]-\'nk mJbGmZx]Ho*. wg#P6-ȝ4to| ~Z3f.K,+=%m#%a41q;Yqͬ6Y" l.6D>o3kʆP9\F (2NltRZo2}tQPP5u=w5;;sԁ2aTla]uـ sV]m)Uޑ+cUPf[C#'"#y8ȃ_y_W1yٝiHKvR>ƟZ>J Uqv׮[ Cv,ҡm6c&4tMaŲvHS+U1;R/R  ǭw'!i$Xjmus1ٜM:z*~נX*2Y,Q׹z yTm_i`j#라q448?_j1z^KkԘk?.Z:{Vɘ+)tGi 51p KkD"ڡ] Tp N*T$ pS$;vyx<tMa6j8ͮ?!K 5\w>ἭĮnjtd'314qV$X]&Ԛz[x+:1ogȞʵ"7 NkztTkWGOXvNmO= K-?͝;*8=g9=1c',ڟ5?.3jY'&Q~`*}cc\K{w^X̨jfjojy`%n@*KF6@R |k_-Fп,:7.C7bȁ=>I{.Y%뚉ZOU[RJQj$̂9drh2u%hܴǟ&H `6D?z0xψ־gc(*oTqPoKXQ FxAIhUrQ%)!hg7x$ 0h}6A*oKi\r籌bz_ -xBFEؓbNQfdu%\ETBJVOggSnw/J 0b[LLOQZ`a_][UU[\YZ`\EAAX_ZXVfZY]^P::LUICNX\eb`]Z)OHh`0 e},֫| Å:wĴPhy+$9Rλ3p'+&=Q2(N> gMW@Xe X(/>2NǛ6:T@m1y^AJ!=P<}0wq&>sX'[_X+uHC33`j @Yrjmz *-aCE|;]'{WBϡh%V- ԯptQp)R =X}@kK#6a!'>[w `v2 *91ԾwV6bg; 1)X.Rxbx. 4?=NvJuJW>xĸxqto٬3 ecFm֟haB3R32<b+T4V[LL,̨@{i΋G>t dvcr\v h# º(5 D˽v *|~gN:NRjB;Bje|RZWS{n$<ܷ=0s3 yw$4G4he4<4=]- [dV.>ze[©w?lP|E&JG̜4ݤYFׇ+k孹D'^/t7g%Ξ3^'ȝdPS$dꅧ'o -e5!VtQJ$VPo!Al&8+Du27|ܣŻ9lz|Pp2dM ƃ;PyDeq\tp'*dUV".3M2$PO|9/eAtP6ṕ(:W #P_(f{Q;~+ y1v;2g48 ^X]؞3B(K] |ϏjʼnQCZ(P\*2z9F*3FfCf M==&P]qiµEJh,`M`J FetyIb8"mn +7=+a( SͅT-U@Lj= #Y uVg Sa.h7fƁ;p̏T MV"(JoRKh~i*)MSJS`JXh*[bAl z v8DcmDu)xrbW55u]{f<:֥>9h޹\`xh{ޠ-DQ$nrY>uΤ :oJIsjv:xjO"k<}YʽXGyYTEv%\-5MC!S Z_7f}meQ 8O8TT=@ PY89 Ч ȕϘ5}%3ߤrr MLnWP@( ̗P&֋*ѱ%`yTrJw ]H6=/^*AFa,(OYi- ~+Ȱ\G[ٶ1^ܹev-jp 1ӏ>8M)́xNMjf%n>-= E KQJ [{$2Ә@[փ#]Z)CYTȴ|S*YvDU~]*P̅ iul=Sib$LXf*Sg08w!rc/Ʀkwݥ 'w c41@C *|(ߋ9 $ f7< B;wnAvdg2 Y BGwgjg]ZOhV{ <뉢B[CoYhG_T8RfM .)&.0:$6 ,FhtzBf\g<^ f mq>x;3"!)1\*CfM.&@ "  1D]M,I!uQRJd#cRӡ._g&$lс g\6_"H; ݅$ Bb1% %`3(?a?&{ _xlү8"x R@M@ } ,Gr H l[=jg+ճE?u9FHGY~lHQXyn+}eZFz+dńQ!䴫O7yД~n9@P_2#dS(gKFǹhZU=44-UOIpv~ʨo]m/՛9[y#4rDv|0 92 n,u/5ǜ{⟫,P I eH#S8mHy3ɚR8J> ?E(łb+&{w,$KGrYk6Y۬!?=]c򇥂%~pStbGl茍r*ϽP?Up!x~|3@= ҥ+!; KNmppη}:ZΡӻOr[j9鴙WsOggSnw03ş/TX\[^VZc`^dYUHFX``^^[YQPS\SJLW`[]\_][]Y[MGVaZ\\?@%SAyu-LL.~v}@ h42Õla E3 I7g7f@ gLg!V$LUppcOƂI(")a KhoȴvLVMV`ub)H,XIdc ,jߎ5כAXDu]u肚k!Pݫ~`|v3RATb`=@k=n g_$~pRa&.!z~QҊ6ByGsb+ncV߻~g9C$U쥎.g9~!-?@` μ؉vpa?$gp?/=\"˸ w[DVUVM#rd! ԡ@#9{ nxJrбr YZ('F. 8C=MDNQWjHQ+̊Ee(1ұ/{='ͼz鄎%1TL̿Z<6u6o(^#uYFأKdǽu|>`n; ̊՞)aJAaoQ,p!i521UWu}FJH&4n<7l.l2}U0|Yu#Jy-qmXzMzVU1 [1jaojմ滩N}}{xM\u: <*~ݤLB젌VڸB{Z^)CnI,n/Ci:L6 66@:@³|+Ϩ ŏvK asr=<(ԚHc׻W,˚(#uT[fǜ h'lHY:t9 @E&,k+^b&h[ᝡݑ9'gxlU:**.;EyG!H/q,5&֜4X]2{+ zoWwfnp< |Hzp/y{Ao^SYQl/jۻȦU'uNLD[ LjmxrXYw <:sŊ ),s@k^3F}] sDl'=[=B@b_ t}1?ϪPnj"6@p""(( @ 9Hg\>=kHs /Yk۩x0qb}MG|?B ըUmCm0c^hڑG|s,w$2,4{=(h$%ix.IY2QI>a M @MbQ$ٜMN챌*RQσm=˽e̔<ڳZ8w5{ƝLš>z[Nf1&B;OGT3 ~o-rNH6D(F Srhoo͖>w@,t݃Ǚa>~ީ/!ttx[=$:&^Џ7$uzeķQt @pY ;dپ&=w&Y`u[ABȰcs'LjT@n h)ZY?1 oĈ.Py#ӖwCGÝl=d {|DDFLD1>\69rlZ5VQġ.pJp/*aV+R$cKldQ>&Vt=L!xm |Ag$@l0@=^[(eF_E>]61kewY ±NO6Hy9iM?M@ *@ ~Y"~tPÉU_ADYԌv3{'{>0챸ߔmBXYvf3$~s6}V ؕπ+|G΂0w%W9UU(k "v8]{~sܟCa#zU(ϟނ[&ǻ9;%q\ꊔ"PIC;(m =A1KcDCr^6"-LO«>.@}YxcwgaoXo!)Ɍn;/m mdJZJ:lT>g1쮼-.69+©OS5wKZL?v(qbLɼ;4!aAgĉnzIO}ۡT6XMb=; `Pϗ-i6㭡K1v5|20eR^ T\qcWsnSŴwEțj#D97l@Gfdp;d62;F^4=ebKdv3Swu,qzq#je^ ٴF}nU-^Ew$x]zHFyϋ&Ry9aU\oe60G~q5QcS^ 3:&+7 j*:[ W%fս3YdF s%K7YZ]$msGZk5(gPXv8ĺ*ue@0b[a=f3ό+omv8bh\GyIЀ- wls`E'w FGu>1c77oO&,є3f"82=>G9ϩOzevr g^],C28Gx æ\VHU}BWKx^ ߀e݇6Snnht`I/XE~F3 [l6qwh С7&n9Ge;!Ik^OE0p4UjzC%vR0K}BK4:hµ7K H@0y˓8Ԟe!ܤG;Z祸~M('] s[9V^bcſ4BmOggS nw10]\QMUSGFG\^WX\SEAJ[VNK_[WOR^h\WZbZTU\_W__Y\Y[^\\*@Ծҙ}m,yԔe%뼹ڮBeHȋh%\)]lem}uYj1vUoJdVoe0 UM%ʛ]/fUИ%zÉ[l r?Q!5\X5,Fkx`\2ƃ9;>VU`FT*^]+L.]kgESҺ25<v3FFa;$ 9 lX~cio92B U+ +e, 4ghFKUaX0 NUpe xWz=`$A3k ʄ2f,N6hm|=¥?-* y6w"Mð6 DFPZ3[q]}v^uW=wjdP[cL:--ŜD%T؝g~g_>Oq axHźbҼ$MI_ȳEX\J /w zg?:|* n!l#lENbEU૾L p_4$`\jlbzgWn> l8T7E2F `iW/APJ{\1m/:,L6#)oYZK:imʝ} &*6*-{3ƥ4߆]"z7zr^zƆ{뭨l_ï_g11(@ޱo_θ&aڒ6\P@?!k48#k9F (/rk Og(` [;FG*< m2o%(7dq^@cAA׷RS(N"o: "`Ѥ)FؚJ!\ P`g2mR " ->(K8jqi\/O NqhdnMG75c{C5h#vGx C8]i@hu'ƣ2SlD,Aϋo_Ba{ ZCUQ;|S̫w! )&9cWNl`ak`zxqCMт?XHNgM1}G9mЄ\27!Bw:cYb30"%sGe BC݇--bʄZke;(9*~ :*C).eչ|mSтc[Dzdl @Aw;ɯ.7ؘitF\UXeZc_:ݰ@ڇ'qwі>ˋ\zGeq)l+8+@}@+~S%sjmE{ͷkh,N°2Vj[ޫ˜a2ō]*^O8/ƫ'f0@P7;.ަ5qq:$"ѳt|*Jߑ/F(iO~HIL:H!9:%eH1114z-Eb=:wJ裯[@@.nl5YA#rC$swnJ""F)-J~g#hlSJ"+V,cF&^H(.* =u'駙|Ntu"%Qz.hrˆ\A[cJEQ(S?0Aynq?_"@Njؑ`7ϯΥƌh$>+Fspy?-{)E*JgxGTl©A~뷴Jpȁn31e{dٺݳzS)XZ&8N* U Eih\%K#-z)˟ :,| }V9n VASʘ o:)֯琶/$gt}i(?c`!n=tßeV5 71BǠf)r}ALubo9[ci| * uDEOZz')QNjb8&9=$!61 L i8_3F uV4O";cǭGZԩgDcăʭsyY5>>Q-]CЪJI.n02f7LFXrR }wD_eY] 6 fyז iAf-o-=ɯO~e>ic 0-M̀=)Y"8閑](YS$TZ甧sl'd PT hDX=|Q[adVgސY&X .n?37dC=#rW Z㤅ϣ ~XHrRUw'P9hp׍Z/ϮWWoB (tNۡ!TjU߬{`d9IRp ]!#r=ǎ( ->Iec2MJ˔ЖwDnF >j)GkZh.#}׏Ms/K> 'GM>ry;7뗌軞$WNHKnwrk'Rg b~>v®|y|Wqn%UN i Qgxeb) ObqfmssS{͕}7'(@aOK߻OrjYHPꞹŶw2+xHhhIdD(SƖ|1(?IN}r]'jU,f )b{~ewGL:yE|W:C #>if |[ݻ~f߳S f䕖bݕ{ 9Ld1ps >0:2 &Zy9I=I6:3G~N&4ζM8j BX#'H`#X/F@ Jϗ/z+s뼬O_Y'R&*t, ԛNؒH1/yyUhc}EW8XZ#E0T?&]%1+դ,*~(U+3|NCR(GJ} ֘ @+ػޓ8:lyanh PFJPܣKoߏKq0-c[C+[;<ŏ+@m D<6;[5sO&Bݟ@yp\E 7u}]GڊB!b?!WM**{ 37vt'b9%t*=&7 jYUn1mk]:U/w;#2f䛌5M7X%agīeR72 lv1Fo;qމGMrC]V(!*O J|o5:gDQ#./Cn^#Rgyԑ} X.mHvN3h&~v5 039C9k2ǰ {*Mm'8A[F:VHSlu o2;Sm^ss.R Zqlj%$AN^>ޙHq>  `0U>e@0Eqg.sKbK8e&kxl$S7tV4֞ot?2n--)u$mtIڑ=, _\f戓Ogs %gょ*@ 9 mNo>L_#,tc逘R&PvR(߇k>ޚBoj;c3>modh 0tЛeك>ueåqg]vӢO$&Ux_*ݬʤ[-x0s.cA:4W/otaSz xFR=GG=8P B~ Xo2D G!:PEW_ ^Pj-w~?R[C b#!]ɥZJv!CUxA $ܯEvGeeR%vjԴ;tƭ#Qf8²(Bl@loꅃQma҈b7Z?d1G̎r\*@/ʵᓝ޵曰 nNbgQn)L4bM?K9! ?bfblbl%/, jwkd礄$`hGOtSwfYa!U(zo{Xw L~Z9)3by^zֻ#KgO!Mx0(ࠚy:ckksK9UBō pˌ yUA]^ HPXDQ$;~/F!-8$ eIsv>u1]SB%+BŌS9}-w܋wP[HrlVD_!@}>9.MX^[bI珢߈zj#>tW r99Ufa1Yƙs%2d)xAYm<8TInonj]+g fTmg[Ti&;75:vL”g {l\iX &h|N]ʼ%.7kd{[S3(MWyZĎQ o94ymy7VI6(aIg(gjL\xr{Ugk50HwbeTF? \#  )">9aj%&%IfLܧ;3})<0x/u7VZ'_7i[Σ@\{oV7 E* ('#*YflN)Uz9/zJPxclL:B3 :՗Q&* zϬϸbll)>,42nrx/"9_<&^@HjE=6|6UZPDr"?z'.n7iFzߡKۄ\J6Ҏʌc_O<-@X&ud4KV,~{6#s+c?:b/9Kc.iԀtdAWo:;+Gne$@'=hl$voF=IYk,4Q9Z;y?=)yS>giy$eUqy<%pm)dD_}eb"O~'wR/gpVSRhdѩb{-HRۥf/N˟7gT:Ӫ΍W8&x a6P$|k`w+--Jk`H=ˏ޶N< ᓿ:l ;^~]YpAkK3zFUOggSa nw30/_b[bYe^WQUVKL\[cSS]]\ZZTSKM_]PN[\[[]XYX\V_\WUQOexY xT{={cI\ ڭbT7p&@T:󜂨~441Ghu6VW lb]y7>֥vZhC vOfVGt̾`hkj8L`4~?g~Z[ x8 [ y!$6C7>)M+9/ D*hbԀ C0 Ds\9Lݺ!߭$$V왾_Kb<ۢHB&qD \:a)ַAP rb7[\ 1>2l:+0@`}2n9c=8j߾ *o$b2TDM}`;fO}L{SU 80p(<S⤚FG06`XZ0H@oPU^5Ry)Z!tܙ<>ΒG} hdO*Mvd~Ҷѩ6/[C#pS 1],Eľ|nk6AcS1*<lL`nnOu~%#TEAUk]_5^j4ghZ:k78yY)c)$hc41[ua31y/4IyoHteD]v)j)tدX{cn&FǼiJy>#歀vFt]K9O]\vzeNS$[K}Ǭ$|(ezH#e0P0$1+v\;{ =qdq (c+ v*PՔ^ȣԧ*Τ=8@QQ*ݾ=OFdºDoo >c}$xCFCĠC£c_beCu<C(@iO~;1|)@!%Z fb!"-@"a4eYmڎyI+Nɥ\Bm5ZWJHW = ]4&S o<g(!gBz< $苴i}||~e#_-᫤ f>NCxjG\b+HޓR1/4,rP!HNiC:?)CN?~X$u6|q̓/5C%}*[بm'"_6&aΨ'߻iCnv/u M)gJk$w&w-jS֭(T,R'1c[[uU(fpԁW?}@\:rv6BZ͘SFfv!B))8L>4$0xuXMel4I7ZrwOjW(-Q]٩ 'h@emQ*UaJi$ڀm icF&M&9o\UF Mr޵&¬wxYVS٨}Kl&*4jM8dgY",VSG)?Bʣ424GýN%9h/'$" iī`g0vrERh֎.3jʘ(:rmn@ؕ61yBY}c%&MB]KQp Ag?_@&ׁ=!{sze06=Q+qM!%Q̣TDQ v2 D6B"(&p)$&j wWKk5f1*di ǝDYȀ2^>P-#g7Tt(Lx,>)g:jc1ga7)U"Tyۻ; 'Lp3̓23wo1 _!{nmܳ'ND Ё  0k49y]!j,]N.d¶zleA?تhYji?9Mmxd\J%mo y.υCL[ *u/S5- a H|jyо ly:M"DyOf ŅP+qAh ZBMr~"rKgh$cO*(0 c0=#R?Qc1 {$tǙ?@%A &))GB7>)cH0w_wU .]ũ;DMQA#B8-R|Urs~|8 foOggS nw4ۡ1NMTQ]YQWRKFT_PJMPHIIZ^_cW``SSWbYZOYPQJXaUMSUTTY^\gG ?vC<)Z5xH0FQp2ѝ(`;Ν#q"AHB;gb} O$zCׯZM Hcix8o*4loʘ%@70b*2_yTx|߯CajxVa' 1LyzbXuOm @F/?X!*@zW=6OJs 4]磽3)Ph<zl93H*drkf.ʣ,.Ѐ:4W͛[[V5 y󩇪5pa"ɡʐ@eXq.ȓf٥]^3NzAU!G a`q}g -He&,qlr{ wDzsgED_! c J-̕\C5 (Qz3Wx}fmz(mt|0TQ/?y_b*R-<1i@HQ"9; c4P0}qn ]gJTV].>B)bSl@Y B]LH|}/Dޑj+|`ߟ%![z-_uybS6A2>Y9c@-Jc'd '͕eG+>` 4(Xz;g\OrmkJts%)Dp;  HQ6I|^]!}@0snuʶ}CC|pZc90_ba},З X`eF=ƤF6@\Ú(`OO7h RP*sjt"jAu`*!N֏qQ՜[IJQ6+`փCcskukCdV^!{|U](oi&C2 /";9 JD>C\ iYkhJqZ)TPЂ2#Zɿ`ldF_m)pF޸_)p-?Wjء7tnX'F@2 ? TME\xiP=uyĆ'iGhxU"1q6U7XWQDѢPg3 -%Pmq;y,$-x\S¨ηk P@7@C it3/+Y 4OL*(Q L>k*>6P@'Etأ7t4'2[68-h;@04OQ1=T[p` '6Ɛ8A8nlϷkk)-C^ ē`0(@obA0$0M`'G%v 6vx͖( OUiy^5C@@}czy@\(-H@27Z7Qz7D6fuq ZͰi#=3 9 oN܇C@,~؜L\}OK+w7iIBцSf4z,3H0!瞛:&n^NzHIn.20$ܺLa((+G0h@ 6Wϓ7)n̙8˔\~JֿGau`Ą"8_51cGWUވIe6u,:Dy<`먡KPץL@%^A4Ǐov뎻5)7ﺿl3Q:q>tCL O4@Nk"&]p{VUȭrcL g(VB肆 }b<ߍf͏VFwJ{DL#MQFq]'6Q/;B_vU2<ӌcvtSgޠ2$Gl]tdBݬ:bJ4X:u.Hc!ÙPf% U'V3HgP7Y<ՠ[gwV wȱǍખ1dܑ SqLttL7uǁٵ*;=idL xq2c/E{NJ.O*%ȍ/ڵ^ˣ>J^yÁeԒ.T7UӺҢMP%*@7:Tv¨M]( [Y[>WW*tj^ij\PJbd!⎖y3i{ %\ ??20) }/8q7uCKʎDY5Om SS{AS~XP*%* Tq*,wXk8hd^Ё&44ews?MܯLqҋNn;LX߈m[䱈NJ H@ghUdLFL(k#C]LGzI#z1MYxA@SpPvyso*TpJ157=HQ7Bg`$ghh55L|O^gIkq|뒷Ueq;FNZB ոzWϻ"gcx`0`|Uc1~^3ڭU5\]#?0h) ,|Bb @=\ W(GLA i Ͳ~B쫊V OʎS/),ԍTK`|+(!@d xW dvٹZF U:Gp-x7'DtsvͰ_r3C!1$u(r@ bW&'k#MsЖN]QyϺ%pna"$m\ H %)㯛3P˰&qוyT236f~[F0! A7ø̧)GjJtE%g9ԟREg/8b[U}Ay| u% [ST +x fef $  B귧>ΈO}]e{"FAXR1:[q:p^N40 dپ8@6@<|TH9祑QtEjK*$8}0b+GP0( , I:>qciJ4AZa;3 WY(~'[]E<A߶>]~lK{Sc%6CvDWbnD$՝iyv5+7b`?V巂BK@xe`| AAوf߅EPCU⑳8 Ԑ4`&@ޛ٪V7'cR,QYf G^Wh7淦4N[nPb(O꽁&"KWYeiI[7ƴlYXIBܱt@ЉbLYu淅d!!-O.x"k(RATgdҮ7fwu|\.IEXM7Ask~_MvN" "s(LE/qhd IS2OggS nw5H.^[ZZYLXX_cb[\X[^]a^]c`\[VZ]bVSXSON[XVTY^OLLW]]'@)Pc P]_nGGWtQo ]xQ RLlŕ0ؐpΌ!3~ }s&Bg gIl&7>{S= 50. -6y" 5aQ ~J\'.#%k%Nt\=h\7;%d$a ;C''f[,=gwHZh@"d_iΩ>>%h皞)AFQ6-vX_EgkU b>tݽ)q{ 𤻪 9 ҴB\8)K`TW#H9`v`)X'O94Y?ȅwyRvc;fj38λ)@xmب+Nvo 63|&[8.۴vsqLaԭIE9/+N*\r;|=}&C3ldi1P=.5F<˨Ճ$: `kDR];?sV7 B*D+M(Cvȷ54~&P'؞GHGSafww[hxlF?8΄?k-r }kW|z45g3I *m;m}__@ƅ:PgyV!c[sH`ٱs.G鷟*yP 8(ŮKcIȽ.L4S'c6Մ6[$Q09ҔJyR=9Mod8bჵ)aV< w0/ !zşyU2lx,K8ށeHE),0pQ]trzR<|=+G~Xڝ/ 5^pMG `%4L2Bvzmeb;QƖzEe-c={a`B"6]&>mFݐ2CVP%>&|e>%]fvSۗI#i$\̡R{`Rdi$u"[irw*{T.Q 爾+(EA(#;`` \E5 [qޫ(Whe*Z<@[=F.YEʂfRO5A$-Kk.k.% XpztϼI*k;mwªB \29tU=Uמj!Y0- 'tI`"C%R/r>> ~4?|ZӔJ*6+xyq^\5"Fg|;`(~C<Ɗ\=_Jk$%-B5zX)$cb; `^Up+7Z_jP&dM8F0J2M|gih_h@JUM;e10U:hz.*Te؇l:Qi*a#HlkAg+èkdT//E_M`,g2 ~"N2:ڑ|uɇqw)29v`5'Nᒩ!Kd/4?q7٭GSEr1IebyCglUL0ZtaRa!(V/֨"˶S'p`(\xLcپwn?i% 4D|M%+(OT@D!r(MFZZ3ccyNR4*\O2WMal4p`(rٻϐŻ򅍘J <ؙp"8brq.grW>ܢ4(˳`Gc_nqcw=e!$ :v1ruFս]iˍ6Oz%]ѕSM;M n,j^:[|A:^jgps:ʫ6`㏢$؁E//KFc*i{/!"Wf[+l7)tc=|"y،$#9?*mj7N`J9N"ǁ,80TFI ,JxuR+%w$4+`h= 呙;͋̿tXY$)ܽۓ yR -M> Y*2 zec?N%#\*s=͵H}$&4{`h9@M 993|86XK̓ta}Oډ+0k}QMё(|!Sˇo$w^!,n ơ+i8]#'MZn(Wa{sszh*"E&gҖ@״%ǒWd'u3&<x֐CxG9: j Jmkƍ>ReGz{U)1:a4t+) O-x.K>?.ZׁdEy@ T\/ȝ=+gGe&Bh`>StODZ\j'"ZK(Y:5`\Ux@7'z: ac.ߓfJ-/g.Rd߂c"vV7.7[ e/+0& 5{Ef_ʦN֑?EqҀ"鵴hw=4Ѐhs ̞N=dQr!}񣰰eP~?N&Ss+\_,nor; 6ʮ>_R ةKl=~`@xj1@,dmK@ Yd|9]}i>T]% Aq&2317NEˆ@۶cPe]OggS nw6/aZ`a[Y^`UOTUWYUVWSJISUPU]b[YR\WQKT[__]a]^\V]^YT(m˘B4)|e.ٙ>ikokvvzѧL,fHUMOⴖRaѹa{i=dq+2hS?{}{o&-LPrVJR:UMxL==wcKDWLl"?[&d);{Ky>rR η+αpu3e!d 1 O[=[v sÚcc,3TU}(2-D0;!婵XcUy\A%Ov!ِ&]W_7XMw_'ǚ\,d"=+3>ﺲgAlRCp~$FhO'WԼ1>(gJWLU/&$;g<%3=1v.k׍?dWx Mv,,xx(N4tcrLF_1Zx!:U <,U27V!*w,zLunF>cv2gYc4 _cO 4t؀X &-td\5xww]Fu(ha<HQYPY~;H#&E)֑J@r@!|'cߪ$H.Ctzvޯ ex{SL*fNLu: Ɠ nVs}q2;̯4\Ȧ]Ƥ2[N(oJj)ipUGP砌:JDQa0Ki[nbZ]z?%c$530 so_?L&V/UObrr;& =ܵ>IHW4,).ai_'(H@QK_crh|ySzE'de'ZW4Ў׎fho9*4Gm(^) L-{U[#(craҚMgJާ v`' `K*pgct4믭Gڪ7?YnCjI3$vH~K+vZ# zbb~2fju9O Ϡ\n j&̱7"G YLkxLz6kʪ3?Qr$ `Nf,\eR7LyK˭' +6ձvVIl52VHc>VEe3XmBN;d={ɻ:1"B+AgU:(O !_yndXU4m4ۆ䒒JPHqu/oR9~F6uGeuU/W:'gԏHB0Ur vsJޜh.(Yɇn^ty~pԯbfU3y`kwʍdGb[%CɆ (9IVNH5:30E rmXDfme3[)s?o<э "C< YZI:WXNKKݥf̞FS*'ΤVÕ<:+^W,t*ɐ)Ac7!1vUw1RLV UmË2w4m#ktD7*o/sH3Ok$Iq{adͫl&Pmfv6t )2n\)#lRnkR[\ q"VFG$s]9*[F_{w޼Y” vq ZV#g.[(mlQU|m_ܘ,j*ԟ_Y)Y?#DJt @uiٲk3޳tW=7gyF-^7偻Q!Ǚ!ATD$d^K9!kt:upp{jbϒn>m|JܬU&ce[J]b%abl:/oCQ@pn0*t]rԯ(nAոfofY'13TT|V.fץ2[{r_w,.t%L(ާ ,bd{ҾIZ@sڵ5uFEaH53y>Dbds1戎X]¤Di(]]7\'tsS&k Y~FNGLg'Lwѝ(RK[V:< sVѻeG9=Ps\:KG5%2ޟ`$P)bh,>Β68D+XfL%*}FGk(zɢW'}Eg:k⸛$:ve08Wrg+!Y?EvO3kol:}@.>OggS nw7_0YUQP[\RLKaWZT[bSSN__WRY_VVY_TQLV^[]]`PSO\\VUNSRU#t3pJ{z^^|ݕH.rF~-sd}^]}Te RyEiչ;GH{isfw^wx!"`vfZ3kՠT{ 8{Q_W.pƨ[$O/>uw9e>CJm.^g6fB8 PJ'5H5{5UHip̓ @hrS68ѕƨF|E@Бwѳw^TـxU1(Hk[dI BE-GXp\'S>0=Cy H{e&;h&9@C zZk0^WD %+E+@kEUG}N6O2pm/T%KΩ:pGv`ۍ9c_WϘ6ʿn Z *PcsNP00O_eS)e&e = l4wܒfғw\,/]@#'B zD\4 q ԍԛe0'c XB -#/._gr:e YOp>E'e#{ C/(zV SSA`EʚC[(~C LiK64}seMdM Գ=̹nGmD$EQi=0┣D P*g%MɌjXy6r(]L l~6韴LjLԔ1p3MĚX*~o &^}LP_PxT Zgd9Y/SI C6ìсm )nۭ( (KTJV)&r-44[nd*@|L޴?LM=Գy۲>lc:Q4CnQ '|"77f˗uUUn\*7[iEg:#&cg}sx|(`|ܘެTLK~o8"⥠!Nm\`m n8si+N"3?udm 8g?s;GңF7GmIS,u=88SԭJ$>Kj2@L~yL`GʢmاFh .Fۉ{ );Qyp%j!+* رwXlXJ/jB`ر !{)G:ݥ+j 'K% HY!ŶFSIy䴔]D1uy`~:6Hʌ&ٻ(3@`N/!3G.g3Ȃ+ 酠BAEXgsοmfgrGe PJ+EzB(*Vqf  5nS5|+8=ӏa8OLBQ2BTcϳIryX}źΝOU{pg2 .lm>OSQJP/htֆK.!LK+#+2/Rr/11`L6{ x"6JtNs8 Mc)c`975 <3J@5Ӫ'Ny~,@_R#|a1.κnFƕC BD,-us "r WM0}956*rϣQIsso*{'@(nrf/%,֦ݘL%Ԩ/21NR 28V펌Tvs&\t"d^]=֟j]ɾFS+(?)y+$tE6_7us}6neLI%4wT(CW*oLs;*Sӑ lh(Oe4zUɇ)nb91?\}&EKV ^~x|4~ﺳ%S1ucehn!|#ku}Y(=[|򦽣n (2 Hx_@?{7a{H̾WÉcػ[v+WgU/+GovJ#H@E/DŽ썸xH>9t#ɀ&~j{@9@7w1fh`8 m h*QL䨡yC9f# H$$K.u, ;mlO$OZ_̱Su  ;K"׬DDXUR~YiyNVMOSz7W&h Y>^bm;RtDJnνu]Ri{;GO:i˵ib9"(dnDeĶPP_?pIl˩~{Ӻjeo&zX@-%0W7Rb#ߕv9}ePs5i] CGcڈyPO[Vfg.Dzk^:W_peh{6N׻%-$ -Asq(:TmRZNRm5nIsf*~KeͰ¤WMp` @h-{OL0s䟓ᕜ?NP'5)Pw`%+;B V“! p@N, K1,cPV)`nh{m\zN̤[gp']\-"su`RN̹9I*Q 57 g36;MXgjgyncm/Mq=@AEyйԛs-G6Q@F٭Nk)![clf,cH( /nvhk $γ2;T#PZNY+) ORMpNEn7y2nPy2Qvh(%Vwd~X0OF'ʩ5+Ђ{Dwm3&`}>ģo1>pgj+ACLPQzt?CP?o wѱS"k8p [W^b]+63، J + q=@Bx,`q2mP%93To ⿫$Xnqo6Сԝ(k<MD^KY&&Cj`6@;ۦS3XFLxSm[efRCFoa~CQ TO6Q 8&@)I$9"609FUp.awk]V6kWu4]}) ܲ8挿[x05Pֶ+L82͊ u_qybķ&l* ЀUTIُެU0z&QDNYRHzU՛4(~kq^<';0xHb1i Ŝ)ÓN4[S||_!BOzjT]e'<B 7)Fk7I6l͉VM]OR7zR=V c3̊fTsǦQfd`V tԶy~WUepq,Q֩Z;`gfG|ר5H#Dg^RA WY:f \BM*> 38ow_ϼ `t@|JM^eZߊ1KfJt!Eݟ\ݳw/5] ʷ4*pSGiґ[3ѕ{OLe{ ]\vA4@k7ˡ;}1ZK7Ξ(w'jkF-MǶ(G3g ж"~Wy>W V\~^]Y^M -`<_Z VdO$W>E'Jiiĵm6H|a=KPM3b3'y)=yx `)F}\>=u͒-VʧH]|]aJJy,`+̽3ᮧ:RjƓ\aa9ImA͕-}(f v x"X/0\sr%Q_8~^ 'ʓɻJ=Od!1h(b3e-Gͣp9zOggS{ nw9vzu.Y^_]_bb[bi]ULSWQUXZ\VQY_\[ZYTMRY]PUWZ]\__Z]ZX]-UP0ϕ8罵i{&[H΃ְ_a>=9qtVfR|\l\, ]0\w>.+Gj W>ګxv?+3nӄ*ھ&w#tL19 쉄0fSOx& <J)d'K:}_?~#~2J/"]8 ncLTKW`+\H]Z4>30g,w ~q'Gc` ߹=z[+CofB\eaku EQb')YĺUOnpmzoc_b NӋpgŮ/|aZ@*D3pwil4~āFݴAageCGB/SY޶B/宻 '`Ҡ@͘6܌ў  EuʼKB-Ĵܒ)+,PA+ 8Pxzm"mx|'A.虑^ FoA \0p(뷽yeM1?txz: (f83~yLj%@{vDPޟX<ƤFy0`ҫA*QjZ%4GuqT:Ni\ 0ؘOG%"ialQ$L@m?8~jMY sv5 g7ghO} + X#c`7iG΢lh) t %_=9eҾ'ckb zaXڮ n1l k,3 YSǎQ:pY<%#K&q0qy9ΡOYMج_Yء5vYU@uf9 )c|Cek(@r@Q<8^^;%_&)[8p˻ĶJrw]q6H(>nȔ;)nhFc~vBfdbS}t6vѿ6G$Y9I{YP^}_rwXOw UM.a bq./{>YuJ: O$ '&׮u g=H=46ǩ`-ܔtX0fsH ,Tde|$YwqDnk'%C뺇0g(siv5StɃ=+V$P",H|.?/jYA;L .tF`*hN)_3$ \ib*mY3nSI)|ghGv?99PiOGn2)*VGo5H&ăD?c>;eZ;v:鶰7IA6!WKDr#[ԲaC|c"sւϡB*8~ VzCz{CN{jG?lmH6=VW&*Ps0Ɣ%T۰6f f$(@u+_ٺ6k<ͼ߷7crg97~=`HLq?sIp=չt\fő #c 1BfϜiDkC t4j[-.kgx>"Ǧ_ׯ­ gW*pMCpJ_ڜ9P`Lm۟3:v1eplά-U(P|W/Y<5wb$γzxWNYt̡ي'zMN|n3^5OkWޮC8Ao+d@k,T_\j ave2z$2׌Qa?BU.R>X?CUò&/紟i:r|_=ڗR *{ڵ=ߕKDKs!;JCrz?7]W\`9HˉU (?*N RζX|ܬ%Cߺ`^M6T!Nhɉ5eU'Nv9~"Il^j=yfOF6LjL>~L7d*0ޓ߬I5d]&v}ܗ]oABK ]);M6\0I%nJuA |QphT^8 ]m5nf[{mf36w8&R6%c3[v)˿wOckՃV Jb )<# 煹NG"v`i=`i(MdZlcEunbL{ԩOL;(&8N zZ?g~}Go]>w2KdL OggS nw: G1\WRPXPOZXYRTUPNJX\MOPONOMW^b]]]]WPN[\WKWVPJY`RQMW(rltXt^mTsV&2:N#>yeTFc9U}^Pp#zҺa{>a ? hDc ':.`b$ðs~=VE"'E^A^goH$L,$Ychcc$zCplKW;[}|\_MsyD=- 8n-"dQb, *n]dlֵNM tsujsqv̟:^/ _(t<\ 2@]KD<&%*0Χjm*W!Sg˯~ȸC?SYnb|==%VmRZ#U 6/O1hu/\(1j^gD~'QXn#OHҚ{њ DG706ۉU6*@H(jC}6J=5wu#>aA\:nmQ(~ $Iuo.XkFRy}b-RH#泹,WJrZϏ&LԒYeEȔwbgخua~Q^1Ԑcd$Νm4}(T}7ʡNH%ʝm|v!}j 4©.YjD֤D!>YΣhbfѼG^9;F,d4:#%Z)]L,4No2zf p.[K+'D26Q rDVx;sߘ~F}p:u$rݵIcq$D3s*'>[Bl uX`!'dz=/-X G)Y@A2szƫc>B4rP^+`(ˊ8F9oclvw26y%Tq~j@hQJ)~c[J|;Z^1aW95 `hc| hvy36|;MhHQ(a3C{iaMWe" }^O} &g/BZhOU:n`e_ .B__GE*(t``'&.(ĥ'B ղU x?R= ؃ 'pʧ<&A?NE"-njↃ@:TTDb.p 7?&MttH|a+c);\ͭbNi >H` 'CmS(qVq:')F han9ɹߩmw2u-i!)mM=H/:QCjxqTX'h ,@u@T~̸u/}h牃iVr @Hy*&Atro[26Cw3J4O2W Wm(m+@ߣ7gc#sZcIi^k%šyf.t?uyBg$ҿZ&d2Ar? ib 9O/)%))Wwg]Y=ӎXvFTWk6DsYFuK<-t ӤޜҰB&=]%3I{ɸ (Ggh@BxZډ#rf\LW΂m޷rڏT/|Ϩ%KL}BsMx4'UąHM7~tDc':\DhU'}*fyo|{铜Z׻DF=5WiO"BWLAȠMփ[Gg)7;?@%R$j&oyM4n H͕!$OϪ\tB9@e! W6#8tX*!gxkCX,o6ښ[,F̉?i\2mLA+knk kIaI0STJ TwoHdп*49@|yXZ_ȋi)\?)YFD3_VZ;m'W(W䪀й@y?^H ã- B~3ma :O4b WY]mh nL*ٔ@+5e[nO׮&Wa2S-FʦxWKhg@aBpnG?4!of~^kȬGoUl ƨmFM| t<Ͼdtr c)=4(Bk\T-+X/E"n d۸0(2w9h:0AO<ZǏn ڒ()DF@S`R7!7D(JFX{3Hx-MlB6|O+[J\3%M`x2V[Nm E PQ ~˭|hdh л&H6דcDŽVi$ʹoJ"D7@X@[1@ -4S꺮A4li q0i hX(\nҥ쵧'wd2ziq$<04#9gx/t-vgBb Dg4݇*ɕ?-E- y#8ǨE1eO&J,va@Pw!QHUODmSh3ĝ"~mwVdq%4^da%`tlw:k)۟!#4R6^(&8;6R&} KIJŁ|cioDA0(#86V ~C)ֻr3viJ7qhp6\!2~3 ՂwĨWfs]%^7zOggS nw;&.UVT[\Y_YaYXW\^ee[\Y_ZZb[`ZX_`YZ[XZXYVPK_TZ[U[Qb:u"F 82r1tc |O~ h , v>շ5< 6GI}Uӹz}bv t$t&@QHm$]&Sx:`QXFrA}M(fڊyKsNx>c A&YRyd~y6*ͺW m"AWpt/]Qffǀ_ אe.MnpF $*㾻W>M/#㓠&\N>N!庘BG',Krbw!C|be#rB=i}h,@8'1 $]w)'gzn_o:ógvs)V{{ k ɴ܊>]\zdy9T_%74)ưݐs?mo?RUk t"fB۱ щ>_d>#bϋCs#Ճ:%Kd6EHt}{_~Jzrl Ml_]z`p_ގ]wUY!dd# eDkC0 tdgK8}oe9DZNjS(HWZ6Fl8~*/33&0!(OC+ɔ=+gD-Afg#]1{ڊsk䀖yvcK0$}$6sXĪ:C*sf $bY %04޽g ޜ#b>U1Fsp[hZl PyuA wCףi'A2%0  `q{ftP4/kI qƻz g2[42V}s.D#)׉P{LJ?>\An^6Sġ#Fb;xR2$ yqv{;Kf#u[}Ʊ8f,;W]|2c.˥BۈqD$'dޯeyY.J=C*rnUg6:0TOZ.Eyv|U+B(t^0f`:E wwg{fkV08_-xe 0jh=I<#-%%V86-c-$?,`$ߒWJC-J#r a_{1.ٳjN4 q󙝫D8sf6OAi74^:bB 8UoP"d`h~co\>99dZ7ݤ:*݇C|۠%!Ā{;,-x6>ѫ+r8!125X%2pn ?rPp8p8D{3`lf:jw3l4aW4_ 7'`v h(*ҺP>yḹ\tsѫU8?;|aU[X['"թ}=>z3LL/(w’Ҷ %tRnٞ\aWroaifGM GLϻҌSwiW"$Ⱥ'푝?L2κbSMu {%#gd;t  l%?Rwe̬[5pjJsNcmͅPTO]o8̽ر N>}%G]/ja(nF "FA8`h.?o{+ev%#e 1d Ṿ7uugu"[''?K%vR/psq,̿ ww6{@ (7 4#i܆z- CCk65MR%ܜ-Uȧ(lp} 0ρ]9< Ʃ涿B(0pVjC_ 됧38'VevU@ջ2F/CCw'1&cksm۫OҴ0i<خZ\?A1T `ȸ- #3 `ρ*?8@)Cվn~Gcb=>d??=[ 5z B־OWxt'"nB'\i?1&X%)+mWɕ-\187M_q^\Vq!U{tN9qb8U=B)WÿR3nF&y!!lm ]9Fu$>14O]pRb']Luy7'}pv>f-C0P/9T%gD$F`( Kz"¯7x/6fbLǟ`!PC=xr$a݋ FM Y F益z ('tҠhJ<^+ab_l$< [*8<D)P#p69R-Z@\sۏ'WnZk''6z!}M~n)/[)$7ej]` nY)~;u4)q5?6}pg)"@  'Lv|նmWď* ZJǤMӁ(G)p `<OggS nw<7/LKZ]a]]Z[V[U_VWN_YRO[^OMFJKUPZcY[T^VRO[`\Y\^[[\gou>fK­6=/;r,(~֨BpV#Z 5 2`fa5x+  h>~L4@wLi[~m :& {=o`i`&,_6W/vbpG͐rGo"W"=+(YyV|kqKu§G  ϩn{:OHZOZ%I, !.α6vGn@ Xsv@U[_yDwZRfg%g@S?}3axLfN-(-z>!JLȈx̖^ǩ/Tr`2rbt;35$G[A+eeRe']NoͫggtU#{x48W<`7 Vz4bvz}DҘJpK' "butWWR7W1~/*:0hzEt ,%0ΥS )T؏IjO!(}a=e܈!&@̓/]ck;kGܸA:yjS$Ꟙ^RoPXBRsJBs#JWo [O!T,'e[4Ht=*_}g&3UzdYUMwD3Mi@w3CgG{SR10~awwi)V!kGv5C/,i4Dx A) T:atk θ}ϓxިcMB>Pfv V$"z Ig-a II&l$ yz3T /m nxX PFgQ 8Zq ݱ$ˀt~>%qiF3&f$&th`P*Gj%Cf ~qja o ,3`W \$, Y1ACM p='HdYy? h%z62-w P%`[p!9K8Y!A] fhH]؀[jK)%UYK_m^?l5sqȲ" !,߷bFk+8ntZގedƆ |@*Lܕ&Ԩf<% #"Nuo4-K5`KU&GX yܐ.Gݶ#uΎ{Oed-(]h__O&9}j-fYu-o{THkD;e[>8`tvz9[B#ƥJcc-|]/&mK_i.%P‰)?҈}*8XHuwWelF]TRc)al>l7CfOLT3__0JzWG! '>(<\q{_'Z6DL 2o3P-,'=E$0Wm.GY]t<9ZĦcYTW:4#s:9=:^˝ Fܬ/9ks<ۇzt||Š0= bHm$ N?@`43Wx} \ 5@Ot:>;+8R6v:XNX8x@ HN`Mho6$t+:Dӹ0w\*Vl (ʿk 0yK/ODŽөO0h2.&ܞKq(XkSwEvzfCꎚF-+BQpk*Pɿ)H_,L?-p~vZVIxb?q4}t]oo]u-xvܵY~70+#Ge t:PYx.uWDGGvaQZ*ɩ&~+TJQ 8?g>>5-\%q@mzbBQ4t=K>9_,[)zq}P1E%[p{ı v6TfI!%;t7@T޺FvwCYnf*Y2H z-ʠ:d[AFq<9%#d{~WFO(-0oϖ=Zx3KKa&9;ҪE+,9LvћqsLÐgp# s :[$ gG^͎vͣR0theI4+R8_xM ZglSʎ12(G=z$ xer]bu~ -MZ: }7B$HbEƞFR( k3„0Kd%f\.CX>UP$GRǀ5&-/g<|;j__||BbyL(?SF9Z~X؉ca:ރ+INɨ} ı)#ˤnFS+k/ v85f.vQxgG]Mr< A)>p*E!{S!+|G K>\ӢU;͛KT=": t*{۷^;rq@Y*Kb9F!ޘwBl皕ѡz9ڛ;G]2.e%upC8l)3qOggS<7 nw=홪/W]_ZVUXWSS[XOO^XZYV_LTPZTTSZXWU[]VPPY^^WZaVRNX\'c* +񶯆>esҍ?6/ ε̈́Ps- W13]7s!>B/=c2b!1(CL`x#GNNZY+92I I,fwVİ]bTcNMr@H;ołc c&.^hxsr sBP=۫[JׄH*F٥x2l@7,Ob]?вL2ٳx̜/PQ4AAK$yEphQ)7d#֬h*e!d,0Р\J\Y\pZ2[gdl4:ޗݲ$Ս։i$:y4 %\K{jT$B's NBGE)ƙĮ;W Ocy6Wh:!&#u?I*͟|\OW3Ifso3!,%@_Lj8 }OGV (Ҡ; >"=t*TT)w6O95 OtD℮^TZ|Ʉbͯ!8iL"quG= ;F q:ع !yq6d0q(0kFuE{<'&jeN6>Z%\Aiŀ[NtЅLv k)ul3 <͙eO>T$\^oP {;ޟ p&D`}8ƯJ+]TЌCg#pox ętSƛG~VlM_;>/ovd##U.%sߎ'c@TTθo۞\xɖ{= L"Ǖ$8bpqg\ kOZ-q&n4J_Yv^%zL4'г7Z&'yR\"gJNZ ,Sbu"`ciz#@맑ƥ֬VgAGcr]ug :#G:,I ^Y ۬dN^'˪x=Ch¤ʓL `V'*6D4+Ʒ-d+: Ԃ= q*EX?:?٥+¦ ['%XPxC>O~Jr,H,ZvL͡-z}(<]2'a?N0igo*8]KJG %{qZ5 =TU7Scj!Bp/]w-zbbCIM͕WS4x%{W'H h܎v{rf:T31i!hʦ+!?v9>{6Gt{m^1TX 54` <밡^ڕ-;jy z0JeL$j jCvsgjb`$K;GB.U9s F`aPO}z.ONa!m\U33#:.̭|%22֩uꌪ6hbeXathgv {i@`Y7͝Z7q$da^Y24LOFP Pt4\"0Kp2c{v '-`Н&m}k6M9=zTz`9@|- Au;X-&,!ˇe֓dnrk j* 婌FMweOD >8 PNJNp1RqZ(enÂI`гCn=v:茻XukPI$^:˶4 N{$.aA҃S+y^N~`0o7'gPĕc_>]"}mS{FdK)A$( uz}:GFg7+Nk q{MFst,P7cg>6r?X@ TBҳ[U1 Yp/6Z%1M&#+R|O@W26sg/Op_w¤R 4 &9@Vl?*pW$䪓QmZͦQp8yBEP{+`grAbSF¢>[u J~_˞k uJ,g; qwqGС :!Ԑ^[!a&g&޿X7@X`N11^N8CDi.\gYDx B@KϙoF1B;HP@A[q%0 .бw>.5x ZT~]»uSr LjD- @Jx># .i+ 1CfPƅ~Cء]N:KP`MP5bh\N;[vC[Z/m[1){ V*t?r >|'&ڥ,@O @ps9y}g=3'N99-,OQkjG6A'c)[*Ziw3^1+'WO^&|C ,^iV`ImL`Ҵq1ц87n`,+1h>V;12fkvD꤆6S+fIs(gv>ZCǃKlZcM,k\-/۵p0yjxF32!XL!(Y-3xQ3i&&+{0?]ѝe2Ea6v 4P͝ZnQ\MɐqN&ƦDm%K&!Vu -~Nŭ22 C8\{fa Av'P)TP{й!&\ #include #include #include "speed.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* generated sample waveforms */ static ALLEGRO_SAMPLE *zap; static ALLEGRO_SAMPLE *bang; static ALLEGRO_SAMPLE *bigbang; static ALLEGRO_SAMPLE *ping; static ALLEGRO_SAMPLE *sine; static ALLEGRO_SAMPLE *square; static ALLEGRO_SAMPLE *saw; static ALLEGRO_SAMPLE *bd; static ALLEGRO_SAMPLE *snare; static ALLEGRO_SAMPLE *hihat; #define RAND (((float)(rand() & 255) / 255.0) - 0.5) /* format: pitch, delay. Zero pitch = silence */ static int part_1[] = { /* tune A bass */ /* C */ 45, 6, 0, 2, /* C */ 45, 6, 0, 10, /* C */ 45, 6, 0, 2, /* C */ 45, 8, 0, 4, /* C */ 45, 8, 0, 4, /* C */ 45, 6, 0, 2, /* F */ 50, 6, 0, 2, /* F */ 50, 6, 0, 10, /* F */ 50, 6, 0, 2, /* F */ 50, 8, 0, 4, /* F */ 50, 8, 0, 4, /* F */ 50, 6, 0, 2, /* Ab */ 53, 6, 0, 2, /* Ab */ 53, 6, 0, 10, /* Ab */ 53, 6, 0, 2, /* G */ 52, 8, 0, 4, /* G */ 52, 8, 0, 4, /* G */ 52, 6, 0, 2, /* C */ 45, 6, 0, 2, /* C */ 45, 6, 0, 10, /* C */ 45, 6, 0, 2, /* C */ 45, 8, 0, 4, /* C */ 45, 8, 0, 4, /* C */ 45, 6, 0, 2, /* tune A repeat bass */ /* C */ 45, 6, 0, 2, /* C */ 45, 6, 0, 10, /* C */ 45, 6, 0, 2, /* C */ 45, 8, 0, 4, /* C */ 45, 8, 0, 4, /* C */ 45, 6, 0, 2, /* F */ 50, 6, 0, 2, /* F */ 50, 6, 0, 10, /* F */ 50, 6, 0, 2, /* F */ 50, 8, 0, 4, /* F */ 50, 8, 0, 4, /* F */ 50, 6, 0, 2, /* Ab */ 53, 6, 0, 2, /* Ab */ 53, 6, 0, 10, /* Ab */ 53, 6, 0, 2, /* G */ 52, 8, 0, 4, /* G */ 52, 8, 0, 4, /* G */ 52, 6, 0, 2, /* C */ 45, 6, 0, 2, /* C */ 45, 6, 0, 10, /* C */ 45, 6, 0, 2, /* C */ 45, 8, 0, 4, /* C */ 45, 8, 0, 4, /* C */ 45, 6, 0, 2, /* tune B bass */ /* C */ 45, 52, 0, 4, /* C */ 45, 6, 0, 2, /* D */ 47, 52, 0, 4, /* D */ 47, 6, 0, 2, /* Eb */ 48, 14, 0, 2, /* F */ 50, 14, 0, 2, /* G */ 52, 14, 0, 2, /* Ab */ 53, 14, 0, 2, /* Bb */ 55, 6, 0, 2, /* Bb */ 55, 6, 0, 10, /* Bb */ 55, 6, 0, 2, /* C */ 57, 14, 0, 2, /* G */ 52, 14, 0, 2, /* tune B repeat bass */ /* C */ 45, 6, 0, 2, /* C */ 45, 6, 0, 10, /* C */ 45, 6, 0, 2, /* C */ 45, 8, 0, 4, /* C */ 45, 8, 0, 4, /* C */ 45, 6, 0, 2, /* D */ 47, 6, 0, 2, /* D */ 47, 6, 0, 10, /* D */ 47, 6, 0, 2, /* D */ 47, 8, 0, 4, /* D */ 47, 8, 0, 4, /* D */ 47, 6, 0, 2, /* Eb */ 48, 14, 0, 2, /* F */ 50, 14, 0, 2, /* G */ 52, 14, 0, 2, /* Ab */ 53, 14, 0, 2, /* Bb */ 55, 6, 0, 2, /* Bb */ 55, 6, 0, 10, /* Bb */ 55, 6, 0, 2, /* C */ 57, 14, 0, 2, /* G */ 52, 14, 0, 2, 0, 0 }; static int part_2[] = { /* tune A harmony */ /* C */ 57, 30, 0, 2, /* Eb */ 60, 14, 0, 2, /* C */ 57, 14, 0, 2, /* F */ 62, 30, 0, 2, /* Ab */ 65, 14, 0, 2, /* F */ 62, 14, 0, 2, /* Ab */ 65, 30, 0, 2, /* G */ 64, 14, 0, 2, /* G */ 52, 14, 0, 2, /* C */ 57, 30, 0, 2, /* Eb */ 60, 14, 0, 2, /* Eb */ 60, 3, 0, 1, /* D */ 59, 3, 0, 1, /* Db */ 58, 3, 0, 1, /* C */ 57, 3, 0, 1, /* tune A repeat harmony */ /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 6, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* F */ 62, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* F */ 62, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* C */ 69, 6, 0, 6, /* C */ 57, 3, 0, 1, /* F */ 62, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* C */ 69, 6, 0, 6, /* C */ 57, 3, 0, 1, /* D */ 59, 3, 0, 1, /* G */ 64, 3, 0, 1, /* D */ 71, 6, 0, 2, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 2, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 6, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* G */ 64, 3, 0, 1, /* C */ 69, 6, 0, 2, /* tune B melody */ /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* F */ 62, 3, 0, 1, /* G */ 64, 5, 0, 3, /* Ab */ 65, 3, 0, 1, /* F */ 62, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F */ 62, 3, 0, 1, /* D */ 59, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 3, 0, 1, /* F# */ 63, 3, 0, 1, /* G */ 64, 3, 0, 1, /* A */ 66, 5, 0, 3, /* Bb */ 67, 3, 0, 1, /* G */ 64, 5, 0, 3, /* A */ 66, 3, 0, 1, /* F# */ 63, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F# */ 63, 2, 0, 1, /* Eb */ 60, 2, 0, 1, /* D */ 59, 1, 0, 1, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* F */ 62, 3, 0, 1, /* G */ 64, 5, 0, 3, /* Ab */ 65, 3, 0, 1, /* F */ 62, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F */ 62, 3, 0, 1, /* D */ 59, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 3, 0, 1, /* E */ 61, 3, 0, 1, /* F# */ 63, 3, 0, 1, /* Ab */ 65, 5, 0, 3, /* F# */ 63, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 69, 8, 0, 24, /* tune B repeat melody */ /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* F */ 62, 3, 0, 1, /* G */ 64, 5, 0, 3, /* Ab */ 65, 3, 0, 1, /* F */ 62, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F */ 62, 3, 0, 1, /* D */ 59, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 3, 0, 1, /* F# */ 63, 3, 0, 1, /* G */ 64, 3, 0, 1, /* A */ 66, 5, 0, 3, /* Bb */ 67, 3, 0, 1, /* G */ 64, 5, 0, 3, /* A */ 66, 3, 0, 1, /* F# */ 63, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F# */ 63, 2, 0, 1, /* Eb */ 60, 2, 0, 1, /* D */ 59, 1, 0, 1, /* C */ 57, 3, 0, 1, /* Eb */ 60, 3, 0, 1, /* F */ 62, 3, 0, 1, /* G */ 64, 5, 0, 3, /* Ab */ 65, 3, 0, 1, /* F */ 62, 5, 0, 3, /* G */ 64, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* F */ 62, 3, 0, 1, /* D */ 59, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 3, 0, 1, /* E */ 61, 3, 0, 1, /* F# */ 63, 3, 0, 1, /* Ab */ 65, 5, 0, 3, /* F# */ 63, 3, 0, 1, /* Ab */ 65, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 69, 8, 0, 24, 0, 0 }; static int part_3[] = { /* tune A melody */ /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 5, 0, 3, /* C */ 57, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 4, 0, 1, /* C */ 57, 4, 0, 1, /* Bb */ 55, 5, 0, 5, /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 8, 0, 4, /* D */ 59, 5, 0, 3, /* C */ 57, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 9, /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 5, 0, 3, /* D */ 59, 5, 0, 3, /* C */ 57, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 1, /* G */ 64, 5, 0, 3, /* G */ 64, 5, 0, 3, /* Bb */ 67, 5, 0, 3, /* C */ 57, 8, 0, 32, /* tune A repeat melody */ /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 5, 0, 3, /* C */ 57, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 1, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* D */ 59, 4, 0, 1, /* C */ 57, 4, 0, 1, /* Bb */ 55, 5, 0, 5, /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 8, 0, 4, /* D */ 59, 5, 0, 3, /* C */ 57, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 9, /* G */ 64, 3, 0, 1, /* G */ 64, 3, 0, 1, /* Bb */ 67, 3, 0, 1, /* C */ 57, 5, 0, 3, /* D */ 59, 5, 0, 3, /* C */ 57, 5, 0, 3, /* Eb */ 60, 5, 0, 3, /* Eb */ 60, 3, 0, 1, /* D */ 59, 3, 0, 1, /* C */ 57, 3, 0, 1, /* G */ 64, 5, 0, 3, /* G */ 64, 5, 0, 3, /* Bb */ 67, 5, 0, 3, /* C */ 57, 8, 0, 32, /* tune B harmony */ /* C */ 57, 52, 0, 4, /* C */ 57, 6, 0, 2, /* D */ 59, 52, 0, 4, /* D */ 59, 6, 0, 2, /* Eb */ 60, 14, 0, 2, /* F */ 62, 14, 0, 2, /* G */ 64, 14, 0, 2, /* Ab */ 65, 14, 0, 2, /* Bb */ 67, 6, 0, 2, /* Bb */ 67, 6, 0, 10, /* Bb */ 67, 6, 0, 2, /* C */ 69, 14, 0, 2, /* G */ 64, 2, /* F# */ 63, 2, /* G */ 64, 2, /* Ab */ 65, 2, /* G */ 64, 3, 0, 1, /* D */ 59, 3, 0, 9, /* tune B repeat harmony */ /* C */ 57, 11, 0, 1, /* D */ 59, 4, 0, 8, /* C */ 57, 11, 0, 1, /* D */ 59, 5, 0, 3, /* C */ 57, 7, 0, 1, /* D */ 59, 3, 0, 9, /* D */ 59, 11, 0, 1, /* Eb */ 60, 4, 0, 8, /* D */ 59, 11, 0, 1, /* Eb */ 60, 5, 0, 3, /* D */ 59, 7, 0, 1, /* Eb */ 60, 3, 0, 9, /* Eb */ 60, 11, 0, 1, /* F */ 62, 5, 0, 7, /* G */ 64, 11, 0, 1, /* Ab */ 65, 10, 0, 2, /* Bb */ 67, 7, 0, 9, /* Bb */ 67, 14, 0, 2, /* Bb */ 67, 6, 0, 2, /* C */ 69, 14, 0, 2, /* G */ 64, 2, /* F# */ 63, 2, /* G */ 64, 2, /* Ab */ 65, 2, /* G */ 64, 3, 0, 1, /* D */ 59, 3, 0, 1, 0, 0 }; static int part_4[] = { /* tune A drums */ 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, /* tune A repeat drums */ 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, 1, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 2, 4, 1, 4, 1, 4, 2, 2, 2, 2, 1, 4, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, /* tune B drums */ 1, 16, 1, 8, 1, 8, 1, 16, 1, 8, 1, 4, 1, 4, 1, 16, 1, 8, 1, 8, 1, 16, 1, 8, 1, 4, 1, 4, 1, 16, 1, 16, 1, 16, 1, 8, 1, 8, 1, 8, 1, 8, 1, 4, 1, 4, 1, 4, 1, 4, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, /* tune B repeat drums */ 1, 8, 2, 8, 1, 12, 1, 4, 1, 16, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, 1, 8, 2, 8, 1, 12, 1, 4, 1, 16, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, 1, 8, 2, 8, 1, 4, 1, 4, 2, 8, 1, 8, 2, 8, 1, 4, 1, 4, 2, 8, 1, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 4, 2, 4, 1, 4, 2, 8, 1, 8, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 0, 0 }; /* music player state */ #define NUM_PARTS 4 static int *part_ptr[NUM_PARTS] = { part_1, part_2, part_3, part_4 }; static int *part_pos[NUM_PARTS]; static int part_time[NUM_PARTS]; static int freq_table[256]; static ALLEGRO_SAMPLE_INSTANCE *part_voice[NUM_PARTS]; static ALLEGRO_TIMER *music_timer; #define PAN(x) (((x) - 128)/128.0) /* the main music player function */ static void music_player() { int i, note; for (i=0; i 0) { al_set_sample_instance_speed(part_voice[i], freq_table[note]/22050.0); al_play_sample_instance(part_voice[i]); } } part_pos[i] += 2; if (!part_pos[i][1]) part_pos[i] = part_ptr[i]; } part_time[i]--; } } /* this code is sick */ static void init_music() { float vol, val; char *p; int i; if (!al_is_audio_installed()) return; /* sine waves (one straight and one with oscillator sync) for the bass */ sine = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(sine); for (i=0; i<64; i++) { *p = 128 + (sin((float)i * M_PI / 32.0) + sin((float)i * M_PI / 12.0)) * 8.0; p++; } /* square wave for melody #1 */ square = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(square); for (i=0; i<64; i++) { *p = (i < 32) ? 120 : 136; p++; } /* saw wave for melody #2 */ saw = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(saw); for (i=0; i<64; i++) { *p = 120 + (i*4 & 255) / 16; p++; } /* bass drum */ bd = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(bd); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 16.0; *p = 128 + (sin((float)i / 48.0) + sin((float)i / 32.0)) * vol; p++; } /* snare drum */ snare = create_sample_u8(22050, 3072); p = (char *)al_get_sample_data(snare); val = 0; for (i=0; i<3072; i++) { vol = (float)(3072-i) / 24.0; val = (val * 0.9) + (RAND * 0.1); *p = 128 + val * vol; p++; } /* hihat */ hihat = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(hihat); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 192.0; *p = 128 + (sin((float)i / 4.2) + RAND) * vol; p++; } /* start up the player */ for (i=0; i<256; i++) freq_table[i] = (int)(350.0 * pow(2.0, (float)i/12.0)); for (i=0; i 1) { ping_vol = 255; ping_freq = 500; } else { ping_vol = 128; ping_freq = 1000; } ping_count = times; play_sample(ping, ping_vol, 128, ping_freq, FALSE); al_start_timer(ping_timer); } else play_sample(ping, 255, 128, 500, FALSE); } allegro-5.0.10/demos/speed/makefile0000644000175000001440000000305611355053656016332 0ustar tjadenusers# makefile for building Shawn's Speed Hack entry OBJ = badguys bullets explode hiscore main message player sound title view .PHONY: clean zip run8 run16 run32 runlo runhi ifdef USE_WATCOM # Watcom version # -------------- OBJS = $(addsuffix .obj,$(OBJ)) speed.exe: $(OBJS) echo option quiet > _tmpfile.arg echo option stack=128k >> _tmpfile.arg echo system dos4g >> _tmpfile.arg echo name speed.exe >> _tmpfile.arg echo library alleg.lib >> _tmpfile.arg echo $(addprefix \nfile ,$(OBJS)) >> _tmpfile.arg wlink @_tmpfile.arg rm _tmpfile.arg %.obj: %.c speed.h wcl386 -bt=dos4g -5s -s -zq -fo=$@ -c $< else ifdef USE_MSVC # MSVC version # ------------ OBJS = $(addsuffix .obj,$(OBJ)) speed.exe: $(OBJS) echo $(OBJS) > _tmpfile.arg link -nologo -out:speed.exe @_tmpfile.arg alleg.lib rm _tmpfile.arg %.obj: %.c speed.h cl -nologo -Gd -Ox -GB -Fo$@ -c $< else # gcc (Linux and djgpp) version # ----------------------------- ifdef DEBUGMODE CFLAGS = -Wall -m486 -g LFLAGS = ALLEG = -lalld else CFLAGS = -Wall -m486 -O3 -ffast-math LFLAGS = -s ALLEG = -lalleg endif OBJS = $(addsuffix .o,$(OBJ)) speed: $(OBJS) gcc $(LFLAGS) -o speed $(OBJS) $(ALLEG) %.o: %.c speed.h gcc $(CFLAGS) -o $@ -c $< endif endif # generic stuff # ------------- clean: rm -rvf speed speed.exe speed.zip speed.rec *.o *.obj core zip: clean cd ..; zip -9 -r speed.zip speed/; mv speed.zip speed run8: speed speed 640 480 8 run16: speed speed 640 480 16 run32: speed speed 640 480 32 runlo: speed speed 320 200 8 runhi: speed speed 1024 768 16 allegro-5.0.10/demos/speed/main.c0000644000175000001440000001700412101073433015701 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Main program body, setup code, action pump, etc. */ #include #include #include #include #include #include #include #include "speed.h" /* are we cheating? */ int cheat = FALSE; /* low detail mode? */ int low_detail = FALSE; /* disable the grid? */ int no_grid = FALSE; /* disable the music? */ int no_music = FALSE; /* how many points did we get? */ int score; /* the main game function */ static int play_game() { ALLEGRO_TIMER *inc_counter; int gameover = 0; int cyclenum = 0; int redraw = 1; /* init */ score = 0; init_view(); init_player(); init_badguys(); init_bullets(); init_explode(); init_message(); #define TIMER_SPEED ALLEGRO_BPS_TO_SECS(30*(cyclenum+2)) inc_counter = al_create_timer(TIMER_SPEED); al_start_timer(inc_counter); while (!gameover) { /* move everyone */ while ((al_get_timer_count(inc_counter) > 0) && (!gameover)) { update_view(); update_bullets(); update_explode(); update_message(); if (update_badguys()) { if (advance_view()) { cyclenum++; al_set_timer_count(inc_counter, 0); lay_attack_wave(TRUE); advance_player(TRUE); } else { lay_attack_wave(FALSE); advance_player(FALSE); } } gameover = update_player(); al_set_timer_count(inc_counter, al_get_timer_count(inc_counter)-1); redraw = 1; } /* take a screenshot? */ if (key[ALLEGRO_KEY_PRINTSCREEN]) { static int ss_count = 0; char fname[80]; sprintf(fname, "speed%03d.tga", ++ss_count); al_save_bitmap(fname, al_get_backbuffer(screen)); while (key[ALLEGRO_KEY_PRINTSCREEN]) poll_input_wait(); al_set_timer_count(inc_counter, 0); } /* toggle fullscreen window */ if (key[ALLEGRO_KEY_F]) { int flags = al_get_display_flags(screen); al_set_display_flag(screen, ALLEGRO_FULLSCREEN_WINDOW, !(flags & ALLEGRO_FULLSCREEN_WINDOW)); while (key[ALLEGRO_KEY_F]) poll_input_wait(); } /* draw everyone */ if (redraw) { draw_view(); redraw = 0; } else { rest(1); } } /* cleanup */ al_destroy_timer(inc_counter); shutdown_view(); shutdown_player(); shutdown_badguys(); shutdown_bullets(); shutdown_explode(); shutdown_message(); if (gameover < 0) { sfx_ping(1); return FALSE; } return TRUE; } /* display a commandline usage message */ static void usage() { printf( "\n" "SPEED - by Shawn Hargreaves, 1999\n" "Allegro 5 port, 2010\n" "\n" "Usage: speed w h [options]\n" "\n" "The w and h values set your desired screen resolution.\n" "What modes are available will depend on your hardware.\n" "\n" "Available options:\n" "\n" "\t-fullscreen enables full screen mode. (w and h are optional)\n" "\t-cheat makes you invulnerable.\n" "\t-simple turns off the more expensive graphics effects.\n" "\t-nogrid turns off the wireframe background grid.\n" "\t-nomusic turns off my most excellent background music.\n" "\t-www invokes the built-in web browser.\n" "\n" "Example usage:\n" "\n" "\tspeed 640 480\n" ); } /* the main program body */ int main(int argc, char *argv[]) { int w = 0, h = 0; int www = FALSE; int i, n; int display_flags = ALLEGRO_GENERATE_EXPOSE_EVENTS; srand(time(NULL)); al_set_org_name("liballeg.org"); al_set_app_name("SPEED"); if (!al_init()) { fprintf(stderr, "Could not initialise Allegro.\n"); return 1; } al_init_primitives_addon(); /* parse the commandline */ for (i=1; i; $msg =~ s/^[\r\n]+//; $msg =~ s/[\r\n]+$//; # clean the project system("make clean"); # add message to the readme open FILE, ">> speed.txt"; $date = "$mon-$mday-$year, at $hour:$min"; print FILE "\n\n$date\n" . ('-' x length($date)) . "\n\n"; print FILE $msg; print FILE "\n\n"; close FILE; # make a backup of the code $dir = "$mon-$mday-$year-at-$hour-$min"; mkdir $dir, 0775; system("cp -v * $dir"); # upload message to the website open FILE, "| lwp-request 'http://www.allegro.cc/speedhack/update.taf?_section=update&_UserReference=D50262AC9D32184E383E8C75' -m POST -c application/x-www-form-data -d" or die "Can't open lwp-request\n"; print FILE < #include #include "speed.h" /* explosion info */ typedef struct EXPLOSION { float x; float y; int big; float time; struct EXPLOSION *next; } EXPLOSION; static EXPLOSION *explosions; /* initialises the explode functions */ void init_explode() { explosions = NULL; } /* closes down the explode module */ void shutdown_explode() { EXPLOSION *e; while (explosions) { e = explosions; explosions = explosions->next; free(e); } } /* triggers a new explosion */ void explode(float x, float y, int big) { EXPLOSION *e = malloc(sizeof(EXPLOSION)); e->x = x; e->y = y; e->big = big; e->time = 0; e->next = explosions; explosions = e; } /* updates the explode position */ void update_explode() { EXPLOSION **p = &explosions; EXPLOSION *e = explosions; EXPLOSION *tmp; while (e) { e->time += 1.0 / (e->big/2.0 + 1); if (e->time > 32) { *p = e->next; tmp = e; e = e->next; free(tmp); } else { p = &e->next; e = e->next; } } } /* draws explosions */ void draw_explode(int r, int g, int b, int (*project)(float *f, int *i, int c)) { EXPLOSION *e = explosions; float size = view_size(); float pos[2]; int ipos[2]; int rr, gg, bb, c, s; ALLEGRO_COLOR col; while (e) { pos[0] = e->x; pos[1] = e->y; if (project(pos, ipos, 2)) { s = e->time * size / (512 / (e->big + 1)); if ((!low_detail) && (e->time < 24)) { c = (24 - e->time) * 255 / 24; col = makecol(c, c, c); circle(ipos[0], ipos[1], s*2, col); circle(ipos[0], ipos[1], s*s/8, col); } if (e->time < 32) { rr = (32 - e->time) * r / 32; gg = (32 - e->time) * g / 32; bb = (32 - e->time) * b / 32; c = MAX((24 - e->time) * 255 / 24, 0); rr = MAX(rr, c); gg = MAX(gg, c); bb = MAX(bb, c); col = makecol(rr, gg, bb); circlefill(ipos[0], ipos[1], s, col); } } e = e->next; } } allegro-5.0.10/demos/speed/CMakeLists.txt0000644000175000001440000000237712137074070017367 0ustar tjadenusers# Prefer local headers to system directories. include_directories( ${CMAKE_SOURCE_DIR}/addons/main ${CMAKE_SOURCE_DIR}/addons/audio ${CMAKE_SOURCE_DIR}/addons/font ${CMAKE_SOURCE_DIR}/addons/primitives ) set(SPEED_SRCS a4_aux.c badguys.c bullets.c explode.c hiscore.c main.c message.c player.c sound.c title.c view.c ) if(NOT SUPPORT_AUDIO OR NOT SUPPORT_PRIMITIVES OR NOT SUPPORT_FONT) message(STATUS "Not building SPEED") return() endif() if(COMPILER_GCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-strict-prototypes -Wno-missing-prototypes") endif(COMPILER_GCC) if(APPLE) set(DEMO_EXECUTABLE_TYPE MACOSX_BUNDLE) else(APPLE) set(DEMO_EXECUTABLE_TYPE "${EXECUTABLE_TYPE}") endif(APPLE) add_executable(speed ${DEMO_EXECUTABLE_TYPE} ${SPEED_SRCS}) fix_executable(speed) target_link_libraries(speed ${ALLEGRO_MAIN_LINK_WITH} ${AUDIO_LINK_WITH} ${PRIMITIVES_LINK_WITH} ${FONT_LINK_WITH} ${IMAGE_LINK_WITH} ) if(NOT BUILD_SHARED_LIBS) set_target_properties(speed PROPERTIES COMPILE_FLAGS "-DALLEGRO_STATICLINK") endif(NOT BUILD_SHARED_LIBS) #-----------------------------------------------------------------------------# # vim: set ts=8 sts=4 sw=4 et: allegro-5.0.10/demos/speed/view.c0000644000175000001440000002227611411645364015751 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Viewport functions (3d projection, wireframe guide rendering, etc). */ #include #include #include #include #include "speed.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #define NUM_VIEWS 4 /* desired position of a viewport window */ typedef struct { float pos[4]; /* left, top, right, bottom */ } VIEWPOS[NUM_VIEWS]; /* current status of a viewport window */ typedef struct { float pos[4]; /* left, top, right, bottom */ float vel[4]; /* rate of change of the above */ } VIEWINFO[NUM_VIEWS]; /* viewport positioning macros */ #define OFF_TL {{ -0.1, -0.1, -0.1, -0.1 }} #define OFF_TR {{ 1.1, -0.1, 1.1, -0.1 }} #define OFF_BL {{ -0.1, 1.1, -0.1, 1.1 }} #define OFF_BR {{ 1.1, 1.1, 1.1, 1.1 }} #define QTR_TL {{ 0, 0, 0.5, 0.5 }} #define QTR_TR {{ 0.5, 0, 1.0, 0.5 }} #define QTR_BL {{ 0, 0.5, 0.5, 1.0 }} #define QTR_BR {{ 0.5, 0.5, 1.0, 1.0 }} #define BIG_TL {{ 0, 0, 0.7, 0.7 }} #define BIG_TR {{ 0.3, 0, 1.0, 0.7 }} #define BIG_BL {{ 0, 0.3, 0.7, 1.0 }} #define BIG_BR {{ 0.3, 0.3, 1.0, 1.0 }} #define FULL {{ 0, 0, 1.0, 1.0 }} /* list of viewport window positions */ static VIEWPOS viewpos[] = { { FULL, OFF_TR, OFF_BL, OFF_BR }, /* 1 single */ { OFF_TL, FULL, OFF_BL, OFF_BR }, /* 2 single */ { BIG_TL, BIG_BR, OFF_BL, OFF_BR }, /* 12 multiple */ { OFF_TL, OFF_TR, FULL, OFF_BR }, /* 3 single */ { BIG_TL, OFF_TR, BIG_BR, OFF_BR }, /* 13 multiple */ { OFF_TL, BIG_TR, BIG_BL, OFF_BR }, /* 23 multiple */ { FULL, FULL, OFF_BL, OFF_BR }, /* 12 superimpose */ { OFF_TL, OFF_TR, OFF_BL, FULL, }, /* 4 single */ { BIG_TL, OFF_TR, OFF_BL, BIG_BR }, /* 14 multiple */ { OFF_TL, FULL, FULL, OFF_BR }, /* 23 superimpose */ { OFF_TL, BIG_TL, OFF_BL, BIG_BR }, /* 24 multiple */ { OFF_TL, FULL, OFF_BL, FULL }, /* 24 superimpose */ { QTR_TL, QTR_TR, QTR_BL, OFF_BR }, /* 123 multiple */ { BIG_TL, OFF_TR, OFF_BL, BIG_BR }, /* 14 superimpose */ { QTR_TL, OFF_TR, QTR_BL, QTR_BR }, /* 134 multiple */ { FULL, OFF_TR, FULL, OFF_BR }, /* 13 superimpose */ { OFF_TL, OFF_TR, BIG_TL, BIG_BR }, /* 34 multiple */ { OFF_TL, QTR_TR, BIG_BL, QTR_BR }, /* 234 multiple */ { OFF_TL, OFF_TR, FULL, FULL }, /* 34 superimpose */ { FULL, QTR_TR, OFF_BL, QTR_BR }, /* 124 multiple */ { FULL, FULL, OFF_BL, FULL }, /* 124 superimpose */ { QTR_TL, QTR_TR, QTR_BL, QTR_BR }, /* 1234 multiple */ { FULL, FULL, FULL, OFF_BR }, /* 123 superimpose */ { FULL, OFF_TR, FULL, FULL }, /* 134 superimpose */ { OFF_TL, FULL, FULL, FULL }, /* 234 superimpose */ { FULL, FULL, FULL, FULL }, /* 1234 superimpose */ }; /* current viewport state */ static VIEWINFO viewinfo; static int viewnum; static float view_left, view_top, view_right, view_bottom; /* returns a scaling factor for 2d graphics effects */ float view_size() { return ((view_right - view_left) + (view_bottom - view_top)) / 2; } /* initialises the view functions */ void init_view() { int i, j; viewnum = 0; for (i=0; i<4; i++) { for (j=0; j<4; j++) { viewinfo[i].pos[j] = 0; viewinfo[i].vel[j] = 0; } } } /* closes down the view module */ void shutdown_view() { } /* advances to the next view position */ int advance_view() { int cycled = FALSE; viewnum++; if (viewnum >= (int)(sizeof(viewpos)/sizeof(VIEWPOS))) { viewnum = 0; cycled = TRUE; } return cycled; } /* updates the view position */ void update_view() { float delta, vel; int i, j; for (i=0; i<4; i++) { for (j=0; j<4; j++) { delta = viewpos[viewnum][i].pos[j] - viewinfo[i].pos[j]; vel = viewinfo[i].vel[j]; vel *= 0.9; delta = log(ABS(delta)+1.0) * SGN(delta) / 64.0; vel += delta; if ((ABS(delta) < 0.00001) && (ABS(vel) < 0.00001)) { viewinfo[i].pos[j] = viewpos[viewnum][i].pos[j]; viewinfo[i].vel[j] = 0; } else { viewinfo[i].pos[j] += vel; viewinfo[i].vel[j] = vel; } } } } /* flat projection function */ static int project_flat(float *f, int *i, int c) { while (c > 0) { i[0] = view_left + f[0] * (view_right - view_left); i[1] = view_top + f[1] * (view_bottom - view_top); f += 2; i += 2; c -= 2; } return TRUE; } /* spherical coordinate projection function */ static int project_spherical(float *f, int *i, int c) { while (c > 0) { float ang = f[0] * M_PI * 2.0; float xsize = view_right - view_left; float ysize = view_bottom - view_top; float size = MIN(xsize, ysize) / 2.0; float ff = (f[1] > 0.99) ? 0 : (1.0 - f[1] * 0.9); float dx = cos(ang) * ff * size; float dy = sin(ang) * ff * size; i[0] = dx + (view_left + view_right) / 2.0; i[1] = dy + (view_top + view_bottom) / 2.0; f += 2; i += 2; c -= 2; } return TRUE; } /* inside of tube projection function */ static int project_tube(float *f, int *i, int c) { while (c > 0) { float ang = f[0] * M_PI * 2.0 + M_PI / 2.0; float xsize = view_right - view_left; float ysize = view_bottom - view_top; float size = MIN(xsize, ysize) / 2.0; float x = cos(ang); float y = sin(ang); float z = 1.0 + (1.0 - f[1]) * 8.0; i[0] = x/z * size + (view_left + view_right) / 2.0; i[1] = y/z * size + (view_top + view_bottom) / 2.0; f += 2; i += 2; c -= 2; } return TRUE; } /* outside of cylinder projection function */ static int project_cylinder(float *f, int *i, int c) { static MATRIX_f mtx; static int virgin = TRUE; if (virgin) { MATRIX_f m1, m2; get_z_rotate_matrix_f(&m1, -64); qtranslate_matrix_f(&m1, 0, 1.75, 0); get_scaling_matrix_f(&m2, 2.0, 1.0, 1.0); matrix_mul_f(&m1, &m2, &mtx); virgin = FALSE; } while (c > 0) { float ang = (f[0] - player_pos()) * M_PI * 2.0; float xsize = view_right - view_left; float ysize = view_bottom - view_top; float size = MIN(xsize, ysize) / 2.0; float x = cos(ang); float y = sin(ang); float z = 1.0 + (1.0 - f[1]) * 4.0; float xout, yout, zout; apply_matrix_f(&mtx, x, y, z, &xout, &yout, &zout); if (yout > 1.5) return FALSE; i[0] = xout/zout * size + (view_left + view_right) / 2.0; i[1] = (yout/zout * 2 - 1) * size + (view_top + view_bottom) / 2.0; f += 2; i += 2; c -= 2; } return TRUE; } /* draws the entire view */ void draw_view() { int SCREEN_W = al_get_display_width(screen); int SCREEN_H = al_get_display_height(screen); int (*project)(float *f, int *i, int c); int r, g, b; ALLEGRO_COLOR c; int i, n, x, y; float point[6]; int ipoint[6]; al_clear_to_color(makecol(0, 0, 0)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (i=0; i<4; i++) { view_left = viewinfo[i].pos[0] * SCREEN_W; view_top = viewinfo[i].pos[1] * SCREEN_H; view_right = viewinfo[i].pos[2] * SCREEN_W; view_bottom = viewinfo[i].pos[3] * SCREEN_H; if ((view_right > view_left) && (view_bottom > view_top) && (view_right > 0) && (view_bottom > 0) && (view_left < SCREEN_W) && (view_top < SCREEN_H)) { switch (i) { case 0: /* flat projection, green */ project = project_flat; r = 0; g = 255; b = 0; break; case 1: /* spherical coordinates, yellow */ project = project_spherical; r = 255; g = 255; b = 0; break; case 2: /* inside a tube, blue */ project = project_tube; r = 0; g = 0; b = 255; break; case 3: /* surface of cylinder, red */ project = project_cylinder; r = 255; g = 0; b = 0; break; default: /* oops! */ assert(FALSE); return; } if (!no_grid) { c = makecol(r/5, g/5, b/5); n = (low_detail) ? 8 : 16; for (x=0; x<=n; x++) { for (y=0; y<=n; y++) { point[0] = (float)x / n; point[1] = (float)y / n; point[2] = (float)(x+1) / n; point[3] = (float)y / n; point[4] = (float)x / n; point[5] = (float)(y+1) / n; if (project(point, ipoint, 6)) { if (x < n) line(ipoint[0], ipoint[1], ipoint[2], ipoint[3], c); if ((y < n) && ((x < n) || (i == 0))) line(ipoint[0], ipoint[1], ipoint[4], ipoint[5], c); } } } } draw_player(r, g, b, project); draw_badguys(r, g, b, project); draw_bullets(r, g, b, project); draw_explode(r, g, b, project); } } solid_mode(); draw_message(); textprintf(font_video, 4, 4, makecol(128, 128, 128), "Lives: %d", lives); textprintf(font_video, 4, 16, makecol(128, 128, 128), "Score: %d", score); textprintf(font_video, 4, 28, makecol(128, 128, 128), "Hiscore: %d", get_hiscore()); al_flip_display(); } allegro-5.0.10/demos/speed/bullets.c0000644000175000001440000000603511355053771016446 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Bullet animation and display routines. */ #include #include #include #include "speed.h" /* bullet info */ typedef struct BULLET { float x; float y; struct BULLET *next; } BULLET; static BULLET *bullets; /* interface for the aliens to query bullet positions */ void *get_first_bullet(float *x, float *y) { if (!bullets) return NULL; *x = bullets->x; *y = bullets->y; return bullets; } /* interface for the aliens to query bullet positions */ void *get_next_bullet(void *b, float *x, float *y) { BULLET *bul = ((BULLET *)b)->next; if (!bul) return NULL; *x = bul->x; *y = bul->y; return bul; } /* interface for the aliens to get rid of bullets when they explode */ void kill_bullet(void *b) { ((BULLET *)b)->y = -65536; } /* initialises the bullets functions */ void init_bullets() { bullets = NULL; } /* closes down the bullets module */ void shutdown_bullets() { BULLET *b; while (bullets) { b = bullets; bullets = bullets->next; free(b); } } /* fires a new bullet */ void fire_bullet() { BULLET *b = malloc(sizeof(BULLET)); b->x = player_pos(); b->y = 0.96; b->next = bullets; bullets = b; sfx_shoot(); } /* updates the bullets position */ void update_bullets() { BULLET **p = &bullets; BULLET *b = bullets; BULLET *tmp; while (b) { b->y -= 0.025; if (b->y < 0) { *p = b->next; tmp = b; b = b->next; free(tmp); } else { p = &b->next; b = b->next; } } } /* draws the bullets */ void draw_bullets(int r, int g, int b, int (*project)(float *f, int *i, int c)) { BULLET *bul = bullets; ALLEGRO_COLOR c1 = makecol(128+r/2, 128+g/2, 128+b/2); ALLEGRO_COLOR c2 = (g) ? makecol(r/5, g/5, b/5) : makecol(r/4, g/4, b/4); float shape[6]; int ishape[6]; int i; while (bul) { if (bul->y > 0) { shape[0] = bul->x - 0.005; shape[1] = bul->y + 0.01; shape[2] = bul->x + 0.005; shape[3] = bul->y + 0.01; shape[4] = bul->x; shape[5] = bul->y - 0.015; if (project(shape, ishape, 6)) { polygon(3, ishape, c1); if (!low_detail) { float cx = (ishape[0] + ishape[2] + ishape[4]) / 3; float cy = (ishape[1] + ishape[3] + ishape[5]) / 3; float boxx[4] = { -1, -1, 1, 1 }; float boxy[4] = { -1, 1, 1, -1 }; for (i=0; i<4; i++) { float rot = ((int)(bul->x*256) & 1) ? bul->y : -bul->y; float tx = cos(rot)*boxx[i] + sin(rot)*boxy[i]; float ty = sin(rot)*boxx[i] - cos(rot)*boxy[i]; boxx[i] = tx * bul->y * view_size() / 8; boxy[i] = ty * bul->y * view_size() / 8; } line(cx+boxx[0], cy+boxy[0], cx+boxx[1], cy+boxy[1], c2); line(cx+boxx[1], cy+boxy[1], cx+boxx[2], cy+boxy[2], c2); line(cx+boxx[2], cy+boxy[2], cx+boxx[3], cy+boxy[3], c2); line(cx+boxx[3], cy+boxy[3], cx+boxx[0], cy+boxy[0], c2); } } } bul = bul->next; } } allegro-5.0.10/demos/speed/message.c0000644000175000001440000000310511411645364016411 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Text message displaying functions. */ #include #include #include "speed.h" typedef struct MESSAGE { char text[80]; int time; float x; float y; struct MESSAGE *next; } MESSAGE; static MESSAGE *msg; /* initialises the message functions */ void init_message() { msg = NULL; } /* closes down the message module */ void shutdown_message() { MESSAGE *m; while (msg) { m = msg; msg = msg->next; free(m); } } /* adds a new message to the display */ void message(char *text) { MESSAGE *m = malloc(sizeof(MESSAGE)); strcpy(m->text, text); m->time = 0; m->x = 0; m->y = 0; m->next = msg; msg = m; } /* updates the message position */ void update_message() { int SCREEN_W = al_get_display_width(screen); int SCREEN_H = al_get_display_height(screen); MESSAGE **p = &msg; MESSAGE *m = msg; MESSAGE *tmp; int y = SCREEN_H/2; while (m) { if (m->time < 100) { m->x *= 0.9; m->x += (float)SCREEN_W * 0.05; } else { m->x += (m->time - 100); } m->y *= 0.9; m->y += y * 0.1; m->time++; if (m->x > SCREEN_W + strlen(m->text)/4) { *p = m->next; tmp = m; m = m->next; free(tmp); } else { p = &m->next; m = m->next; } y += 16; } } /* draws messages */ void draw_message() { MESSAGE *m = msg; while (m) { textout_centre(font_video, m->text, m->x, m->y, makecol(255, 255, 255)); m = m->next; } } allegro-5.0.10/demos/speed/player.c0000644000175000001440000001234711355053771016273 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Main player control functions. */ #include #include #include #include "speed.h" /* how many lives do we have left? */ int lives; /* counters for various time delays */ static int init_time; static int die_time; static int fire_time; /* current position and velocity */ static float pos; static float vel; /* which segments of health we currently possess */ #define SEGMENTS 16 static int ganja[SEGMENTS]; /* Did you ever come across a DOS shareware game called "Ganja Farmer"? * It is really very cool: you have to protect your crop from "Da Man", * who is trying to bomb it, spray it with defoliants, etc. Superb * reggae soundtrack, and the gameplay concept here is kind of similar, * hence my variable names... */ /* tell other people where we are */ float player_pos() { return pos; } /* tell other people where to avoid us */ float find_target(float x) { int seg = (int)(x * SEGMENTS) % SEGMENTS; int i, j; if (seg < 0) seg += SEGMENTS; for (i=0; i= 0.97) { int seg = (int)(x * SEGMENTS) % SEGMENTS; if (ganja[seg]) { ganja[seg] = FALSE; explode(x, 0.98, 1); sfx_explode_block(); } ret = TRUE; } if ((y >= 0.95) && (!init_time) && (!die_time) && (!cheat)) { float d = pos - x; if (d < -0.5) d += 1; else if (d > 0.5) d -= 1; if (ABS(d) < 0.06) { die_time = 128; explode(x, 0.98, 2); explode(x, 0.98, 4); sfx_explode_player(); message("Ship Destroyed"); ret = TRUE; } } return ret; } /* initialises the player functions */ void init_player() { int i; lives = 3; init_time = 128; die_time = 0; fire_time = 0; pos = 0.5; vel = 0; for (i=0; i 0) && (score > get_hiscore()) && (old_score <= get_hiscore())) { message("New Record Score!"); sfx_ping(3); } else if ((bonus == SEGMENTS) || (cycle)) { sfx_ping(1); } } /* updates the player position */ int update_player() { poll_input(); /* quit game? */ if (key[ALLEGRO_KEY_ESCAPE]) return -1; /* safe period while initing */ if (init_time) init_time--; /* blown up? */ if (die_time) { die_time--; if (!die_time) { lives--; if (!lives) return 1; init_time = 128; pos = 0.5; vel = 0; if (lives == 1) message("This Is Your Final Life"); else message("One Life Remaining"); } } /* handle user left/right input */ if (!die_time) { if ((joy_left) || (key[ALLEGRO_KEY_LEFT])) vel -= 0.005; if ((joy_right) || (key[ALLEGRO_KEY_RIGHT])) vel += 0.005; } /* move left and right */ pos += vel; if (pos >= 1.0) pos -= 1.0; if (pos < 0.0) pos += 1.0; vel *= 0.67; /* fire bullets */ if ((!die_time) && (!init_time) && (!fire_time)) { if ((key[ALLEGRO_KEY_SPACE]) || (joy_b1)) { fire_bullet(); fire_time = 24; } } if (fire_time) fire_time--; return 0; } /* draws the player */ void draw_player(int r, int g, int b, int (*project)(float *f, int *i, int c)) { float shape[12]; int ishape[12]; int i; /* draw health segments */ for (i=0; i #include #include #include #include #include "speed.h" #define NUM_SCORES 8 #define MAX_NAME_LEN 24 /* the score table */ static int scores[NUM_SCORES] = { 666, 512, 440, 256, 192, 128, 64, 42 }; static char names[NUM_SCORES][MAX_NAME_LEN+1]; static char yourname[MAX_NAME_LEN+1] = ""; /* initialises the hiscore system */ void init_hiscore() { ALLEGRO_PATH *path; ALLEGRO_CONFIG *cfg; char buf1[256]; int i; path = al_get_standard_path(ALLEGRO_USER_DATA_PATH); if (!path) return; al_make_directory(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); al_set_path_filename(path, "speed.rec"); cfg = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); if (!cfg) cfg = al_create_config(); for (i=0; i scores[i]) { for (j=NUM_SCORES-1; j>i; j--) { scores[j] = scores[j-1]; strcpy(names[j], names[j-1]); } scores[i] = score; strcpy(names[i], yourname); myscore = i; break; } } bmp = create_memory_bitmap(SCREEN_W, SCREEN_H); al_set_target_bitmap(bmp); for (i=0; i= 0) draw_entry_box(myscore, 0); bmp = replace_bitmap(bmp); al_set_target_bitmap(al_get_backbuffer(screen)); start_retrace_count(); for (i=0; i<=SCREEN_H/16; i++) { al_clear_to_color(makecol(0, 0, 0)); for (j=0; j<=16; j++) { x = j*(SCREEN_W/16); al_draw_bitmap_region(bmp, x, 0, i, SCREEN_H, x, 0, 0); y = j*(SCREEN_H/16); al_draw_bitmap_region(bmp, 0, y, SCREEN_W, i, 0, y, 0); } al_flip_display(); do { poll_input_wait(); } while (retrace_count() < i*512/SCREEN_W); } while (joy_b1 || key[ALLEGRO_KEY_SPACE] || key[ALLEGRO_KEY_ENTER] || key[ALLEGRO_KEY_ESCAPE]) poll_input_wait(); if (myscore >= 0) { clear_keybuf(); for (;;) { poll_input_wait(); if ((joy_b1) && (yourname[0])) { strcpy(names[myscore], yourname); break; } if (keypressed()) { c = readkey(); if (((c >> 8) == ALLEGRO_KEY_ENTER) && (yourname[0])) { strcpy(names[myscore], yourname); sfx_explode_player(); break; } else if (((c >> 8) == ALLEGRO_KEY_ESCAPE) && (names[myscore][0])) { strcpy(yourname, names[myscore]); sfx_ping(2); break; } else if (((c >> 8) == ALLEGRO_KEY_BACKSPACE) && (strlen(yourname) > 0)) { yourname[strlen(yourname)-1] = 0; sfx_shoot(); } else if (((c & 0xFF) >= ' ') && ((c & 0xFF) <= '~') && (strlen(yourname) < MAX_NAME_LEN)) { yourname[strlen(yourname)+1] = 0; yourname[strlen(yourname)] = (c & 0xFF); sfx_explode_alien(); } } al_draw_bitmap(bmp, 0, 0, 0); draw_entry_box(myscore, retrace_count()); al_flip_display(); } } else { while (!key[ALLEGRO_KEY_SPACE] && !key[ALLEGRO_KEY_ENTER] && !key[ALLEGRO_KEY_ESCAPE] && !joy_b1) { poll_input_wait(); al_draw_bitmap(bmp, 0, 0, 0); al_flip_display(); } sfx_ping(2); } stop_retrace_count(); al_destroy_bitmap(bmp); } /* returns the best score, for other modules to display */ int get_hiscore() { return scores[0]; } allegro-5.0.10/demos/speed/speed.txt0000644000175000001440000001447111355053656016476 0ustar tjadenusers SPEED: Simultaneous Projections Employing an Ensemble of Displays. Or alternatively: Stupid Pointless Effort at Establishing a Dumb Acronym. By Shawn Hargreaves, November 1999. This program is my entry for the Allegro SpeedHack 1999, and was written over the weekend of November 27/28. Many thanks to Arron Shutt for organising this competition, and to the various musicians who kept me sane (?) during it (notably Trent Reznor, Adrian Belew, Charles Mingus, Miles Davis, Mike Keneally, and Robert Fripp). It should be pretty obvious how to play, as long as you know how to press the spacebar and left/right arrow keys. The objective is to protect the blocks underneath your ship: you get one point for each block left at the end of an attack wave, and a hundred bonus points if you manage to preserve all sixteen blocks. Hint: the later levels of this game are much easier to play if you view them through tinted glasses, to filter out only one of the views :-) You gain very little from running it in a truecolor mode (the title screens look a bit nicer, but game graphics are almost identical to in 8 bit color). It does look very cramped in a 320x200 resolution, though, so I recommend playing it in 640x480x8. This code is free: do with it as you will. The remainder of this file is a realtime log, with entries added chronologically during the course of the hack. The numbered subdirectories contain snapshots of the code taken at various times over the weekend. It is unlikely that anything but the final version will compile on systems other than Linux. 10-26-1999, at 14:56 -------------------- I've written myself a makefile, and a script which ought to be able to send this message to the website automatically. If you see this text, then it worked! 10-26-1999, at 15:18 -------------------- Design doc: Traditional Space Invaders type gameplay: aliens move down the screen, you move across the bottom firing upwards. Three lives. Your goal is to protect blocks underneath you, and you get score for having blocks left at the end of each attack wave. Alien motion will be as complex as I have time for, including Centipede style splitting. This 2d action will be rendered in four different psuedo-3d viewports: normal flat mode, inside of a tube, outside of a large cylinder, and in spherical coordinates. Early attack waves use only one viewpoint, later ones tile multiple views of the same action, and toward the end of the sequence the views are overlaid (additive color). If you complete the sequence, it cycles but with vastly increased game speed. When changing attack waves, views will slide around to their new locations (that should look pretty cool). Any color depth, any resolution. No time for drawing graphics, so everything will be simple vector art. Bullets are surrounded by spining wireframe square, flightsim targetting style. Explosions are expanding XLU circlefill, plus more rapidly expanding single circle shockwaves. Wow, I think that is the most detailed formal game design that I have ever written! I don't have time for this, better get coding... 10-26-1999, at 17:37 -------------------- Basic game structure is in place: init code, commandline parsing, title screen, stupid little music bit at the end. 10-27-1999, at 10:21 -------------------- 10:30 AM on saturday morning: just got out of bed and am ready to start some serious work. Title and ending screens are finished, so it is just the game itself left to be written! 10-27-1999, at 13:14 -------------------- Lots of new source files added: 3d viewport system is in place (sliding screen windows and all but one of the 3d projections). 10-27-1999, at 14:04 -------------------- Player movement is in, so you can see the different projections in action... 10-27-1999, at 15:08 -------------------- Added text messages (for status display, number of lives left, etc) that float over the middle of the screen, and implemented the final 3d projection mode, so all the different views are working now. 10-27-1999, at 16:17 -------------------- Bullet code is finished. 10-27-1999, at 17:55 -------------------- Enemies are in, and you can shoot them now. Still todo: more interesting enemy movememnt, you dying. This is going faster than I expected, so I should be able to get that finished this evening, and then have tomorrow free either to relax, or perhaps to add sound and a hiscore table... 10-27-1999, at 19:18 -------------------- You can die now, and the scoring mechanism is complete. 10-27-1999, at 22:55 -------------------- Enemy wave patterns are finished! It is a table-driven system, with a cycle of 26 different attack patterns before the thing repeats. I've just finished typing in all the tables, so the game can now be played the whole way through, ie. the gameplay side of things is complete! All that remains is cosmetic tweaking (sound, hiscore, etc). 10-28-1999, at 00:02 -------------------- Various tweaks to get it working with djgpp, MSVC, and Watcom (I've been developing in X up until now). 10-28-1999, at 13:42 -------------------- Scoretable is finished. Unfortunately this thing has reached the point where it is actually quite fun to play, which is getting in the way of my actually finishing it :-) 10-28-1999, at 15:40 -------------------- Some (really cheesy old-skool arcade style :-) sound effects are in. 10-28-1999, at 19:43 -------------------- Music is finished! And that means, the whole thing is pretty much complete. I just need to test that it still works in DOS/Windows, and take some screenshots, and then I can upload it. Yippee! And it is still pretty early on Sunday evening... The music is quite possibly even more crap than the sound effects, which is quite an achievement! The goal was to avoid using any external resources at all, which means that all graphics and sounds have to be written as pure C code in a text editor. In other words, sound samples are generated from basic waveforms, and I typed in all the music notes as data tables. I haven't done that since the old days on my 8 bit Oric machine, but it was quite satisfying. The results don't sound _quite_ up to what you can do with more capable sound editing tools, but hey, for an arrangement done entirely inside a text editor, I don't think this is too bad :-) Stay tuned for an upload of the final version... The End. allegro-5.0.10/demos/speed/a4_aux.h0000644000175000001440000000550112137075110016145 0ustar tjadenusers#ifndef __A4_AUX_H__ #define __A4_AUX_H__ #ifndef TRUE #define TRUE -1 #define FALSE 0 #endif #undef MIN #undef MAX #undef MID #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #undef ABS #define ABS(x) (((x) >= 0) ? (x) : (-(x))) #undef SGN #define SGN(x) (((x) >= 0) ? 1 : -1) typedef struct MATRIX_f /* transformation matrix (floating point) */ { float v[3][3]; /* scaling and rotation */ float t[3]; /* translation */ } MATRIX_f; /* global variables */ extern int key[ALLEGRO_KEY_MAX]; extern int joy_left; extern int joy_right; extern int joy_b1; extern struct ALLEGRO_DISPLAY *screen; extern struct ALLEGRO_FONT *font; extern struct ALLEGRO_FONT *font_video; const char *get_config_string(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, const char *def); int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, int def); void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, int val); void init_input(); void shutdown_input(); void poll_input(); void poll_input_wait(); int keypressed(); int readkey(); void clear_keybuf(); ALLEGRO_BITMAP *create_memory_bitmap(int w, int h); ALLEGRO_BITMAP *replace_bitmap(ALLEGRO_BITMAP *bmp); void solid_mode(); ALLEGRO_COLOR makecol(int r, int g, int b); void hline(int x1, int y, int x2, ALLEGRO_COLOR c); void vline(int x, int y1, int y2, ALLEGRO_COLOR c); void line(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color); void rectfill(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color); void circle(int x, int y, int radius, ALLEGRO_COLOR color); void circlefill(int x, int y, int radius, ALLEGRO_COLOR color); void stretch_sprite(ALLEGRO_BITMAP *bmp, ALLEGRO_BITMAP *sprite, int x, int y, int w, int h); void polygon(int vertices, const int *points, ALLEGRO_COLOR color); void textout(struct ALLEGRO_FONT const *font, const char *s, int x, int y, ALLEGRO_COLOR c); void textout_centre(struct ALLEGRO_FONT const *font, const char *s, int x, int y, ALLEGRO_COLOR c); void textprintf(struct ALLEGRO_FONT const *f, int x, int y, ALLEGRO_COLOR color, const char *fmt, ...); void get_scaling_matrix_f(MATRIX_f *m, float x, float y, float z); void get_z_rotate_matrix_f(MATRIX_f *m, float r); void qtranslate_matrix_f(MATRIX_f *m, float x, float y, float z); void matrix_mul_f(const MATRIX_f *m1, const MATRIX_f *m2, MATRIX_f *out); void apply_matrix_f(const MATRIX_f *m, float x, float y, float z, float *xout, float *yout, float *zout); void start_retrace_count(); void stop_retrace_count(); int64_t retrace_count(); void rest(unsigned int time); struct ALLEGRO_SAMPLE *create_sample_u8(int freq, int len); void play_sample(struct ALLEGRO_SAMPLE *spl, int vol, int pan, int freq, int loop); #endif /* __A4_AUX_H__ */ allegro-5.0.10/demos/speed/title.c0000644000175000001440000001716512115575734016126 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Title screen and results display. */ #include #include #include #include #include #include #include "speed.h" /* draws text with a dropshadow */ static void textout_shadow(char *msg, int x, int y, ALLEGRO_COLOR c) { textout_centre(font, msg, x+1, y+1, makecol(0, 0, 0)); textout_centre(font, msg, x, y, c); } /* display the title screen */ int title_screen() { int SCREEN_W = al_get_display_width(screen); int SCREEN_H = al_get_display_height(screen); ALLEGRO_BITMAP *bmp, *b; ALLEGRO_COLOR white = makecol(255, 255, 255); int i, j, y; bmp = create_memory_bitmap(SCREEN_W, SCREEN_H); al_set_target_bitmap(bmp); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); for (i=0; i #include #include #include #include #include #include "a4_aux.h" /* * Configuration files */ /* emulate get_config_string() */ const char *get_config_string(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, const char *def) { const char *v = al_get_config_value(cfg, section, name); return (v) ? v : def; } /* emulate get_config_int() */ int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, int def) { const char *v = al_get_config_value(cfg, section, name); return (v) ? atoi(v) : def; } /* emulate set_config_int() */ void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, int val) { char buf[32]; sprintf(buf, "%d", val); al_set_config_value(cfg, section, name, buf); } /* * Input routines */ #define MAX_KEYBUF 16 int key[ALLEGRO_KEY_MAX]; int joy_left; int joy_right; int joy_b1; static int keybuf[MAX_KEYBUF]; static int keybuf_len = 0; static ALLEGRO_MUTEX *keybuf_mutex; static ALLEGRO_EVENT_QUEUE *input_queue; /* initialises the input emulation */ void init_input() { ALLEGRO_JOYSTICK *joy; keybuf_len = 0; keybuf_mutex = al_create_mutex(); input_queue = al_create_event_queue(); al_register_event_source(input_queue, al_get_keyboard_event_source()); al_register_event_source(input_queue, al_get_display_event_source(screen)); if (al_get_num_joysticks() > 0) { joy = al_get_joystick(0); if (joy) al_register_event_source(input_queue, al_get_joystick_event_source()); } } /* closes down the input emulation */ void shutdown_input() { al_destroy_mutex(keybuf_mutex); keybuf_mutex = NULL; al_destroy_event_queue(input_queue); input_queue = NULL; } /* helper function to add a keypress to a buffer */ static void add_key(ALLEGRO_KEYBOARD_EVENT *event) { if ((event->unichar == 0) || (event->unichar > 255)) return; al_lock_mutex(keybuf_mutex); if (keybuf_len < MAX_KEYBUF) { keybuf[keybuf_len] = event->unichar | ((event->keycode << 8) & 0xff00); keybuf_len++; } al_unlock_mutex(keybuf_mutex); } /* emulate poll_keyboard() and poll_joystick() combined */ void poll_input() { ALLEGRO_EVENT event; while (al_get_next_event(input_queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_KEY_DOWN: key[event.keyboard.keycode] = 1; break; case ALLEGRO_EVENT_KEY_UP: key[event.keyboard.keycode] = 0; break; case ALLEGRO_EVENT_KEY_CHAR: add_key(&event.keyboard); break; case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: if (event.joystick.button == 0) joy_b1 = 1; break; case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: if (event.joystick.button == 0) joy_b1 = 0; break; case ALLEGRO_EVENT_JOYSTICK_AXIS: if (event.joystick.stick == 0 && event.joystick.axis == 0) { float pos = event.joystick.pos; joy_left = (pos < 0.0); joy_right = (pos > 0.0); } break; case ALLEGRO_EVENT_TIMER: /* retrace_count incremented */ break; case ALLEGRO_EVENT_DISPLAY_EXPOSE: break; } } } /* blocking version of poll_input(), also wakes on retrace_count */ void poll_input_wait() { al_wait_for_event(input_queue, NULL); poll_input(); } /* emulate keypressed() */ int keypressed() { poll_input(); return keybuf_len > 0; } /* emulate readkey(), except this version never blocks */ int readkey() { int c = 0; poll_input(); al_lock_mutex(keybuf_mutex); if (keybuf_len > 0) { c = keybuf[0]; keybuf_len--; memmove(keybuf, keybuf + 1, sizeof(keybuf[0]) * keybuf_len); } al_unlock_mutex(keybuf_mutex); return c; } /* emulate clear_keybuf() */ void clear_keybuf() { al_lock_mutex(keybuf_mutex); keybuf_len = 0; al_unlock_mutex(keybuf_mutex); } /* * Graphics routines */ #define MAX_POLYGON_VERTICES 6 ALLEGRO_DISPLAY *screen; ALLEGRO_FONT *font; ALLEGRO_FONT *font_video; /* like create_bitmap() */ ALLEGRO_BITMAP *create_memory_bitmap(int w, int h) { int oldflags; int newflags; ALLEGRO_BITMAP *bmp; oldflags = al_get_new_bitmap_flags(); newflags = (oldflags &~ ALLEGRO_VIDEO_BITMAP) | ALLEGRO_MEMORY_BITMAP; al_set_new_bitmap_flags(newflags); bmp = al_create_bitmap(w, h); al_set_new_bitmap_flags(oldflags); return bmp; } /* used to clone a video bitmap from a memory bitmap; no such function in A4 */ ALLEGRO_BITMAP *replace_bitmap(ALLEGRO_BITMAP *bmp) { ALLEGRO_BITMAP *tmp = al_clone_bitmap(bmp); al_destroy_bitmap(bmp); return tmp; } /* approximate solid_mode() function, but we we use alpha for transparent * pixels instead of a mask color */ void solid_mode() { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); } /* emulate makecol() */ ALLEGRO_COLOR makecol(int r, int g, int b) { return al_map_rgb(r, g, b); } /* emulate hline() */ void hline(int x1, int y, int x2, ALLEGRO_COLOR c) { al_draw_line(x1+0.5, y+0.5, x2+0.5, y+0.5, c, 1); } /* emulate vline() */ void vline(int x, int y1, int y2, ALLEGRO_COLOR c) { al_draw_line(x+0.5, y1+0.5, x+0.5, y2+0.5, c, 1); } /* emulate line() */ void line(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color) { al_draw_line(x1+0.5, y1+0.5, x2+0.5, y2+0.5, color, 1); } /* emulate rectfill() */ void rectfill(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color) { al_draw_filled_rectangle(x1, y1, x2+1, y2+1, color); } /* emulate circle() */ void circle(int x, int y, int radius, ALLEGRO_COLOR color) { al_draw_circle(x+0.5, y+0.5, radius, color, 1); } /* emulate circlefill() */ void circlefill(int x, int y, int radius, ALLEGRO_COLOR color) { al_draw_filled_circle(x+0.5, y+0.5, radius, color); } /* emulate stretch_sprite() */ void stretch_sprite(ALLEGRO_BITMAP *bmp, ALLEGRO_BITMAP *sprite, int x, int y, int w, int h) { ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(bmp); al_draw_scaled_bitmap(sprite, 0, 0, al_get_bitmap_width(sprite), al_get_bitmap_height(sprite), x, y, w, h, 0); al_restore_state(&state); } /* emulate polygon() for convex polygons only */ void polygon(int vertices, const int *points, ALLEGRO_COLOR color) { ALLEGRO_VERTEX vtxs[MAX_POLYGON_VERTICES + 2]; int i; assert(vertices <= MAX_POLYGON_VERTICES); vtxs[0].x = 0.0; vtxs[0].y = 0.0; vtxs[0].z = 0.0; vtxs[0].color = color; vtxs[0].u = 0; vtxs[0].v = 0; for (i = 0; i < vertices; i++) { vtxs[0].x += points[i*2]; vtxs[0].y += points[i*2 + 1]; } vtxs[0].x /= vertices; vtxs[0].y /= vertices; for (i = 1; i <= vertices; i++) { vtxs[i].x = points[0]; vtxs[i].y = points[1]; vtxs[i].z = 0.0; vtxs[i].color = color; vtxs[i].u = 0; vtxs[i].v = 0; points += 2; } vtxs[vertices + 1] = vtxs[1]; al_draw_prim(vtxs, NULL, NULL, 0, vertices + 2, ALLEGRO_PRIM_TRIANGLE_FAN); } /* emulate textout() */ void textout(const ALLEGRO_FONT *font, const char *s, int x, int y, ALLEGRO_COLOR c) { al_draw_text(font, c, x, y, ALLEGRO_ALIGN_LEFT, s); } /* emulate textout_centre() */ void textout_centre(const ALLEGRO_FONT *font, const char *s, int x, int y, ALLEGRO_COLOR c) { al_draw_text(font, c, x, y, ALLEGRO_ALIGN_CENTRE, s); } /* emulate textprintf() */ void textprintf(const ALLEGRO_FONT *f, int x, int y, ALLEGRO_COLOR color, const char *fmt, ...) { va_list ap; char buf[256]; va_start(ap, fmt); #if defined(__WATCOMC__) || defined(_MSC_VER) _vsnprintf(buf, sizeof(buf), fmt, ap); buf[sizeof(buf)-1] = '\0'; #else vsnprintf(buf, sizeof(buf), fmt, ap); #endif va_end(ap); textout(f, buf, x, y, color); } /* * Matrix routines */ static const MATRIX_f identity_matrix_f = { { /* 3x3 identity */ { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, }, /* zero translation */ { 0.0, 0.0, 0.0 } }; /* get_scaling_matrix_f: * Floating point version of get_scaling_matrix(). */ void get_scaling_matrix_f(MATRIX_f *m, float x, float y, float z) { *m = identity_matrix_f; m->v[0][0] = x; m->v[1][1] = y; m->v[2][2] = z; } /* get_z_rotate_matrix_f: * Floating point version of get_z_rotate_matrix(). */ void get_z_rotate_matrix_f(MATRIX_f *m, float r) { float c, s; s = sin(r * ALLEGRO_PI / 128.0); c = cos(r * ALLEGRO_PI / 128.0); *m = identity_matrix_f; m->v[0][0] = c; m->v[0][1] = -s; m->v[1][0] = s; m->v[1][1] = c; } /* qtranslate_matrix_f: * Floating point version of qtranslate_matrix(). */ void qtranslate_matrix_f(MATRIX_f *m, float x, float y, float z) { m->t[0] += x; m->t[1] += y; m->t[2] += z; } /* matrix_mul_f: * Floating point version of matrix_mul(). */ void matrix_mul_f(const MATRIX_f *m1, const MATRIX_f *m2, MATRIX_f *out) { MATRIX_f temp; int i, j; if (m1 == out) { temp = *m1; m1 = &temp; } else if (m2 == out) { temp = *m2; m2 = &temp; } for (i=0; i<3; i++) { for (j=0; j<3; j++) { out->v[i][j] = (m1->v[0][j] * m2->v[i][0]) + (m1->v[1][j] * m2->v[i][1]) + (m1->v[2][j] * m2->v[i][2]); } out->t[i] = (m1->t[0] * m2->v[i][0]) + (m1->t[1] * m2->v[i][1]) + (m1->t[2] * m2->v[i][2]) + m2->t[i]; } } /* apply_matrix_f: * Floating point vector by matrix multiplication routine. */ void apply_matrix_f(const MATRIX_f *m, float x, float y, float z, float *xout, float *yout, float *zout) { #define CALC_ROW(n) (x * m->v[(n)][0] + y * m->v[(n)][1] + z * m->v[(n)][2] + m->t[(n)]) *xout = CALC_ROW(0); *yout = CALC_ROW(1); *zout = CALC_ROW(2); #undef CALC_ROW } /* * Timing routines */ static ALLEGRO_TIMER *retrace_counter = NULL; /* start incrementing retrace_count */ void start_retrace_count() { retrace_counter = al_create_timer(1/70.0); al_register_event_source(input_queue, al_get_timer_event_source(retrace_counter)); al_start_timer(retrace_counter); } /* stop incrementing retrace_count */ void stop_retrace_count() { al_destroy_timer(retrace_counter); retrace_counter = NULL; } /* emulate 'retrace_count' variable */ int64_t retrace_count() { return al_get_timer_count(retrace_counter); } /* emulate rest() */ void rest(unsigned int time) { al_rest(0.001 * time); } /* * Sound routines */ /* emulate create_sample(), for unsigned 8-bit mono samples */ ALLEGRO_SAMPLE *create_sample_u8(int freq, int len) { char *buf = al_malloc(freq * len); return al_create_sample(buf, len, freq, ALLEGRO_AUDIO_DEPTH_UINT8, ALLEGRO_CHANNEL_CONF_1, true); } /* emulate play_sample() */ void play_sample(ALLEGRO_SAMPLE *spl, int vol, int pan, int freq, int loop) { int playmode = loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE; al_play_sample(spl, vol/255.0, (pan - 128)/128.0, freq/1000.0, playmode, NULL); } allegro-5.0.10/demos/speed/port.txt0000644000175000001440000000147011355053771016353 0ustar tjadenusers SPEED: Simultaneous Projections Employing an Ensemble of Displays. By Shawn Hargreaves, November 1999. Allegro 5 port by Peter Wang, April 2010 This is a port of SPEED to Allegro 5. a4_aux.c contains a small "compatibility" layer so that the original code did not need to be disturbed too much. See speed.txt for the original information about the game. Have fun! User-visible changes from the original -------------------------------------- - The game now defaults to a 640x480 screen resolution if you do not supply any command line arguments. - The bpp (colour depth) command line option was removed. - The intersection points in the game grid only appear half as bright as in the original. I'm not sure why, unless it was a bug in Allegro 4.x. Admittedly the brighter pixels looked cooler. allegro-5.0.10/demos/speed/29.txt0000644000175000001440000000402311355053656015620 0ustar tjadenusers The competition rules state that I must "include the number '29' somewhere in the program" (to commemorate it being Arron's birthday). But unfortunately, although the number 29 is certainly a very fine thing to have as the age for an Arron, it didn't strike me as a particularly useful or numerologically significant thing to build into a computer game. However, since the rules do not specify which number base they are talking about, it occurs to me that this could just as well be a reference to the hexadecimal value 0x29, which is decimal 41. Admittedly, this number has nothing to do with the age of the Arron, or at least won't do for another dozen dozens of quartets of weeks, but the rules never actually spell out that they are talking about the particular 29 which happens to be his current age (they strongly imply that, but I decided to look the other way and miss this hint :-) Now, 0x29, when mapped onto the ASCII character set, refers to the closing bracket character, ')'. So in order to comply with the competition rules, I have included several of these symbols in my program. In fact, as reported by the command: sed -e "s/[^)]//g" *.[ch] | tr -d "\n" | wc -c there are currently no less than ONE THOUSAND AND EIGHTY TWO unique occurrences of a twenty nine in this game! This figure is likely to have increased even further by the time you get hold of the code, since I haven't quite finished writing it yet. And there are four more just in this text file, so if you included the documentation in the above search command, that would get you up to a total of 1086 different ')' characters! (and since I just typed another there, that makes it 1087 (and having opened a bracket to interject this, I'm going to have to close it, which makes 1088 (and now that I've opened a nested bracket, we are up to 1089 or something, I'm losing count here))) (btw. I hope I got the right number of closes there). I'm tempted to say that this is all a joke :-) except that by doing so, I've just bumped up the count one more... allegro-5.0.10/demos/speed/badguys.c0000644000175000001440000002321011355053771016424 0ustar tjadenusers/* * SPEED - by Shawn Hargreaves, 1999 * * Enemy control routines (attack waves). */ #include #include #include "speed.h" /* description of an attack wave */ typedef struct WAVEINFO { int count; /* how many to create */ float delay; /* how long to delay them */ float delay_rand; /* random delay factor */ float speed; /* how fast they move */ float speed_rand; /* speed random factor */ float move; /* movement speed */ float move_rand; /* movement random factor */ float sin_depth; /* depth of sine wave motion */ float sin_depth_rand; /* sine depth random factor */ float sin_speed; /* speed of sine wave motion */ float sin_speed_rand; /* sine speed random factor */ int split; /* split into multiple dudes? */ int aggro; /* attack the player? */ int evade; /* evade the player? */ } WAVEINFO; #define END_WAVEINFO { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* attack wave #1 (straight downwards) */ static WAVEINFO wave1[] = { /* c del rnd speed r mv r dp r sd r sp ag ev */ { 4, 0.0, 1.0, 0.0015, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, { 2, 0.7, 0.0, 0.0055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 2, 0.5, 0.0, 0.0045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 4, 0.0, 1.0, 0.0035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 4, 0.0, 1.0, 0.0025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, END_WAVEINFO }; /* attack wave #2 (diagonal motion) */ static WAVEINFO wave2[] = { /* c del rnd speed rnd move rnd dp r sd r sp ag ev */ { 6, 2.0, 1.0, 0.0025, 0.002, 0.0000, 0.020, 0, 0, 0, 0, 0, 0, 0 }, { 6, 1.2, 1.0, 0.0025, 0.001, 0.0000, 0.010, 0, 0, 0, 0, 0, 0, 0 }, { 6, 0.5, 1.0, 0.0025, 0.000, 0.0000, 0.005, 0, 0, 0, 0, 0, 0, 0 }, { 4, 0.0, 1.0, 0.0025, 0.000, -0.0025, 0.000, 0, 0, 0, 0, 0, 0, 0 }, { 4, 0.0, 1.0, 0.0025, 0.000, 0.0025, 0.000, 0, 0, 0, 0, 0, 0, 0 }, END_WAVEINFO }; /* attack wave #3 (sine wave motion) */ static WAVEINFO wave3[] = { /* c del rnd speed rnd mv r sdepth rnd sspd rnd sp ag ev */ { 4, 0.0, 2.0, 0.0020, 0.0000, 0, 0, 0.005, 0.000, 0.020, 0.00, 1, 0, 0 }, { 4, 1.5, 1.0, 0.0016, 0.0024, 0, 0, 0.002, 0.006, 0.010, 0.03, 0, 0, 0 }, { 4, 1.0, 1.0, 0.0019, 0.0016, 0, 0, 0.003, 0.004, 0.015, 0.02, 0, 0, 0 }, { 4, 0.5, 1.0, 0.0022, 0.0008, 0, 0, 0.004, 0.002, 0.020, 0.01, 0, 0, 0 }, { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0, 0.005, 0.000, 0.025, 0.00, 0, 0, 0 }, END_WAVEINFO }; /* attack wave #4 (evade you) */ static WAVEINFO wave4[] = { /* c del rnd speed rnd mv rnd dp r sd r sp ag ev */ { 4, 0.0, 2.0, 0.0020, 0.0000, 0, 0.000, 0, 0, 0, 0, 1, 0, 1 }, { 3, 1.5, 1.0, 0.0016, 0.0024, 0, 0.010, 0, 0, 0, 0, 0, 0, 1 }, { 3, 1.0, 1.0, 0.0019, 0.0016, 0, 0.001, 0, 0, 0, 0, 0, 0, 1 }, { 4, 0.5, 1.0, 0.0022, 0.0008, 0, 0.000, 0, 0, 0, 0, 0, 0, 1 }, { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0.000, 0, 0, 0, 0, 0, 0, 1 }, END_WAVEINFO }; /* attack wave #5 (attack you) */ static WAVEINFO wave5[] = { /* c del rnd speed rnd mv rnd sd r sd r sp ag ev */ { 4, 0.0, 2.0, 0.0010, 0.0000, 0, 0.000, 0, 0, 0, 0, 1, 1, 0 }, { 3, 1.5, 1.0, 0.0016, 0.0024, 0, 0.010, 0, 0, 0, 0, 0, 1, 0 }, { 3, 1.0, 1.0, 0.0019, 0.0016, 0, 0.001, 0, 0, 0, 0, 0, 1, 0 }, { 3, 0.5, 1.0, 0.0022, 0.0008, 0, 0.000, 0, 0, 0, 0, 0, 1, 0 }, { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0.000, 0, 0, 0, 0, 0, 1, 0 }, END_WAVEINFO }; /* attack wave #6 (the boss wave, muahaha) */ static WAVEINFO wave6[] = { /* c del rnd speed rnd mv rnd dp rnd sd rnd sp ag ev */ { 8, 6.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 1, 0 }, { 8, 4.5, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 0, 1 }, { 8, 3.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0.006, 0, 0.03, 1, 0, 0 }, { 8, 1.5, 2.0, 0.002, 0.001, 0, 0.01, 0, 0, 0, 0, 1, 0, 0 }, { 8, 0.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 0, 0 }, END_WAVEINFO }; /* list of available attack waves */ static WAVEINFO *waveinfo[] = { wave1+4, wave2+4, wave3+4, wave4+4, wave5+4, wave1+3, wave2+3, wave3+3, wave4+3, wave5+3, wave1+2, wave2+2, wave3+2, wave4+2, wave5+2, wave1+1, wave2+1, wave3+1, wave4+1, wave5+1, wave1+0, wave2+0, wave3+0, wave4+0, wave5+0, wave6 }; /* info about someone nasty */ typedef struct BADGUY { float x; /* x position */ float y; /* y position */ float speed; /* vertical speed */ float move; /* horizontal motion */ float sin_depth; /* depth of sine motion */ float sin_speed; /* speed of sine motion */ int split; /* whether to split ourselves */ int aggro; /* whether to attack the player */ int evade; /* whether to evade the player */ float v; /* horizontal velocity */ int t; /* integer counter */ struct BADGUY *next; } BADGUY; static BADGUY *evildudes; static int finished_counter; static int wavenum; /* creates a new swarm of badguys */ void lay_attack_wave(int reset) { WAVEINFO *info; BADGUY *b; int i; if (reset) { wavenum = 0; } else { wavenum++; if (wavenum >= (int)(sizeof(waveinfo)/sizeof(WAVEINFO *))) wavenum = 0; } info = waveinfo[wavenum]; while (info->count) { for (i=0; icount; i++) { b = malloc(sizeof(BADGUY)); #define URAND ((float)(rand() & 255) / 255.0) #define SRAND (((float)(rand() & 255) / 255.0) - 0.5) b->x = URAND; b->y = -info->delay - URAND * info->delay_rand; b->speed = info->speed + URAND * info->speed_rand; b->move = info->move + SRAND * info->move_rand; b->sin_depth = info->sin_depth + URAND * info->sin_depth_rand; b->sin_speed = info->sin_speed + URAND * info->sin_speed_rand; b->split = info->split; b->aggro = info->aggro; b->evade = info->evade; b->v = 0; b->t = rand() & 255; b->next = evildudes; evildudes = b; } info++; } finished_counter = 0; } /* initialises the badguy functions */ void init_badguys() { evildudes = NULL; lay_attack_wave(TRUE); } /* closes down the badguys module */ void shutdown_badguys() { BADGUY *b; while (evildudes) { b = evildudes; evildudes = evildudes->next; free(b); } } /* updates the badguy position */ int update_badguys() { BADGUY **p = &evildudes; BADGUY *b = evildudes; BADGUY *tmp1, *tmp2; void *bullet; float x, y, d; int dead; /* testcode: enter clears the level */ if ((cheat) && (key[ALLEGRO_KEY_ENTER])) { shutdown_badguys(); b = NULL; while (key[ALLEGRO_KEY_ENTER]) poll_input_wait(); } while (b) { dead = FALSE; if (b->aggro) { /* attack the player */ d = player_pos() - b->x; if (d < -0.5) d += 1; else if (d > 0.5) d -= 1; if (b->y < 0.5) d = -d; b->v *= 0.99; b->v += SGN(d) * 0.00025; } else if (b->evade) { /* evade the player */ if (b->y < 0.75) d = player_pos() + 0.5; else d = b->x; if (b->move) d += SGN(b->move) / 16.0; d = find_target(d) - b->x; if (d < -0.5) d += 1; else if (d > 0.5) d -= 1; b->v *= 0.96; b->v += SGN(d) * 0.0004; } /* horizontal move */ b->x += b->move + sin(b->t * b->sin_speed) * b->sin_depth + b->v; if (b->x < 0) b->x += 1; else if (b->x > 1) b->x -= 1; /* vertical move */ b->y += b->speed; if ((b->y > 0.5) && (b->y - b->speed <= 0.5) && (b->split)) { /* split ourselves */ tmp1 = malloc(sizeof(BADGUY)); tmp2 = malloc(sizeof(BADGUY)); *tmp1 = *tmp2 = *b; tmp1->move -= 0.001; tmp2->move += 0.001; b->speed += 0.001; tmp1->t = rand() & 255; tmp2->t = rand() & 255; tmp1->next = tmp2; tmp2->next = evildudes; evildudes = tmp1; } b->t++; if (b->y > 0) { if (kill_player(b->x, b->y)) { /* did we hit someone? */ dead = TRUE; } else { /* or did someone else hit us? */ bullet = get_first_bullet(&x, &y); while (bullet) { x = x - b->x; if (x < -0.5) x += 1; else if (x > 0.5) x -= 1; x = ABS(x); y = ABS(y - b->y); if (x < y) d = y/2 + x; else d = x/2 + y; if (d < 0.025) { kill_bullet(bullet); explode(b->x, b->y, 0); sfx_explode_alien(); dead = TRUE; break; } bullet = get_next_bullet(bullet, &x, &y); } } } /* advance to the next dude */ if (dead) { *p = b->next; tmp1 = b; b = b->next; free(tmp1); } else { p = &b->next; b = b->next; } } if ((!evildudes) && (!player_dying())) { if (!finished_counter) { message("Wave Complete"); sfx_ping(0); } finished_counter++; if (finished_counter > 64) return TRUE; } return FALSE; } /* draws the badguys */ void draw_badguys(int r, int g, int b, int (*project)(float *f, int *i, int c)) { BADGUY *bad = evildudes; ALLEGRO_COLOR c = makecol(r, g, b); float shape[12]; int ishape[12]; while (bad) { if (bad->y > 0) { shape[0] = bad->x - 0.02; shape[1] = bad->y + 0.01; shape[2] = bad->x; shape[3] = bad->y + 0.02; shape[4] = bad->x + 0.02; shape[5] = bad->y + 0.01; shape[6] = bad->x + 0.01; shape[7] = bad->y + 0.005; shape[8] = bad->x; shape[9] = bad->y - 0.015; shape[10] = bad->x - 0.01; shape[11] = bad->y + 0.005; if (project(shape, ishape, 12)) polygon(6, ishape, c); } bad = bad->next; } } allegro-5.0.10/CONTRIBUTORS.txt0000644000175000001440000000070211467730603015112 0ustar tjadenusersPeople who have contributed code to Allegro 5: Angelo Mottola Chris Robinson David Capello Dennis Busch Elias Pschernig Evert Glebbeek John-Kim Murphy Jon Rafkind Matthew Leverton Michał Cichoń Milan Mimica Paul Suntsov Peter Hull Peter Wang Ryan Dickie Ryan Patterson Steven Wallace Thomas Fjellstrom Todd Cope Trent Gamblin Please let us know if we left anyone out. We must also thank everyone who contributed to previous versions of Allegro! allegro-5.0.10/allegro.mft0000644000175000001440000017452512157230723014563 0ustar tjadenusersallegro/ allegro/addons/ allegro/addons/acodec/ allegro/addons/acodec/acodec.c allegro/addons/acodec/acodec.h allegro/addons/acodec/allegro5/ allegro/addons/acodec/allegro5/allegro_acodec.h allegro/addons/acodec/allegro5/internal/ allegro/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake allegro/addons/acodec/CMakeLists.txt allegro/addons/acodec/flac.c allegro/addons/acodec/helper.c allegro/addons/acodec/helper.h allegro/addons/acodec/modaudio.c allegro/addons/acodec/ogg.c allegro/addons/acodec/wav.c allegro/addons/audio/ allegro/addons/audio/allegro5/ allegro/addons/audio/allegro5/allegro_audio.h allegro/addons/audio/allegro5/internal/ allegro/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake allegro/addons/audio/allegro5/internal/aintern_audio.h allegro/addons/audio/alsa.c allegro/addons/audio/aqueue.m allegro/addons/audio/audio.c allegro/addons/audio/audio_io.c allegro/addons/audio/CMakeLists.txt allegro/addons/audio/dsound.cpp allegro/addons/audio/kcm_dtor.c allegro/addons/audio/kcm_instance.c allegro/addons/audio/kcm_mixer.c allegro/addons/audio/kcm_mixer_helpers.inc allegro/addons/audio/kcm_sample.c allegro/addons/audio/kcm_stream.c allegro/addons/audio/kcm_voice.c allegro/addons/audio/openal.c allegro/addons/audio/oss.c allegro/addons/audio/pulseaudio.c allegro/addons/CMakeLists.txt allegro/addons/color/ allegro/addons/color/allegro5/ allegro/addons/color/allegro5/allegro_color.h allegro/addons/color/CMakeLists.txt allegro/addons/color/color.c allegro/addons/font/ allegro/addons/font/allegro5/ allegro/addons/font/allegro5/allegro_font.h allegro/addons/font/CMakeLists.txt allegro/addons/font/fontbmp.c allegro/addons/font/font.c allegro/addons/font/font.h allegro/addons/font/stdfont.c allegro/addons/font/text.c allegro/addons/image/ allegro/addons/image/allegro5/ allegro/addons/image/allegro5/allegro_image.h allegro/addons/image/allegro5/internal/ allegro/addons/image/allegro5/internal/aintern_image_cfg.h.cmake allegro/addons/image/allegro5/internal/aintern_image.h allegro/addons/image/bmp.c allegro/addons/image/CMakeLists.txt allegro/addons/image/gdiplus.cpp allegro/addons/image/iio.c allegro/addons/image/iio.h allegro/addons/image/iphone.m allegro/addons/image/jpg.c allegro/addons/image/macosx.m allegro/addons/image/pcx.c allegro/addons/image/png.c allegro/addons/image/tga.c allegro/addons/main/ allegro/addons/main/CMakeLists.txt allegro/addons/main/generic_main.c allegro/addons/main/osx_main.m allegro/addons/memfile/ allegro/addons/memfile/allegro5/ allegro/addons/memfile/allegro5/allegro_memfile.h allegro/addons/memfile/CMakeLists.txt allegro/addons/memfile/memfile.c allegro/addons/native_dialog/ allegro/addons/native_dialog/allegro5/ allegro/addons/native_dialog/allegro5/allegro_native_dialog.h allegro/addons/native_dialog/allegro5/internal/ allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog.h allegro/addons/native_dialog/CMakeLists.txt allegro/addons/native_dialog/dialog.c allegro/addons/native_dialog/gtk_dialog.c allegro/addons/native_dialog/gtk_dialog.h allegro/addons/native_dialog/gtk_filesel.c allegro/addons/native_dialog/gtk_msgbox.c allegro/addons/native_dialog/gtk_textlog.c allegro/addons/native_dialog/gtk_thread.c allegro/addons/native_dialog/iphone_dialog.m allegro/addons/native_dialog/osx_dialog.m allegro/addons/native_dialog/textlog.c allegro/addons/native_dialog/win_dialog.c allegro/addons/physfs/ allegro/addons/physfs/a5_physfs.c allegro/addons/physfs/a5_physfs_dir.c allegro/addons/physfs/allegro5/ allegro/addons/physfs/allegro5/allegro_physfs.h allegro/addons/physfs/allegro_physfs_intern.h allegro/addons/physfs/CMakeLists.txt allegro/addons/primitives/ allegro/addons/primitives/allegro5/ allegro/addons/primitives/allegro5/allegro_primitives.h allegro/addons/primitives/allegro5/internal/ allegro/addons/primitives/allegro5/internal/aintern_prim_directx.h allegro/addons/primitives/allegro5/internal/aintern_prim.h allegro/addons/primitives/allegro5/internal/aintern_prim_opengl.h allegro/addons/primitives/allegro5/internal/aintern_prim_soft.h allegro/addons/primitives/CMakeLists.txt allegro/addons/primitives/directx_shaders.c allegro/addons/primitives/high_primitives.c allegro/addons/primitives/line_soft.c allegro/addons/primitives/nshader.cpp allegro/addons/primitives/nshader.fx allegro/addons/primitives/point_soft.c allegro/addons/primitives/prim_directx.c allegro/addons/primitives/primitives.c allegro/addons/primitives/prim_opengl.c allegro/addons/primitives/prim_soft.c allegro/addons/ttf/ allegro/addons/ttf/allegro5/ allegro/addons/ttf/allegro5/allegro_ttf.h allegro/addons/ttf/allegro5/internal/ allegro/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake allegro/addons/ttf/CMakeLists.txt allegro/addons/ttf/ttf.c allegro/allegro5.cfg allegro/CHANGES-5.0.txt allegro/cmake/ allegro/cmake/AllegroFindOSS.cmake allegro/cmake/Common.cmake allegro/cmake/FileList.cmake allegro/cmake/FindD3D9.cmake allegro/cmake/FindD3DX9.cmake allegro/cmake/FindDInput.cmake allegro/cmake/FindDSound.cmake allegro/cmake/FindDUMB.cmake allegro/cmake/FindDXGuid.cmake allegro/cmake/FindFLAC.cmake allegro/cmake/FindGDIPLUS.cmake allegro/cmake/FindOgg.cmake allegro/cmake/FindTremor.cmake allegro/cmake/FindVorbis.cmake allegro/CMakeLists.txt allegro/cmake/Toolchain-iphone.cmake allegro/cmake/Toolchain-mingw.cmake allegro/cmake/Toolchain-openwiz.cmake allegro/CONTRIBUTORS.txt allegro/demos/ allegro/demos/cosmic_protector/ allegro/demos/cosmic_protector/CMakeLists.txt allegro/demos/cosmic_protector/data/ allegro/demos/cosmic_protector/data/gfx/ allegro/demos/cosmic_protector/data/gfx/background.tga allegro/demos/cosmic_protector/data/gfx/Icon.icns allegro/demos/cosmic_protector/data/gfx/large_asteroid.tga allegro/demos/cosmic_protector/data/gfx/large_bullet.tga allegro/demos/cosmic_protector/data/gfx/large_explosion_0.tga allegro/demos/cosmic_protector/data/gfx/large_explosion_1.tga allegro/demos/cosmic_protector/data/gfx/large_explosion_2.tga allegro/demos/cosmic_protector/data/gfx/large_explosion_3.tga allegro/demos/cosmic_protector/data/gfx/large_explosion_4.tga allegro/demos/cosmic_protector/data/gfx/large_font.tga allegro/demos/cosmic_protector/data/gfx/life_powerup.tga allegro/demos/cosmic_protector/data/gfx/logo.tga allegro/demos/cosmic_protector/data/gfx/medium_asteroid.tga allegro/demos/cosmic_protector/data/gfx/ship_icon.tga allegro/demos/cosmic_protector/data/gfx/ship.tga allegro/demos/cosmic_protector/data/gfx/ship_trans.tga allegro/demos/cosmic_protector/data/gfx/small_asteroid.tga allegro/demos/cosmic_protector/data/gfx/small_bullet.tga allegro/demos/cosmic_protector/data/gfx/small_explosion_0.tga allegro/demos/cosmic_protector/data/gfx/small_explosion_1.tga allegro/demos/cosmic_protector/data/gfx/small_explosion_2.tga allegro/demos/cosmic_protector/data/gfx/small_explosion_3.tga allegro/demos/cosmic_protector/data/gfx/small_explosion_4.tga allegro/demos/cosmic_protector/data/gfx/small_font.tga allegro/demos/cosmic_protector/data/gfx/trail.tga allegro/demos/cosmic_protector/data/gfx/ufo0.tga allegro/demos/cosmic_protector/data/gfx/ufo1.tga allegro/demos/cosmic_protector/data/gfx/ufo2.tga allegro/demos/cosmic_protector/data/gfx/weapon_powerup.tga allegro/demos/cosmic_protector/data/sfx/ allegro/demos/cosmic_protector/data/sfx/big_explosion.ogg allegro/demos/cosmic_protector/data/sfx/collision.ogg allegro/demos/cosmic_protector/data/sfx/fire_large.ogg allegro/demos/cosmic_protector/data/sfx/fire_small.ogg allegro/demos/cosmic_protector/data/sfx/game_music.ogg allegro/demos/cosmic_protector/data/sfx/powerup.ogg allegro/demos/cosmic_protector/data/sfx/small_explosion.ogg allegro/demos/cosmic_protector/data/sfx/title_music.ogg allegro/demos/cosmic_protector/include/ allegro/demos/cosmic_protector/include/Asteroid.hpp allegro/demos/cosmic_protector/include/BitmapResource.hpp allegro/demos/cosmic_protector/include/Bullet.hpp allegro/demos/cosmic_protector/include/ButtonWidget.hpp allegro/demos/cosmic_protector/include/collision.hpp allegro/demos/cosmic_protector/include/cosmic_protector.hpp allegro/demos/cosmic_protector/include/Debug.hpp allegro/demos/cosmic_protector/include/DisplayResource.hpp allegro/demos/cosmic_protector/include/Entity.hpp allegro/demos/cosmic_protector/include/Explosion.hpp allegro/demos/cosmic_protector/include/FontResource.hpp allegro/demos/cosmic_protector/include/Game.hpp allegro/demos/cosmic_protector/include/gui.hpp allegro/demos/cosmic_protector/include/Input.hpp allegro/demos/cosmic_protector/include/LargeAsteroid.hpp allegro/demos/cosmic_protector/include/LargeBullet.hpp allegro/demos/cosmic_protector/include/LargeSlowBullet.hpp allegro/demos/cosmic_protector/include/logic.hpp allegro/demos/cosmic_protector/include/MediumAsteroid.hpp allegro/demos/cosmic_protector/include/Player.hpp allegro/demos/cosmic_protector/include/PowerUp.hpp allegro/demos/cosmic_protector/include/render.hpp allegro/demos/cosmic_protector/include/Resource.hpp allegro/demos/cosmic_protector/include/ResourceManager.hpp allegro/demos/cosmic_protector/include/SampleResource.hpp allegro/demos/cosmic_protector/include/SmallAsteroid.hpp allegro/demos/cosmic_protector/include/SmallBullet.hpp allegro/demos/cosmic_protector/include/sound.hpp allegro/demos/cosmic_protector/include/StreamResource.hpp allegro/demos/cosmic_protector/include/UFO.hpp allegro/demos/cosmic_protector/include/Wave.hpp allegro/demos/cosmic_protector/include/Weapon.hpp allegro/demos/cosmic_protector/include/Widget.hpp allegro/demos/cosmic_protector/src/ allegro/demos/cosmic_protector/src/Asteroid.cpp allegro/demos/cosmic_protector/src/BitmapResource.cpp allegro/demos/cosmic_protector/src/Bullet.cpp allegro/demos/cosmic_protector/src/ButtonWidget.cpp allegro/demos/cosmic_protector/src/collision.cpp allegro/demos/cosmic_protector/src/cosmic_protector.cpp allegro/demos/cosmic_protector/src/Debug.cpp allegro/demos/cosmic_protector/src/DisplayResource.cpp allegro/demos/cosmic_protector/src/Entity.cpp allegro/demos/cosmic_protector/src/Explosion.cpp allegro/demos/cosmic_protector/src/FontResource.cpp allegro/demos/cosmic_protector/src/Game.cpp allegro/demos/cosmic_protector/src/GUI.cpp allegro/demos/cosmic_protector/src/Input.cpp allegro/demos/cosmic_protector/src/LargeAsteroid.cpp allegro/demos/cosmic_protector/src/LargeBullet.cpp allegro/demos/cosmic_protector/src/LargeSlowBullet.cpp allegro/demos/cosmic_protector/src/logic.cpp allegro/demos/cosmic_protector/src/MediumAsteroid.cpp allegro/demos/cosmic_protector/src/Player.cpp allegro/demos/cosmic_protector/src/PowerUp.cpp allegro/demos/cosmic_protector/src/render.cpp allegro/demos/cosmic_protector/src/Resource.cpp allegro/demos/cosmic_protector/src/ResourceManager.cpp allegro/demos/cosmic_protector/src/SampleResource.cpp allegro/demos/cosmic_protector/src/SmallAsteroid.cpp allegro/demos/cosmic_protector/src/SmallBullet.cpp allegro/demos/cosmic_protector/src/sound.cpp allegro/demos/cosmic_protector/src/StreamResource.cpp allegro/demos/cosmic_protector/src/UFO.cpp allegro/demos/cosmic_protector/src/wave.cpp allegro/demos/speed/ allegro/demos/speed/29.txt allegro/demos/speed/a4_aux.c allegro/demos/speed/a4_aux.h allegro/demos/speed/badguys.c allegro/demos/speed/bullets.c allegro/demos/speed/CMakeLists.txt allegro/demos/speed/explode.c allegro/demos/speed/hiscore.c allegro/demos/speed/main.c allegro/demos/speed/makefile allegro/demos/speed/message.c allegro/demos/speed/player.c allegro/demos/speed/port.txt allegro/demos/speed/sound.c allegro/demos/speed/speed.h allegro/demos/speed/speed.txt allegro/demos/speed/title.c allegro/demos/speed/update.pl allegro/demos/speed/view.c allegro/docs/ allegro/docs/CMakeLists.txt allegro/docs/html/ allegro/docs/html/refman/ allegro/docs/html/refman/acodec.html allegro/docs/html/refman/audio.html allegro/docs/html/refman/autosuggest.js allegro/docs/html/refman/color.html allegro/docs/html/refman/config.html allegro/docs/html/refman/direct3d.html allegro/docs/html/refman/display.html allegro/docs/html/refman/events.html allegro/docs/html/refman/file.html allegro/docs/html/refman/fixed.html allegro/docs/html/refman/font.html allegro/docs/html/refman/fshook.html allegro/docs/html/refman/fullscreen_mode.html allegro/docs/html/refman/getting_started.html allegro/docs/html/refman/graphics.html allegro/docs/html/refman/image.html allegro/docs/html/refman/images/ allegro/docs/html/refman/images/primitives1.png allegro/docs/html/refman/images/primitives2.png allegro/docs/html/refman/index_all.html allegro/docs/html/refman/index.html allegro/docs/html/refman/joystick.html allegro/docs/html/refman/keyboard.html allegro/docs/html/refman/main.html allegro/docs/html/refman/memfile.html allegro/docs/html/refman/memory.html allegro/docs/html/refman/misc.html allegro/docs/html/refman/monitor.html allegro/docs/html/refman/mouse.html allegro/docs/html/refman/native_dialog.html allegro/docs/html/refman/opengl.html allegro/docs/html/refman/pandoc.css allegro/docs/html/refman/path.html allegro/docs/html/refman/physfs.html allegro/docs/html/refman/platform.html allegro/docs/html/refman/primitives.html allegro/docs/html/refman/search_index.js allegro/docs/html/refman/state.html allegro/docs/html/refman/system.html allegro/docs/html/refman/threads.html allegro/docs/html/refman/time.html allegro/docs/html/refman/timer.html allegro/docs/html/refman/transformations.html allegro/docs/html/refman/utf8.html allegro/docs/man/ allegro/docs/man/al_acknowledge_resize.3 allegro/docs/man/al_add_config_comment.3 allegro/docs/man/al_add_config_section.3 allegro/docs/man/al_add_new_bitmap_flag.3 allegro/docs/man/al_add_timer_count.3 allegro/docs/man/al_append_native_text_log.3 allegro/docs/man/al_append_path_component.3 allegro/docs/man/al_attach_audio_stream_to_mixer.3 allegro/docs/man/al_attach_audio_stream_to_voice.3 allegro/docs/man/al_attach_mixer_to_mixer.3 allegro/docs/man/al_attach_mixer_to_voice.3 allegro/docs/man/al_attach_sample_instance_to_mixer.3 allegro/docs/man/al_attach_sample_instance_to_voice.3 allegro/docs/man/al_broadcast_cond.3 allegro/docs/man/al_build_transform.3 allegro/docs/man/al_calculate_arc.3 allegro/docs/man/al_calculate_ribbon.3 allegro/docs/man/al_calculate_spline.3 allegro/docs/man/al_calloc.3 allegro/docs/man/al_calloc_with_context.3 allegro/docs/man/al_change_directory.3 allegro/docs/man/al_check_inverse.3 allegro/docs/man/al_clear_to_color.3 allegro/docs/man/al_clone_bitmap.3 allegro/docs/man/al_clone_path.3 allegro/docs/man/al_close_directory.3 allegro/docs/man/al_close_native_text_log.3 allegro/docs/man/al_color_cmyk.3 allegro/docs/man/al_color_cmyk_to_rgb.3 allegro/docs/man/al_color_hsl.3 allegro/docs/man/al_color_hsl_to_rgb.3 allegro/docs/man/al_color_hsv.3 allegro/docs/man/al_color_hsv_to_rgb.3 allegro/docs/man/al_color_html.3 allegro/docs/man/al_color_html_to_rgb.3 allegro/docs/man/al_color_name.3 allegro/docs/man/al_color_name_to_rgb.3 allegro/docs/man/al_color_rgb_to_cmyk.3 allegro/docs/man/al_color_rgb_to_hsl.3 allegro/docs/man/al_color_rgb_to_hsv.3 allegro/docs/man/al_color_rgb_to_html.3 allegro/docs/man/al_color_rgb_to_name.3 allegro/docs/man/al_color_rgb_to_yuv.3 allegro/docs/man/al_color_yuv.3 allegro/docs/man/al_color_yuv_to_rgb.3 allegro/docs/man/al_compose_transform.3 allegro/docs/man/al_convert_mask_to_alpha.3 allegro/docs/man/al_copy_transform.3 allegro/docs/man/al_create_audio_stream.3 allegro/docs/man/al_create_bitmap.3 allegro/docs/man/al_create_builtin_font.3 allegro/docs/man/al_create_cond.3 allegro/docs/man/al_create_config.3 allegro/docs/man/al_create_display.3 allegro/docs/man/al_create_event_queue.3 allegro/docs/man/al_create_file_handle.3 allegro/docs/man/al_create_fs_entry.3 allegro/docs/man/al_create_mixer.3 allegro/docs/man/al_create_mouse_cursor.3 allegro/docs/man/al_create_mutex.3 allegro/docs/man/al_create_mutex_recursive.3 allegro/docs/man/al_create_native_file_dialog.3 allegro/docs/man/al_create_path.3 allegro/docs/man/al_create_path_for_directory.3 allegro/docs/man/al_create_sample.3 allegro/docs/man/al_create_sample_instance.3 allegro/docs/man/al_create_sub_bitmap.3 allegro/docs/man/al_create_thread.3 allegro/docs/man/al_create_timer.3 allegro/docs/man/al_create_vertex_decl.3 allegro/docs/man/al_create_voice.3 allegro/docs/man/al_cstr.3 allegro/docs/man/al_cstr_dup.3 allegro/docs/man/al_current_time.3 allegro/docs/man/al_destroy_audio_stream.3 allegro/docs/man/al_destroy_bitmap.3 allegro/docs/man/al_destroy_cond.3 allegro/docs/man/al_destroy_config.3 allegro/docs/man/al_destroy_display.3 allegro/docs/man/al_destroy_event_queue.3 allegro/docs/man/al_destroy_font.3 allegro/docs/man/al_destroy_fs_entry.3 allegro/docs/man/al_destroy_mixer.3 allegro/docs/man/al_destroy_mouse_cursor.3 allegro/docs/man/al_destroy_mutex.3 allegro/docs/man/al_destroy_native_file_dialog.3 allegro/docs/man/al_destroy_path.3 allegro/docs/man/al_destroy_sample.3 allegro/docs/man/al_destroy_sample_instance.3 allegro/docs/man/al_destroy_thread.3 allegro/docs/man/al_destroy_timer.3 allegro/docs/man/al_destroy_user_event_source.3 allegro/docs/man/al_destroy_vertex_decl.3 allegro/docs/man/al_destroy_voice.3 allegro/docs/man/al_detach_audio_stream.3 allegro/docs/man/al_detach_mixer.3 allegro/docs/man/al_detach_sample_instance.3 allegro/docs/man/al_detach_voice.3 allegro/docs/man/al_drain_audio_stream.3 allegro/docs/man/al_draw_arc.3 allegro/docs/man/al_draw_bitmap.3 allegro/docs/man/al_draw_bitmap_region.3 allegro/docs/man/al_draw_circle.3 allegro/docs/man/al_draw_ellipse.3 allegro/docs/man/al_draw_elliptical_arc.3 allegro/docs/man/al_draw_filled_circle.3 allegro/docs/man/al_draw_filled_ellipse.3 allegro/docs/man/al_draw_filled_pieslice.3 allegro/docs/man/al_draw_filled_rectangle.3 allegro/docs/man/al_draw_filled_rounded_rectangle.3 allegro/docs/man/al_draw_filled_triangle.3 allegro/docs/man/al_draw_indexed_prim.3 allegro/docs/man/al_draw_justified_text.3 allegro/docs/man/al_draw_justified_textf.3 allegro/docs/man/al_draw_justified_ustr.3 allegro/docs/man/al_draw_line.3 allegro/docs/man/al_draw_pieslice.3 allegro/docs/man/al_draw_pixel.3 allegro/docs/man/al_draw_prim.3 allegro/docs/man/al_draw_rectangle.3 allegro/docs/man/al_draw_ribbon.3 allegro/docs/man/al_draw_rotated_bitmap.3 allegro/docs/man/al_draw_rounded_rectangle.3 allegro/docs/man/al_draw_scaled_bitmap.3 allegro/docs/man/al_draw_scaled_rotated_bitmap.3 allegro/docs/man/al_draw_soft_line.3 allegro/docs/man/al_draw_soft_triangle.3 allegro/docs/man/al_draw_spline.3 allegro/docs/man/al_draw_text.3 allegro/docs/man/al_draw_textf.3 allegro/docs/man/al_draw_tinted_bitmap.3 allegro/docs/man/al_draw_tinted_bitmap_region.3 allegro/docs/man/al_draw_tinted_rotated_bitmap.3 allegro/docs/man/al_draw_tinted_scaled_bitmap.3 allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap.3 allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.3 allegro/docs/man/al_draw_triangle.3 allegro/docs/man/al_draw_ustr.3 allegro/docs/man/al_drop_next_event.3 allegro/docs/man/al_drop_path_tail.3 allegro/docs/man/al_emit_user_event.3 allegro/docs/man/al_fclearerr.3 allegro/docs/man/al_fclose.3 allegro/docs/man/al_feof.3 allegro/docs/man/al_ferror.3 allegro/docs/man/al_fflush.3 allegro/docs/man/al_fgetc.3 allegro/docs/man/al_fgets.3 allegro/docs/man/al_fget_ustr.3 allegro/docs/man/al_filename_exists.3 allegro/docs/man/al_fixacos.3 allegro/docs/man/al_fixadd.3 allegro/docs/man/al_fixasin.3 allegro/docs/man/al_fixatan2.3 allegro/docs/man/al_fixatan.3 allegro/docs/man/al_fixceil.3 allegro/docs/man/al_fixcos.3 allegro/docs/man/al_fixdiv.3 allegro/docs/man/al_fixed.3 allegro/docs/man/al_fixfloor.3 allegro/docs/man/al_fixhypot.3 allegro/docs/man/al_fixmul.3 allegro/docs/man/al_fixsin.3 allegro/docs/man/al_fixsqrt.3 allegro/docs/man/al_fixsub.3 allegro/docs/man/al_fixtan.3 allegro/docs/man/al_fixtof.3 allegro/docs/man/al_fixtoi.3 allegro/docs/man/al_fixtorad_r.3 allegro/docs/man/al_flip_display.3 allegro/docs/man/al_flush_event_queue.3 allegro/docs/man/al_fopen.3 allegro/docs/man/al_fopen_fd.3 allegro/docs/man/al_fopen_interface.3 allegro/docs/man/al_fopen_slice.3 allegro/docs/man/al_fputc.3 allegro/docs/man/al_fputs.3 allegro/docs/man/al_fread16be.3 allegro/docs/man/al_fread16le.3 allegro/docs/man/al_fread.3 allegro/docs/man/al_fread32be.3 allegro/docs/man/al_fread32le.3 allegro/docs/man/al_free.3 allegro/docs/man/al_free_with_context.3 allegro/docs/man/al_fseek.3 allegro/docs/man/al_fs_entry_exists.3 allegro/docs/man/al_fsize.3 allegro/docs/man/al_ftell.3 allegro/docs/man/al_ftofix.3 allegro/docs/man/al_fungetc.3 allegro/docs/man/al_fwrite16be.3 allegro/docs/man/al_fwrite16le.3 allegro/docs/man/al_fwrite.3 allegro/docs/man/al_fwrite32be.3 allegro/docs/man/al_fwrite32le.3 allegro/docs/man/al_get_allegro_acodec_version.3 allegro/docs/man/al_get_allegro_audio_version.3 allegro/docs/man/al_get_allegro_color_version.3 allegro/docs/man/al_get_allegro_font_version.3 allegro/docs/man/al_get_allegro_image_version.3 allegro/docs/man/al_get_allegro_memfile_version.3 allegro/docs/man/al_get_allegro_native_dialog_version.3 allegro/docs/man/al_get_allegro_physfs_version.3 allegro/docs/man/al_get_allegro_primitives_version.3 allegro/docs/man/al_get_allegro_ttf_version.3 allegro/docs/man/al_get_allegro_version.3 allegro/docs/man/al_get_app_name.3 allegro/docs/man/al_get_audio_depth_size.3 allegro/docs/man/al_get_audio_stream_attached.3 allegro/docs/man/al_get_audio_stream_channels.3 allegro/docs/man/al_get_audio_stream_depth.3 allegro/docs/man/al_get_audio_stream_event_source.3 allegro/docs/man/al_get_audio_stream_fragment.3 allegro/docs/man/al_get_audio_stream_fragments.3 allegro/docs/man/al_get_audio_stream_frequency.3 allegro/docs/man/al_get_audio_stream_gain.3 allegro/docs/man/al_get_audio_stream_length.3 allegro/docs/man/al_get_audio_stream_length_secs.3 allegro/docs/man/al_get_audio_stream_pan.3 allegro/docs/man/al_get_audio_stream_playing.3 allegro/docs/man/al_get_audio_stream_playmode.3 allegro/docs/man/al_get_audio_stream_position_secs.3 allegro/docs/man/al_get_audio_stream_speed.3 allegro/docs/man/al_get_available_audio_stream_fragments.3 allegro/docs/man/al_get_backbuffer.3 allegro/docs/man/al_get_bitmap_flags.3 allegro/docs/man/al_get_bitmap_format.3 allegro/docs/man/al_get_bitmap_height.3 allegro/docs/man/al_get_bitmap_width.3 allegro/docs/man/al_get_blender.3 allegro/docs/man/al_get_channel_count.3 allegro/docs/man/al_get_clipping_rectangle.3 allegro/docs/man/al_get_config_value.3 allegro/docs/man/al_get_current_directory.3 allegro/docs/man/al_get_current_display.3 allegro/docs/man/al_get_current_transform.3 allegro/docs/man/al_get_d3d_device.3 allegro/docs/man/al_get_d3d_system_texture.3 allegro/docs/man/al_get_d3d_texture_position.3 allegro/docs/man/al_get_d3d_video_texture.3 allegro/docs/man/al_get_default_mixer.3 allegro/docs/man/al_get_display_event_source.3 allegro/docs/man/al_get_display_flags.3 allegro/docs/man/al_get_display_format.3 allegro/docs/man/al_get_display_height.3 allegro/docs/man/al_get_display_mode.3 allegro/docs/man/al_get_display_option.3 allegro/docs/man/al_get_display_refresh_rate.3 allegro/docs/man/al_get_display_width.3 allegro/docs/man/al_get_errno.3 allegro/docs/man/al_get_event_source_data.3 allegro/docs/man/al_get_file_userdata.3 allegro/docs/man/al_get_first_config_entry.3 allegro/docs/man/al_get_first_config_section.3 allegro/docs/man/al_get_font_ascent.3 allegro/docs/man/al_get_font_descent.3 allegro/docs/man/al_get_font_line_height.3 allegro/docs/man/al_get_fs_entry_atime.3 allegro/docs/man/al_get_fs_entry_ctime.3 allegro/docs/man/al_get_fs_entry_mode.3 allegro/docs/man/al_get_fs_entry_mtime.3 allegro/docs/man/al_get_fs_entry_name.3 allegro/docs/man/al_get_fs_entry_size.3 allegro/docs/man/al_get_fs_interface.3 allegro/docs/man/al_get_joystick.3 allegro/docs/man/al_get_joystick_active.3 allegro/docs/man/al_get_joystick_axis_name.3 allegro/docs/man/al_get_joystick_button_name.3 allegro/docs/man/al_get_joystick_event_source.3 allegro/docs/man/al_get_joystick_name.3 allegro/docs/man/al_get_joystick_num_axes.3 allegro/docs/man/al_get_joystick_num_buttons.3 allegro/docs/man/al_get_joystick_num_sticks.3 allegro/docs/man/al_get_joystick_state.3 allegro/docs/man/al_get_joystick_stick_flags.3 allegro/docs/man/al_get_joystick_stick_name.3 allegro/docs/man/al_get_keyboard_event_source.3 allegro/docs/man/al_get_keyboard_state.3 allegro/docs/man/al_get_mixer_attached.3 allegro/docs/man/al_get_mixer_channels.3 allegro/docs/man/al_get_mixer_depth.3 allegro/docs/man/al_get_mixer_frequency.3 allegro/docs/man/al_get_mixer_gain.3 allegro/docs/man/al_get_mixer_playing.3 allegro/docs/man/al_get_mixer_quality.3 allegro/docs/man/al_get_monitor_info.3 allegro/docs/man/al_get_mouse_cursor_position.3 allegro/docs/man/al_get_mouse_event_source.3 allegro/docs/man/al_get_mouse_num_axes.3 allegro/docs/man/al_get_mouse_num_buttons.3 allegro/docs/man/al_get_mouse_state.3 allegro/docs/man/al_get_mouse_state_axis.3 allegro/docs/man/al_get_native_file_dialog_count.3 allegro/docs/man/al_get_native_file_dialog_path.3 allegro/docs/man/al_get_native_text_log_event_source.3 allegro/docs/man/al_get_new_bitmap_flags.3 allegro/docs/man/al_get_new_bitmap_format.3 allegro/docs/man/al_get_new_display_adapter.3 allegro/docs/man/al_get_new_display_flags.3 allegro/docs/man/al_get_new_display_option.3 allegro/docs/man/al_get_new_display_refresh_rate.3 allegro/docs/man/al_get_new_file_interface.3 allegro/docs/man/al_get_new_window_position.3 allegro/docs/man/al_get_next_config_entry.3 allegro/docs/man/al_get_next_config_section.3 allegro/docs/man/al_get_next_event.3 allegro/docs/man/al_get_num_display_modes.3 allegro/docs/man/al_get_num_joysticks.3 allegro/docs/man/al_get_num_video_adapters.3 allegro/docs/man/al_get_opengl_extension_list.3 allegro/docs/man/al_get_opengl_fbo.3 allegro/docs/man/al_get_opengl_proc_address.3 allegro/docs/man/al_get_opengl_texture.3 allegro/docs/man/al_get_opengl_texture_position.3 allegro/docs/man/al_get_opengl_texture_size.3 allegro/docs/man/al_get_opengl_variant.3 allegro/docs/man/al_get_opengl_version.3 allegro/docs/man/al_get_org_name.3 allegro/docs/man/al_get_parent_bitmap.3 allegro/docs/man/al_get_path_basename.3 allegro/docs/man/al_get_path_component.3 allegro/docs/man/al_get_path_drive.3 allegro/docs/man/al_get_path_extension.3 allegro/docs/man/al_get_path_filename.3 allegro/docs/man/al_get_path_num_components.3 allegro/docs/man/al_get_path_tail.3 allegro/docs/man/al_get_pixel.3 allegro/docs/man/al_get_pixel_format_bits.3 allegro/docs/man/al_get_pixel_size.3 allegro/docs/man/al_get_sample.3 allegro/docs/man/al_get_sample_channels.3 allegro/docs/man/al_get_sample_data.3 allegro/docs/man/al_get_sample_depth.3 allegro/docs/man/al_get_sample_frequency.3 allegro/docs/man/al_get_sample_instance_attached.3 allegro/docs/man/al_get_sample_instance_channels.3 allegro/docs/man/al_get_sample_instance_depth.3 allegro/docs/man/al_get_sample_instance_frequency.3 allegro/docs/man/al_get_sample_instance_gain.3 allegro/docs/man/al_get_sample_instance_length.3 allegro/docs/man/al_get_sample_instance_pan.3 allegro/docs/man/al_get_sample_instance_playing.3 allegro/docs/man/al_get_sample_instance_playmode.3 allegro/docs/man/al_get_sample_instance_position.3 allegro/docs/man/al_get_sample_instance_speed.3 allegro/docs/man/al_get_sample_instance_time.3 allegro/docs/man/al_get_sample_length.3 allegro/docs/man/al_get_separate_blender.3 allegro/docs/man/al_get_standard_path.3 allegro/docs/man/al_get_system_config.3 allegro/docs/man/al_get_target_bitmap.3 allegro/docs/man/al_get_text_dimensions.3 allegro/docs/man/al_get_text_width.3 allegro/docs/man/al_get_thread_should_stop.3 allegro/docs/man/al_get_time.3 allegro/docs/man/al_get_timer_count.3 allegro/docs/man/al_get_timer_event_source.3 allegro/docs/man/al_get_timer_speed.3 allegro/docs/man/al_get_timer_started.3 allegro/docs/man/al_get_ustr_dimensions.3 allegro/docs/man/al_get_ustr_width.3 allegro/docs/man/al_get_voice_channels.3 allegro/docs/man/al_get_voice_depth.3 allegro/docs/man/al_get_voice_frequency.3 allegro/docs/man/al_get_voice_playing.3 allegro/docs/man/al_get_voice_position.3 allegro/docs/man/al_get_window_position.3 allegro/docs/man/al_get_win_window_handle.3 allegro/docs/man/al_grab_font_from_bitmap.3 allegro/docs/man/al_grab_mouse.3 allegro/docs/man/al_have_d3d_non_pow2_texture_support.3 allegro/docs/man/al_have_d3d_non_square_texture_support.3 allegro/docs/man/al_have_opengl_extension.3 allegro/docs/man/al_hide_mouse_cursor.3 allegro/docs/man/al_hold_bitmap_drawing.3 allegro/docs/man/al_identity_transform.3 allegro/docs/man/al_inhibit_screensaver.3 allegro/docs/man/al_init.3 allegro/docs/man/al_init_acodec_addon.3 allegro/docs/man/al_init_font_addon.3 allegro/docs/man/al_init_image_addon.3 allegro/docs/man/al_init_native_dialog_addon.3 allegro/docs/man/al_init_primitives_addon.3 allegro/docs/man/al_init_timeout.3 allegro/docs/man/al_init_ttf_addon.3 allegro/docs/man/al_init_user_event_source.3 allegro/docs/man/al_insert_path_component.3 allegro/docs/man/al_install_audio.3 allegro/docs/man/al_install_joystick.3 allegro/docs/man/al_install_keyboard.3 allegro/docs/man/al_install_mouse.3 allegro/docs/man/al_install_system.3 allegro/docs/man/al_invert_transform.3 allegro/docs/man/al_iphone_override_screen_scale.3 allegro/docs/man/al_iphone_program_has_halted.3 allegro/docs/man/al_is_audio_installed.3 allegro/docs/man/al_is_bitmap_drawing_held.3 allegro/docs/man/al_is_bitmap_locked.3 allegro/docs/man/al_is_compatible_bitmap.3 allegro/docs/man/al_is_d3d_device_lost.3 allegro/docs/man/al_is_event_queue_empty.3 allegro/docs/man/al_is_joystick_installed.3 allegro/docs/man/al_is_keyboard_installed.3 allegro/docs/man/al_is_mouse_installed.3 allegro/docs/man/al_is_sub_bitmap.3 allegro/docs/man/al_is_system_installed.3 allegro/docs/man/al_itofix.3 allegro/docs/man/al_join_paths.3 allegro/docs/man/al_join_thread.3 allegro/docs/man/al_keycode_to_name.3 allegro/docs/man/al_key_down.3 allegro/docs/man/ALLEGRO_AUDIO_DEPTH.3 allegro/docs/man/ALLEGRO_AUDIO_PAN_NONE.3 allegro/docs/man/ALLEGRO_AUDIO_STREAM.3 allegro/docs/man/ALLEGRO_BITMAP.3 allegro/docs/man/ALLEGRO_BPM_TO_SECS.3 allegro/docs/man/ALLEGRO_BPS_TO_SECS.3 allegro/docs/man/ALLEGRO_CHANNEL_CONF.3 allegro/docs/man/ALLEGRO_COLOR.3 allegro/docs/man/ALLEGRO_COND.3 allegro/docs/man/ALLEGRO_CONFIG.3 allegro/docs/man/ALLEGRO_DISPLAY.3 allegro/docs/man/ALLEGRO_DISPLAY_MODE.3 allegro/docs/man/ALLEGRO_EVENT.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_CLOSE.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_EXPOSE.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_FOUND.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_LOST.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_ORIENTATION.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_RESIZE.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_SWITCH_IN.3 allegro/docs/man/ALLEGRO_EVENT_DISPLAY_SWITCH_OUT.3 allegro/docs/man/ALLEGRO_EVENT_JOYSTICK_AXIS.3 allegro/docs/man/ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN.3 allegro/docs/man/ALLEGRO_EVENT_JOYSTICK_BUTTON_UP.3 allegro/docs/man/ALLEGRO_EVENT_JOYSTICK_CONFIGURATION.3 allegro/docs/man/ALLEGRO_EVENT_KEY_CHAR.3 allegro/docs/man/ALLEGRO_EVENT_KEY_DOWN.3 allegro/docs/man/ALLEGRO_EVENT_KEY_UP.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_AXES.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_BUTTON_DOWN.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_BUTTON_UP.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY.3 allegro/docs/man/ALLEGRO_EVENT_MOUSE_WARPED.3 allegro/docs/man/ALLEGRO_EVENT_QUEUE.3 allegro/docs/man/ALLEGRO_EVENT_SOURCE.3 allegro/docs/man/ALLEGRO_EVENT_TIMER.3 allegro/docs/man/ALLEGRO_EVENT_TYPE.3 allegro/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.3 allegro/docs/man/ALLEGRO_FILE.3 allegro/docs/man/ALLEGRO_FILECHOOSER.3 allegro/docs/man/ALLEGRO_FILE_INTERFACE.3 allegro/docs/man/ALLEGRO_FILE_MODE.3 allegro/docs/man/ALLEGRO_FONT.3 allegro/docs/man/ALLEGRO_FS_ENTRY.3 allegro/docs/man/ALLEGRO_FS_INTERFACE.3 allegro/docs/man/ALLEGRO_GET_EVENT_TYPE.3 allegro/docs/man/ALLEGRO_JOYFLAGS.3 allegro/docs/man/ALLEGRO_JOYSTICK.3 allegro/docs/man/ALLEGRO_JOYSTICK_STATE.3 allegro/docs/man/ALLEGRO_KEYBOARD_STATE.3 allegro/docs/man/ALLEGRO_LOCKED_REGION.3 allegro/docs/man/ALLEGRO_MEMORY_INTERFACE.3 allegro/docs/man/ALLEGRO_MIXER.3 allegro/docs/man/ALLEGRO_MIXER_QUALITY.3 allegro/docs/man/ALLEGRO_MONITOR_INFO.3 allegro/docs/man/ALLEGRO_MOUSE_STATE.3 allegro/docs/man/ALLEGRO_MSECS_TO_SECS.3 allegro/docs/man/ALLEGRO_MUTEX.3 allegro/docs/man/ALLEGRO_PI.3 allegro/docs/man/ALLEGRO_PIXEL_FORMAT.3 allegro/docs/man/ALLEGRO_PLAYMODE.3 allegro/docs/man/ALLEGRO_PRIM_ATTR.3 allegro/docs/man/ALLEGRO_PRIM_QUALITY.3 allegro/docs/man/ALLEGRO_PRIM_STORAGE.3 allegro/docs/man/ALLEGRO_PRIM_TYPE.3 allegro/docs/man/ALLEGRO_SAMPLE.3 allegro/docs/man/ALLEGRO_SAMPLE_ID.3 allegro/docs/man/ALLEGRO_SAMPLE_INSTANCE.3 allegro/docs/man/ALLEGRO_SEEK.3 allegro/docs/man/ALLEGRO_STATE.3 allegro/docs/man/ALLEGRO_STATE_FLAGS.3 allegro/docs/man/ALLEGRO_TEXTLOG.3 allegro/docs/man/ALLEGRO_THREAD.3 allegro/docs/man/ALLEGRO_TIMEOUT.3 allegro/docs/man/ALLEGRO_TIMER.3 allegro/docs/man/ALLEGRO_TRANSFORM.3 allegro/docs/man/ALLEGRO_USECS_TO_SECS.3 allegro/docs/man/ALLEGRO_USER_EVENT.3 allegro/docs/man/ALLEGRO_USTR.3 allegro/docs/man/ALLEGRO_USTR_INFO.3 allegro/docs/man/ALLEGRO_VERTEX.3 allegro/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.3 allegro/docs/man/ALLEGRO_VERTEX_DECL.3 allegro/docs/man/ALLEGRO_VERTEX_ELEMENT.3 allegro/docs/man/ALLEGRO_VOICE.3 allegro/docs/man/al_load_audio_stream.3 allegro/docs/man/al_load_audio_stream_f.3 allegro/docs/man/al_load_bitmap.3 allegro/docs/man/al_load_bitmap_f.3 allegro/docs/man/al_load_bitmap_font.3 allegro/docs/man/al_load_config_file.3 allegro/docs/man/al_load_config_file_f.3 allegro/docs/man/al_load_font.3 allegro/docs/man/al_load_sample.3 allegro/docs/man/al_load_sample_f.3 allegro/docs/man/al_load_ttf_font.3 allegro/docs/man/al_load_ttf_font_f.3 allegro/docs/man/al_load_ttf_font_stretch.3 allegro/docs/man/al_load_ttf_font_stretch_f.3 allegro/docs/man/al_lock_bitmap.3 allegro/docs/man/al_lock_bitmap_region.3 allegro/docs/man/al_lock_mutex.3 allegro/docs/man/al_make_directory.3 allegro/docs/man/al_make_path_canonical.3 allegro/docs/man/al_make_temp_file.3 allegro/docs/man/al_malloc.3 allegro/docs/man/al_malloc_with_context.3 allegro/docs/man/al_map_rgb.3 allegro/docs/man/al_map_rgba.3 allegro/docs/man/al_map_rgba_f.3 allegro/docs/man/al_map_rgb_f.3 allegro/docs/man/al_merge_config.3 allegro/docs/man/al_merge_config_into.3 allegro/docs/man/al_mouse_button_down.3 allegro/docs/man/al_open_directory.3 allegro/docs/man/al_open_fs_entry.3 allegro/docs/man/al_open_memfile.3 allegro/docs/man/al_open_native_text_log.3 allegro/docs/man/al_osx_get_window.3 allegro/docs/man/al_path_cstr.3 allegro/docs/man/al_peek_next_event.3 allegro/docs/man/al_play_sample.3 allegro/docs/man/al_play_sample_instance.3 allegro/docs/man/al_put_blended_pixel.3 allegro/docs/man/al_put_pixel.3 allegro/docs/man/al_radtofix_r.3 allegro/docs/man/al_read_directory.3 allegro/docs/man/al_realloc.3 allegro/docs/man/al_realloc_with_context.3 allegro/docs/man/al_rebase_path.3 allegro/docs/man/al_reconfigure_joysticks.3 allegro/docs/man/al_ref_buffer.3 allegro/docs/man/al_ref_cstr.3 allegro/docs/man/al_ref_ustr.3 allegro/docs/man/al_register_assert_handler.3 allegro/docs/man/al_register_audio_stream_loader.3 allegro/docs/man/al_register_audio_stream_loader_f.3 allegro/docs/man/al_register_bitmap_loader.3 allegro/docs/man/al_register_bitmap_loader_f.3 allegro/docs/man/al_register_bitmap_saver.3 allegro/docs/man/al_register_bitmap_saver_f.3 allegro/docs/man/al_register_event_source.3 allegro/docs/man/al_register_font_loader.3 allegro/docs/man/al_register_sample_loader.3 allegro/docs/man/al_register_sample_loader_f.3 allegro/docs/man/al_register_sample_saver.3 allegro/docs/man/al_register_sample_saver_f.3 allegro/docs/man/al_release_joystick.3 allegro/docs/man/al_remove_filename.3 allegro/docs/man/al_remove_fs_entry.3 allegro/docs/man/al_remove_opengl_fbo.3 allegro/docs/man/al_remove_path_component.3 allegro/docs/man/al_replace_path_component.3 allegro/docs/man/al_reserve_samples.3 allegro/docs/man/al_reset_clipping_rectangle.3 allegro/docs/man/al_reset_new_display_options.3 allegro/docs/man/al_resize_display.3 allegro/docs/man/al_rest.3 allegro/docs/man/al_restore_default_mixer.3 allegro/docs/man/al_restore_state.3 allegro/docs/man/al_rewind_audio_stream.3 allegro/docs/man/al_rotate_transform.3 allegro/docs/man/al_run_detached_thread.3 allegro/docs/man/al_run_main.3 allegro/docs/man/al_save_bitmap.3 allegro/docs/man/al_save_bitmap_f.3 allegro/docs/man/al_save_config_file.3 allegro/docs/man/al_save_config_file_f.3 allegro/docs/man/al_save_sample.3 allegro/docs/man/al_save_sample_f.3 allegro/docs/man/al_scale_transform.3 allegro/docs/man/al_seek_audio_stream_secs.3 allegro/docs/man/al_set_app_name.3 allegro/docs/man/al_set_audio_stream_fragment.3 allegro/docs/man/al_set_audio_stream_gain.3 allegro/docs/man/al_set_audio_stream_loop_secs.3 allegro/docs/man/al_set_audio_stream_pan.3 allegro/docs/man/al_set_audio_stream_playing.3 allegro/docs/man/al_set_audio_stream_playmode.3 allegro/docs/man/al_set_audio_stream_speed.3 allegro/docs/man/al_set_blender.3 allegro/docs/man/al_set_clipping_rectangle.3 allegro/docs/man/al_set_config_value.3 allegro/docs/man/al_set_current_opengl_context.3 allegro/docs/man/al_set_default_mixer.3 allegro/docs/man/al_set_display_flag.3 allegro/docs/man/al_set_display_icon.3 allegro/docs/man/al_set_display_icons.3 allegro/docs/man/al_set_errno.3 allegro/docs/man/al_set_event_source_data.3 allegro/docs/man/al_set_exe_name.3 allegro/docs/man/al_set_fs_interface.3 allegro/docs/man/al_set_keyboard_leds.3 allegro/docs/man/al_set_memory_interface.3 allegro/docs/man/al_set_mixer_frequency.3 allegro/docs/man/al_set_mixer_gain.3 allegro/docs/man/al_set_mixer_playing.3 allegro/docs/man/al_set_mixer_postprocess_callback.3 allegro/docs/man/al_set_mixer_quality.3 allegro/docs/man/al_set_mouse_axis.3 allegro/docs/man/al_set_mouse_cursor.3 allegro/docs/man/al_set_mouse_w.3 allegro/docs/man/al_set_mouse_xy.3 allegro/docs/man/al_set_mouse_z.3 allegro/docs/man/al_set_new_bitmap_flags.3 allegro/docs/man/al_set_new_bitmap_format.3 allegro/docs/man/al_set_new_display_adapter.3 allegro/docs/man/al_set_new_display_flags.3 allegro/docs/man/al_set_new_display_option.3 allegro/docs/man/al_set_new_display_refresh_rate.3 allegro/docs/man/al_set_new_file_interface.3 allegro/docs/man/al_set_new_window_position.3 allegro/docs/man/al_set_org_name.3 allegro/docs/man/al_set_path_drive.3 allegro/docs/man/al_set_path_extension.3 allegro/docs/man/al_set_path_filename.3 allegro/docs/man/al_set_physfs_file_interface.3 allegro/docs/man/al_set_sample.3 allegro/docs/man/al_set_sample_instance_gain.3 allegro/docs/man/al_set_sample_instance_length.3 allegro/docs/man/al_set_sample_instance_pan.3 allegro/docs/man/al_set_sample_instance_playing.3 allegro/docs/man/al_set_sample_instance_playmode.3 allegro/docs/man/al_set_sample_instance_position.3 allegro/docs/man/al_set_sample_instance_speed.3 allegro/docs/man/al_set_separate_blender.3 allegro/docs/man/al_set_standard_file_interface.3 allegro/docs/man/al_set_standard_fs_interface.3 allegro/docs/man/al_set_system_mouse_cursor.3 allegro/docs/man/al_set_target_backbuffer.3 allegro/docs/man/al_set_target_bitmap.3 allegro/docs/man/al_set_thread_should_stop.3 allegro/docs/man/al_set_timer_count.3 allegro/docs/man/al_set_timer_speed.3 allegro/docs/man/al_set_voice_playing.3 allegro/docs/man/al_set_voice_position.3 allegro/docs/man/al_set_window_position.3 allegro/docs/man/al_set_window_title.3 allegro/docs/man/al_show_mouse_cursor.3 allegro/docs/man/al_show_native_file_dialog.3 allegro/docs/man/al_show_native_message_box.3 allegro/docs/man/al_shutdown_font_addon.3 allegro/docs/man/al_shutdown_image_addon.3 allegro/docs/man/al_shutdown_native_dialog_addon.3 allegro/docs/man/al_shutdown_primitives_addon.3 allegro/docs/man/al_shutdown_ttf_addon.3 allegro/docs/man/al_signal_cond.3 allegro/docs/man/al_start_thread.3 allegro/docs/man/al_start_timer.3 allegro/docs/man/al_stop_sample.3 allegro/docs/man/al_stop_sample_instance.3 allegro/docs/man/al_stop_samples.3 allegro/docs/man/al_stop_timer.3 allegro/docs/man/al_store_state.3 allegro/docs/man/al_toggle_display_flag.3 allegro/docs/man/al_transform_coordinates.3 allegro/docs/man/al_translate_transform.3 allegro/docs/man/al_ungrab_mouse.3 allegro/docs/man/al_uninstall_audio.3 allegro/docs/man/al_uninstall_joystick.3 allegro/docs/man/al_uninstall_keyboard.3 allegro/docs/man/al_uninstall_mouse.3 allegro/docs/man/al_uninstall_system.3 allegro/docs/man/al_unlock_bitmap.3 allegro/docs/man/al_unlock_mutex.3 allegro/docs/man/al_unmap_rgb.3 allegro/docs/man/al_unmap_rgba.3 allegro/docs/man/al_unmap_rgba_f.3 allegro/docs/man/al_unmap_rgb_f.3 allegro/docs/man/al_unref_user_event.3 allegro/docs/man/al_unregister_event_source.3 allegro/docs/man/al_update_display_region.3 allegro/docs/man/al_update_fs_entry.3 allegro/docs/man/al_use_transform.3 allegro/docs/man/al_ustr_append.3 allegro/docs/man/al_ustr_append_chr.3 allegro/docs/man/al_ustr_append_cstr.3 allegro/docs/man/al_ustr_appendf.3 allegro/docs/man/al_ustr_assign.3 allegro/docs/man/al_ustr_assign_cstr.3 allegro/docs/man/al_ustr_assign_substr.3 allegro/docs/man/al_ustr_compare.3 allegro/docs/man/al_ustr_dup.3 allegro/docs/man/al_ustr_dup_substr.3 allegro/docs/man/al_ustr_empty_string.3 allegro/docs/man/al_ustr_encode_utf16.3 allegro/docs/man/al_ustr_equal.3 allegro/docs/man/al_ustr_find_chr.3 allegro/docs/man/al_ustr_find_cset.3 allegro/docs/man/al_ustr_find_cset_cstr.3 allegro/docs/man/al_ustr_find_cstr.3 allegro/docs/man/al_ustr_find_replace.3 allegro/docs/man/al_ustr_find_replace_cstr.3 allegro/docs/man/al_ustr_find_set.3 allegro/docs/man/al_ustr_find_set_cstr.3 allegro/docs/man/al_ustr_find_str.3 allegro/docs/man/al_ustr_free.3 allegro/docs/man/al_ustr_get.3 allegro/docs/man/al_ustr_get_next.3 allegro/docs/man/al_ustr_has_prefix.3 allegro/docs/man/al_ustr_has_prefix_cstr.3 allegro/docs/man/al_ustr_has_suffix.3 allegro/docs/man/al_ustr_has_suffix_cstr.3 allegro/docs/man/al_ustr_insert.3 allegro/docs/man/al_ustr_insert_chr.3 allegro/docs/man/al_ustr_insert_cstr.3 allegro/docs/man/al_ustr_length.3 allegro/docs/man/al_ustr_ltrim_ws.3 allegro/docs/man/al_ustr_ncompare.3 allegro/docs/man/al_ustr_new.3 allegro/docs/man/al_ustr_newf.3 allegro/docs/man/al_ustr_new_from_buffer.3 allegro/docs/man/al_ustr_new_from_utf16.3 allegro/docs/man/al_ustr_next.3 allegro/docs/man/al_ustr_offset.3 allegro/docs/man/al_ustr_prev.3 allegro/docs/man/al_ustr_prev_get.3 allegro/docs/man/al_ustr_remove_chr.3 allegro/docs/man/al_ustr_remove_range.3 allegro/docs/man/al_ustr_replace_range.3 allegro/docs/man/al_ustr_rfind_chr.3 allegro/docs/man/al_ustr_rfind_cstr.3 allegro/docs/man/al_ustr_rfind_str.3 allegro/docs/man/al_ustr_rtrim_ws.3 allegro/docs/man/al_ustr_set_chr.3 allegro/docs/man/al_ustr_size.3 allegro/docs/man/al_ustr_size_utf16.3 allegro/docs/man/al_ustr_to_buffer.3 allegro/docs/man/al_ustr_trim_ws.3 allegro/docs/man/al_ustr_truncate.3 allegro/docs/man/al_ustr_vappendf.3 allegro/docs/man/al_utf16_encode.3 allegro/docs/man/al_utf16_width.3 allegro/docs/man/al_utf8_encode.3 allegro/docs/man/al_utf8_width.3 allegro/docs/man/al_wait_cond.3 allegro/docs/man/al_wait_cond_until.3 allegro/docs/man/al_wait_for_event.3 allegro/docs/man/al_wait_for_event_timed.3 allegro/docs/man/al_wait_for_event_until.3 allegro/docs/man/al_wait_for_vsync.3 allegro/docs/Refman.cmake allegro/docs/scripts/ allegro/docs/scripts/aatree.c allegro/docs/scripts/aatree.h allegro/docs/scripts/check_consistency allegro/docs/scripts/dawk.c allegro/docs/scripts/dawk.h allegro/docs/scripts/insert_timestamp.c allegro/docs/scripts/make_doc.c allegro/docs/scripts/make_doc.h allegro/docs/scripts/make_dummy_refs.c allegro/docs/scripts/make_html_refs.c allegro/docs/scripts/make_index.c allegro/docs/scripts/make_man.c allegro/docs/scripts/make_protos.c allegro/docs/scripts/make_search_index.c allegro/docs/scripts/make_single.c allegro/docs/scripts/trex.c allegro/docs/scripts/trex.h allegro/docs/scripts/trex.txt allegro/docs/scripts/update_web.py allegro/docs/src/ allegro/docs/src/autosuggest.js allegro/docs/src/changes-5.0.txt allegro/docs/src/custom_header.html allegro/docs/src/pandoc.css allegro/docs/src/refman/ allegro/docs/src/refman/acodec.txt allegro/docs/src/refman/audio.txt allegro/docs/src/refman/color.txt allegro/docs/src/refman/config.txt allegro/docs/src/refman/direct3d.txt allegro/docs/src/refman/display.txt allegro/docs/src/refman/events.txt allegro/docs/src/refman/file.txt allegro/docs/src/refman/fixed.txt allegro/docs/src/refman/font.txt allegro/docs/src/refman/fshook.txt allegro/docs/src/refman/fullscreen_mode.txt allegro/docs/src/refman/getting_started.txt allegro/docs/src/refman/graphics.txt allegro/docs/src/refman/images/ allegro/docs/src/refman/images/primitives1.png allegro/docs/src/refman/images/primitives1.svg allegro/docs/src/refman/images/primitives2.png allegro/docs/src/refman/images/primitives2.svg allegro/docs/src/refman/image.txt allegro/docs/src/refman/inc.a.txt allegro/docs/src/refman/inc.z.txt allegro/docs/src/refman/index.txt allegro/docs/src/refman/joystick.txt allegro/docs/src/refman/keyboard.txt allegro/docs/src/refman/latex.template allegro/docs/src/refman/main.txt allegro/docs/src/refman/memfile.txt allegro/docs/src/refman/memory.txt allegro/docs/src/refman/misc.txt allegro/docs/src/refman/monitor.txt allegro/docs/src/refman/mouse.txt allegro/docs/src/refman/native_dialog.txt allegro/docs/src/refman/opengl.txt allegro/docs/src/refman/path.txt allegro/docs/src/refman/physfs.txt allegro/docs/src/refman/platform.txt allegro/docs/src/refman/primitives.txt allegro/docs/src/refman/state.txt allegro/docs/src/refman/system.txt allegro/docs/src/refman/threads.txt allegro/docs/src/refman/timer.txt allegro/docs/src/refman/time.txt allegro/docs/src/refman/transformations.txt allegro/docs/src/refman/utf8.txt allegro/examples/ allegro/examples/CMakeLists.txt allegro/examples/common.c allegro/examples/data/ allegro/examples/data/a4_font.tga allegro/examples/data/allegro.pcx allegro/examples/data/bkg.png allegro/examples/data/bmpfont.tga allegro/examples/data/cursor.tga allegro/examples/data/DejaVuSans.LICENSE allegro/examples/data/DejaVuSans.ttf allegro/examples/data/exconfig.ini allegro/examples/data/ex_physfs.zip allegro/examples/data/ex_ttf.ini allegro/examples/data/fakeamp.bmp allegro/examples/data/fixed_font.tga allegro/examples/data/font.tga allegro/examples/data/green.png allegro/examples/data/haiku/ allegro/examples/data/haiku/air_0.ogg allegro/examples/data/haiku/air_1.ogg allegro/examples/data/haiku/air_2.ogg allegro/examples/data/haiku/air_3.ogg allegro/examples/data/haiku/air_4.ogg allegro/examples/data/haiku/air_5.ogg allegro/examples/data/haiku/air_6.ogg allegro/examples/data/haiku/air_7.ogg allegro/examples/data/haiku/air_effect.png allegro/examples/data/haiku/black_bead_opaque_A.png allegro/examples/data/haiku/dropshadow.png allegro/examples/data/haiku/earth_0.ogg allegro/examples/data/haiku/earth_1.ogg allegro/examples/data/haiku/earth_2.ogg allegro/examples/data/haiku/earth_3.ogg allegro/examples/data/haiku/earth_4.ogg allegro/examples/data/haiku/earth4.png allegro/examples/data/haiku/earth_5.ogg allegro/examples/data/haiku/earth_6.ogg allegro/examples/data/haiku/earth_7.ogg allegro/examples/data/haiku/fire_0.ogg allegro/examples/data/haiku/fire_1.ogg allegro/examples/data/haiku/fire_2.ogg allegro/examples/data/haiku/fire_3.ogg allegro/examples/data/haiku/fire_4.ogg allegro/examples/data/haiku/fire_5.ogg allegro/examples/data/haiku/fire_6.ogg allegro/examples/data/haiku/fire_7.ogg allegro/examples/data/haiku/fire.png allegro/examples/data/haiku/flame2.png allegro/examples/data/haiku/healthy_glow.png allegro/examples/data/haiku/main_flame2.png allegro/examples/data/haiku/overlay_pretty.png allegro/examples/data/haiku/select.ogg allegro/examples/data/haiku/water_0.ogg allegro/examples/data/haiku/water_1.ogg allegro/examples/data/haiku/water_2.ogg allegro/examples/data/haiku/water_3.ogg allegro/examples/data/haiku/water_4.ogg allegro/examples/data/haiku/water_5.ogg allegro/examples/data/haiku/water_6.ogg allegro/examples/data/haiku/water_7.ogg allegro/examples/data/haiku/water_droplets.png allegro/examples/data/haiku/water.png allegro/examples/data/haiku/wind3.png allegro/examples/data/icon.png allegro/examples/data/icon.tga allegro/examples/data/mask.pcx allegro/examples/data/mysha256x256.png allegro/examples/data/mysha.pcx allegro/examples/data/mysha.tga allegro/examples/data/obp.jpg allegro/examples/data/planet.pcx allegro/examples/data/sample.cfg allegro/examples/data/testing.ogg allegro/examples/data/texture.tga allegro/examples/ex_acodec.c allegro/examples/ex_acodec_multi.c allegro/examples/ex_audio_chain.cpp allegro/examples/ex_audio_props.cpp allegro/examples/ex_audio_simple.c allegro/examples/ex_audio_timer.c allegro/examples/ex_bitmap.c allegro/examples/ex_bitmap_flip.c allegro/examples/ex_bitmap_target.c allegro/examples/ex_blend2.cpp allegro/examples/ex_blend_bench.c allegro/examples/ex_blend.c allegro/examples/ex_blend_test.c allegro/examples/ex_blit.c allegro/examples/ex_clip.c allegro/examples/ex_color.cpp allegro/examples/ex_config.c allegro/examples/ex_convert.c allegro/examples/ex_curl.c allegro/examples/ex_d3d.cpp allegro/examples/ex_dir.c allegro/examples/ex_disable_screensaver.c allegro/examples/ex_display_events.c allegro/examples/ex_display_options.c allegro/examples/ex_draw_bitmap.c allegro/examples/ex_draw.c allegro/examples/ex_drawpixels.c allegro/examples/ex_dualies.c allegro/examples/ex_expose.c allegro/examples/ex_file_slice.c allegro/examples/ex_filter.c allegro/examples/ex_font.c allegro/examples/ex_font_justify.cpp allegro/examples/ex_fs_resize.c allegro/examples/ex_fs_window.c allegro/examples/ex_get_path.c allegro/examples/ex_gldepth.c allegro/examples/ex_glext.c allegro/examples/ex_gp2xwiz.c allegro/examples/ex_haiku.c allegro/examples/ex_icon2.c allegro/examples/ex_icon.c allegro/examples/ex_iphone.c allegro/examples/ex_joystick_events.c allegro/examples/ex_joystick_hotplugging.c allegro/examples/ex_kcm_direct.c allegro/examples/ex_keyboard_events.c allegro/examples/ex_keyboard_focus.c allegro/examples/ex_lines.c allegro/examples/ex_lockbitmap.c allegro/examples/ex_logo.c allegro/examples/ex_membmp.c allegro/examples/ex_memfile.c allegro/examples/ex_mixer_chain.c allegro/examples/ex_mixer_pp.c allegro/examples/ex_monitorinfo.c allegro/examples/ex_mouse.c allegro/examples/ex_mouse_cursor.c allegro/examples/ex_mouse_events.c allegro/examples/ex_mouse_focus.c allegro/examples/ex_multisample.c allegro/examples/ex_multiwin.c allegro/examples/ex_native_filechooser.c allegro/examples/ex_nodisplay.c allegro/examples/ex_noframe.c allegro/examples/ex_ogre3d.cpp allegro/examples/ex_opengl.c allegro/examples/ex_opengl_pixel_shader.c allegro/examples/ex_path.c allegro/examples/ex_path_test.c allegro/examples/ex_physfs.c allegro/examples/ex_pixelformat.cpp allegro/examples/ex_premulalpha.c allegro/examples/ex_prim.c allegro/examples/ex_resample_test.c allegro/examples/ex_resize2.c allegro/examples/ex_resize.c allegro/examples/ex_rotate.c allegro/examples/ex_saw.c allegro/examples/ex_scale.c allegro/examples/ex_stream_file.c allegro/examples/ex_stream_seek.c allegro/examples/ex_subbitmap.c allegro/examples/ex_synth.cpp allegro/examples/ex_threads2.c allegro/examples/ex_threads.c allegro/examples/ex_timedwait.c allegro/examples/ex_timer.c allegro/examples/ex_transform.c allegro/examples/ex_ttf.c allegro/examples/ex_user_events.c allegro/examples/ex_utf8.c allegro/examples/ex_vsync.c allegro/examples/ex_warp_mouse.c allegro/examples/ex_windows.c allegro/examples/ex_winfull.c allegro/examples/nihgui.cpp allegro/examples/nihgui.hpp allegro/include/ allegro/include/allegro5/ allegro/include/allegro5/alcompat.h allegro/include/allegro5/alinline.h allegro/include/allegro5/allegro5.h allegro/include/allegro5/allegro_direct3d.h allegro/include/allegro5/allegro.h allegro/include/allegro5/allegro_iphone.h allegro/include/allegro5/allegro_opengl.h allegro/include/allegro5/allegro_osx.h allegro/include/allegro5/allegro_windows.h allegro/include/allegro5/altime.h allegro/include/allegro5/base.h allegro/include/allegro5/bitmap_draw.h allegro/include/allegro5/bitmap.h allegro/include/allegro5/bitmap_io.h allegro/include/allegro5/bitmap_lock.h allegro/include/allegro5/blender.h allegro/include/allegro5/color.h allegro/include/allegro5/config.h allegro/include/allegro5/debug.h allegro/include/allegro5/display.h allegro/include/allegro5/drawing.h allegro/include/allegro5/error.h allegro/include/allegro5/events.h allegro/include/allegro5/file.h allegro/include/allegro5/fixed.h allegro/include/allegro5/fmaths.h allegro/include/allegro5/fshook.h allegro/include/allegro5/fullscreen_mode.h allegro/include/allegro5/inline/ allegro/include/allegro5/inline/fmaths.inl allegro/include/allegro5/internal/ allegro/include/allegro5/internal/aintern_aatree.h allegro/include/allegro5/internal/aintern_atomicops.h allegro/include/allegro5/internal/aintern_bitmap.h allegro/include/allegro5/internal/aintern_blend.h allegro/include/allegro5/internal/aintern_config.h allegro/include/allegro5/internal/aintern_convert.h allegro/include/allegro5/internal/aintern_debug.h allegro/include/allegro5/internal/aintern_direct3d.h allegro/include/allegro5/internal/aintern_display.h allegro/include/allegro5/internal/aintern_driver.h allegro/include/allegro5/internal/aintern_dtor.h allegro/include/allegro5/internal/aintern_events.h allegro/include/allegro5/internal/aintern_exitfunc.h allegro/include/allegro5/internal/aintern_file.h allegro/include/allegro5/internal/aintern_float.h allegro/include/allegro5/internal/aintern_fshook.h allegro/include/allegro5/internal/aintern_gp2xwiz.h allegro/include/allegro5/internal/aintern.h allegro/include/allegro5/internal/aintern_iphone.h allegro/include/allegro5/internal/aintern_joystick.h allegro/include/allegro5/internal/aintern_keyboard.h allegro/include/allegro5/internal/aintern_list.h allegro/include/allegro5/internal/aintern_memblit.h allegro/include/allegro5/internal/aintern_memdraw.h allegro/include/allegro5/internal/aintern_mouse.h allegro/include/allegro5/internal/aintern_opengl.h allegro/include/allegro5/internal/aintern_path.h allegro/include/allegro5/internal/aintern_pixels.h allegro/include/allegro5/internal/aintern_system.h allegro/include/allegro5/internal/aintern_thread.h allegro/include/allegro5/internal/aintern_timer.h allegro/include/allegro5/internal/aintern_tls.h allegro/include/allegro5/internal/aintern_transform.h allegro/include/allegro5/internal/aintern_tri_soft.h allegro/include/allegro5/internal/aintern_vector.h allegro/include/allegro5/internal/aintern_wunicode.h allegro/include/allegro5/internal/aintern_xcursor.h allegro/include/allegro5/internal/aintern_xdisplay.h allegro/include/allegro5/internal/aintern_xevents.h allegro/include/allegro5/internal/aintern_xfullscreen.h allegro/include/allegro5/internal/aintern_xglx_config.h allegro/include/allegro5/internal/aintern_x.h allegro/include/allegro5/internal/aintern_xkeyboard.h allegro/include/allegro5/internal/aintern_xmouse.h allegro/include/allegro5/internal/aintern_xsystem.h allegro/include/allegro5/internal/aintern_xwindow.h allegro/include/allegro5/internal/alconfig.h allegro/include/allegro5/internal/bstrlib.h allegro/include/allegro5/joystick.h allegro/include/allegro5/keyboard.h allegro/include/allegro5/keycodes.h allegro/include/allegro5/memory.h allegro/include/allegro5/monitor.h allegro/include/allegro5/mouse_cursor.h allegro/include/allegro5/mouse.h allegro/include/allegro5/opengl/ allegro/include/allegro5/opengl/GLext/ allegro/include/allegro5/opengl/GLext/gl_ext_alias.h allegro/include/allegro5/opengl/GLext/gl_ext_api.h allegro/include/allegro5/opengl/GLext/gl_ext_defs.h allegro/include/allegro5/opengl/GLext/gl_ext_list.h allegro/include/allegro5/opengl/GLext/glx_ext_alias.h allegro/include/allegro5/opengl/GLext/glx_ext_api.h allegro/include/allegro5/opengl/GLext/glx_ext_defs.h allegro/include/allegro5/opengl/GLext/glx_ext_list.h allegro/include/allegro5/opengl/gl_ext.h allegro/include/allegro5/opengl/GLext/wgl_ext_alias.h allegro/include/allegro5/opengl/GLext/wgl_ext_api.h allegro/include/allegro5/opengl/GLext/wgl_ext_defs.h allegro/include/allegro5/opengl/GLext/wgl_ext_list.h allegro/include/allegro5/path.h allegro/include/allegro5/platform/ allegro/include/allegro5/platform/aintiphone.h allegro/include/allegro5/platform/aintlnx.h allegro/include/allegro5/platform/aintosx.h allegro/include/allegro5/platform/aintunix.h allegro/include/allegro5/platform/aintuthr.h allegro/include/allegro5/platform/aintwin.h allegro/include/allegro5/platform/aintwiz.h allegro/include/allegro5/platform/aintwthr.h allegro/include/allegro5/platform/aintxglx.h allegro/include/allegro5/platform/albcc32.h allegro/include/allegro5/platform/aldmc.h allegro/include/allegro5/platform/aliphonecfg.h allegro/include/allegro5/platform/aliphone.h allegro/include/allegro5/platform/almngw32.h allegro/include/allegro5/platform/almsvc.h allegro/include/allegro5/platform/alosxcfg.h allegro/include/allegro5/platform/alosx.h allegro/include/allegro5/platform/alplatf.h.cmake allegro/include/allegro5/platform/alucfg.h allegro/include/allegro5/platform/alunix.h allegro/include/allegro5/platform/alwatcom.h allegro/include/allegro5/platform/alwin.h allegro/include/allegro5/platform/alwizcfg.h allegro/include/allegro5/platform/alwiz.h allegro/include/allegro5/platform/astdbool.h allegro/include/allegro5/platform/astdint.h allegro/include/allegro5/system.h allegro/include/allegro5/threads.h allegro/include/allegro5/timer.h allegro/include/allegro5/tls.h allegro/include/allegro5/transformations.h allegro/include/allegro5/utf8.h allegro/indent.pro allegro/LICENSE.txt allegro/misc/ allegro/misc/allegro_acodec.pc.in allegro/misc/allegro_audio.pc.in allegro/misc/allegro_color.pc.in allegro/misc/allegro_dialog.pc.in allegro/misc/allegro_font.pc.in allegro/misc/allegro_image.pc.in allegro/misc/allegro_main.pc.in allegro/misc/allegro_memfile.pc.in allegro/misc/allegro.pc.in allegro/misc/allegro_physfs.pc.in allegro/misc/allegro_primitives.pc.in allegro/misc/allegro_ttf.pc.in allegro/misc/askq.c allegro/misc/convert_line_endings.sh allegro/misc/coverage.sh allegro/misc/dtou.sh allegro/misc/embedman.bat allegro/misc/fixver.sh allegro/misc/gcc-uni.sh allegro/misc/gl_mkalias.sh allegro/misc/icon.png allegro/misc/icon.xpm allegro/misc/make_converters.py allegro/misc/make_mixer_helpers.py allegro/misc/make_scanline_drawers.py allegro/misc/mkunixdists.sh allegro/misc/msvchelp.c allegro/misc/regenerate.sh allegro/misc/release.txt allegro/misc/sf-cf.py allegro/misc/utod.sh allegro/misc/vcvars.c allegro/misc/zipup.sh allegro/misc/zipwin.sh allegro/python/ allegro/python/checkdocs.py allegro/python/CMakeLists.txt allegro/python/ex_draw_bitmap.py allegro/python/generate_python_ctypes.py allegro/python/readme.txt allegro/README_cmake.txt allegro/README_iphone.txt allegro/README_macosx.txt allegro/README_make.txt allegro/README_msvc.txt allegro/README_packaging.txt allegro/README_pkgconfig.txt allegro/README.txt allegro/src/ allegro/src/allegro.c allegro/src/bitmap.c allegro/src/bitmap_draw.c allegro/src/bitmap_io.c allegro/src/bitmap_lock.c allegro/src/bitmap_pixel.c allegro/src/blenders.c allegro/src/config.c allegro/src/convert.c allegro/src/debug.c allegro/src/display.c allegro/src/display_settings.c allegro/src/drawing.c allegro/src/dtor.c allegro/src/events.c allegro/src/evtsrc.c allegro/src/exitfunc.c allegro/src/file.c allegro/src/file_slice.c allegro/src/file_stdio.c allegro/src/fshook.c allegro/src/fshook_stdio.c allegro/src/fshook_win.inc allegro/src/fullscreen_mode.c allegro/src/gp2xwiz/ allegro/src/gp2xwiz/wiz_display_fb.c allegro/src/gp2xwiz/wiz_display_opengl.c allegro/src/gp2xwiz/wiz_joystick.c allegro/src/gp2xwiz/wiz_system.c allegro/src/inline.c allegro/src/iphone/ allegro/src/iphone/allegroAppDelegate.h allegro/src/iphone/allegroAppDelegate.m allegro/src/iphone/EAGLView.h allegro/src/iphone/EAGLView.m allegro/src/iphone/iphone_display.c allegro/src/iphone/iphone_joystick.m allegro/src/iphone/iphone_keyboard.c allegro/src/iphone/iphone_main.m allegro/src/iphone/iphone_mouse.m allegro/src/iphone/iphone_path.m allegro/src/iphone/iphone_system.c allegro/src/joynu.c allegro/src/keybdnu.c allegro/src/libc.c allegro/src/linux/ allegro/src/linux/lasyncio.c allegro/src/linux/lconsole.c allegro/src/linux/ljoynu.c allegro/src/linux/lkeybdnu.c allegro/src/linux/lmemory.c allegro/src/linux/lmouse.c allegro/src/linux/lmsedrv.c allegro/src/linux/lmseev.c allegro/src/linux/lmsegpmd.c allegro/src/linux/lmsems.c allegro/src/linux/lmseps2.c allegro/src/linux/lstddrv.c allegro/src/linux/lsystem.c allegro/src/linux/vtswitch.c allegro/src/macosx/ allegro/src/macosx/hidjoy-10.4.m allegro/src/macosx/hidjoy.m allegro/src/macosx/hidman.m allegro/src/macosx/keybd.m allegro/src/macosx/osx_app_delegate.m allegro/src/macosx/osxgl.h allegro/src/macosx/osxgl.m allegro/src/macosx/qzmouse.m allegro/src/macosx/system.m allegro/src/math.c allegro/src/memblit.c allegro/src/memdraw.c allegro/src/memory.c allegro/src/misc/ allegro/src/misc/aatree.c allegro/src/misc/bstrlib.c allegro/src/misc/bstrlib.txt allegro/src/misc/list.c allegro/src/misc/vector.c allegro/src/monitor.c allegro/src/mouse_cursor.c allegro/src/mousenu.c allegro/src/opengl/ allegro/src/opengl/extensions.c allegro/src/opengl/ogl_bitmap.c allegro/src/opengl/ogl_display.c allegro/src/opengl/ogl_draw.c allegro/src/optimized.c allegro/src/path.c allegro/src/pixels.c allegro/src/scanline_drawers.inc allegro/src/system.c allegro/src/threads.c allegro/src/timernu.c allegro/src/tls.c allegro/src/tls_dll.inc allegro/src/tls_native.inc allegro/src/tls_pthread.inc allegro/src/transformations.c allegro/src/tri_soft.c allegro/src/unix/ allegro/src/unix/udrvlist.c allegro/src/unix/ufdwatch.c allegro/src/unix/ugfxdrv.c allegro/src/unix/ujoydrv.c allegro/src/unix/ukeybd.c allegro/src/unix/umouse.c allegro/src/unix/upath.c allegro/src/unix/utime.c allegro/src/unix/uxthread.c allegro/src/utf8.c allegro/src/win/ allegro/src/win/d3d_bmp.cpp allegro/src/win/d3d_disp.cpp allegro/src/win/d3d_display_formats.cpp allegro/src/win/d3d.h allegro/src/win/wgl_disp.c allegro/src/win/wgl.h allegro/src/win/wjoydrv.c allegro/src/win/wjoydxnu.c allegro/src/win/wkeyboard.c allegro/src/win/wmcursor.c allegro/src/win/wmouse.c allegro/src/win/wsystem.c allegro/src/win/wthread.c allegro/src/win/wtime.c allegro/src/win/wunicode.c allegro/src/win/wwindow.c allegro/src/win/wxthread.c allegro/src/x/ allegro/src/x/icon.xpm allegro/src/x/xcursor.c allegro/src/x/xdisplay.c allegro/src/x/xevents.c allegro/src/x/xfullscreen.c allegro/src/x/xglx_config.c allegro/src/x/xkeyboard.c allegro/src/x/xmousenu.c allegro/src/x/xrandr.c allegro/src/x/xsystem.c allegro/src/x/xwindow.c allegro/tests/ allegro/tests/CMakeLists.txt allegro/tests/manual_bmpsuite1.ini allegro/tests/manual_bmpsuite2.ini allegro/tests/manual_bmpsuite3.ini allegro/tests/test_backbuffer.ini allegro/tests/test_bitmaps2.ini allegro/tests/test_bitmaps.ini allegro/tests/test_blend.ini allegro/tests/test_driver.c allegro/tests/test_driver.txt allegro/tests/test_fonts.ini allegro/tests/test_image.ini allegro/tests/test_locking2.ini allegro/tests/test_locking.ini allegro/tests/test_prim.ini allegro/tools/ allegro/tools/macosx/ allegro/tools/macosx/fixbundle.c allegro/tools/win/ allegro/tools/win/wfixicon.c allegro/tools/win/wfixicon.txt allegro/tools/x11/ allegro/tools/x11/xf2pcx.c allegro/tools/x11/xfixicon.sh allegro/tools/x11/xkeymap.c allegro/tools/x11/xkeymap.txt allegro/allegro.mft allegro-5.0.10/README_packaging.txt0000644000175000001440000000057311461261231016112 0ustar tjadenusersNote to packagers (e.g. for Linux distributions) ------------------------------------------------ Allegro 5.x is *not* source compatible with Allegro 4.2.x or 4.4.x. When packaging Allegro 5, please make it possible for users to install Allegro 4.x and 5.x simultaneously. For example, if you already have an 'allegro' package, then you might name the new package 'allegro5'. allegro-5.0.10/tools/0000755000175000001440000000000012157230515013547 5ustar tjadenusersallegro-5.0.10/tools/win/0000755000175000001440000000000012157230747014353 5ustar tjadenusersallegro-5.0.10/tools/win/wfixicon.txt0000644000175000001440000000510007526463545016746 0ustar tjadenusers ____ _ _ _ _ ___ __ _ |_ | \/ | | | | |\ | | | _/\_ | |__ |_| | \| by Elias Pschernig The wfixicon utility converts Allegro images to Windows icons, that is it lets you convert one or several images in any format supported by Allegro into icons suitable to be included in your Windows executable. It has two main execution modes: you can either directly pass it image files from your hard drive or bitmaps and RLE sprites from an Allegro datafile. The only difference between the two modes is for 8-bit images: in the former case, wfixicon will automatically extract the palette from the image file, whereas in the latter case you will have to explicitly provide a palette object from the datafile. The general syntax for the first mode is as follows: 'wfixicon icon [options] bitmap [bitmap...]' where 'icon' is the icon file to be generated (usually with the standard .ico extension) and each 'bitmap' is a source bitmaps to be processed. The general syntax for the second mode is as follows: 'wfixicon icon [options] -d datafile object [palette] [object...]' where 'icon' is the icon file to be generated (see above), 'datafile' is the source from which all objects are taken, and each 'object' is a bitmap or RLE sprite (DAT_BITMAP or DAT_RLE) within the datafile, specified by name. If you have used any 8-bit images, you must also specify a palette. For each palette object you include on the command line, any images between it and the last palette will be given that palette. For example: 'wfixicon i.ico -d d.dat icon icon2 pal1 tool tool2 pal2' will give the icons called 'icon' and 'icon2' the palette 'pal1', and the icons 'tool' and 'tool2' will be given 'pal2'. The wfixicon utility accepts the following options: '-r' Outputs a resource source file (.rc) suited to the icon, in addition to the icon itself. When compiled and linked to an Allegro Windows executable, this file attachs the icon to the executable and makes it the default icon, displayed in the window caption and the task list. '-ro' Same as '-r' but additionally call the resource compiler on the .rc file, making it produce an object file ready to be linked to an Allegro Windows executable, with the same effects as described above. An example of use is provided in the Allegro distribution: the demo program gets a nice little icon (or an ugly one, it's up to you...) extracted from its datafile (with the Borland C++ compiler you need to type 'make fixdemo' from the main directory once you have properly installed the library). allegro-5.0.10/tools/win/wfixicon.c0000644000175000001440000002175311343175441016350 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Allegro bitmap -> Windows icon converter. * * By Elias Pschernig. * * See readme.txt for copyright information. */ #define ALLEGRO_USE_CONSOLE #include #include #include #include #define ICON_MAX 16 /* save_ico: * Saves bitmaps as an .ico, using as palette for 8-bit bitmaps. * Other color depths are saved as 24-bit. */ int save_ico(const char *filename, BITMAP *bmp[], int num, PALETTE pal[]) { PACKFILE *f; int depth, bpp, bw, bitsw; int size, offset, n, i; int c, x, y, b, m, v; errno = 0; f = pack_fopen(filename, F_WRITE); if (!f) return errno; offset = 6 + num * 16; /* ICONDIR + ICONDIRENTRYs */ /* ICONDIR */ pack_iputw(0, f); /* reserved */ pack_iputw(1, f); /* resource type: ICON */ pack_iputw(num, f); /* number of icons */ for(n = 0; n < num; n++) { depth = bitmap_color_depth(bmp[n]); bpp = (depth == 8) ? 8 : 24; bw = (((bmp[n]->w * bpp / 8) + 3) / 4) * 4; bitsw = ((((bmp[n]->w + 7) / 8) + 3) / 4) * 4; size = bmp[n]->h * (bw + bitsw) + 40; if (bpp == 8) size += 256 * 4; /* ICONDIRENTRY */ pack_putc(bmp[n]->w, f); /* width */ pack_putc(bmp[n]->h, f); /* height */ pack_putc(0, f); /* color count */ pack_putc(0, f); /* reserved */ pack_iputw(1, f); /* color planes */ pack_iputw(bpp, f); /* bits per pixel */ pack_iputl(size, f); /* size in bytes of image data */ pack_iputl(offset, f); /* file offset to image data */ offset += size; } for(n = 0; n < num; n++) { depth = bitmap_color_depth(bmp[n]); bpp = (depth == 8) ? 8 : 24; bw = (((bmp[n]->w * bpp / 8) + 3) / 4) * 4; bitsw = ((((bmp[n]->w + 7) / 8) + 3) / 4) * 4; size = bmp[n]->h * (bw + bitsw) + 40; if (bpp == 8) size += 256 * 4; /* BITMAPINFOHEADER */ pack_iputl(40, f); /* size */ pack_iputl(bmp[n]->w, f); /* width */ pack_iputl(bmp[n]->h * 2, f); /* height x 2 */ pack_iputw(1, f); /* planes */ pack_iputw(bpp, f); /* bitcount */ pack_iputl(0, f); /* unused for ico */ pack_iputl(size, f); /* size */ pack_iputl(0, f); /* unused for ico */ pack_iputl(0, f); /* unused for ico */ pack_iputl(0, f); /* unused for ico */ pack_iputl(0, f); /* unused for ico */ /* PALETTE */ if (bpp == 8) { pack_iputl(0, f); /* color 0 is black, so the XOR mask works */ for (i = 1; i<256; i++) { if (pal[n]) { pack_putc(_rgb_scale_6[pal[n][i].b], f); pack_putc(_rgb_scale_6[pal[n][i].g], f); pack_putc(_rgb_scale_6[pal[n][i].r], f); pack_putc(0, f); } else { pack_iputl(0, f); } } } /* XOR MASK */ for (y = bmp[n]->h - 1; y >= 0; y--) { for (x = 0; x < bmp[n]->w; x++) { if (bpp == 8) { pack_putc(getpixel(bmp[n], x, y), f); } else { c = getpixel(bmp[n], x, y); pack_putc(getb_depth(depth, c), f); pack_putc(getg_depth(depth, c), f); pack_putc(getr_depth(depth, c), f); } } /* every scanline must be 32-bit aligned */ while (x&3) { pack_putc(0, f); x++; } } /* AND MASK */ for (y = bmp[n]->h - 1; y >= 0; y--) { for (x = 0; x < (bmp[n]->w + 7)/8; x++) { m = 0; v = 128; for (b = 0; b < 8; b++) { c = getpixel(bmp[n], x * 8 + b, y); if (c == bitmap_mask_color(bmp[n])) m += v; v /= 2; } pack_putc(m, f); } /* every scanline must be 32-bit aligned */ while (x&3) { pack_putc(0, f); x++; } } } pack_fclose(f); return errno; } void usage(void) { printf("\nWindows icon converter for Allegro " ALLEGRO_VERSION_STR "\n"); printf("By Elias Pschernig, " ALLEGRO_DATE_STR "\n\n"); printf("Usage: wfixicon icon [-r[o]] bitmap [bitmap...]\n"); printf(" or\n"); printf(" wfixicon icon [-r[o]] -d datafile object [palette] [object...]\n"); printf(" where each 'object' is a bitmap or a RLE sprite.\n"); printf("Options:\n"); printf(" -r output .rc file for the icon\n"); printf(" -ro call the resource compiler on the .rc file\n"); exit(1); } int main(int argc, char *argv[]) { char dat_name[128], rc_name[128], res_name[128], str[256]; int icon_num = 0, pal_start = 0; int create_rc = FALSE, call_windres = FALSE; int i, j, arg; BITMAP *bmp[ICON_MAX]; PALETTE pal[ICON_MAX]; RLE_SPRITE *sprite; DATAFILE *dat; PACKFILE *f; if (install_allegro(SYSTEM_NONE, &errno, atexit) != 0) exit(EXIT_FAILURE); set_color_conversion(COLORCONV_NONE); if (argc < 3) usage(); dat_name[0] = '\0'; for (arg = 2; arg < argc; arg++) { if (argv[arg][0] == '-') { switch(argv[arg][1]) { case 'd': /* datafile argument */ if (argc < arg+2) usage(); strcpy(dat_name, argv[++arg]); pal_start = icon_num; break; case 'r': create_rc = TRUE; if (argv[arg][2] == 'o') { call_windres = TRUE; } break; default: usage(); } } /* end of '-' handling */ else { if (dat_name[0]) { dat = load_datafile_object(dat_name, argv[arg]); if (!dat) { printf("Error reading %s from %s.\n", argv[arg], dat_name); exit(EXIT_FAILURE); } switch (dat->type) { case DAT_BITMAP: bmp[icon_num] = (BITMAP *)dat->dat; icon_num++; break; case DAT_RLE_SPRITE: sprite = (RLE_SPRITE *)dat->dat; bmp[icon_num] = create_bitmap_ex(sprite->color_depth, sprite->w, sprite->h); clear_to_color(bmp[icon_num], bitmap_mask_color(bmp[icon_num])); draw_rle_sprite(bmp[icon_num], sprite, 0, 0); icon_num++; break; case DAT_PALETTE: if (pal_start == icon_num) usage(); for (j = pal_start; j < icon_num; j++) for (i = 0; i < PAL_SIZE; i++) pal[j][i] = ((RGB *)dat->dat)[i]; pal_start = icon_num; break; default: usage(); } } else { bmp[icon_num] = load_bitmap(argv[arg], pal[icon_num]); if (!bmp[icon_num]) { printf("Error reading %s.\n", argv[arg]); exit(EXIT_FAILURE); } icon_num++; } if (icon_num == ICON_MAX) break; } /* end of normal argument handling */ } if (icon_num == 0) usage(); /* do the hard work */ if (save_ico(argv[1], bmp, icon_num, pal) != 0) { printf("Error writing %s.\n", argv[1]); exit(EXIT_FAILURE); } /* output a .rc file along with the ico, to be processed by the resource compiler */ if (create_rc) { replace_extension(rc_name, argv[1], "rc", sizeof(rc_name)); f = pack_fopen(rc_name, F_WRITE); sprintf(str, "allegro_icon ICON %s\n", argv[1]); pack_fwrite(str, strlen(str), f); pack_fclose(f); if (call_windres) { replace_extension(res_name, argv[1], "res", sizeof(res_name)); #if defined ALLEGRO_MINGW32 sprintf(str, "windres -O coff -o %s -i %s", res_name, rc_name); #elif defined ALLEGRO_MSVC sprintf(str, "rc -fo %s %s", res_name, rc_name); #elif defined ALLEGRO_BCC32 sprintf(str, "brc32 -r -fo %s %s", res_name, rc_name); #endif system(str); delete_file(argv[1]); delete_file(rc_name); } } return 0; } allegro-5.0.10/tools/macosx/0000755000175000001440000000000012157230747015050 5ustar tjadenusersallegro-5.0.10/tools/macosx/fixbundle.c0000644000175000001440000005116311343175441017175 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * MacOS X application bundle fixer utility. Creates an application * bundle out of an executable and some optional icon image files. * * By Angelo Mottola. * * See readme.txt for copyright information. */ #define ALLEGRO_USE_CONSOLE #include #include #include #include #include #include #undef TRUE #undef FALSE #ifndef SCAN_DEPEND #include #endif #undef TRUE #undef FALSE #define TRUE -1 #define FALSE 0 /* 16x16 */ #define ICON_SMALL 0 /* 32x32 */ #define ICON_LARGE 1 /* 48x48 */ #define ICON_HUGE 2 /* 128x128 */ #define ICON_THUMBNAIL 3 #define F_SMALL_DEFINED 0x1 #define F_LARGE_DEFINED 0x2 #define F_HUGE_DEFINED 0x4 #define F_THUMBNAIL_DEFINED 0x8 #define F_ICONS_DEFINED 0xf #define F_MOVE 0x10 #define F_GOT_VERSION 0x20 #define F_GOT_LONG_VERSION 0x40 #define F_EMBED_FRAMEWORK 0x80 #define MAX_STRING_SIZE 1024 #define ONE_SIXTH (1.0 / 6.0) typedef struct ICON_DATA { BITMAP *original, *workspace, *scaled; int size; OSType data, mask8, mask1; int defined; } ICON_DATA; static ICON_DATA icon_data[4] = { { NULL, NULL, NULL, 16, kSmall32BitData, kSmall8BitMask, kSmall1BitMask, F_SMALL_DEFINED }, { NULL, NULL, NULL, 32, kLarge32BitData, kLarge8BitMask, kLarge1BitMask, F_LARGE_DEFINED }, { NULL, NULL, NULL, 48, kHuge32BitData, kHuge8BitMask, kHuge1BitMask, F_HUGE_DEFINED }, { NULL, NULL, NULL, 128, kThumbnail32BitData, kThumbnail8BitMask, 0, F_THUMBNAIL_DEFINED } }; static int flags = 0; static float cubic_bspline(float x) { float a, b, c, d; if (x <= -2.0) a = 0.0; else a = (x + 2.0) * (x + 2.0) * (x + 2.0); if (x <= -1.0) b = 0.0; else b = ((x + 1.0) * (x + 1.0) * (x + 1.0)) * -4.0; if (x <= 0) c = 0.0; else c = (x * x * x) * 6.0; if (x <= 1.0) d = 0.0; else d = ((x - 1.0) * (x - 1.0) * (x - 1.0)) * -4.0; return (a + b + c + d) * ONE_SIXTH; } static int scale_icon(ICON_DATA *icon) { BITMAP *shape; int size, x_ofs = 2, y_ofs = 2; int x, y, m, n; int i_x, i_y; float k, f_x, f_y, a, b, r1, r2; float red, green, blue, alpha; unsigned char *p; unsigned int color; if (icon->original->w > icon->original->h) { size = 4 + icon->original->w; y_ofs = 2 + ((icon->original->w - icon->original->h) / 2); } else { size = 4 + icon->original->h; x_ofs = 2 + ((icon->original->h - icon->original->w) / 2); } k = (float)(size - 4) / (float)icon->size; icon->workspace = create_bitmap_ex(32, size, size); if (!icon->workspace) return -1; icon->scaled = create_bitmap_ex(32, icon->size, icon->size); if (!icon->scaled) return -1; shape = create_bitmap_ex(32, icon->original->w, icon->original->h); if (!shape) return -1; blit(icon->original, shape, 0, 0, 0, 0, icon->original->w, icon->original->h); clear_to_color(icon->workspace, makeacol32(0, 0, 0, 255)); shape->vtable->mask_color = makeacol32(255, 0, 255, 0); masked_blit(shape, icon->workspace, 0, 0, x_ofs, y_ofs, shape->w, shape->h); destroy_bitmap(shape); for (y = 0; y < icon->size; y++) { f_y = (float)y * k; i_y = (int)floor(f_y); a = f_y - floor(f_y); for (x = 0; x < icon->size; x++) { f_x = (float)x * k; i_x = (int)floor(f_x); b = f_x - floor(f_x); red = green = blue = alpha = 0.0; for (m = -1; m < 3; m++) { r1 = cubic_bspline((float)m - a); for (n = -1; n < 3; n++) { r2 = cubic_bspline(b - (float)n); color = ((unsigned int *)(icon->workspace->line[i_y + m + 2]))[i_x + n + 2]; red += ((float)getr32(color) * r1 * r2); green += ((float)getg32(color) * r1 * r2); blue += ((float)getb32(color) * r1 * r2); alpha += ((float)geta32(color) * r1 * r2); } } color = makeacol32((int)floor(red), (int)floor(green), (int)floor(blue), 255 - (int)floor(alpha)); ((unsigned int *)(icon->scaled->line[y]))[x] = color; } } return 0; } static int load_resource(char *datafile, char *name, ICON_DATA *icon) { DATAFILE *data; BITMAP *temp, *bitmap = NULL; RLE_SPRITE *rle_sprite; PALETTE palette; int size, type, i; int result = 0; if (datafile[0] != '\0') { data = load_datafile_object(datafile, name); if (!data) { fprintf(stderr, "Error loading object '%s' from %s\n", name, datafile); return -1; } switch (data->type) { case DAT_BITMAP: temp = (BITMAP *)data->dat; bitmap = create_bitmap_ex(temp->vtable->color_depth, temp->w, temp->h); blit(temp, bitmap, 0, 0, 0, 0, temp->w, temp->h); break; case DAT_RLE_SPRITE: rle_sprite = (RLE_SPRITE *)data->dat; bitmap = create_bitmap_ex(rle_sprite->color_depth, rle_sprite->w, rle_sprite->h); clear_to_color(bitmap, bitmap->vtable->mask_color); draw_rle_sprite(bitmap, rle_sprite, 0, 0); break; case DAT_PALETTE: select_palette((RGB *)data->dat); unload_datafile_object(data); return 0; default: fprintf(stderr, "'%s' is not a BITMAP, RLE_SPRITE or PALETTE object in datafile '%s'\n", name, datafile); unload_datafile_object(data); return -1; } unload_datafile_object(data); } else { bitmap = load_bitmap(name, palette); select_palette(palette); if (!bitmap) { fprintf(stderr, "Unable to load '%s'\n", name); return -1; } } if (!icon) { size = MAX(bitmap->w, bitmap->h); if (size <= 16) type = ICON_SMALL; else if (size <= 32) type = ICON_LARGE; else if (size <= 48) type = ICON_HUGE; else type = ICON_THUMBNAIL; icon = &icon_data[type]; if (flags & icon->defined) { for (i = 0; i < 3; i++) { type = (type + 1) % 4; icon = &icon_data[type]; if (!(flags & icon->defined)) break; } if (flags & icon->defined) { fprintf(stderr, "Too many icon resources!"); result = -1; goto exit_error; } } } else { if (icon->scaled) { fprintf(stderr, "Multiple icon resources of the same size"); result = -1; goto exit_error; } } icon->original = create_bitmap_ex(bitmap->vtable->color_depth, bitmap->w, bitmap->h); blit(bitmap, icon->original, 0, 0, 0, 0, bitmap->w, bitmap->h); result = scale_icon(icon); flags |= icon->defined; exit_error: destroy_bitmap(bitmap); return result; } static void usage(void) { fprintf(stderr, "\nMacOS X application bundle fixer utility for Allegro " ALLEGRO_VERSION_STR "\n" "By Angelo Mottola, " ALLEGRO_DATE_STR "\n\n" "Usage: fixbundle exename [-m] [-o bundlename] [-v version] [-V long_version]\n" "\t\t[-e] [[-d datafile] [[palette] [-{16,32,48,128}] icon] ...]\n" "\twhere icon is either a datafile bitmap or a RLE sprite object, either\n" "\tan image file.\n" "Options:\n" "\t-m\t\tMoves executable inside bundle instead of copying it\n" "\t-o bundlename\tSpecifies a bundle name (default: exename.app)\n" "\t-v version\tSets application version string (default: 1.0)\n" "\t-V long_version\tSets long application version string\n" "\t-e\t\tEmbeds the Allegro framework into the application bundle\n" "\t-d datafile\tUses datafile as source for objects and palettes\n" "\t-{16,32,48,128}\tForces next icon image into the 16x16, 32x32, 48x48 or\n" "\t\t\t128x128 icon resource slot\n" "\n"); exit(EXIT_FAILURE); } static int copy_file(const char *filename, const char *dest_path) { char *buffer = NULL; char dest_file[1024]; PACKFILE *f; size_t size; if (!exists(filename)) return -1; buffer = malloc(size = file_size_ex(filename)); if (!buffer) return -1; append_filename(dest_file, dest_path, get_filename(filename), 1024); f = pack_fopen(filename, F_READ); if (!f) { free(buffer); return -1; } pack_fread(buffer, size, f); pack_fclose(f); f = pack_fopen(dest_file, F_WRITE); if (!f) { free(buffer); return -1; } pack_fwrite(buffer, size, f); pack_fclose(f); free(buffer); return 0; } /* main: * Guess what this function does. */ int main(int argc, char *argv[]) { PACKFILE *f; CFURLRef cf_url_ref; FSRef fs_ref; FSSpec fs_spec; IconFamilyHandle icon_family; Handle raw_data; char datafile[MAX_STRING_SIZE]; char bundle[MAX_STRING_SIZE]; char bundle_dir[MAX_STRING_SIZE]; char bundle_contents_dir[MAX_STRING_SIZE]; char bundle_contents_resources_dir[MAX_STRING_SIZE]; char bundle_contents_macos_dir[MAX_STRING_SIZE]; char bundle_contents_frameworks_dir[MAX_STRING_SIZE]; char *bundle_exe = NULL; char bundle_plist[MAX_STRING_SIZE]; char bundle_pkginfo[MAX_STRING_SIZE]; char bundle_icns[MAX_STRING_SIZE]; char bundle_version[MAX_STRING_SIZE]; char bundle_long_version[MAX_STRING_SIZE]; char *buffer = NULL; int arg, type = 0, result = 0; int i, size, x, y, mask_bit, mask_byte; unsigned char *data; install_allegro(SYSTEM_NONE, &errno, &atexit); set_color_depth(32); set_color_conversion(COLORCONV_TOTAL | COLORCONV_KEEP_TRANS); if (argc < 2) usage(); datafile[0] = '\0'; bundle[0] = '\0'; select_palette(black_palette); /* Parse command line and load any given resource */ for (arg = 2; arg < argc; arg++) { if (!strcmp(argv[arg], "-m")) flags |= F_MOVE; else if (!strcmp(argv[arg], "-e")) flags |= F_EMBED_FRAMEWORK; else if (!strcmp(argv[arg], "-o")) { if ((argc < arg + 2) || (bundle[0] != '\0')) usage(); strcpy(bundle, argv[++arg]); } else if (!strcmp(argv[arg], "-v")) { if (argc < arg + 2) usage(); flags |= F_GOT_VERSION; strcpy(bundle_version, argv[++arg]); } else if (!strcmp(argv[arg], "-V")) { if (argc < arg + 2) usage(); flags |= F_GOT_LONG_VERSION; strcpy(bundle_long_version, argv[++arg]); } else if (!strcmp(argv[arg], "-d")) { if (argc < arg + 2) usage(); strcpy(datafile, argv[++arg]); } else if ((!strcmp(argv[arg], "-16")) || (!strcmp(argv[arg], "-32")) || (!strcmp(argv[arg], "-48")) || (!strcmp(argv[arg], "-128"))) { if (argc < arg + 2) usage(); switch (atoi(&argv[arg][1])) { case 16: type = 0; break; case 32: type = 1; break; case 48: type = 2; break; case 128: type = 3; break; } if (load_resource(datafile, argv[++arg], &icon_data[type])) { result = -1; goto exit_error; } } else { if (load_resource(datafile, argv[arg], NULL)) { result = -1; goto exit_error; } } } buffer = malloc(4096); if (!buffer) { result = -1; goto exit_error_bundle; } bundle_exe = argv[1]; if (!exists(bundle_exe)) { fprintf(stderr, "Cannot locate executable file '%s'\n", bundle_exe); result = -1; goto exit_error; } if (bundle[0] == '\0') strcpy(bundle, bundle_exe); replace_extension(bundle_dir, bundle, "app", MAX_STRING_SIZE); strcpy(bundle_contents_dir, bundle_dir); strcat(bundle_contents_dir, "/Contents"); strcpy(bundle_contents_resources_dir, bundle_contents_dir); strcat(bundle_contents_resources_dir, "/Resources"); strcpy(bundle_contents_macos_dir, bundle_contents_dir); strcat(bundle_contents_macos_dir, "/MacOS"); strcpy(bundle_contents_frameworks_dir, bundle_contents_dir); strcat(bundle_contents_frameworks_dir, "/Frameworks"); bundle_icns[0] = '\0'; bundle_plist[0] = '\0'; bundle_pkginfo[0] = '\0'; /* Create bundle structure */ if ((mkdir(bundle_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_resources_dir, 0777) && (errno != EEXIST)) || (mkdir(bundle_contents_macos_dir, 0777) && (errno != EEXIST))) { fprintf(stderr, "Cannot create %s\n", bundle_dir); result = -1; goto exit_error_bundle; } /* Copy/move executable into the bundle */ if (copy_file(bundle_exe, bundle_contents_macos_dir)) { fprintf(stderr, "Cannot create %s\n", bundle_contents_macos_dir); result = -1; goto exit_error_bundle; } strcat(bundle_contents_macos_dir, "/"); strcat(bundle_contents_macos_dir, get_filename(bundle_exe)); chmod(bundle_contents_macos_dir, 0755); if (flags & F_MOVE) unlink(bundle_exe); /* Embed Allegro framework if requested */ if (flags & F_EMBED_FRAMEWORK) { if (!file_exists("/Library/Frameworks/Allegro.framework", FA_RDONLY | FA_DIREC, NULL)) { fprintf(stderr, "Cannot find Allegro framework\n"); result = -1; goto exit_error_bundle; } if (!exists("/Library/Frameworks/Allegro.framework/Resources/Embeddable")) { fprintf(stderr, "Cannot embed system wide Allegro framework; install embeddable version first!\n"); result = -1; goto exit_error_bundle; } sprintf(buffer, "/Developer/Tools/pbxcp -exclude .DS_Store -exclude CVS -resolve-src-symlinks /Library/Frameworks/Allegro.framework %s", bundle_contents_frameworks_dir); if ((mkdir(bundle_contents_frameworks_dir, 0777) && (errno != EEXIST)) || (system(buffer))) { fprintf(stderr, "Cannot create %s\n", bundle_contents_frameworks_dir); result = -1; goto exit_error_bundle; } } /* Setup the .icns resource */ if (flags & F_ICONS_DEFINED) { strcat(bundle_contents_resources_dir, "/"); strcat(bundle_contents_resources_dir, get_filename(bundle)); replace_extension(bundle_icns, bundle_contents_resources_dir, "icns", MAX_STRING_SIZE); icon_family = (IconFamilyHandle)NewHandle(0); for (i = 0; i < 4; i++) { if (flags & icon_data[i].defined) { /* Set 32bit RGBA data */ raw_data = NewHandle(icon_data[i].size * icon_data[i].size * 4); data = *(unsigned char **)raw_data; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getr32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getg32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); *data++ = getb32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); } } if (SetIconFamilyData(icon_family, icon_data[i].data, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource RGBA data\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); /* Set 8bit mask */ raw_data = NewHandle(icon_data[i].size * icon_data[i].size); data = *(unsigned char **)raw_data; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); } } if (SetIconFamilyData(icon_family, icon_data[i].mask8, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource 8bit mask\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); /* Set 1bit mask */ if (icon_data[i].mask1) { size = ((icon_data[i].size * icon_data[i].size) + 7) / 8; raw_data = NewHandle(size * 2); data = *(unsigned char **)raw_data; mask_byte = 0; mask_bit = 7; for (y = 0; y < icon_data[i].size; y++) { for (x = 0; x < icon_data[i].size; x++) { if (geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]) >= 0xfd) mask_byte |= (1 << mask_bit); mask_bit--; if (mask_bit < 0) { *data++ = mask_byte; mask_byte = 0; mask_bit = 7; } } } memcpy(*raw_data + size, *raw_data, size); if (SetIconFamilyData(icon_family, icon_data[i].mask1, raw_data) != noErr) { DisposeHandle(raw_data); fprintf(stderr, "Error setting %dx%d icon resource 1bit mask\n", icon_data[i].size, icon_data[i].size); result = -1; goto exit_error_bundle; } DisposeHandle(raw_data); } } } f = pack_fopen(bundle_icns, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } pack_fclose(f); cf_url_ref = CFURLCreateWithBytes(kCFAllocatorDefault, (unsigned char *)bundle_icns, strlen(bundle_icns), 0, NULL); if (!cf_url_ref) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } CFURLGetFSRef(cf_url_ref, &fs_ref); CFRelease(cf_url_ref); if ((FSGetCatalogInfo(&fs_ref, kFSCatInfoNone, NULL, NULL, &fs_spec, NULL)) || (WriteIconFile(icon_family, &fs_spec) != noErr)) { fprintf(stderr, "Cannot create %s\n", bundle_icns); result = -1; goto exit_error_bundle; } DisposeHandle((Handle)icon_family); } /* Setup Info.plist */ sprintf(bundle_plist, "%s/Info.plist", bundle_contents_dir); f = pack_fopen(bundle_plist, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_plist); result = -1; goto exit_error_bundle; } sprintf(buffer, "\n" "\n" "\n" "\n" "\tCFBundleExecutable\n" "\t%s\n" "\tCFBundleInfoDictionaryVersion\n" "\t6.0\n" "\tCFBundlePackageType\n" "\tAPPL\n" "\tCFBundleSignature\n" "\t%s\n" "\tCFBundleVersion\n" "\t%s\n" "\tCFBundleDocumentTypes\n" "\t\n" "\t\t\n" "\t\t\tCFBundleTypeExtensions\n" "\t\t\t\n" "\t\t\t\t*\n" "\t\t\t\n" "\t\t\tCFBundleTypeName\n" "\t\t\tNSStringPboardType\n" "\t\t\tCFBundleTypeOSTypes\n" "\t\t\t\n" "\t\t\t\t****\n" "\t\t\t\n" "\t\t\tCFBundleTypeRole\n" "\t\t\tViewer\n" "\t\t\n" "\t\n", get_filename(bundle_exe), "????", (flags & F_GOT_VERSION) ? bundle_version : "1.0"); pack_fputs(buffer, f); if (flags & F_GOT_LONG_VERSION) { sprintf(buffer, "\tCFBundleGetInfoString\n" "\t%s\n", bundle_long_version); pack_fputs(buffer, f); } if (flags & F_ICONS_DEFINED) { sprintf(buffer, "\tCFBundleIconFile\n" "\t%s\n", get_filename(bundle_icns)); pack_fputs(buffer, f); } pack_fputs("\n\n", f); pack_fclose(f); /* Setup PkgInfo */ sprintf(bundle_pkginfo, "%s/PkgInfo", bundle_contents_dir); f = pack_fopen(bundle_pkginfo, F_WRITE); if (!f) { fprintf(stderr, "Cannot create %s\n", bundle_pkginfo); result = -1; goto exit_error_bundle; } pack_fputs("APPL????", f); pack_fclose(f); exit_error: if (buffer) free(buffer); for (i = 0; i < 4; i++) { if (icon_data[i].original) destroy_bitmap(icon_data[i].original); if (icon_data[i].workspace) destroy_bitmap(icon_data[i].workspace); if (icon_data[i].scaled) destroy_bitmap(icon_data[i].scaled); } return result; exit_error_bundle: sprintf(buffer, "%s/%s", bundle_contents_macos_dir, get_filename(bundle_exe)); unlink(buffer); unlink(bundle_plist); unlink(bundle_pkginfo); unlink(bundle_icns); rmdir(bundle_dir); rmdir(bundle_contents_dir); rmdir(bundle_contents_resources_dir); rmdir(bundle_contents_macos_dir); goto exit_error; } allegro-5.0.10/tools/x11/0000755000175000001440000000000012157230751014162 5ustar tjadenusersallegro-5.0.10/tools/x11/xkeymap.txt0000644000175000001440000001011307571172556016411 0ustar tjadenusersxkeymap - X Window System keyboard mapping utility for Allegro by Michael Bukin, modified by Elias Pschernig 0. Quickstart - Make sure you have an appropriate "keyboard=" entry in your allegro.cfg. - Run xkeymap, and click on the "Setup key mappings" button. - Select Allegro scancodes from the list, and hit corresponding keys on your keyboard. - "Save and exit", and paste the generated file xkeymap.cfg into your allegro.cfg. - If Allegro's keyboard mapping is still broken, reading on probably won't help - in this case you can write to the mailing lists or the web forum on allegro.cc. 1. Why it is needed To achieve maximum portability, Allegro does its own key-mapping, directly reading in raw scancodes from the keyboard. While on some platforms, like DOS, Windows or QNX, it is possible to directly read in these scancodes, on other platforms, like X, this is not possible. In X, Allegro can only read in virtual keycodes produced by X, which already depend on the keyboard layout specifications. Because of that, you have to provide a keyboard configuration which maps the X virtual keycodes back to the raw scancodes. This utility makes it easy to create the right configuration, by giving you a selection of Allegro keycodes and asking you to press the corresponding key on your keyboard, so the X virtual keycode can be detected. Note that X may completely block some keys which, therefore, can't be detected at all by user programs. (For me, this is the case for the left control key and the menu key.) 2. How to use it Make sure your standard allegro.cfg (either ./allegro.cfg, ~/allegro.cfg, ~/.allegrorc, /etc/allegro.cfg, or /etc/allegrorc) contains the right "keyboard=" line for your keyboard layout, for example "keyboard=es" for a Spanish layout - before running the program. Alternatively, you can click on the button labelled "Default" to directly load a keyboard layout file. Some layouts ship with Allegro and can be found in the "resources/keyboard" folder. Or you can create your own with the keyconf utility. Now click on the "Setup key mappings" button. It shows you a list containing all Allegro keycodes. Select any keycode with the mouse or cursor keys, and hit return (or double-click, or click the button below it). Then press the key on your keyboard whose X code should be seen by Allegro as the selected key. Normally, you want to ignore the "KEY_" name of the key, and only look at the letters displayed below the "Produces:" button, which tell what characters are produced when hitting the key, or Shift+key or AltGr+key combinations. For example, if you have "keyboard=de" in your allegro.cfg, the key KEY_Y will show "z Z", and you should press the key labelled 'Z' on your keyboard, not 'Y'. The "Done" button takes you back to the main menu, where you can test the current mapping with the "Test key mappings" button. Use "Save and exit" to write the X mappings into a file called "xkeymap.cfg", the contents of which you should paste into your allegro.cfg. 3. Example from my current system I'm using a Debian-Linux-i386 version with XFree86 4.2.1 and a PC keyboard, and the following standard keyboard layout is specified in /etc/X11/XF86Config (for a german keyboard layout): Section "InputDevice" Identifier "Keyboard0" Driver "keyboard" Option "XkbKeycodes" "xfree86" Option "XkbTypes" "default" Option "XkbCompat" "default" Option "XkbSymbols" "en_US(pc105)+de" Option "XkbGeometry" "pc(pc105)" EndSection My allegro.cfg is in /etc/allegro.cfg, and contains this: [system] keyboard = de language = de Using the xkeymap utility, and typing in all keys which were not working before, produced the following xkeymap.cfg for me. I just pasted it at the beginning of my /etc/allegro.cfg - and now have a 100% working keyboard in Allegro programs :) [xkeymap] keycode20 = 12 keycode21 = 13 keycode29 = 21 keycode34 = 26 keycode35 = 27 keycode47 = 39 keycode48 = 40 keycode49 = 41 keycode51 = 43 keycode52 = 44 keycode59 = 51 keycode60 = 52 keycode61 = 53 keycode64 = 56 keycode94 = 214 keycode113 = 184 keycode115 = 219 keycode116 = 220 allegro-5.0.10/tools/x11/xfixicon.sh0000644000175000001440000000237210732545712016354 0ustar tjadenusers#! /bin/sh # Generate X11 icon # Usage: xfixicon iconfile if test -z "$1"; then echo "Usage:" echo " xfixicon iconfile [-o outputfile]" echo "this will generate a C file that can be linked with your application" echo "to set the X11 icon automatically." echo "" echo "Options:" echo " -o Set the name of the output file. Default name is allegro_icon.c" exit fi outfile="allegro_icon.c" while !(test -z "$1"); do if (test "$1" = "-o"); then outfile=$2 shift else file=$1 fi shift done if !(test -e "$file"); then echo "File not found: $file" exit 1 fi if !(convert -transparent "magenta" "$file" "/tmp/allegico_xpm.xpm"); then echo "Conversion failed" exit 1 fi echo "#include " > $outfile cat /tmp/allegico_xpm.xpm | sed -e 's,static char,static const char,' >> $outfile echo "#if defined ALLEGRO_WITH_XWINDOWS && defined ALLEGRO_USE_CONSTRUCTOR" >> $outfile echo "extern void *allegro_icon;" >> $outfile echo "CONSTRUCTOR_FUNCTION(static void _set_allegro_icon(void));" >> $outfile echo "static void _set_allegro_icon(void)" >> $outfile echo "{" >> $outfile echo " allegro_icon = allegico_xpm;" >> $outfile echo "}" >> $outfile echo "#endif" >> $outfile rm /tmp/allegico_xpm.xpm allegro-5.0.10/tools/x11/xf2pcx.c0000644000175000001440000002173711327152025015545 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Utility to convert X11 fonts to a PCX file, ready for use in the * grabber. * * By Michael Bukin, 1998. * * Minor changes in 2002 by Peter Wang. * * Minor changes in 2003 by Elias Pschernig. * * See readme.txt for copyright information. */ #include #include #include #include #ifndef SCAN_DEPEND #include #include #endif /* usage: * Show usage information. */ static void usage(char *argv0) { printf("Usage: %s [OPTIONS]\n\n", argv0); printf(" -f FONTNAME Font name pattern ('*' by default).\n" " -o FILENAME Output file name ('font.pcx' by default).\n" " -r NUM-NUM Character range, default = 0x20-0xff.\n" " -c COLOR Character color (default 000000000 -- black).\n" " -b COLOR Background color (default 255255255 -- white).\n" " -g COLOR Grid color (default 255000255 -- magenta).\n" " Colors are specified as RRRGGGBBB values,\n" " with each RRR, GGG and BBB in the range [0, 255].\n" " -h This help.\n" "\n" "Find the font you want to convert using xlsfonts or xfontsel.\n\n" "Example 1:\n" "bash> xlsfonts -fn '*' | less\n" "bash> %s -f '-adobe-courier-medium-r-normal--34-*'\n" "bash> grabber\n\n" "In grabber, create a new font 'Object|New|Font'. Use 'Object|Grab'\n" "on this object and choose the pcx file with the font (font.pcx).\n\n" "Example 2:\n" "./xf2pcx -f '-*-clearlyu-*-*-*-*-17-*-*-*-p--iso10646-1' -r 0x2800-0x28ff -o braille.pcx\n\n" "Writes the Braille alphabet into braille.pcx.\n", argv0); } int main(int argc, char *argv[]) { /* default values for -f, -i, -r, -c, -b, -g */ char *fontname = "*"; char *filename = "font.pcx"; int start_char = 32, end_char = 255; int ccolor = 000000000; int bcolor = 255255255; int gcolor = 255000255; /* X11 variables */ Display *display; int screen_number; int default_depth; Window window; Font font; GC gc, gc2; Pixmap pixmap; XImage *image; XCharStruct overall; /* misc variables */ int bitmap_width, bitmap_height; int max_ascent, max_descent; int max_width, max_height; int i, opt, x, y, cx, cy, sx, sy, lines; unsigned long black, white; BITMAP *bitmap; RGB palette[256]; /* show usage if no options */ if (argc == 1) { usage(argv[0]); exit(EXIT_SUCCESS); } /* only to access bitmap operations */ install_allegro(SYSTEM_NONE, &errno, atexit); /* parse options */ opterr = 0; while ((opt = getopt(argc, argv, "f:o:z:c:b:g:r:h")) != EOF) { switch (opt) { case 'f': fontname = optarg; break; case 'o': filename = optarg; break; case 'c': ccolor = atol(optarg); break; case 'b': bcolor = atol(optarg); break; case 'g': gcolor = atol(optarg); break; case 'r': { char *str; start_char = strtol(optarg, &str, 0); end_char = strtol(str + 1, NULL, 0); break; } case 'h': usage(argv[0]); exit(EXIT_SUCCESS); default: fprintf(stderr, "%s: unrecognized option -- '%c'\n", argv[0], optopt); fprintf(stderr, "%s: try '%s -h' for more information\n", argv[0], argv[0]); exit(EXIT_FAILURE); } } /* open display */ display = XOpenDisplay(0); if (display == 0) { fprintf(stderr, "%s: XOpenDisplay failed\n", argv[0]); exit(EXIT_FAILURE); } /* default screen number and window */ screen_number = XDefaultScreen(display); default_depth = XDefaultDepth(display, screen_number); window = XDefaultRootWindow(display); /* load font */ font = XLoadFont(display, fontname); /* create gcs */ { unsigned long val_mask; XGCValues val_bits; val_mask = GCForeground | GCBackground | GCFont | GCFunction; val_bits.function = GXcopy; val_bits.foreground = white = WhitePixel(display, screen_number); val_bits.background = black = BlackPixel(display, screen_number); val_bits.font = font; gc = XCreateGC(display, window, val_mask, &val_bits); val_mask = GCForeground; val_bits.foreground = black; gc2 = XCreateGC(display, window, val_mask, &val_bits); } /* query font ascent and descent */ { XFontStruct *xfs; int min, max; xfs = XQueryFont(display, font); max_ascent = xfs->ascent; max_descent = xfs->descent; if (xfs->min_byte1 == 0 && xfs->max_byte1 == 0) { min = xfs->min_char_or_byte2; max = xfs->max_char_or_byte2; } else { min = (xfs->min_byte1 << 8) + xfs->min_char_or_byte2; max = (xfs->max_byte1 << 8) + xfs->max_char_or_byte2; } if (start_char < min || end_char > max) fprintf(stderr, "You specified characters %04x-%04x, but this font " "only has the range %04x-%04x\n", start_char, end_char, min, max); XFreeFontInfo(NULL, xfs, 0); } /* calculate bitmap width and maximum ascent and descent of characters * (can exceed the font ascent/descent queried above!) */ max_width = 0; lines = 1 + (end_char - start_char) / 16; for (cy = 0; cy < lines; cy++) { for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { int dir, ascent, descent; int width; XChar2b string[2] = { {0, 0}, {0, 0} }; /* query character size */ string[0].byte1 = (start_char + cy * 16 + cx) >> 8; string[0].byte2 = (start_char + cy * 16 + cx) & 255; XQueryTextExtents16(display, font, string, 1, &dir, &ascent, &descent, &overall); width = overall.width; if (width < 1) width = 1; if (width > max_width) max_width = width; if (max_ascent < overall.ascent) max_ascent = overall.ascent; if (max_descent < overall.descent) max_descent = overall.descent; } } max_height = max_ascent + max_descent; bitmap_width = (max_width + 1) * 16 + 1; bitmap_height = (max_height + 1) * lines + 1; /* create bitmap */ bitmap = create_bitmap(bitmap_width, bitmap_height); if (bitmap == 0) { fprintf(stderr, "%s: can not create bitmap\n", argv[0]); exit(EXIT_FAILURE); } /* fill with filler color */ clear_to_color(bitmap, 255); /* process all characters */ sy = 1; for (cy = 0; cy < lines; cy++) { sx = 1; for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { int dir, ascent, descent; XChar2b string[2] = { {0, 0}, {0, 0} }; /* query character size */ string[0].byte1 = (start_char + cy * 16 + cx) >> 8; string[0].byte2 = (start_char + cy * 16 + cx) & 255; XQueryTextExtents16(display, font, string, 1, &dir, &ascent, &descent, &overall); if (overall.width < 1) overall.width = 1; /* create pixmap and draw character there */ pixmap = XCreatePixmap(display, window, overall.width, max_height, default_depth); /* some fonts draw outside their ascent/descent, so we need to clear * the pixmap before drawing the glyph */ XFillRectangle(display, pixmap, gc2, 0, 0, overall.width, max_height); XDrawImageString16(display, pixmap, gc, 0, max_ascent, string, 1); /* create image with pixmap contents */ image = XGetImage(display, pixmap, 0, 0, overall.width, max_height, AllPlanes, ZPixmap); if (image == 0) { fprintf(stderr, "%s: can not get image\n", argv[0]); exit(EXIT_FAILURE); } /* copy image to bitmap */ for (y = 0; y < max_height; y++) for (x = 0; x < overall.width; x++) { if (XGetPixel(image, x, y) == white) putpixel(bitmap, sx + x, sy + y, 1); else putpixel(bitmap, sx + x, sy + y, 0); } XDestroyImage(image); XFreePixmap(display, pixmap); sx += max_width + 1; } sy += max_height + 1; } /* initialize palette */ for (i = 0; i < 256; i++) palette[i].r = palette[i].g = palette[i].b = 0; #define CLAMP(v) (((v / 4) > 63) ? 63 : (v / 4)) palette[0].r = CLAMP(bcolor / 1000000); palette[0].g = CLAMP((bcolor % 1000000) / 1000); palette[0].b = CLAMP(bcolor % 1000); palette[1].r = CLAMP(ccolor / 1000000); palette[1].g = CLAMP((ccolor % 1000000) / 1000); palette[1].b = CLAMP(ccolor % 1000); palette[255].r = CLAMP(gcolor / 1000000); palette[255].g = CLAMP((gcolor % 1000000) / 1000); palette[255].b = CLAMP(gcolor % 1000); #undef CLAMP save_pcx(filename, bitmap, palette); /* clean up */ destroy_bitmap(bitmap); XFreeGC(display, gc); XFreeGC(display, gc2); XUnloadFont(display, font); XCloseDisplay(display); exit(EXIT_SUCCESS); } allegro-5.0.10/tools/x11/xkeymap.c0000644000175000001440000002031011343175441016000 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Utility to create mapping from X keycodes to Allegro scancodes. * * By Michael Bukin, modified by Elias Pschernig. * * See readme.txt for copyright information. */ #include #include #include #include #define FILENAME_LENGTH 1024 char unicode_description[256] = ""; static DIALOG main_dialog[]; static DIALOG keymap_dialog[]; static int black = 0; static int white = 1; static int red = 2; static int yellow = 3; static volatile int waiting_for_key = 0; static volatile int new_keycode = 0; static int keycode_to_scancode[256]; static void get_raw_keycode(int pressed, int keycode) { if (pressed && waiting_for_key) { new_keycode = keycode; waiting_for_key = 0; } } static const char *keycode_getter(int index, int *list_size) { if (index >= 0) { return scancode_to_name(index + 1); } else { *list_size = KEY_MAX - 1; return NULL; } } static DIALOG keymap_dialog[] = { /* 0 */{d_clear_proc, 0, 0, 250, 230, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}, /* 1 */{d_ctext_proc, 125, 10, 0, 16, 0, 255, 0, 0, 0, 0, "Select Keycode:", NULL, NULL}, /* 2 */{d_list_proc, 0, 32, 230, 92, 0, 255, 0, D_EXIT, 0, 0, (void *)keycode_getter, NULL, NULL}, /* 3 */{d_ctext_proc, 125, 142, 0, 16, 0, 255, 0, 0, 0, 0, unicode_description, NULL, NULL}, /* 4 */{d_button_proc, 10, 164, 230, 16, 0, 255, 0, D_EXIT, 0, 0, "Define &X Key !", NULL, NULL}, /* 5 */{d_button_proc, 10, 186, 110, 16, 0, 255, 27, D_EXIT, 0, 0, "&Cancel", NULL, NULL}, /* 6 */{d_button_proc, 130, 186, 110, 16 , 0, 255, 0, D_EXIT, 0, 0, "&Done", NULL, NULL}, /* 7 */{d_ctext_proc, 125, 208, 0, 16, 0, 255, 0, 0, 0, 0, "", NULL, NULL}, {d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}, {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL} }; /* handle the setup command */ static void setup_all_keys(void) { int focus = 2; int i; /* Prepare dialog. */ set_dialog_color(keymap_dialog, black, white); centre_dialog(keymap_dialog); /* Parse input. */ while (1) { focus = do_dialog(keymap_dialog, focus); switch (focus) { case 2: case 4: textprintf_centre_ex (screen, font, keymap_dialog[7].x, keymap_dialog[7].y, red, -1, "Press a key to map to the current scancode"); textprintf_centre_ex (screen, font, keymap_dialog[7].x, keymap_dialog[7].y + 8, red, -1, "(or a mouse button to leave it unchanged)"); /* Wait for new key press. */ new_keycode = -1; waiting_for_key = 1; do { poll_keyboard(); poll_mouse(); if (mouse_b) waiting_for_key = 0; } while (waiting_for_key); /* Save keycode to scancode mapping. */ if ((new_keycode >= 0) && (new_keycode < 256)) { keycode_to_scancode[new_keycode] = keymap_dialog[2].d1 + 1; } clear_keybuf(); break; case 5: return; case 6: for (i = 0; i < 256; i++) { if (keycode_to_scancode[i] >= 0) _xwin.keycode_to_scancode[i] = keycode_to_scancode[i]; } return; } } } static void test_key_map(void) { int i, k, u; static int key_was_pressed[KEY_MAX + 1] = {0}; static int key_is_pressed[KEY_MAX + 1] = {0}; static char *welcome[] = { "Key that is pressed now is marked with red", "Key that was pressed is marked with yellow", "Press mouse button or Escape to exit test", 0 }; /* Clear screen and output prompt. */ clear_to_color(screen, white); for (i = 0; welcome[i] != 0; i++) textout_ex(screen, font, welcome[i], 8, i * 8 + 8, black, -1); clear_to_color(screen, white); for (i = 0; i < KEY_MAX; i++) textprintf_ex(screen, font, 32 + (i % 4) * 160, 32 + (i / 4) * 14, black, -1, "%s", scancode_to_name (i)); do { poll_keyboard(); poll_mouse(); } while ((key[KEY_ESC]) || (mouse_b)); do { while (keypressed()) { u = ureadkey (&k); textprintf_centre_ex (screen, font, SCREEN_W / 2, 8, red, white, "> %c <", u); } poll_keyboard(); poll_mouse(); for (i = 0; i < KEY_MAX; i++) { if (key[i]) key_was_pressed[i] = key_is_pressed[i] = 1; else key_is_pressed[i] = 0; } for (i = 0; i < KEY_MAX; i++) { int x = 16 + (i % 4) * 160; int y = 32 + (i / 4) * 14; if (key_is_pressed[i]) rectfill(screen, x, y, x + 7, y + 7, red); else if (key_was_pressed[i]) rectfill(screen, x, y, x + 7, y + 7, yellow); else rectfill(screen, x, y, x + 7, y + 7, white); } rest(1); } while ((!key[KEY_ESC]) && (!mouse_b)); do { poll_keyboard(); poll_mouse(); } while ((key[KEY_ESC]) || (mouse_b)); clear_keybuf(); } /* handle the save command */ static void save_key_map(void) { int i; char *section, *option_format, option[80], tmp1[80], tmp2[80]; set_config_file("xkeymap.cfg"); section = uconvert_ascii("xkeymap", tmp1); option_format = uconvert_ascii("keycode%d", tmp2); for (i = 0; i < 256; i++) { if (keycode_to_scancode[i] > 0) { uszprintf(option, sizeof(option), option_format, i); set_config_int(section, option, keycode_to_scancode[i]); } } } /* reads a specific keymapping table from the config file */ void load_table(unsigned short *table, char *section) { char name[80]; int i; for (i=0; i Copyright (c) 2002-2008 Paul Hsieh All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of bstrlib nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------- Some Allegro examples use a font from DejaVu fonts, their license can be found here: allegro-5.0.10/README_iphone.txt0000644000175000001440000000334711721435714015462 0ustar tjadenusersIPhone ====== Can use either OpenGL ES 1 or 2 for graphics, by default OpenGL ES 1 is used. The accelerometer axes are reported as joystick axes. Dependencies ------------ For most things no additional dependencies besides the IPhone SDK are needed. The download section on liballeg.org has some pre-compiled IPhone versions of Freetype (.ttf support), Tremor (.ogg support) and Physfs (.zip) support. Building -------- In theory, you build like this: mkdir build cd build cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-iphone.cmake -G Xcode .. xcodebuild # but does not work without manual changes, see below However, many things cannot be set up by cmake, so you have to do them by hand. (An Xcode project named ALLEGRO should be in your build folder which you can open by double clicking.) Here's a list of things to adjust: - Set per-project XCode options (like ipad/iphone target). Some things are right now set per-target from cmake so to change those you need to edit the CMakeLists.txt. Here are some settings you want to change in the Build Settings for your project: * Base SDK * Architectures * Code Signing Identity * Targeted Device Family - Find the correct libraries (cmake always thinks it is building for OSX instead of IPhone). They are all hacked in with linker flags right now. The deps folder (see README_cmake.txt) can however make things a lot easier. For example if you have freetype for iphone you could do this: mkdir deps cp -r my_iphone_freetype/{libs,include} deps And cmake should pick it up if they use the standard names. - Attach resources to a bundle. For the demos and examples you need to add the data folder by hand to get them transferred to the device. allegro-5.0.10/README_msvc.txt0000644000175000001440000000715611520362452015145 0ustar tjadenusersBuilding Allegro with MSVC ========================== There are a lot of variations to the build process, but we will just stick with one to keep things simple. If you know what you are doing, you can do something else. 1. Unpack Allegro into a directory *without spaces or other "weird" characters in the path*. This is a known problem. 2. Create a build directory under the Allegro directory. Optionally, create a deps directory and place the headers and libraries of third party dependencies in there. See README_cmake.txt about this. 3. Start the Microsoft Visual Studio IDE, then bring up a command prompt by clicking "Tools > Visual Studio 20xx Command Prompt". 4. Make sure cmake is in your PATH. Typing "cmake" should display the help message. If it doesn't, you can set the PATH manually by typing "SET PATH=C:\cmake\bin\;%PATH%" or similar. Make sure the MSVC compiler cl.exe and lib.exe also run correctly. 5. Go to the Allegro build directory: cd \allegro\Build 6. Run CMake to configure everything. We will use the CMake GUI. cmake-gui .. 7. Press "Configure". Watch for messages about missing headers and libraries. If anything is missing, you can give CMake a helping hand by setting _INCLUDE_DIR and _LIBRARY options manually, e.g. if ZLIB is not found you would set ZLIB_INCLUDE_DIR and ZLIB_LIBRARY. You may have to switch to "Advanced View" in order to see the variables. Once done, press "Configure" again. 8. Press "Generate". CMake will now generate a project solution. *Note:* As of the time this is written, CMake has a bug that causes the DLLs in MSVC 10 to be named incorrectly. To work around this, generate MSVC 9 projects instead. You may need to uncomment the line "#define ALLEGRO_HAVE_STDINT_H" in alplatf.h. Alternatively, use nmake instead of project files. 9. Open up the project solution with the MSVC IDE and start building. Running the examples ==================== If you build Allegro as a shared library (the default), the example programs will probably not run as-is, because they cannot find the Allegro DLLs. You may: - manually copy the Allegro DLLs into the Build/examples directory where they will be found when the example is run; or - build the INSTALL project, which copies the library files into the MSVC search path (%VCINSTALLDIR%\bin). You may not want to make a mess in there. - The most drastic solution is to copy them into your C:\WINDOWS\SYSTEM32 directory, but most people prefer not to make a mess in that directory. By default, Allegro will load FLAC and Ogg Vorbis DLLs at runtime. If it cannot find them, FLAC and Vorbis file format support will be disabled. Again, the solution is to copy those DLLs where they can be found. Hints on setting up Visual C++ 2005 Express Edition =================================================== After installing Visual C++, you need to install the Platform SDK (or Windows SDK), otherwise CMake will fail at a linking step. You can do a web install to avoid downloading a massive file. For me, installation seemed to take an inordinately long (half an hour or more), but eventually it completed. Don't be too quick to hit Cancel. You also need to install the DirectX SDK. This is a big download, which I don't know how to avoid. Next, you'll need to tell VC++ about the Platform SDK. Start the IDE. Under "Tools > Options > Projects and Solutions > VC++ Directories", add the Platform SDK executable (bin), include and lib directories to the respective lists. The DirectX SDK seems to add itself when it's installed. For debugging, use the DirectX control panel applet to switch to the debugging runtime. It's really useful. allegro-5.0.10/examples/0000755000175000001440000000000012157230751014227 5ustar tjadenusersallegro-5.0.10/examples/ex_disable_screensaver.c0000644000175000001440000000357012152725670021103 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include #include "common.c" int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; bool done = false; bool active = true; bool fullscreen = false; if (argc == 2) { if (!strcmp(argv[1], "-fullscreen")) { fullscreen = true; } } if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS | (fullscreen ? ALLEGRO_FULLSCREEN : 0)); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } font = al_load_font("data/font.tga", 0, 0); if (!font) { abort_example("Error loading font\n"); } events = al_create_event_queue(); al_register_event_source(events, al_get_keyboard_event_source()); /* For expose events */ al_register_event_source(events, al_get_display_event_source(display)); do { al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_textf(font, al_map_rgb_f(1, 1, 1), 0, 0, 0, "Screen saver: %s", active ? "Normal" : "Inhibited"); al_flip_display(); al_wait_for_event(events, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) done = true; else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { if (al_inhibit_screensaver(active)) { active = !active; } } break; } } while (!done); al_destroy_font(font); al_destroy_event_queue(events); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_get_path.c0000644000175000001440000000302611721437071016663 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "common.c" static void show_path(int id, const char *label) { ALLEGRO_PATH *path; const char *path_str; path = al_get_standard_path(id); path_str = (path) ? al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP) : ""; log_printf("%s: %s\n", label, path_str); al_destroy_path(path); } int main(void) { int pass; /* defaults to blank */ al_set_org_name("liballeg.org"); /* defaults to the exename, set it here to remove the .exe on windows */ al_set_app_name("ex_get_path"); if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); for (pass = 1; pass <= 3; pass++) { if (pass == 1) { log_printf("With default exe name:\n"); } else if (pass == 2) { log_printf("\nOverriding exe name to blahblah\n"); al_set_exe_name("blahblah"); } else if (pass == 3) { log_printf("\nOverriding exe name to /tmp/blahblah.exe:\n"); al_set_exe_name("/tmp/blahblah.exe"); } show_path(ALLEGRO_RESOURCES_PATH, "RESOURCES_PATH"); show_path(ALLEGRO_TEMP_PATH, "TEMP_PATH"); show_path(ALLEGRO_USER_DATA_PATH, "USER_DATA_PATH"); show_path(ALLEGRO_USER_SETTINGS_PATH, "USER_SETTINGS_PATH"); show_path(ALLEGRO_USER_HOME_PATH, "USER_HOME_PATH"); show_path(ALLEGRO_USER_DOCUMENTS_PATH, "USER_DOCUMENTS_PATH"); show_path(ALLEGRO_EXENAME_PATH, "EXENAME_PATH"); } close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_audio_chain.cpp0000644000175000001440000005467712031751243017710 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Demonstrate the audio addons. */ #include #include #include #include #include #include #include #include #include #include #include "common.c" #define DISP_W 800 #define DISP_H 600 using namespace std; class Element; class Voice; class Mixer; class SampleInstance; class Sample; class Audiostream; struct Context { ALLEGRO_FONT *font; ALLEGRO_COLOR bg; ALLEGRO_COLOR fg; ALLEGRO_COLOR fill; ALLEGRO_COLOR disabled; ALLEGRO_COLOR highlight; }; class Element { public: Element(); virtual ~Element() {}; void set_pos(int x, int y); void set_random_pos(); bool attach(Element *elt); bool detach(); bool is_attached_to(Element const *elt); virtual bool is_playing() const = 0; virtual bool toggle_playing() = 0; virtual float get_gain() const = 0; virtual bool adjust_gain(float d) = 0; void draw(Context const& ctx, bool highlight) const; void draw_arrow(Context const& ctx, float px, float py, bool highlight) const; void move_by(int dx, int dy); bool contains(int x, int y) const; void output_point(float & ox, float & oy) const; void input_point(float & ox, float & oy) const; virtual char const *get_label() const = 0; typedef vector::iterator iter; protected: int x, y, w, h; private: virtual bool do_attach(Mixer & mixer); virtual bool do_attach(SampleInstance & spl); virtual bool do_attach(Audiostream & stream); virtual bool do_detach() = 0; void set_attached_to(Element const *elt); Element const *attached_to; }; class Voice : public Element { public: Voice(); ~Voice(); bool valid() const; bool is_playing() const; bool toggle_playing(); float get_gain() const; bool adjust_gain(float d); char const *get_label() const; private: bool do_attach(Mixer & mixer); bool do_attach(SampleInstance & spl); bool do_attach(Audiostream & stream); bool do_detach(); ALLEGRO_VOICE *voice; }; class Mixer : public Element { public: Mixer(); ~Mixer(); operator ALLEGRO_MIXER *() const { return mixer; } bool is_playing() const; bool toggle_playing(); float get_gain() const; bool adjust_gain(float d); char const *get_label() const; private: bool do_attach(Mixer & mixer); bool do_attach(SampleInstance & spl); bool do_attach(Audiostream & stream); bool do_detach(); ALLEGRO_MIXER *mixer; }; class SampleInstance : public Element { public: SampleInstance(); ~SampleInstance(); operator ALLEGRO_SAMPLE_INSTANCE *() const { return splinst; } bool is_playing() const; bool toggle_playing(); float get_gain() const; bool adjust_gain(float d); char const *get_label() const; bool set_sample(Sample const & wav); private: bool do_detach(); ALLEGRO_SAMPLE_INSTANCE *splinst; Sample const *spl; unsigned pos; }; class Sample { public: Sample(char const *filename); ~Sample(); operator ALLEGRO_SAMPLE *() const { return spl; } bool valid() const; string const& get_filename() const; private: ALLEGRO_SAMPLE *spl; string filename; }; class Audiostream : public Element { public: Audiostream(string const& filename); ~Audiostream(); operator ALLEGRO_AUDIO_STREAM *() const { return stream; } bool valid() const; bool is_playing() const; bool toggle_playing(); float get_gain() const; bool adjust_gain(float d); char const *get_label() const; private: bool do_detach(); ALLEGRO_AUDIO_STREAM *stream; string filename; }; /*---------------------------------------------------------------------------*/ static ALLEGRO_PATH *make_path(char const *str) { static ALLEGRO_PATH *dir; ALLEGRO_PATH *path; if (!dir) { dir = al_get_standard_path(ALLEGRO_RESOURCES_PATH); #ifdef ALLEGRO_MSVC { /* Hack to cope automatically with MSVC workspaces. */ const char *last = al_get_path_component(dir, -1); if (0 == strcmp(last, "Debug") || 0 == strcmp(last, "RelWithDebInfo") || 0 == strcmp(last, "Release") || 0 == strcmp(last, "Profile")) { al_remove_path_component(dir, -1); } } #endif } path = al_create_path(str); al_rebase_path(dir, path); return path; } static void basename(const string & filename, string & out) { size_t pos = filename.find_last_of("/"); if (pos != string::npos) out = filename.substr(pos + 1); else out = filename; } static float clamp(float lo, float mid, float hi) { if (mid < lo) return lo; if (mid > hi) return hi; return mid; } /*---------------------------------------------------------------------------*/ Element::Element() : x(0), y(0), w(40), h(40), attached_to(0) { } void Element::set_pos(int x, int y) { this->x = x; this->y = y; } void Element::set_random_pos() { /* Could be smarter. */ x = rand() % (DISP_W - w); y = rand() % (DISP_H - h); } bool Element::attach(Element *elt) { Mixer *mixer; SampleInstance *splinst; Audiostream *stream; bool rc = false; if ((mixer = dynamic_cast(elt))) { rc = do_attach(*mixer); } else if ((splinst = dynamic_cast(elt))) { rc = do_attach(*splinst); } else if ((stream = dynamic_cast(elt))) { rc = do_attach(*stream); } if (rc) { elt->set_attached_to(this); } return rc; } bool Element::do_attach(Mixer & other) { (void)other; return false; } bool Element::do_attach(SampleInstance & other) { (void)other; return false; } bool Element::do_attach(Audiostream & other) { (void)other; return false; } bool Element::detach() { bool rc = attached_to && do_detach(); if (rc) { attached_to = NULL; } return rc; } void Element::set_attached_to(Element const *attached_to) { this->attached_to = attached_to; } bool Element::is_attached_to(Element const *elt) { return attached_to == elt; } void Element::draw(Context const& ctx, bool highlight) const { if (attached_to) { float x2, y2; attached_to->input_point(x2, y2); draw_arrow(ctx, x2, y2, highlight); } ALLEGRO_COLOR textcol = ctx.fg; ALLEGRO_COLOR boxcol = ctx.fg; if (highlight) boxcol = ctx.highlight; if (!is_playing()) textcol = ctx.disabled; float rad = 7.0; al_draw_filled_rounded_rectangle(x+0.5, y+0.5, x+w-0.5, y+h-0.5, rad, rad, ctx.fill); al_draw_rounded_rectangle(x+0.5, y+0.5, x+w-0.5, y+h-0.5, rad, rad, boxcol, 1.0); float th = al_get_font_line_height(ctx.font); al_draw_text(ctx.font, textcol, x + w/2, y + h/2 - th/2, ALLEGRO_ALIGN_CENTRE, get_label()); float gain = get_gain(); if (gain > 0.0) { float igain = 1.0 - clamp(0.0, gain, 2.0)/2.0; al_draw_rectangle(x+w+1.5, y+h*igain, x+w+3.5, y+h, ctx.fg, 1.0); } } void Element::draw_arrow(Context const& ctx, float x2, float y2, bool highlight) const { float x1, y1; ALLEGRO_COLOR col; output_point(x1, y1); col = (highlight ? ctx.highlight : ctx.fg); al_draw_line(x1, y1, x2, y2, col, 1.0); float a = atan2(y1-y2, x1-x2); float a1 = a + 0.5; float a2 = a - 0.5; float len = 7.0; al_draw_line(x2, y2, x2 + len*cos(a1), y2 + len*sin(a1), col, 1.0); al_draw_line(x2, y2, x2 + len*cos(a2), y2 + len*sin(a2), col, 1.0); } void Element::move_by(int dx, int dy) { x += dx; y += dy; if (x < 0) x = 0; if (y < 0) y = 0; if (x+w > DISP_W) x = DISP_W-w; if (y+h > DISP_H) y = DISP_H-h; } bool Element::contains(int px, int py) const { return px >= x && px < x + w && py >= y && py < y + h; } void Element::output_point(float & ox, float & oy) const { ox = x + w/2; oy = y; } void Element::input_point(float & ox, float & oy) const { ox = x + w/2; oy = y + h; } /*---------------------------------------------------------------------------*/ Voice::Voice() { set_random_pos(); voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); } Voice::~Voice() { al_destroy_voice(voice); } bool Voice::valid() const { return (voice != NULL); } bool Voice::do_attach(Mixer & mixer) { return al_attach_mixer_to_voice(mixer, voice); } bool Voice::do_attach(SampleInstance & spl) { return al_attach_sample_instance_to_voice(spl, voice); } bool Voice::do_attach(Audiostream & stream) { return al_attach_audio_stream_to_voice(stream, voice); } bool Voice::do_detach() { return false; } bool Voice::is_playing() const { return al_get_voice_playing(voice); } bool Voice::toggle_playing() { bool playing = al_get_voice_playing(voice); return al_set_voice_playing(voice, !playing); } float Voice::get_gain() const { return 0.0; } bool Voice::adjust_gain(float d) { (void)d; return false; } char const *Voice::get_label() const { return "Voice"; } /*---------------------------------------------------------------------------*/ Mixer::Mixer() { set_random_pos(); mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); } Mixer::~Mixer() { al_destroy_mixer(mixer); } bool Mixer::do_attach(Mixer & other) { return al_attach_mixer_to_mixer(other, mixer); } bool Mixer::do_attach(SampleInstance & spl) { return al_attach_sample_instance_to_mixer(spl, mixer); } bool Mixer::do_attach(Audiostream & stream) { return al_attach_audio_stream_to_mixer(stream, mixer); } bool Mixer::do_detach() { return al_detach_mixer(mixer); } bool Mixer::is_playing() const { return al_get_mixer_playing(mixer); } bool Mixer::toggle_playing() { bool playing = al_get_mixer_playing(mixer); return al_set_mixer_playing(mixer, !playing); } float Mixer::get_gain() const { return al_get_mixer_gain(mixer); } bool Mixer::adjust_gain(float d) { float gain = al_get_mixer_gain(mixer) + d; gain = clamp(0, gain, 2); return al_set_mixer_gain(mixer, gain); } char const *Mixer::get_label() const { return "Mixer"; } /*---------------------------------------------------------------------------*/ SampleInstance::SampleInstance() : spl(NULL), pos(0) { w = 150; set_random_pos(); splinst = al_create_sample_instance(NULL); } SampleInstance::~SampleInstance() { al_destroy_sample_instance(splinst); } bool SampleInstance::do_detach() { return al_detach_sample_instance(splinst); } bool SampleInstance::is_playing() const { return al_get_sample_instance_playing(splinst); } bool SampleInstance::toggle_playing() { bool playing = is_playing(); if (playing) pos = al_get_sample_instance_position(splinst); else al_set_sample_instance_position(splinst, pos); return al_set_sample_instance_playing(splinst, !playing); } float SampleInstance::get_gain() const { return al_get_sample_instance_gain(splinst); } bool SampleInstance::adjust_gain(float d) { float gain = al_get_sample_instance_gain(splinst) + d; gain = clamp(0, gain, 2); return al_set_sample_instance_gain(splinst, gain); } bool SampleInstance::set_sample(Sample const & spl) { bool playing = is_playing(); bool rc = al_set_sample(splinst, spl); if (rc) { this->spl = &spl; al_set_sample_instance_playmode(splinst, ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playing(splinst, playing); } return rc; } char const *SampleInstance::get_label() const { if (spl) { return spl->get_filename().c_str(); } return "No sample"; } /*---------------------------------------------------------------------------*/ Sample::Sample(char const *filename) { spl = al_load_sample(filename); basename(filename, this->filename); } Sample::~Sample() { al_destroy_sample(spl); } bool Sample::valid() const { return spl; } string const& Sample::get_filename() const { return filename; } /*---------------------------------------------------------------------------*/ Audiostream::Audiostream(string const& filename) { w = 150; set_random_pos(); basename(filename, this->filename); stream = al_load_audio_stream(filename.c_str(), 4, 2048); if (stream) { al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); } } Audiostream::~Audiostream() { al_destroy_audio_stream(stream); } bool Audiostream::valid() const { return stream; } bool Audiostream::do_detach() { return al_detach_audio_stream(stream); } bool Audiostream::is_playing() const { return al_get_audio_stream_playing(stream); } bool Audiostream::toggle_playing() { bool playing = al_get_audio_stream_playing(stream); return al_set_audio_stream_playing(stream, !playing); } float Audiostream::get_gain() const { return al_get_audio_stream_gain(stream); } bool Audiostream::adjust_gain(float d) { float gain = al_get_audio_stream_gain(stream) + d; gain = clamp(0, gain, 2); return al_set_audio_stream_gain(stream, gain); } char const *Audiostream::get_label() const { return filename.c_str(); } /*---------------------------------------------------------------------------*/ class Prog { public: Prog(); void init(); void add_sample(char const *filename); void add_stream_path(char const *filename); void initial_config(); void run(void); private: Voice *new_voice(); Mixer *new_mixer(); SampleInstance *new_sample_instance(); Audiostream *new_audiostream(); void process_mouse_button_down(int mb, int mx, int my); void process_mouse_button_up(int mb, int mx, int my); void process_mouse_axes(int mx, int my, int dx, int dy); void process_mouse_wheel(int dz); void process_key_char(int unichar); Element *find_element(int x, int y); void delete_element(Element *elt); void redraw(); ALLEGRO_DISPLAY *dpy; ALLEGRO_EVENT_QUEUE *queue; Context ctx; vector samples; vector stream_paths; vector elements; int cur_button; Element *cur_element; float connect_x; float connect_y; }; Prog::Prog() : cur_button(0), cur_element(NULL) { } void Prog::init() { if (!al_init()) { abort_example("Could not initialise Allegro.\n"); } if (!al_init_primitives_addon()) { abort_example("Could not initialise primitives.\n"); } al_init_font_addon(); if (!al_init_ttf_addon()) { abort_example("Could not initialise TTF fonts.\n"); } if (!al_install_audio()) { abort_example("Could not initialise audio.\n"); } if (!al_init_acodec_addon()) { abort_example("Could not initialise audio codecs.\n"); } if (!(dpy = al_create_display(800, 600))) { abort_example("Could not create display.\n"); } if (!al_install_keyboard()) { abort_example("Could not install keyboard.\n"); } if (!al_install_mouse()) { abort_example("Could not install mouse.\n"); } ctx.font = al_load_ttf_font("data/DejaVuSans.ttf", 10, 0); if (!ctx.font) { abort_example("Could not load font.\n"); } ctx.bg = al_map_rgb_f(0.9, 0.9, 0.9); ctx.fg = al_map_rgb_f(0, 0, 0); ctx.fill = al_map_rgb_f(0.85, 0.85, 0.85); ctx.disabled = al_map_rgb_f(0.6, 0.6, 0.6); ctx.highlight = al_map_rgb_f(1, 0.1, 0.1); queue = al_create_event_queue(); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(dpy)); } void Prog::add_sample(char const *filename) { ALLEGRO_PATH *path = make_path(filename); Sample *spl = new Sample(al_path_cstr(path, '/')); if (spl) { samples.push_back(spl); } else { delete spl; } al_destroy_path(path); } void Prog::add_stream_path(char const *filename) { ALLEGRO_PATH *path = make_path(filename); stream_paths.push_back(al_path_cstr(path, '/')); al_destroy_path(path); } void Prog::initial_config() { Voice *voice = new_voice(); if (!voice) { abort_example("Could not create initial voice.\n"); } voice->set_pos(300, 50); Mixer *mixer = new_mixer(); mixer->set_pos(300, 150); voice->attach(mixer); SampleInstance *splinst = new_sample_instance(); splinst->set_pos(220, 300); mixer->attach(splinst); splinst->toggle_playing(); SampleInstance *splinst2 = new_sample_instance(); splinst2->set_pos(120, 240); mixer->attach(splinst2); splinst2->toggle_playing(); Mixer *mixer2 = new_mixer(); mixer2->set_pos(500, 250); mixer->attach(mixer2); Audiostream *stream; if ((stream = new_audiostream())) { stream->set_pos(450, 350); mixer2->attach(stream); } } Voice *Prog::new_voice() { Voice *voice = new Voice(); if (voice->valid()) { elements.push_back(voice); } else { delete voice; voice = NULL; } return voice; } Mixer *Prog::new_mixer() { Mixer *mixer = new Mixer(); elements.push_back(mixer); return mixer; } SampleInstance *Prog::new_sample_instance() { SampleInstance *splinst = new SampleInstance(); if (samples.size() > 0) { static unsigned i = 0; unsigned n = (i++) % samples.size(); splinst->set_sample(*samples[n]); i++; } elements.push_back(splinst); return splinst; } Audiostream *Prog::new_audiostream() { if (stream_paths.size() > 0) { static unsigned i = 0; unsigned n = (i++) % stream_paths.size(); Audiostream *stream = new Audiostream(stream_paths[n]); if (stream->valid()) { elements.push_back(stream); return stream; } delete stream; } return NULL; } void Prog::run() { for (;;) { if (al_is_event_queue_empty(queue)) { redraw(); } ALLEGRO_EVENT ev; al_wait_for_event(queue, &ev); switch (ev.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: process_mouse_button_down(ev.mouse.button, ev.mouse.x, ev.mouse.y); break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: process_mouse_button_up(ev.mouse.button, ev.mouse.x, ev.mouse.y); break; case ALLEGRO_EVENT_MOUSE_AXES: if (ev.mouse.dz) { process_mouse_wheel(ev.mouse.dz); } else { process_mouse_axes(ev.mouse.x, ev.mouse.y, ev.mouse.dx, ev.mouse.dy); } break; case ALLEGRO_EVENT_KEY_CHAR: if (ev.keyboard.unichar == 27) { return; } process_key_char(ev.keyboard.unichar); break; } } } void Prog::process_mouse_button_down(int mb, int mx, int my) { if (cur_button == 0) { cur_element = find_element(mx, my); if (cur_element) { cur_button = mb; } if (cur_button == 2) { connect_x = mx; connect_y = my; } } } void Prog::process_mouse_button_up(int mb, int mx, int my) { if (mb != cur_button) return; if (cur_button == 2 && cur_element) { Element *sink = find_element(mx, my); cur_element->detach(); if (sink && sink != cur_element) { sink->attach(cur_element); } cur_element = NULL; } cur_button = 0; } void Prog::process_mouse_axes(int mx, int my, int dx, int dy) { if (cur_button == 1 && cur_element) { cur_element->move_by(dx, dy); } if (cur_button == 2 && cur_element) { connect_x = mx; connect_y = my; } } void Prog::process_mouse_wheel(int dz) { if (cur_element) { cur_element->adjust_gain(dz * 0.1); } } void Prog::process_key_char(int unichar) { int upper = toupper(unichar); if (upper == 'V') { new_voice(); } else if (upper == 'M') { new_mixer(); } else if (upper == 'S') { new_sample_instance(); } else if (upper == 'A') { new_audiostream(); } else if (upper == ' ') { if (cur_element) { cur_element->toggle_playing(); } } else if (upper == 'X') { if (cur_element) { delete_element(cur_element); cur_element = NULL; } } else if (upper >= '1' && upper <= '9') { unsigned n = upper - '1'; SampleInstance *splinst; if (n < samples.size() && (splinst = dynamic_cast(cur_element))) { splinst->set_sample(*samples.at(n)); } } } Element *Prog::find_element(int x, int y) { for (Element::iter it = elements.begin(); it != elements.end(); it++) { if ((*it)->contains(x, y)) return *it; } return NULL; } void Prog::delete_element(Element *elt) { for (Element::iter it = elements.begin(); it != elements.end(); it++) { if ((*it)->is_attached_to(elt)) { (*it)->detach(); } } for (Element::iter it = elements.begin(); it != elements.end(); it++) { if (*it == elt) { (*it)->detach(); delete *it; elements.erase(it); break; } } } void Prog::redraw() { al_clear_to_color(ctx.bg); for (Element::iter it = elements.begin(); it != elements.end(); it++) { bool highlight = (*it == cur_element); (*it)->draw(ctx, highlight); if (highlight && cur_button == 2) { (*it)->draw_arrow(ctx, connect_x, connect_y, highlight); } } float y = al_get_display_height(dpy); float th = al_get_font_line_height(ctx.font); al_draw_textf(ctx.font, ctx.fg, 0, y-th*2, ALLEGRO_ALIGN_LEFT, "Create [v]oices, [m]ixers, [s]ample instances, [a]udiostreams. " "[SPACE] pause playback. " "[1]-[9] set sample. " "[x] delete."); al_draw_textf(ctx.font, ctx.fg, 0, y-th*1, ALLEGRO_ALIGN_LEFT, "Mouse: [LMB] select element. " "[RMB] attach sources to sinks " "(sample->mixer, mixer->mixer, mixer->voice, sample->voice)"); al_flip_display(); } int main(int argc, char **argv) { Prog prog; prog.init(); prog.add_sample("data/haiku/air_0.ogg"); prog.add_sample("data/haiku/air_1.ogg"); prog.add_sample("data/haiku/earth_0.ogg"); prog.add_sample("data/haiku/earth_1.ogg"); prog.add_sample("data/haiku/earth_2.ogg"); prog.add_sample("data/haiku/fire_0.ogg"); prog.add_sample("data/haiku/fire_1.ogg"); prog.add_sample("data/haiku/water_0.ogg"); prog.add_sample("data/haiku/water_1.ogg"); prog.add_stream_path("../demos/cosmic_protector/data/sfx/game_music.ogg"); prog.add_stream_path("../demos/cosmic_protector/data/sfx/title_music.ogg"); prog.initial_config(); prog.run(); /* Let Allegro handle the cleanup. */ return 0; (void)argc; (void)argv; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_monitorinfo.c0000644000175000001440000000171512152725670017442 0ustar tjadenusers#include "allegro5/allegro.h" #include #include "common.c" int main(void) { ALLEGRO_MONITOR_INFO info; int num_adapters; int i, j; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); num_adapters = al_get_num_video_adapters(); log_printf("%d adapters found...\n", num_adapters); for (i = 0; i < num_adapters; i++) { al_get_monitor_info(i, &info); log_printf("Adapter %d: ", i); log_printf("(%d, %d) - (%d, %d)\n", info.x1, info.y1, info.x2, info.y2); al_set_new_display_adapter(i); log_printf(" Available fullscreen display modes:\n"); for (j = 0; j < al_get_num_display_modes(); j++) { ALLEGRO_DISPLAY_MODE mode; al_get_display_mode(j, &mode); log_printf(" Mode %3d: %4d x %4d, %d Hz\n", j, mode.width, mode.height, mode.refresh_rate); } } close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_prim.c0000644000175000001440000006104412152725670016047 0ustar tjadenusers/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * A sampler of the primitive addon. * All primitives are rendered using the additive blender, so overdraw will manifest itself as overly bright pixels. * * * By Pavel Sountsov. * * See readme.txt for copyright information. */ #include #include #include #include #include #include #include "common.c" typedef void (*Screen)(int); int ScreenW = 800, ScreenH = 600; #define NUM_SCREENS 10 #define ROTATE_SPEED 0.0001f Screen Screens[NUM_SCREENS]; const char *ScreenName[NUM_SCREENS]; ALLEGRO_FONT* Font; ALLEGRO_TRANSFORM Identity; ALLEGRO_BITMAP* Buffer; ALLEGRO_BITMAP* Texture; ALLEGRO_COLOR solid_white; int Soft = 0; int Blend = 1; float Speed = ROTATE_SPEED; float Theta; int Background = 1; float Thickness = 0; ALLEGRO_TRANSFORM MainTrans; enum MODE { INIT, LOGIC, DRAW }; typedef struct { ALLEGRO_COLOR color; short u, v; short x, y; int junk[6]; } CUSTOM_VERTEX; static void CustomVertexFormatPrimitives(int mode) { static CUSTOM_VERTEX vtx[4]; static ALLEGRO_VERTEX_DECL* decl; if (mode == INIT) { int ii = 0; ALLEGRO_VERTEX_ELEMENT elems[] = { {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_SHORT_2, offsetof(CUSTOM_VERTEX, x)}, {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_SHORT_2, offsetof(CUSTOM_VERTEX, u)}, {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(CUSTOM_VERTEX, color)}, {0, 0, 0} }; decl = al_create_vertex_decl(elems, sizeof(CUSTOM_VERTEX)); for (ii = 0; ii < 4; ii++) { float x, y; x = 200 * cosf((float)ii / 4.0f * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 4.0f * 2 * ALLEGRO_PI); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); } } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_prim(vtx, decl, Texture, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); al_use_transform(&Identity); } } static void TexturePrimitives(int mode) { static ALLEGRO_VERTEX vtx[13]; static ALLEGRO_VERTEX vtx2[13]; if (mode == INIT) { int ii = 0; ALLEGRO_COLOR color; for (ii = 0; ii < 13; ii++) { float x, y; x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; vtx2[ii].u = 64 * x / 100; vtx2[ii].v = 64 * y / 100; if(ii < 10) vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); else vtx[ii].color = color; vtx2[ii].color = vtx[ii].color; } } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_prim(vtx, 0, Texture, 0, 4, ALLEGRO_PRIM_LINE_LIST); al_draw_prim(vtx, 0, Texture, 4, 9, ALLEGRO_PRIM_LINE_STRIP); al_draw_prim(vtx, 0, Texture, 9, 13, ALLEGRO_PRIM_LINE_LOOP); al_draw_prim(vtx2, 0, Texture, 0, 13, ALLEGRO_PRIM_POINT_LIST); al_use_transform(&Identity); } } static void FilledTexturePrimitives(int mode) { static ALLEGRO_VERTEX vtx[21]; if (mode == INIT) { int ii = 0; for (ii = 0; ii < 21; ii++) { float x, y; ALLEGRO_COLOR color; if (ii % 2 == 0) { x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } else { x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } if (ii == 0) { x = y = 0; } color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; if(ii < 10) vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); else vtx[ii].color = color; } } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_prim(vtx, 0, Texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN); al_draw_prim(vtx, 0, Texture, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_prim(vtx, 0, Texture, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP); al_use_transform(&Identity); } } static void FilledPrimitives(int mode) { static ALLEGRO_VERTEX vtx[21]; if (mode == INIT) { int ii = 0; for (ii = 0; ii < 21; ii++) { float x, y; ALLEGRO_COLOR color; if (ii % 2 == 0) { x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } else { x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } if (ii == 0) { x = y = 0; } color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx[ii].color = color; } } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_prim(vtx, 0, 0, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN); al_draw_prim(vtx, 0, 0, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_prim(vtx, 0, 0, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP); al_use_transform(&Identity); } } static void IndexedFilledPrimitives(int mode) { static ALLEGRO_VERTEX vtx[21]; static int indices1[] = {12, 13, 14, 16, 17, 18}; static int indices2[] = {6, 7, 8, 9, 10, 11}; static int indices3[] = {0, 1, 2, 3, 4, 5}; if (mode == INIT) { int ii = 0; for (ii = 0; ii < 21; ii++) { float x, y; ALLEGRO_COLOR color; if (ii % 2 == 0) { x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } else { x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); } if (ii == 0) { x = y = 0; } color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx[ii].color = color; } } else if (mode == LOGIC) { int ii; Theta += Speed; for (ii = 0; ii < 6; ii++) { indices1[ii] = ((int)al_get_time() + ii) % 20 + 1; indices2[ii] = ((int)al_get_time() + ii + 6) % 20 + 1; if (ii > 0) indices3[ii] = ((int)al_get_time() + ii + 12) % 20 + 1; } al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_indexed_prim(vtx, 0, 0, indices1, 6, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_indexed_prim(vtx, 0, 0, indices2, 6, ALLEGRO_PRIM_TRIANGLE_STRIP); al_draw_indexed_prim(vtx, 0, 0, indices3, 6, ALLEGRO_PRIM_TRIANGLE_FAN); al_use_transform(&Identity); } } static void HighPrimitives(int mode) { if (mode == INIT) { } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { float points[8] = { -300, -200, 700, 200, -700, 200, 300, -200 }; if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_line(-300, -200, 300, 200, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); al_draw_triangle(-150, -250, 0, 250, 150, -250, al_map_rgba_f(0.5, 0, 0.5, 1), Thickness); al_draw_rectangle(-300, -200, 300, 200, al_map_rgba_f(0.5, 0, 0, 1), Thickness); al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, al_map_rgba_f(0.2, 0.2, 0, 1), Thickness); al_draw_ellipse(0, 0, 300, 150, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); al_draw_elliptical_arc(-20, 0, 300, 200, -ALLEGRO_PI / 2, -ALLEGRO_PI, al_map_rgba_f(0.25, 0.25, 0.5, 1), Thickness); al_draw_arc(0, 0, 200, -ALLEGRO_PI / 2, ALLEGRO_PI, al_map_rgba_f(0.5, 0.25, 0, 1), Thickness); al_draw_spline(points, al_map_rgba_f(0.1, 0.2, 0.5, 1), Thickness); al_draw_pieslice(0, 25, 150, ALLEGRO_PI * 3 / 4, -ALLEGRO_PI / 2, al_map_rgba_f(0.4, 0.3, 0.1, 1), Thickness); al_use_transform(&Identity); } } static void HighFilledPrimitives(int mode) { if (mode == INIT) { } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, al_map_rgb_f(0.5, 0.7, 0.3)); al_draw_filled_rectangle(20, -50, 200, 50, al_map_rgb_f(0.3, 0.2, 0.6)); al_draw_filled_ellipse(-250, 0, 100, 150, al_map_rgb_f(0.3, 0.3, 0.3)); al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, al_map_rgb_f(0.4, 0.2, 0)); al_draw_filled_pieslice(200, 125, 50, ALLEGRO_PI / 4, 3 * ALLEGRO_PI / 2, al_map_rgb_f(0.3, 0.3, 0.1)); al_use_transform(&Identity); } } static void TransformationsPrimitives(int mode) { float t = al_get_time(); if (mode == INIT) { } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, sinf(t / 5), cosf(t / 5), Theta); } else if (mode == DRAW) { float points[8] = { -300, -200, 700, 200, -700, 200, 300, -200 }; if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_line(-300, -200, 300, 200, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); al_draw_triangle(-150, -250, 0, 250, 150, -250, al_map_rgba_f(0.5, 0, 0.5, 1), Thickness); al_draw_rectangle(-300, -200, 300, 200, al_map_rgba_f(0.5, 0, 0, 1), Thickness); al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, al_map_rgba_f(0.2, 0.2, 0, 1), Thickness); al_draw_ellipse(0, 0, 300, 150, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); al_draw_elliptical_arc(-20, 0, 300, 200, -ALLEGRO_PI / 2, -ALLEGRO_PI, al_map_rgba_f(0.25, 0.25, 0.5, 1), Thickness); al_draw_arc(0, 0, 200, -ALLEGRO_PI / 2, ALLEGRO_PI, al_map_rgba_f(0.5, 0.25, 0, 1), Thickness); al_draw_spline(points, al_map_rgba_f(0.1, 0.2, 0.5, 1), Thickness); al_draw_pieslice(0, 25, 150, ALLEGRO_PI * 3 / 4, -ALLEGRO_PI / 2, al_map_rgba_f(0.4, 0.3, 0.1, 1), Thickness); al_use_transform(&Identity); } } static void LowPrimitives(int mode) { static ALLEGRO_VERTEX vtx[13]; static ALLEGRO_VERTEX vtx2[13]; if (mode == INIT) { int ii = 0; ALLEGRO_COLOR color; for (ii = 0; ii < 13; ii++) { float x, y; x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; vtx[ii].color = color; vtx2[ii].color = color; } } else if (mode == LOGIC) { Theta += Speed; al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_LINE_LIST); al_draw_prim(vtx, 0, 0, 4, 9, ALLEGRO_PRIM_LINE_STRIP); al_draw_prim(vtx, 0, 0, 9, 13, ALLEGRO_PRIM_LINE_LOOP); al_draw_prim(vtx2, 0, 0, 0, 13, ALLEGRO_PRIM_POINT_LIST); al_use_transform(&Identity); } } static void IndexedPrimitives(int mode) { static int indices1[] = {0, 1, 3, 4}; static int indices2[] = {5, 6, 7, 8}; static int indices3[] = {9, 10, 11, 12}; static ALLEGRO_VERTEX vtx[13]; static ALLEGRO_VERTEX vtx2[13]; if (mode == INIT) { int ii = 0; ALLEGRO_COLOR color; for (ii = 0; ii < 13; ii++) { float x, y; x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; vtx[ii].color = color; vtx2[ii].color = color; } } else if (mode == LOGIC) { int ii; Theta += Speed; for (ii = 0; ii < 4; ii++) { indices1[ii] = ((int)al_get_time() + ii) % 13; indices2[ii] = ((int)al_get_time() + ii + 4) % 13; indices3[ii] = ((int)al_get_time() + ii + 8) % 13; } al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); } else if (mode == DRAW) { if (Blend) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); else al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_use_transform(&MainTrans); al_draw_indexed_prim(vtx, 0, 0, indices1, 4, ALLEGRO_PRIM_LINE_LIST); al_draw_indexed_prim(vtx, 0, 0, indices2, 4, ALLEGRO_PRIM_LINE_STRIP); al_draw_indexed_prim(vtx, 0, 0, indices3, 4, ALLEGRO_PRIM_LINE_LOOP); al_draw_indexed_prim(vtx2, 0, 0, indices3, 4, ALLEGRO_PRIM_POINT_LIST); al_use_transform(&Identity); } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP* bkg; ALLEGRO_COLOR black; ALLEGRO_EVENT_QUEUE *queue; // Initialize Allegro 5 and addons if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_init_primitives_addon(); // Create a window to display things on: 640x480 pixels display = al_create_display(ScreenW, ScreenH); if (!display) { abort_example("Error creating display.\n"); } // Install the keyboard handler if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } if (!al_install_mouse()) { abort_example("Error installing mouse.\n"); } // Load a font Font = al_load_font("data/fixed_font.tga", 0, 0); if (!Font) { abort_example("Error loading \"data/fixed_font.tga\".\n"); } solid_white = al_map_rgba_f(1, 1, 1, 1); bkg = al_load_bitmap("data/bkg.png"); Texture = al_load_bitmap("data/texture.tga"); // Make and set some color to draw with black = al_map_rgba_f(0.0, 0.0, 0.0, 1.0); // Start the event queue to handle keyboard input and our timer queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_mouse_event_source()); al_set_window_title(display, "Primitives Example"); { int refresh_rate = 60; int frames_done = 0; double time_diff = al_get_time(); double fixed_timestep = 1.0f / refresh_rate; double real_time = al_get_time(); double game_time = al_get_time(); int ii; int cur_screen = 0; bool done = false; int clip = 0; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *timer_queue; int old; timer = al_create_timer(ALLEGRO_BPS_TO_SECS(refresh_rate)); al_start_timer(timer); timer_queue = al_create_event_queue(); al_register_event_source(timer_queue, al_get_timer_event_source(timer)); old = al_get_new_bitmap_flags(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); Buffer = al_create_bitmap(ScreenW, ScreenH); al_set_new_bitmap_flags(old); al_identity_transform(&Identity); Screens[0] = LowPrimitives; Screens[1] = IndexedPrimitives; Screens[2] = HighPrimitives; Screens[3] = TransformationsPrimitives; Screens[4] = FilledPrimitives; Screens[5] = IndexedFilledPrimitives; Screens[6] = HighFilledPrimitives; Screens[7] = TexturePrimitives; Screens[8] = FilledTexturePrimitives; Screens[9] = CustomVertexFormatPrimitives; ScreenName[0] = "Low Level Primitives"; ScreenName[1] = "Indexed Primitives"; ScreenName[2] = "High Level Primitives"; ScreenName[3] = "Transformations"; ScreenName[4] = "Low Level Filled Primitives"; ScreenName[5] = "Indexed Filled Primitives"; ScreenName[6] = "High Level Filled Primitives"; ScreenName[7] = "Textured Primitives"; ScreenName[8] = "Filled Textured Primitives"; ScreenName[9] = "Custom Vertex Format"; for (ii = 0; ii < NUM_SCREENS; ii++) Screens[ii](INIT); while (!done) { double frame_duration = al_get_time() - real_time; al_rest(fixed_timestep - frame_duration); //rest at least fixed_dt frame_duration = al_get_time() - real_time; real_time = al_get_time(); if (real_time - game_time > frame_duration) { //eliminate excess overflow game_time += fixed_timestep * floor((real_time - game_time) / fixed_timestep); } while (real_time - game_time >= 0) { ALLEGRO_EVENT key_event; double start_time = al_get_time(); game_time += fixed_timestep; Screens[cur_screen](LOGIC); while (al_get_next_event(queue, &key_event)) { switch (key_event.type) { case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { cur_screen++; if (cur_screen >= NUM_SCREENS) { cur_screen = 0; } break; } case ALLEGRO_EVENT_DISPLAY_CLOSE: { done = true; break; } case ALLEGRO_EVENT_KEY_CHAR: { switch (key_event.keyboard.keycode) { case ALLEGRO_KEY_ESCAPE: { done = true; break; } case ALLEGRO_KEY_S: { Soft = !Soft; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_C: { clip = !clip; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_L: { Blend = !Blend; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_B: { Background = !Background; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_LEFT: { Speed -= ROTATE_SPEED; break; } case ALLEGRO_KEY_RIGHT: { Speed += ROTATE_SPEED; break; } case ALLEGRO_KEY_PGUP: { Thickness += 0.5f; if (Thickness < 1.0f) Thickness = 1.0f; break; } case ALLEGRO_KEY_PGDN: { Thickness -= 0.5f; if (Thickness < 1.0f) Thickness = 0.0f; break; } case ALLEGRO_KEY_UP: { cur_screen++; if (cur_screen >= NUM_SCREENS) { cur_screen = 0; } break; } case ALLEGRO_KEY_SPACE: { Speed = 0; break; } case ALLEGRO_KEY_DOWN: { cur_screen--; if (cur_screen < 0) { cur_screen = NUM_SCREENS - 1; } break; } } } } } if (al_get_time() - start_time >= fixed_timestep) { //break if we start taking too long break; } } al_clear_to_color(black); if (Soft == 1) { al_set_target_bitmap(Buffer); al_clear_to_color(black); } if (Background && bkg) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_scaled_bitmap(bkg, 0, 0, al_get_bitmap_width(bkg), al_get_bitmap_height(bkg), 0, 0, ScreenW, ScreenH, 0); } if (clip == 1) { al_set_clipping_rectangle(ScreenW / 2, ScreenH / 2, ScreenW / 2, ScreenH / 2); } Screens[cur_screen](DRAW); al_set_clipping_rectangle(0, 0, ScreenW, ScreenH); if (Soft == 1) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_set_target_backbuffer(display); al_draw_bitmap(Buffer, 0, 0, 0); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(Font, solid_white, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "%s", ScreenName[cur_screen]); al_draw_textf(Font, solid_white, 0, 0, 0, "FPS: %f", (float)frames_done / (al_get_time() - time_diff)); al_draw_textf(Font, solid_white, 0, 20, 0, "Change Screen (Up/Down). Esc to Quit."); al_draw_textf(Font, solid_white, 0, 40, 0, "Rotation (Left/Right/Space): %f", Speed); al_draw_textf(Font, solid_white, 0, 60, 0, "Thickness (PgUp/PgDown): %f", Thickness); al_draw_textf(Font, solid_white, 0, 80, 0, "Software (S): %d", Soft); al_draw_textf(Font, solid_white, 0, 100, 0, "Blending (L): %d", Blend); al_draw_textf(Font, solid_white, 0, 120, 0, "Background (B): %d", Background); al_draw_textf(Font, solid_white, 0, 140, 0, "Clip (C): %d", clip); al_flip_display(); frames_done++; } } return 0; } allegro-5.0.10/examples/nihgui.hpp0000644000175000001440000001412611520367522016227 0ustar tjadenusers#ifndef __included_nihgui_hpp #define __included_nihgui_hpp #include #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" class Theme; class Dialog; class Widget; class Theme { public: ALLEGRO_COLOR bg; ALLEGRO_COLOR fg; ALLEGRO_COLOR highlight; const ALLEGRO_FONT *font; // Null font is fine if you don't use a widget that requires text. explicit Theme(const ALLEGRO_FONT *font=NULL); }; class Widget { private: int grid_x; int grid_y; int grid_w; int grid_h; protected: Dialog *dialog; int x1; int y1; int x2; int y2; public: Widget(); virtual ~Widget() {} void configure(int xsize, int ysize, int x_padding, int y_padding); virtual bool contains(int x, int y); unsigned int width() { return x2 - x1 + 1; } unsigned int height() { return y2 - y1 + 1; } virtual bool want_mouse_focus() { return true; } virtual void got_mouse_focus() {} virtual void lost_mouse_focus() {} virtual void on_mouse_button_down(int mx, int my) { (void)mx; (void)my; } virtual void on_mouse_button_hold(int mx, int my) { (void)mx; (void)my; } virtual void on_mouse_button_up(int mx, int my) { (void)mx; (void)my; } virtual void on_click(int mx, int my) { (void)mx; (void)my; } virtual bool want_key_focus() { return false; } virtual void got_key_focus() {} virtual void lost_key_focus() {} virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { (void)event; } virtual void draw() = 0; friend class Dialog; }; class EventHandler { public: virtual ~EventHandler() {} virtual void handle_event(const ALLEGRO_EVENT & event) = 0; }; class Dialog { private: const Theme & theme; ALLEGRO_DISPLAY * display; ALLEGRO_EVENT_QUEUE *event_queue; int grid_m; int grid_n; int x_padding; int y_padding; bool draw_requested; bool quit_requested; std::list all_widgets; Widget * mouse_over_widget; Widget * mouse_down_widget; Widget * key_widget; EventHandler * event_handler; public: Dialog(const Theme & theme, ALLEGRO_DISPLAY *display, int grid_m, int grid_n); ~Dialog(); void set_padding(int x_padding, int y_padding); void add(Widget & widget, int grid_x, int grid_y, int grid_w, int grid_h); void prepare(); void run_step(bool block); void request_quit(); bool is_quit_requested() const; void request_draw(); bool is_draw_requested() const; void draw(); const Theme & get_theme() const; void register_event_source(ALLEGRO_EVENT_SOURCE *source); void set_event_handler(EventHandler *handler); private: void configure_all(); void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); void on_mouse_axes(const ALLEGRO_MOUSE_EVENT & event); void check_mouse_over(int mx, int my); void on_mouse_button_down(const ALLEGRO_MOUSE_EVENT & event); void on_mouse_button_up(const ALLEGRO_MOUSE_EVENT & event); }; /*---------------------------------------------------------------------------*/ class Label : public Widget { private: std::string text; bool centred; public: Label(std::string text="", bool centred=true); void set_text(std::string text); virtual void draw(); virtual bool want_mouse_focus(); }; class Button : public Widget { protected: std::string text; bool pushed; public: explicit Button(std::string text); virtual void on_mouse_button_down(int mx, int my); virtual void on_mouse_button_up(int mx, int my); virtual void draw(); bool get_pushed(); }; class ToggleButton : public Button { public: explicit ToggleButton(std::string text); virtual void on_mouse_button_down(int mx, int my); virtual void on_mouse_button_up(int mx, int my); void set_pushed(bool pushed); }; class List : public Widget { private: static const std::string empty_string; std::vector items; unsigned int selected_item; public: List(int initial_selection = 0); virtual bool want_key_focus(); virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); virtual void on_click(int mx, int my); virtual void draw(); void clear_items(); void append_item(std::string text); const std::string & get_selected_item_text() const; int get_cur_value() const; }; class VSlider : public Widget { private: int cur_value; int max_value; public: VSlider(int cur_value = 0, int max_value = 1); virtual void on_mouse_button_down(int mx, int my); virtual void on_mouse_button_hold(int mx, int my); virtual void draw(); int get_cur_value() const; void set_cur_value(int v); }; class HSlider : public Widget { private: int cur_value; int max_value; public: HSlider(int cur_value = 0, int max_value = 1); virtual void on_mouse_button_down(int mx, int my); virtual void on_mouse_button_hold(int mx, int my); virtual void draw(); int get_cur_value() const; void set_cur_value(int v); }; class TextEntry : public Widget { private: static const int CURSOR_WIDTH = 8; ALLEGRO_USTR *text; bool focused; int cursor_pos; int left_pos; public: explicit TextEntry(const char *initial_text=""); ~TextEntry(); virtual bool want_key_focus(); virtual void got_key_focus(); virtual void lost_key_focus(); virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); virtual void draw(); const char * get_text(); private: void maybe_scroll(); }; #endif /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_warp_mouse.c0000644000175000001440000000676712152725670017274 0ustar tjadenusers#include #include #include #include #include #include "common.c" int width = 640; int height = 480; int main(void) { ALLEGRO_FONT *font; ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *event_queue; ALLEGRO_EVENT event; bool right_button_down = false; bool redraw = true; int fake_x = 0, fake_y = 0; ALLEGRO_COLOR white; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_init_primitives_addon(); al_init_font_addon(); al_init_image_addon(); al_install_mouse(); al_install_keyboard(); al_set_new_display_flags(ALLEGRO_WINDOWED); display = al_create_display(width, height); if (!display) { abort_example("Could not create display.\n"); } memset(&event, 0, sizeof(event)); event_queue = al_create_event_queue(); al_register_event_source(event_queue, al_get_display_event_source(display)); al_register_event_source(event_queue, al_get_mouse_event_source()); al_register_event_source(event_queue, al_get_keyboard_event_source()); font = al_load_font("data/fixed_font.tga", 0, 0); white = al_map_rgb_f(1, 1, 1); while (1) { if (redraw && al_is_event_queue_empty(event_queue)) { int th = al_get_font_line_height(font); al_clear_to_color(al_map_rgb_f(0, 0, 0)); if (right_button_down) { al_draw_line(width / 2, height / 2, fake_x, fake_y, al_map_rgb_f(1, 0, 0), 1); al_draw_line(fake_x - 5, fake_y, fake_x + 5, fake_y, al_map_rgb_f(1, 1, 1), 2); al_draw_line(fake_x, fake_y - 5, fake_x, fake_y + 5, al_map_rgb_f(1, 1, 1), 2); } al_draw_textf(font, white, 0, 0, 0, "x: %i y: %i dx: %i dy %i", event.mouse.x, event.mouse.y, event.mouse.dx, event.mouse.dy); al_draw_textf(font, white, width / 2, height / 2 - th, ALLEGRO_ALIGN_CENTRE, "Left-Click to warp pointer to the middle once."); al_draw_textf(font, white, width / 2, height / 2, ALLEGRO_ALIGN_CENTRE, "Hold right mouse button to constantly move pointer to the middle."); al_flip_display(); redraw = false; } al_wait_for_event(event_queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; } if (event.type == ALLEGRO_EVENT_MOUSE_WARPED) { log_printf("Warp\n"); } if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { if (right_button_down) { al_set_mouse_xy(display, width / 2, height / 2); fake_x += event.mouse.dx; fake_y += event.mouse.dy; } redraw = true; } if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { if (event.mouse.button == 1) al_set_mouse_xy(display, width / 2, height / 2); if (event.mouse.button == 2) { right_button_down = true; fake_x = width / 2; fake_y = height / 2; } } if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { if (event.mouse.button == 2) { right_button_down = false; } } } al_destroy_event_queue(event_queue); al_destroy_display(display); close_log(false); return 0; } allegro-5.0.10/examples/ex_joystick_events.c0000644000175000001440000001300612152725670020316 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * This program tests joystick events. */ #include #include #include "common.c" #define MAX_STICKS 8 #define MAX_AXES 3 #define MAX_BUTTONS 32 /* globals */ ALLEGRO_EVENT_QUEUE *event_queue; ALLEGRO_COLOR black; ALLEGRO_COLOR grey; ALLEGRO_COLOR white; int num_sticks = 0; int num_buttons = 0; int num_axes[MAX_STICKS] = { 0 }; float joys[MAX_STICKS][MAX_AXES] = {{ 0 }}; bool joys_buttons[MAX_BUTTONS] = { 0 }; static void setup_joystick_values(ALLEGRO_JOYSTICK *joy) { ALLEGRO_JOYSTICK_STATE jst; int i, j; if (joy == NULL) { num_sticks = 0; num_buttons = 0; return; } al_get_joystick_state(joy, &jst); num_sticks = al_get_joystick_num_sticks(joy); if (num_sticks > MAX_STICKS) num_sticks = MAX_STICKS; for (i = 0; i < num_sticks; i++) { num_axes[i] = al_get_joystick_num_axes(joy, i); for (j = 0; j < num_axes[i]; ++j) joys[i][j] = jst.stick[i].axis[j]; } num_buttons = al_get_joystick_num_buttons(joy); if (num_buttons > MAX_BUTTONS) { num_buttons = MAX_BUTTONS; } for (i = 0; i < num_buttons; i++) { joys_buttons[i] = (jst.button[i] >= 16384); } } static void draw_joystick_axes(int cx, int cy, int stick) { const int size = 30; const int csize = 5; const int osize = size + csize; int zx = cx + osize + csize * 2; int x = cx + joys[stick][0] * size; int y = cy + joys[stick][1] * size; int z = cy + joys[stick][2] * size; al_draw_filled_rectangle(cx-osize, cy-osize, cx+osize, cy+osize, grey); al_draw_rectangle(cx-osize+0.5, cy-osize+0.5, cx+osize-0.5, cy+osize-0.5, black, 0); al_draw_filled_rectangle(x-5, y-5, x+5, y+5, black); if (num_axes[stick] == 3) { al_draw_filled_rectangle(zx-csize, cy-osize, zx+csize, cy+osize, grey); al_draw_rectangle(zx-csize+0.5f, cy-osize+0.5f, zx+csize-0.5f, cy+osize-0.5f, black, 0); al_draw_filled_rectangle(zx-5, z-5, zx+5, z+5, black); } } static void draw_joystick_button(int button, bool down) { ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); int x = al_get_bitmap_width(bmp)/2-120 + (button % 8) * 30; int y = al_get_bitmap_height(bmp)-120 + (button / 8) * 30; al_draw_filled_rectangle(x, y, x + 25, y + 25, grey); al_draw_rectangle(x+0.5, y+0.5, x + 24.5, y + 24.5, black, 0); if (down) { al_draw_filled_rectangle(x + 2, y + 2, x + 23, y + 23, black); } } static void draw_all(void) { ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); int width = al_get_bitmap_width(bmp); int height = al_get_bitmap_height(bmp); int i; al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); for (i = 0; i < num_sticks; i++) { int cx = (i + 0.5) * width / num_sticks; int cy = height / 2; draw_joystick_axes(cx, cy, i); } for (i = 0; i < num_buttons; i++) { draw_joystick_button(i, joys_buttons[i]); } al_flip_display(); } static void main_loop(void) { ALLEGRO_EVENT event; while (true) { if (al_is_event_queue_empty(event_queue)) draw_all(); al_wait_for_event(event_queue, &event); switch (event.type) { /* ALLEGRO_EVENT_JOYSTICK_AXIS - a joystick axis value changed. */ case ALLEGRO_EVENT_JOYSTICK_AXIS: if (event.joystick.stick < MAX_STICKS && event.joystick.axis < MAX_AXES) { joys[event.joystick.stick][event.joystick.axis] = event.joystick.pos; } break; /* ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN - a joystick button was pressed. */ case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: joys_buttons[event.joystick.button] = true; break; /* ALLEGRO_EVENT_JOYSTICK_BUTTON_UP - a joystick button was released. */ case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: joys_buttons[event.joystick.button] = false; break; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; /* ALLEGRO_EVENT_DISPLAY_CLOSE - the window close button was pressed. */ case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: al_reconfigure_joysticks(); setup_joystick_values(al_get_joystick(0)); break; /* We received an event of some type we don't know about. * Just ignore it. */ default: break; } } } int main(void) { ALLEGRO_DISPLAY *display; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); display = al_create_display(640, 480); if (!display) { abort_example("al_create_display failed\n"); } al_install_keyboard(); black = al_map_rgb(0, 0, 0); grey = al_map_rgb(0xe0, 0xe0, 0xe0); white = al_map_rgb(255, 255, 255); al_install_joystick(); event_queue = al_create_event_queue(); if (!event_queue) { abort_example("al_create_event_queue failed\n"); } if (al_get_keyboard_event_source()) { al_register_event_source(event_queue, al_get_keyboard_event_source()); } al_register_event_source(event_queue, al_get_display_event_source(display)); al_register_event_source(event_queue, al_get_joystick_event_source()); setup_joystick_values(al_get_joystick(0)); main_loop(); return 0; } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_timer.c0000644000175000001440000001163212152725670016216 0ustar tjadenusers/* A test of timer events. Since both al_get_time() as well as the timer * events may be the source of inaccuracy, it doesn't tell a lot. */ #include #include #include #include #include #include #include #include "common.c" /* A structure holding all variables of our example program. */ struct Example { ALLEGRO_FONT *myfont; /* Our font. */ ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */ double FPS; /* How often to update per second. */ int x[4]; bool first_tick; double this_time, prev_time, accum_time; double min_diff, max_diff, second_spread; double second; double timer_events; double timer_error; double timestamp; } ex; /* Initialize the example. */ static void init(void) { ex.FPS = 50; ex.first_tick = true; ex.myfont = al_load_font("data/fixed_font.tga", 0, 0); if (!ex.myfont) { abort_example("data/fixed_font.tga not found\n"); } } /* Cleanup. Always a good idea. */ static void cleanup(void) { al_destroy_font(ex.myfont); ex.myfont = NULL; } /* Print some text. */ static void print(int x, int y, char const *format, ...) { va_list list; char message[1024]; va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); /* Actual text. */ al_draw_text(ex.myfont, al_map_rgb_f(0, 0, 0), x, y, 0, message); } /* Draw our example scene. */ static void draw(void) { int h, y, i; double cur_time, event_overhead, total_error; cur_time = al_get_time(); event_overhead = cur_time - ex.timestamp; total_error = event_overhead + ex.timer_error; h = al_get_font_line_height(ex.myfont); al_clear_to_color(al_map_rgb_f(1, 1, 1)); print(0, 0, "%.9f target for %.0f Hz Timer", 1.0 / ex.FPS, ex.FPS); print(0, h, "%.9f now", ex.this_time - ex.prev_time); print(0, 2 * h, "%.9f accum over one second", ex.accum_time / ex.timer_events); print(0, 3 * h, "%.9f min", ex.min_diff); print(0, 4 * h, "%.9f max", ex.max_diff); print(300, 3.5 * h, "%.9f (max - min)", ex.second_spread); print(300, 4.5 * h, "%.9f (timer error)", ex.timer_error); print(300, 5.5 * h ,"%.9f (event overhead)", event_overhead); print(300, 6.5 * h, "%.9f (total error)" , total_error); y = 240; for (i = 0; i < 4; i++) { al_draw_filled_rectangle(ex.x[i], y + i * 60, ex.x[i] + (1 << i), y + i * 60 + 60, al_map_rgb(1, 0, 0)); } } /* Called a fixed amount of times per second. */ static void tick(ALLEGRO_TIMER_EVENT* timer_event) { int i; ex.this_time = al_get_time(); if (ex.first_tick) { ex.first_tick = false; } else { double duration; if (ex.this_time - ex.second >= 1) { ex.second = ex.this_time; ex.accum_time = 0; ex.timer_events = 0; ex.second_spread = ex.max_diff - ex.min_diff; ex.max_diff = 0; ex.min_diff = 1; } duration = ex.this_time - ex.prev_time; if (duration < ex.min_diff) ex.min_diff = duration; if (duration > ex.max_diff) ex.max_diff = duration; ex.accum_time += duration; ex.timer_events++; ex.timer_error = timer_event->error; ex.timestamp = timer_event->timestamp; } draw(); al_flip_display(); for (i = 0; i < 4; i++) { ex.x[i] += 1 << i; ex.x[i] %= 640; } ex.prev_time = ex.this_time; } /* Run our test. */ static void run(void) { ALLEGRO_EVENT event; while (1) { al_wait_for_event(ex.queue, &event); switch (event.type) { /* Was the X button on the window pressed? */ case ALLEGRO_EVENT_DISPLAY_CLOSE: return; /* Was a key pressed? */ case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; /* Is it time for the next timer tick? */ case ALLEGRO_EVENT_TIMER: tick(&event.timer); break; } } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } init(); timer = al_create_timer(1.000 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); cleanup(); return 0; } allegro-5.0.10/examples/ex_clip.c0000644000175000001440000001275212152725670016031 0ustar tjadenusers/* Test performance of al_draw_bitmap_region, al_create_sub_bitmap and * al_set_clipping_rectangle when clipping a bitmap. */ #include #include #include #include #include #include #include #include "common.c" struct Example { ALLEGRO_BITMAP *pattern; ALLEGRO_FONT *font; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_COLOR background, text, white; double timer[4], counter[4]; int FPS; float text_x, text_y; } ex; static ALLEGRO_BITMAP *example_bitmap(int w, int h) { int i, j; float mx = w * 0.5; float my = h * 0.5; ALLEGRO_STATE state; ALLEGRO_BITMAP *pattern = al_create_bitmap(w, h); al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(pattern); al_lock_bitmap(pattern, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); for (i = 0; i < w; i++) { for (j = 0; j < h; j++) { float a = atan2(i - mx, j - my); float d = sqrt(pow(i - mx, 2) + pow(j - my, 2)); float l = 1 - pow(1.0 - 1 / (1 + d * 0.1), 5); float hue = a * 180 / ALLEGRO_PI; float sat = 1; if (i == 0 || j == 0 || i == w - 1 || j == h - 1) { hue += 180; } else if (i == 1 || j == 1 || i == w - 2 || j == h - 2) { hue += 180; sat = 0.5; } al_put_pixel(i, j, al_color_hsl(hue, sat, l)); } } al_unlock_bitmap(pattern); al_restore_state(&state); return pattern; } static void set_xy(float x, float y) { ex.text_x = x; ex.text_y = y; } static void get_xy(float *x, float *y) { *x = ex.text_x; *y = ex.text_y; } static void print(char const *format, ...) { va_list list; char message[1024]; int th = al_get_font_line_height(ex.font); va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); ex.text_y += th; } static void start_timer(int i) { ex.timer[i] -= al_get_time(); ex.counter[i]++; } static void stop_timer(int i) { ex.timer[i] += al_get_time(); } static double get_fps(int i) { if (ex.timer[i] == 0) return 0; return ex.counter[i] / ex.timer[i]; } static void draw(void) { float x, y; int iw = al_get_bitmap_width(ex.pattern); int ih = al_get_bitmap_height(ex.pattern); ALLEGRO_BITMAP *temp; int cx, cy, cw, ch, gap = 8; al_get_clipping_rectangle(&cx, &cy, &cw, &ch); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_clear_to_color(ex.background); /* Test 1. */ set_xy(8, 8); print("al_draw_bitmap_region (%.1f fps)", get_fps(0)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(0); al_draw_bitmap_region(ex.pattern, 1, 1, iw - 2, ih - 2, x + 8 + iw + 1, y + 1, 0); stop_timer(0); set_xy(x, y + ih + gap); /* Test 2. */ print("al_create_sub_bitmap (%.1f fps)", get_fps(1)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(1); temp = al_create_sub_bitmap(ex.pattern, 1, 1, iw - 2, ih - 2); al_draw_bitmap(temp, x + 8 + iw + 1, y + 1, 0); al_destroy_bitmap(temp); stop_timer(1); set_xy(x, y + ih + gap); /* Test 3. */ print("al_set_clipping_rectangle (%.1f fps)", get_fps(2)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(2); al_set_clipping_rectangle(x + 8 + iw + 1, y + 1, iw - 2, ih - 2); al_draw_bitmap(ex.pattern, x + 8 + iw, y, 0); al_set_clipping_rectangle(cx, cy, cw, ch); stop_timer(2); set_xy(x, y + ih + gap); } static void tick(void) { draw(); al_flip_display(); } static void run(void) { ALLEGRO_EVENT event; bool need_draw = true; while (1) { if (need_draw && al_is_event_queue_empty(ex.queue)) { tick(); need_draw = false; } al_wait_for_event(ex.queue, &event); switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; case ALLEGRO_EVENT_TIMER: need_draw = true; break; } } } static void init(void) { ex.FPS = 60; ex.font = al_load_font("data/fixed_font.tga", 0, 0); if (!ex.font) { abort_example("data/fixed_font.tga not found.\n"); } ex.background = al_color_name("beige"); ex.text = al_color_name("blue"); ex.white = al_color_name("white"); ex.pattern = example_bitmap(100, 100); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } init(); timer = al_create_timer(1.0 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); return 0; } allegro-5.0.10/examples/ex_multisample.c0000644000175000001440000001562512152725670017440 0ustar tjadenusers/* This example demonstrates the effect of multi-sampling on primitives and * bitmaps. * * * In the window without multi-sampling, the edge of the colored lines will not * be anti-aliased - each pixel is either filled completely with the primitive * color or not at all. * * The same is true for bitmaps. They will always be drawn at the nearest * full-pixel position. However this is only true for the bitmap outline - * when texture filtering is enabled the texture itself will honor the sub-pixel * position. * * Therefore in the case with no multi-sampling but texture-filtering the * outer black edge will stutter in one-pixel steps while the inside edge will * be filtered and appear smooth. * * * In the multi-sampled version the colored lines will be anti-aliased. * * Same with the bitmaps. This means the bitmap outlines will always move in * smooth sub-pixel steps. However if texture filtering is turned off the * texels still are rounded to the next integer position. * * Therefore in the case where multi-sampling is enabled but texture-filtering * is not the outer bitmap edges will move smoothly but the inner will not. */ #include #include #include #include #include #include #include "common.c" static ALLEGRO_FONT *font, *font_ms; static ALLEGRO_BITMAP *bitmap_normal; static ALLEGRO_BITMAP *bitmap_filter; static ALLEGRO_BITMAP *bitmap_normal_ms; static ALLEGRO_BITMAP *bitmap_filter_ms; static float bitmap_x[8], bitmap_y[8]; static float bitmap_t; static ALLEGRO_BITMAP *create_bitmap(void) { const int checkers_size = 8; const int bitmap_size = 24; ALLEGRO_BITMAP *bitmap; ALLEGRO_LOCKED_REGION *locked; int x, y, p; unsigned char *rgba; bitmap = al_create_bitmap(bitmap_size, bitmap_size); locked = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, 0); rgba = locked->data; p = locked->pitch; for (y = 0; y < bitmap_size; y++) { for (x = 0; x < bitmap_size; x++) { int c = (((x / checkers_size) + (y / checkers_size)) & 1) * 255; rgba[y * p + x * 4 + 0] = 0; rgba[y * p + x * 4 + 1] = 0; rgba[y * p + x * 4 + 2] = 0; rgba[y * p + x * 4 + 3] = c; } } al_unlock_bitmap(bitmap); return bitmap; } static void bitmap_move(void) { int i; bitmap_t++; for (i = 0; i < 8; i++) { float a = 2 * ALLEGRO_PI * i / 16; float s = sin((bitmap_t + i * 40) / 180 * ALLEGRO_PI); s *= 90; bitmap_x[i] = 100 + s * cos(a); bitmap_y[i] = 100 + s * sin(a); } } static void draw(ALLEGRO_BITMAP *bitmap, int y, char const *text) { int i; al_draw_text(font_ms, al_map_rgb(0, 0, 0), 0, y, 0, text); for (i = 0; i < 16; i++) { float a = 2 * ALLEGRO_PI * i / 16; ALLEGRO_COLOR c = al_color_hsv(i * 360 / 16, 1, 1); al_draw_line(150 + cos(a) * 10, y + 100 + sin(a) * 10, 150 + cos(a) * 90, y + 100 + sin(a) * 90, c, 3); } for (i = 0; i < 8; i++) { float a = 2 * ALLEGRO_PI * i / 16; int s = al_get_bitmap_width(bitmap); al_draw_rotated_bitmap(bitmap, s / 2, s / 2, 50 + bitmap_x[i], y + bitmap_y[i], a, 0); } } int main(void) { ALLEGRO_DISPLAY *display, *ms_display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; ALLEGRO_BITMAP *memory; char title[1024]; bool quit = false; bool redraw = true; int wx, wy; if (!al_init()) { abort_example("Couldn't initialise Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); memory = create_bitmap(); /* Create the normal display. */ al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_REQUIRE); al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_SUGGEST); display = al_create_display(300, 450); if (!display) { abort_example("Error creating display\n"); } al_set_window_title(display, "Normal"); /* Create bitmaps for the normal display. */ al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); bitmap_filter = al_clone_bitmap(memory); al_set_new_bitmap_flags(0); bitmap_normal = al_clone_bitmap(memory); font = al_create_builtin_font(); al_get_window_position(display, &wx, &wy); if (wx < 160) wx = 160; /* Create the multi-sampling display. */ al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE); al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); ms_display = al_create_display(300, 450); if (!ms_display) { abort_example("Multisampling not available.\n"); } sprintf(title, "Multisampling (%dx)", al_get_display_option( ms_display, ALLEGRO_SAMPLES)); al_set_window_title(ms_display, title); /* Create bitmaps for the multi-sampling display. */ al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); bitmap_filter_ms = al_clone_bitmap(memory); al_set_new_bitmap_flags(0); bitmap_normal_ms = al_clone_bitmap(memory); font_ms = al_create_builtin_font(); /* Move the windows next to each other, because some window manager * would put them on top of each other otherwise. */ al_set_window_position(display, wx - 160, wy); al_set_window_position(ms_display, wx + 160, wy); timer = al_create_timer(1.0 / 30.0); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_display_event_source(ms_display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (!quit) { ALLEGRO_EVENT event; /* Check for ESC key or close button event and quit in either case. */ al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: quit = true; break; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) quit = true; break; case ALLEGRO_EVENT_TIMER: bitmap_move(); redraw = true; break; } if (redraw && al_is_event_queue_empty(queue)) { /* Draw the multi-sampled version into the first window. */ al_set_target_backbuffer(ms_display); al_clear_to_color(al_map_rgb_f(1, 1, 1)); draw(bitmap_filter_ms, 0, "filtered, multi-sample"); draw(bitmap_normal_ms, 250, "no filter, multi-sample"); al_flip_display(); /* Draw the normal version into the second window. */ al_set_target_backbuffer(display); al_clear_to_color(al_map_rgb_f(1, 1, 1)); draw(bitmap_filter, 0, "filtered"); draw(bitmap_normal, 250, "no filter"); al_flip_display(); redraw = false; } } return 0; } allegro-5.0.10/examples/ex_joystick_hotplugging.c0000644000175000001440000001001612152725670021337 0ustar tjadenusers#include #include #include #include "common.c" static void print_joystick_info(ALLEGRO_JOYSTICK *joy) { int i, n, a; if (!joy) return; log_printf("Joystick: '%s'\n", al_get_joystick_name(joy)); log_printf(" Buttons:"); n = al_get_joystick_num_buttons(joy); for (i = 0; i < n; i++) { log_printf(" '%s'", al_get_joystick_button_name(joy, i)); } log_printf("\n"); n = al_get_joystick_num_sticks(joy); for (i = 0; i < n; i++) { log_printf(" Stick %d: '%s'\n", i, al_get_joystick_stick_name(joy, i)); for (a = 0; a < al_get_joystick_num_axes(joy, i); a++) { log_printf(" Axis %d: '%s'\n", a, al_get_joystick_axis_name(joy, i, a)); } } } static void draw(ALLEGRO_JOYSTICK *curr_joy) { int x = 100; int y = 100; ALLEGRO_JOYSTICK_STATE joystate; int i; al_clear_to_color(al_map_rgb(0, 0, 0)); if (curr_joy) { al_get_joystick_state(curr_joy, &joystate); al_draw_filled_circle( x+joystate.stick[0].axis[0]*20, y+joystate.stick[0].axis[1]*20, 20, al_map_rgb(255, 255, 255) ); for (i = 0; i < al_get_joystick_num_buttons(curr_joy); i++) { if (joystate.button[i]) { al_draw_filled_circle( i*20+10, 400, 9, al_map_rgb(255, 255, 255) ); } } } al_flip_display(); } int main(void) { int num_joysticks; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_JOYSTICK *curr_joy; ALLEGRO_DISPLAY *display; if (!al_init()) { abort_example("Could not init Allegro.\n"); } if (!al_install_joystick()) { abort_example("Could not init joysticks.\n"); } al_install_keyboard(); al_init_primitives_addon(); open_log(); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_joystick_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); num_joysticks = al_get_num_joysticks(); log_printf("Num joysticks: %d\n", num_joysticks); if (num_joysticks > 0) { curr_joy = al_get_joystick(0); print_joystick_info(curr_joy); } else { curr_joy = NULL; } draw(curr_joy); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_KEY_CHAR) { int n = event.keyboard.unichar - '0'; if (n >= 0 && n < num_joysticks) { curr_joy = al_get_joystick(n); log_printf("switching to joystick %d\n", n); print_joystick_info(curr_joy); } } else if (event.type == ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) { int old = al_get_num_joysticks(); al_reconfigure_joysticks(); num_joysticks = al_get_num_joysticks(); log_printf("after reconfiguration num joysticks = %d\n", num_joysticks); if (curr_joy) { log_printf("current joystick is: %s\n", al_get_joystick_active(curr_joy) ? "active" : "inactive"); } if (old < num_joysticks) { curr_joy = al_get_joystick(0); } } else if (event.type == ALLEGRO_EVENT_JOYSTICK_AXIS) { log_printf("axis event from %p, stick %d, axis %d\n", event.joystick.id, event.joystick.stick, event.joystick.axis); } else if (event.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN) { log_printf("button down event %d from %p\n", event.joystick.button, event.joystick.id); } draw(curr_joy); } close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_keyboard_focus.c0000644000175000001440000000271612152725670020100 0ustar tjadenusers/* * Example program for the Allegro library. * * This program tests if the ALLEGRO_KEYBOARD_STATE `display' field * is set correctly to the focused display. */ #include "allegro5/allegro.h" #include "common.c" static ALLEGRO_DISPLAY *display1; static ALLEGRO_DISPLAY *display2; static void redraw(ALLEGRO_COLOR color1, ALLEGRO_COLOR color2) { al_set_target_backbuffer(display1); al_clear_to_color(color1); al_flip_display(); al_set_target_backbuffer(display2); al_clear_to_color(color2); al_flip_display(); } int main(void) { ALLEGRO_COLOR black; ALLEGRO_COLOR red; ALLEGRO_KEYBOARD_STATE kbdstate; if (!al_init()) { abort_example("Error initialising Allegro.\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } display1 = al_create_display(300, 300); display2 = al_create_display(300, 300); if (!display1 || !display2) { abort_example("Error creating displays.\n"); } black = al_map_rgb(0, 0, 0); red = al_map_rgb(255, 0, 0); while (1) { al_get_keyboard_state(&kbdstate); if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)) { break; } if (kbdstate.display == display1) { redraw(red, black); } else if (kbdstate.display == display2) { redraw(black, red); } else { redraw(black, black); } al_rest(0.1); } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_draw_bitmap.c0000644000175000001440000002604312152727422017366 0ustar tjadenusers#include #include #include #include #include #include "common.c" #define FPS 60 #define MAX_SPRITES 1024 typedef struct Sprite { float x, y, dx, dy; } Sprite; char const *text[] = { "Space - toggle use of textures", "B - toggle alpha blending", "Left/Right - change bitmap size", "Up/Down - change bitmap count", "F1 - toggle help text" }; struct Example { Sprite sprites[MAX_SPRITES]; bool use_memory_bitmaps; int blending; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *mysha, *bitmap; int bitmap_size; int sprite_count; bool show_help; ALLEGRO_FONT *font; bool mouse_down; int last_x, last_y; ALLEGRO_COLOR white; ALLEGRO_COLOR half_white; ALLEGRO_COLOR dark; ALLEGRO_COLOR red; double direct_speed_measure; int ftpos; double frame_times[FPS]; } example; static void add_time(void) { example.frame_times[example.ftpos++] = al_get_time(); if (example.ftpos >= FPS) example.ftpos = 0; } static void get_fps(int *average, int *minmax) { int i; int prev = FPS - 1; double min_dt = 1; double max_dt = 1 / 1000000.0; double av = 0; double d; for (i = 0; i < FPS; i++) { if (i != example.ftpos) { double dt = example.frame_times[i] - example.frame_times[prev]; if (dt < min_dt) min_dt = dt; if (dt > max_dt) max_dt = dt; av += dt; } prev = i; } av /= (FPS - 1); *average = ceil(1 / av); d = 1 / min_dt - 1 / max_dt; *minmax = floor(d / 2); } static void add_sprite(void) { if (example.sprite_count < MAX_SPRITES) { int w = al_get_display_width(example.display); int h = al_get_display_height(example.display); int i = example.sprite_count++; Sprite *s = example.sprites + i; float a = rand() % 360; s->x = rand() % (w - example.bitmap_size); s->y = rand() % (h - example.bitmap_size); s->dx = cos(a) * FPS * 2; s->dy = sin(a) * FPS * 2; } } static void add_sprites(int n) { int i; for (i = 0; i < n; i++) add_sprite(); } static void remove_sprites(int n) { example.sprite_count -= n; if (example.sprite_count < 0) example.sprite_count = 0; } static void change_size(int size) { int bw, bh; if (size < 1) size = 1; if (size > 1024) size = 1024; if (example.bitmap) al_destroy_bitmap(example.bitmap); al_set_new_bitmap_flags( example.use_memory_bitmaps ? ALLEGRO_MEMORY_BITMAP : ALLEGRO_VIDEO_BITMAP); example.bitmap = al_create_bitmap(size, size); example.bitmap_size = size; al_set_target_bitmap(example.bitmap); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); bw = al_get_bitmap_width(example.mysha); bh = al_get_bitmap_height(example.mysha); al_draw_scaled_bitmap(example.mysha, 0, 0, bw, bh, 0, 0, size, size, 0); al_set_target_backbuffer(example.display); } static void sprite_update(Sprite *s) { int w = al_get_display_width(example.display); int h = al_get_display_height(example.display); s->x += s->dx / FPS; s->y += s->dy / FPS; if (s->x < 0) { s->x = -s->x; s->dx = -s->dx; } if (s->x + example.bitmap_size > w) { s->x = -s->x + 2 * (w - example.bitmap_size); s->dx = -s->dx; } if (s->y < 0) { s->y = -s->y; s->dy = -s->dy; } if (s->y + example.bitmap_size > h) { s->y = -s->y + 2 * (h - example.bitmap_size); s->dy = -s->dy; } if (example.bitmap_size > w) s->x = w / 2 - example.bitmap_size / 2; if (example.bitmap_size > h) s->y = h / 2 - example.bitmap_size / 2; } static void update(void) { int i; for (i = 0; i < example.sprite_count; i++) sprite_update(example.sprites + i); } static void redraw(void) { int w = al_get_display_width(example.display); int h = al_get_display_height(example.display); int i; int f1, f2; int fh = al_get_font_line_height(example.font); char const *info[] = {"textures", "memory buffers"}; char const *binfo[] = {"alpha", "additive", "tinted", "solid"}; ALLEGRO_COLOR tint = example.white; if (example.blending == 0) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); tint = example.half_white; } else if (example.blending == 1) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); tint = example.dark; } else if (example.blending == 2) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); tint = example.red; } else if (example.blending == 3) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); for (i = 0; i < example.sprite_count; i++) { Sprite *s = example.sprites + i; al_draw_tinted_bitmap(example.bitmap, tint, s->x, s->y, 0); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (example.show_help) { for (i = 0; i < 5; i++) al_draw_text(example.font, example.white, 0, h - 5 * fh + i * fh, 0, text[i]); } al_draw_textf(example.font, example.white, 0, 0, 0, "count: %d", example.sprite_count); al_draw_textf(example.font, example.white, 0, fh, 0, "size: %d", example.bitmap_size); al_draw_textf(example.font, example.white, 0, fh * 2, 0, "%s", info[example.use_memory_bitmaps]); al_draw_textf(example.font, example.white, 0, fh * 3, 0, "%s", binfo[example.blending]); get_fps(&f1, &f2); al_draw_textf(example.font, example.white, w, 0, ALLEGRO_ALIGN_RIGHT, "FPS: %4d +- %-4d", f1, f2); al_draw_textf(example.font, example.white, w, fh, ALLEGRO_ALIGN_RIGHT, "%4d / sec", (int)(1.0 / example.direct_speed_measure)); } int main(void) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_MONITOR_INFO info; int w = 640, h = 480; bool done = false; bool need_redraw = true; example.show_help = true; if (!al_init()) { abort_example("Failed to init Allegro.\n"); } if (!al_init_image_addon()) { abort_example("Failed to init IIO addon.\n"); } al_init_font_addon(); al_get_num_video_adapters(); al_get_monitor_info(0, &info); if (info.x2 - info.x1 < w) w = info.x2 - info.x1; if (info.y2 - info.y1 < h) h = info.y2 - info.y1; example.display = al_create_display(w, h); if (!example.display) { abort_example("Error creating display.\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } if (!al_install_mouse()) { abort_example("Error installing mouse.\n"); } example.font = al_load_font("data/fixed_font.tga", 0, 0); if (!example.font) { abort_example("Error loading data/fixed_font.tga\n"); } example.mysha = al_load_bitmap("data/mysha256x256.png"); if (!example.mysha) { abort_example("Error loading data/mysha256x256.png\n"); } example.white = al_map_rgb_f(1, 1, 1); example.half_white = al_map_rgba_f(1, 1, 1, 0.5); example.dark = al_map_rgb(15, 15, 15); example.red = al_map_rgb_f(1, 0.2, 0.1); change_size(256); add_sprite(); add_sprite(); timer = al_create_timer(1.0 / FPS); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(example.display)); al_start_timer(timer); while (!done) { ALLEGRO_EVENT event; if (need_redraw && al_is_event_queue_empty(queue)) { double t = -al_get_time(); add_time(); al_clear_to_color(al_map_rgb_f(0, 0, 0)); redraw(); t += al_get_time(); example.direct_speed_measure = t; al_flip_display(); need_redraw = false; } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_CHAR: /* includes repeats */ if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) done = true; else if (event.keyboard.keycode == ALLEGRO_KEY_UP) { add_sprites(1); } else if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { remove_sprites(1); } else if (event.keyboard.keycode == ALLEGRO_KEY_LEFT) { change_size(example.bitmap_size - 1); } else if (event.keyboard.keycode == ALLEGRO_KEY_RIGHT) { change_size(example.bitmap_size + 1); } else if (event.keyboard.keycode == ALLEGRO_KEY_F1) { example.show_help ^= 1; } else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { example.use_memory_bitmaps ^= 1; change_size(example.bitmap_size); } else if (event.keyboard.keycode == ALLEGRO_KEY_B) { example.blending++; if (example.blending == 4) example.blending = 0; } break; case ALLEGRO_EVENT_DISPLAY_CLOSE: done = true; break; case ALLEGRO_EVENT_TIMER: update(); need_redraw = true; break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: example.mouse_down = true; example.last_x = event.mouse.x; example.last_y = event.mouse.y; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: { int fh = al_get_font_line_height(example.font); example.mouse_down = false; if (event.mouse.x < 40 && event.mouse.y >= h - fh * 5) { int button = (event.mouse.y - (h - fh * 5)) / fh; if (button == 0) { example.use_memory_bitmaps ^= 1; change_size(example.bitmap_size); } if (button == 1) { example.blending++; if (example.blending == 4) example.blending = 0; } if (button == 4) { example.show_help ^= 1; } } break; } case ALLEGRO_EVENT_MOUSE_AXES: if (example.mouse_down) { double dx = event.mouse.x - example.last_x; double dy = event.mouse.y - example.last_y; if (dy > 4) { add_sprites(dy / 4); } if (dy < -4) { remove_sprites(-dy / 4); } if (dx > 4) { change_size(example.bitmap_size + dx - 4); } if (dx < -4) { change_size(example.bitmap_size + dx + 4); } example.last_x = event.mouse.x; example.last_y = event.mouse.y; } break; } } al_destroy_bitmap(example.bitmap); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_bitmap_flip.c0000644000175000001440000000765512152725670017376 0ustar tjadenusers/* An example showing bitmap flipping flags, by Steven Wallace. */ #include #include #include #include "common.c" #define INTERVAL 0.01 float bmp_x = 200; float bmp_y = 200; float bmp_dx = 96; float bmp_dy = 96; int bmp_flag = 0; static void update(ALLEGRO_BITMAP *bmp) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); int display_w = al_get_bitmap_width(target); int display_h = al_get_bitmap_height(target); int bitmap_w = al_get_bitmap_width(bmp); int bitmap_h = al_get_bitmap_height(bmp); bmp_x += bmp_dx * INTERVAL; bmp_y += bmp_dy * INTERVAL; /* Make sure bitmap is still on the screen. */ if (bmp_y < 0) { bmp_y = 0; bmp_dy *= -1; bmp_flag &= ~ALLEGRO_FLIP_VERTICAL; } if (bmp_x < 0) { bmp_x = 0; bmp_dx *= -1; bmp_flag &= ~ALLEGRO_FLIP_HORIZONTAL; } if (bmp_y > display_h - bitmap_h) { bmp_y = display_h - bitmap_h; bmp_dy *= -1; bmp_flag |= ALLEGRO_FLIP_VERTICAL; } if (bmp_x > display_w - bitmap_w) { bmp_x = display_w - bitmap_w; bmp_dx *= -1; bmp_flag |= ALLEGRO_FLIP_HORIZONTAL; } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_BITMAP *bmp; ALLEGRO_BITMAP *mem_bmp; ALLEGRO_BITMAP *disp_bmp; ALLEGRO_FONT *font; char *text; bool done = false; bool redraw = true; if (!al_init()) { abort_example("Failed to init Allegro.\n"); } if (!al_init_image_addon()) { abort_example("Failed to init IIO addon.\n"); } al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { abort_example("Error loading data/fixed_font.tga\n"); } bmp = disp_bmp = al_load_bitmap("data/mysha.pcx"); if (!bmp) { abort_example("Error loading data/mysha.pcx\n"); } text = "Display bitmap (space to change)"; al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); mem_bmp = al_load_bitmap("data/mysha.pcx"); if (!mem_bmp) { abort_example("Error loading data/mysha.pcx\n"); } timer = al_create_timer(INTERVAL); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(display)); al_start_timer(timer); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); while (!done) { ALLEGRO_EVENT event; if (redraw && al_is_event_queue_empty(queue)) { update(bmp); al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_draw_tinted_bitmap(bmp, al_map_rgba_f(1, 1, 1, 0.5), bmp_x, bmp_y, bmp_flag); al_draw_text(font, al_map_rgba_f(1, 1, 1, 0.5), 0, 0, 0, text); al_flip_display(); redraw = false; } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) done = true; else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { if (bmp == mem_bmp) { bmp = disp_bmp; text = "Display bitmap (space to change)"; } else { bmp = mem_bmp; text = "Memory bitmap (space to change)"; } } break; case ALLEGRO_EVENT_DISPLAY_CLOSE: done = true; break; case ALLEGRO_EVENT_TIMER: redraw = true; break; } } al_destroy_bitmap(bmp); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_filter.c0000644000175000001440000001216212152725670016362 0ustar tjadenusers#include #include #include #include #include #include "common.c" #define FPS 60 static struct Example { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; ALLEGRO_BITMAP *bitmaps[2][9]; ALLEGRO_COLOR bg, fg, info; int bitmap; int ticks; } example; static int const filter_flags[6] = { 0, ALLEGRO_MIN_LINEAR, ALLEGRO_MIPMAP, ALLEGRO_MIN_LINEAR | ALLEGRO_MIPMAP, 0, ALLEGRO_MAG_LINEAR }; static char const *filter_text[4] = { "nearest", "linear", "nearest mipmap", "linear mipmap" }; static void update(void) { example.ticks++; } static void redraw(void) { int w = al_get_display_width(example.display); int h = al_get_display_height(example.display); int i; al_clear_to_color(example.bg); for (i = 0; i < 6; i++) { float x = (i / 2) * w / 3 + w / 6; float y = (i % 2) * h / 2 + h / 4; ALLEGRO_BITMAP *bmp = example.bitmaps[example.bitmap][i]; float bw = al_get_bitmap_width(bmp); float bh = al_get_bitmap_height(bmp); float t = 1 - 2 * fabsf((example.ticks % (FPS * 16)) / 16.0 / FPS - 0.5); float scale; float angle = example.ticks * ALLEGRO_PI * 2 / FPS / 8; if (i < 4) scale = 1 - t * 0.9; else scale = 1 + t * 9; al_draw_textf(example.font, example.fg, x, y - 64 - 14, ALLEGRO_ALIGN_CENTRE, "%s", filter_text[i % 4]); al_set_clipping_rectangle(x - 64, y - 64, 128, 128); al_draw_scaled_rotated_bitmap(bmp, bw / 2, bh / 2, x, y, scale, scale, angle, 0); al_set_clipping_rectangle(0, 0, w, h); } al_draw_textf(example.font, example.info, w / 2, h - 14, ALLEGRO_ALIGN_CENTRE, "press space to change"); } int main(void) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; int w = 640, h = 480; bool done = false; bool need_redraw = true; int i; ALLEGRO_BITMAP *mysha; if (!al_init()) { abort_example("Failed to init Allegro.\n"); } if (!al_init_image_addon()) { abort_example("Failed to init IIO addon.\n"); } al_init_font_addon(); example.display = al_create_display(w, h); if (!example.display) { abort_example("Error creating display.\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); } if (!al_install_mouse()) { abort_example("Error installing mouse.\n"); } example.font = al_load_font("data/fixed_font.tga", 0, 0); if (!example.font) { abort_example("Error loading data/fixed_font.tga\n"); } mysha = al_load_bitmap("data/mysha256x256.png"); if (!mysha) { abort_example("Error loading data/mysha256x256.png\n"); } for (i = 0; i < 6; i++) { ALLEGRO_LOCKED_REGION *lock; int x, y; /* Only power-of-two bitmaps can have mipmaps. */ al_set_new_bitmap_flags(filter_flags[i]); example.bitmaps[0][i] = al_create_bitmap(1024, 1024); example.bitmaps[1][i] = al_clone_bitmap(mysha); lock = al_lock_bitmap(example.bitmaps[0][i], ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); for (y = 0; y < 1024; y++) { unsigned char *row = (unsigned char *)lock->data + lock->pitch * y; unsigned char *ptr = row; for (x = 0; x < 1024; x++) { int c = 0; if (((x >> 2) & 1) ^ ((y >> 2) & 1)) c = 255; *(ptr++) = c; *(ptr++) = c; *(ptr++) = c; *(ptr++) = 255; } } al_unlock_bitmap(example.bitmaps[0][i]); } example.bg = al_map_rgb_f(0, 0, 0); example.fg = al_map_rgb_f(1, 1, 1); example.info = al_map_rgb_f(0.5, 0.5, 1); timer = al_create_timer(1.0 / FPS); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(example.display)); al_start_timer(timer); while (!done) { ALLEGRO_EVENT event; if (need_redraw && al_is_event_queue_empty(queue)) { redraw(); al_flip_display(); need_redraw = false; } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) done = true; if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) example.bitmap = (example.bitmap + 1) % 2; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: done = true; break; case ALLEGRO_EVENT_TIMER: update(); need_redraw = true; break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: example.bitmap = (example.bitmap + 1) % 2; break; } } for (i = 0; i < 6; i++) { al_destroy_bitmap(example.bitmaps[0][i]); al_destroy_bitmap(example.bitmaps[1][i]); } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_bitmap.c0000644000175000001440000001006712152725670016353 0ustar tjadenusers#include #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "common.c" int main(int argc, const char *argv[]) { const char *filename; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *membitmap, *bitmap; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; bool redraw = true; double zoom = 1; double t0; double t1; if (argc > 1) { filename = argv[1]; } else { filename = "data/mysha.pcx"; } if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc > 2) { al_set_new_display_adapter(atoi(argv[2])); } al_install_mouse(); al_install_keyboard(); al_init_image_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } al_set_window_title(display, filename); /* We load the bitmap into a memory bitmap, because creating a * display bitmap could fail if the bitmap is too big to fit into a * single texture. * FIXME: Or should A5 automatically created multiple display bitmaps? */ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); t0 = al_get_time(); membitmap = al_load_bitmap(filename); t1 = al_get_time(); if (!membitmap) { abort_example("%s not found or failed to load\n", filename); } al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); log_printf("Loading took %.4f seconds\n", t1 - t0); // FIXME: // Now try to split the memory bitmap into display bitmaps? bitmap = al_clone_bitmap(membitmap); if (!bitmap) bitmap = membitmap; timer = al_create_timer(1.0 / 30); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_ORIENTATION) { int o = event.display.orientation; if (o == ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) { log_printf("0 degrees\n"); } else if (o == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) { log_printf("90 degrees\n"); } else if (o == ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES) { log_printf("180 degrees\n"); } else if (o == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) { log_printf("270 degrees\n"); } else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_UP) { log_printf("Face up\n"); } else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN) { log_printf("Face down\n"); } } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.unichar == '1') zoom = 1; if (event.keyboard.unichar == '+') zoom *= 1.1; if (event.keyboard.unichar == '-') zoom /= 1.1; if (event.keyboard.unichar == 'f') zoom = (double)al_get_display_width(display) / al_get_bitmap_width(bitmap); } if (event.type == ALLEGRO_EVENT_TIMER) redraw = true; if (redraw && al_is_event_queue_empty(queue)) { redraw = false; al_clear_to_color(al_map_rgb_f(0, 0, 0)); if (zoom == 1) al_draw_bitmap(bitmap, 0, 0, 0); else al_draw_scaled_rotated_bitmap( bitmap, 0, 0, 0, 0, zoom, zoom, 0, 0); al_flip_display(); } } al_destroy_bitmap(bitmap); close_log(false); return 0; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/examples/ex_pixelformat.cpp0000644000175000001440000001452112152725670017770 0ustar tjadenusers/* * Simple (incomplete) test of pixel format conversions. * * This should be made comprehensive. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_primitives.h" #include "nihgui.hpp" #include "common.c" typedef struct FORMAT { int format; char const *name; } FORMAT; const FORMAT formats[ALLEGRO_NUM_PIXEL_FORMATS] = { {ALLEGRO_PIXEL_FORMAT_ANY, "any"}, {ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, "no alpha"}, {ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, "alpha"}, {ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, "15"}, {ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, "16"}, {ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, "16 alpha"}, {ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, "24"}, {ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, "32"}, {ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, "32 alpha"}, {ALLEGRO_PIXEL_FORMAT_ARGB_8888, "ARGB8888"}, {ALLEGRO_PIXEL_FORMAT_RGBA_8888, "RGBA8888"}, {ALLEGRO_PIXEL_FORMAT_ARGB_4444, "ARGB4444"}, {ALLEGRO_PIXEL_FORMAT_RGB_888, "RGB888"}, {ALLEGRO_PIXEL_FORMAT_RGB_565, "RGB565"}, {ALLEGRO_PIXEL_FORMAT_RGB_555, "RGB555"}, {ALLEGRO_PIXEL_FORMAT_RGBA_5551, "RGBA5551"}, {ALLEGRO_PIXEL_FORMAT_ARGB_1555, "ARGB1555"}, {ALLEGRO_PIXEL_FORMAT_ABGR_8888, "ABGR8888"}, {ALLEGRO_PIXEL_FORMAT_XBGR_8888, "XBGR8888"}, {ALLEGRO_PIXEL_FORMAT_BGR_888, "BGR888"}, {ALLEGRO_PIXEL_FORMAT_BGR_565, "BGR565"}, {ALLEGRO_PIXEL_FORMAT_BGR_555, "BGR555"}, {ALLEGRO_PIXEL_FORMAT_RGBX_8888, "RGBX8888"}, {ALLEGRO_PIXEL_FORMAT_XRGB_8888, "XRGB8888"}, {ALLEGRO_PIXEL_FORMAT_ABGR_F32, "ABGR32F"}, {ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, "ABGR(LE)"}, {ALLEGRO_PIXEL_FORMAT_RGBA_4444, "RGBA4444"} }; #define NUM_FORMATS ALLEGRO_NUM_PIXEL_FORMATS const char *get_format_name(ALLEGRO_BITMAP *bmp) { if (!bmp) return "none"; int format = al_get_bitmap_format(bmp); for (unsigned i = 0; i < NUM_FORMATS; i++) { if (formats[i].format == format) return formats[i].name; } return "unknown"; } class Prog { private: Dialog d; Label source_label; Label dest_label; List source_list; List dest_list; Label true_formats; ToggleButton use_memory_button; ToggleButton enable_timing_button; Label time_label; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); void run(); private: void draw_sample(); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 20, 30)), source_label(Label("Source")), dest_label(Label("Destination")), source_list(List()), dest_list(List()), true_formats(Label("")), use_memory_button(ToggleButton("Use memory bitmaps")), enable_timing_button(ToggleButton("Enable timing")), time_label(Label("")) { d.add(source_label, 11, 0, 4, 1); d.add(source_list, 11, 1, 4, 27); d.add(dest_label, 15, 0, 4, 1); d.add(dest_list, 15, 1, 4, 27); d.add(true_formats, 0, 15, 10, 1); d.add(use_memory_button, 0, 17, 10, 2); d.add(enable_timing_button, 0, 19, 10, 2); d.add(time_label, 0, 21, 10, 1); for (unsigned i = 0; i < NUM_FORMATS; i++) { source_list.append_item(formats[i].name); dest_list.append_item(formats[i].name); } } void Prog::run() { d.prepare(); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { al_clear_to_color(al_map_rgb(128, 128, 128)); draw_sample(); d.draw(); al_flip_display(); } d.run_step(true); } } void Prog::draw_sample() { const int i = source_list.get_cur_value(); const int j = dest_list.get_cur_value(); ALLEGRO_BITMAP *bitmap1; ALLEGRO_BITMAP *bitmap2; bool use_memory = use_memory_button.get_pushed(); bool enable_timing = enable_timing_button.get_pushed(); if (use_memory) al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); else al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); al_set_new_bitmap_format(formats[i].format); bitmap1 = al_load_bitmap("data/allegro.pcx"); if (!bitmap1) { log_printf("Could not load image, bitmap format = %d\n", formats[i].format); } al_set_new_bitmap_format(formats[j].format); bitmap2 = al_create_bitmap(320, 200); if (!bitmap2) { log_printf("Could not create bitmap, format = %d\n", formats[j].format); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); if (bitmap1 && bitmap2) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); al_set_target_bitmap(bitmap2); if (enable_timing) { double t0, t1; char str[256]; int frames = 0; t0 = al_get_time(); log_printf("Timing...\n"); do { al_draw_bitmap(bitmap1, 0, 0, 0); frames++; t1 = al_get_time(); } while (t1 - t0 < 0.25); log_printf(" ...done.\n"); sprintf(str, "%.0f FPS", (double)frames / (t1 - t0)); time_label.set_text(str); } else { al_draw_bitmap(bitmap1, 0, 0, 0); time_label.set_text(""); } al_set_target_bitmap(target); al_draw_bitmap(bitmap2, 0, 0, 0); } else { al_draw_line(0, 0, 320, 200, al_map_rgb_f(1, 0, 0), 0); al_draw_line(0, 200, 320, 0, al_map_rgb_f(1, 0, 0), 0); } std::string s = get_format_name(bitmap1); s += " -> "; s += get_format_name(bitmap2); true_formats.set_text(s); al_destroy_bitmap(bitmap1); al_destroy_bitmap(bitmap2); } int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_init_primitives_addon(); al_init_image_addon(); al_init_font_addon(); al_install_keyboard(); al_install_mouse(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } //log_printf("Display format = %d\n", al_get_display_format()); font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { abort_example("Failed to load data/fixed_font.tga\n"); } /* Don't remove these braces. */ { Theme theme(font); Prog prog(theme, display); prog.run(); } al_destroy_font(font); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/CMakeLists.txt0000644000175000001440000001577012136625073017003 0ustar tjadenusersinclude_directories( ../addons/acodec ../addons/audio ../addons/color ../addons/font ../addons/image ../addons/main ../addons/memfile ../addons/native_dialog ../addons/physfs ../addons/primitives ../addons/ttf ) if(SUPPORT_PHYSFS) # The physfs example directly includes physfs.h include_directories(${PHYSFS_INCLUDE_DIR}) endif() #-----------------------------------------------------------------------------# # Conditionally build an example program. If any of its arguments is the exact # string "x", do nothing. Otherwise strip off the "x" prefixes on arguments # and call the example macro. function(example name) set(is_console) set(args) foreach(arg ${ARGN}) if(arg STREQUAL "x") message(STATUS "Not building ${name}") return() endif() if(arg STREQUAL "CONSOLE") set(is_console ON) else() string(REGEX REPLACE "^x" "" arg ${arg}) list(APPEND args ${arg}) endif() endforeach(arg) if(WIN32) if(is_console) # We need stdout and stderr available from cmd.exe, # so we must not use WIN32 here. set(EXECUTABLE_TYPE) else() set(EXECUTABLE_TYPE "WIN32") endif(is_console) endif(WIN32) if(IPHONE) set(EXECUTABLE_TYPE MACOSX_BUNDLE) endif(IPHONE) add_example(${name} ${args}) endfunction(example) macro(add_example nm) if(WANT_POPUP_EXAMPLES AND SUPPORT_NATIVE_DIALOG) add_our_executable(${nm} ${ARGN} ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} ${NATIVE_DIALOG_LINK_WITH}) else() add_our_executable(${nm} ${ARGN} ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} ) endif() endmacro(add_example nm) #-----------------------------------------------------------------------------# set(AUDIO x${AUDIO_LINK_WITH}) set(ACODEC x${ACODEC_LINK_WITH}) set(COLOR x${COLOR_LINK_WITH}) set(DIALOG x${NATIVE_DIALOG_LINK_WITH}) set(FONT x${FONT_LINK_WITH}) set(IMAGE x${IMAGE_LINK_WITH}) set(MEMFILE x${MEMFILE_LINK_WITH}) set(PHYSFS x${PHYSFS_LINK_WITH}) set(PRIM x${PRIMITIVES_LINK_WITH}) set(TTF x${TTF_LINK_WITH}) set(NIHGUI nihgui.cpp ${FONT} ${PRIM}) #-----------------------------------------------------------------------------# example(ex_config) example(ex_dir) example(ex_file_slice CONSOLE) example(ex_get_path) example(ex_memfile CONSOLE ${MEMFILE}) example(ex_monitorinfo) example(ex_path) example(ex_path_test) example(ex_user_events) if(NOT MSVC) # UTF-8 strings are problematic under MSVC. example(ex_utf8) endif(NOT MSVC) example(ex_bitmap ${IMAGE}) example(ex_bitmap_flip ${IMAGE} ${FONT}) example(ex_bitmap_target ${FONT} ${IMAGE} ${PRIM}) example(ex_blend ${FONT} ${IMAGE} ${PRIM}) example(ex_blend2 ex_blend2.cpp ${NIHGUI} ${IMAGE}) example(ex_blend_bench ${IMAGE} ${PRIM}) example(ex_blend_test ${PRIM}) example(ex_blit ${FONT} ${IMAGE} ${COLOR}) example(ex_clip ${FONT} ${IMAGE} ${COLOR}) example(ex_color ex_color.cpp ${NIHGUI} ${TTF} ${COLOR}) example(ex_convert CONSOLE ${IMAGE}) example(ex_disable_screensaver ${FONT} ${IMAGE}) example(ex_display_events ${FONT} ${IMAGE} ${PRIM}) example(ex_display_options ${FONT} ${IMAGE} ${PRIM}) example(ex_draw ${FONT} ${IMAGE} ${COLOR} ${PRIM}) example(ex_draw_bitmap ${IMAGE} ${FONT}) example(ex_drawpixels) example(ex_dualies ${IMAGE}) example(ex_expose ${IMAGE} ${PRIM}) example(ex_filter ${FONT} ${IMAGE} ${COLOR}) example(ex_fs_resize ${IMAGE} ${PRIM}) example(ex_fs_window ${IMAGE} ${PRIM} ${FONT}) example(ex_icon ${IMAGE}) example(ex_icon2 ${IMAGE}) example(ex_joystick_events ${PRIM}) example(ex_joystick_hotplugging ${PRIM}) example(ex_keyboard_events) example(ex_keyboard_focus) example(ex_lines ${PRIM}) example(ex_lockbitmap) example(ex_membmp ${FONT} ${IMAGE}) example(ex_mouse ${IMAGE} ${PRIM}) example(ex_mouse_cursor ${FONT} ${IMAGE}) example(ex_mouse_events ${FONT} ${IMAGE} ${PRIM}) example(ex_mouse_focus) example(ex_multisample ${FONT} ${COLOR} ${PRIM}) example(ex_multiwin ${IMAGE}) example(ex_nodisplay ${IMAGE}) example(ex_noframe ${IMAGE}) example(ex_physfs ${PHYSFS} ${IMAGE}) example(ex_pixelformat ex_pixelformat.cpp ${NIHGUI} ${IMAGE}) example(ex_premulalpha ${IMAGE} ${FONT}) example(ex_prim ${FONT} ${IMAGE} ${PRIM}) example(ex_resize ${PRIM}) example(ex_resize2 ${IMAGE}) example(ex_rotate ${IMAGE}) example(ex_scale ${IMAGE}) example(ex_subbitmap ${IMAGE} ${PRIM}) example(ex_threads ${PRIM}) example(ex_threads2) example(ex_timedwait) example(ex_timer ${FONT} ${IMAGE} ${PRIM}) example(ex_transform ${FONT} ${IMAGE} ${PRIM}) example(ex_vsync ${FONT} ${IMAGE}) example(ex_warp_mouse ${FONT} ${PRIM} ${IMAGE}) example(ex_windows ${FONT} ${IMAGE}) example(ex_winfull) if(WANT_D3D AND D3DX9_FOUND) example(ex_d3d ex_d3d.cpp ${D3DX9_LIBRARY}) endif(WANT_D3D AND D3DX9_FOUND) if(SUPPORT_OPENGL AND NOT IPHONE) example(ex_gldepth ${FONT} ${IMAGE}) example(ex_glext) example(ex_opengl) example(ex_opengl_pixel_shader ${IMAGE}) endif(SUPPORT_OPENGL AND NOT IPHONE) example(ex_font ${FONT} ${IMAGE}) example(ex_font_justify ex_font_justify.cpp ${NIHGUI} ${IMAGE} ${TTF}) example(ex_logo ${FONT} ${TTF} ${IMAGE} ${PRIM}) example(ex_ttf ${TTF} ${PRIM}) example(ex_acodec CONSOLE ${AUDIO} ${ACODEC}) example(ex_acodec_multi CONSOLE ${AUDIO} ${ACODEC}) example(ex_audio_chain ex_audio_chain.cpp ${AUDIO} ${ACODEC} ${PRIM} ${FONT} ${TTF}) example(ex_audio_props CONSOLE ex_audio_props.cpp ${NIHGUI} ${IMAGE} ${AUDIO} ${ACODEC}) example(ex_audio_simple CONSOLE ${AUDIO} ${ACODEC}) example(ex_audio_timer ${AUDIO} ${FONT}) example(ex_haiku ${AUDIO} ${ACODEC} ${IMAGE}) example(ex_kcm_direct CONSOLE ${AUDIO} ${ACODEC}) example(ex_mixer_chain CONSOLE ${AUDIO} ${ACODEC}) example(ex_mixer_pp ${AUDIO} ${ACODEC} ${PRIM} ${IMAGE}) example(ex_resample_test ${AUDIO}) example(ex_saw ${AUDIO}) example(ex_stream_file CONSOLE ${AUDIO} ${ACODEC}) example(ex_stream_seek CONSOLE ${AUDIO} ${ACODEC} ${PRIM} ${FONT} ${IMAGE}) example(ex_synth ex_synth.cpp ${NIHGUI} ${AUDIO} ${TTF}) example(ex_native_filechooser ${DIALOG} ${FONT} ${IMAGE} ${COLOR}) # In some configurations CURL pulls in dependencies which we don't check for. # This example isn't important so it's disabled by default to prevent problems. option(WANT_CURL_EXAMPLE "Build ex_curl example" off) if(WANT_CURL_EXAMPLE) find_package(CURL) if(CURL_FOUND) if(WIN32) # select() is in the Winsock library. example(ex_curl ${CURL_LIBRARIES} ${IMAGE} ws2_32) else(WIN32) example(ex_curl ${CURL_LIBRARIES} ${IMAGE}) endif(WIN32) endif(CURL_FOUND) endif(WANT_CURL_EXAMPLE) # Not yet added: # ex_gp2x # ex_iphone # example(ex_ogre3d ex_ogre3d.cpp) # include_directories(/usr/include/OGRE) # target_link_libraries(ex_ogre3d OgreMain) copy_data_dir_to_build(copy_example_data data .) # This is useful for developers to add temporary test programs. include(${CMAKE_CURRENT_SOURCE_DIR}/local_examples.cmake OPTIONAL) #-----------------------------------------------------------------------------# # vim: set ts=8 sts=4 sw=4 et: allegro-5.0.10/examples/nihgui.cpp0000644000175000001440000004271711771522411016227 0ustar tjadenusers/* * This is a GUI for example programs that require GUI-style interaction. * It's intended to be as simple and transparent as possible (simplistic, * even). */ #include #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include #include "nihgui.hpp" #define CLAMP(x,y,z) (std::max)(x, (std::min)(y, z)) namespace { class SaveState { ALLEGRO_STATE state; public: SaveState(int save=ALLEGRO_STATE_ALL) { al_store_state(&state, save); } ~SaveState() { al_restore_state(&state); } }; class UString { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *ustr; public: UString(const ALLEGRO_USTR *s, int first, int end = -1) { if (end == -1) end = al_ustr_size(s); ustr = al_ref_ustr(&info, s, first, end); } // Conversion operator const ALLEGRO_USTR *() const { return ustr; } }; }; /*---------------------------------------------------------------------------*/ Theme::Theme(const ALLEGRO_FONT *font) { this->bg = al_map_rgb(255, 255, 255); this->fg = al_map_rgb(0, 0, 0); this->highlight = al_map_rgb(128, 128, 255); this->font = font; } /*---------------------------------------------------------------------------*/ Widget::Widget(): grid_x(0), grid_y(0), grid_w(0), grid_h(0), dialog(NULL), x1(0), y1(0), x2(0), y2(0) { } void Widget::configure(int xsize, int ysize, int x_padding, int y_padding) { this->x1 = xsize * this->grid_x + x_padding; this->y1 = ysize * this->grid_y + y_padding; this->x2 = xsize * (this->grid_x + this->grid_w) - x_padding - 1; this->y2 = ysize * (this->grid_y + this->grid_h) - y_padding - 1; } bool Widget::contains(int x, int y) { return (x >= this->x1 && y >= this->y1 && x <= this->x2 && y <= this->y2); } /*---------------------------------------------------------------------------*/ Dialog::Dialog(const Theme & theme, ALLEGRO_DISPLAY *display, int grid_m, int grid_n): theme(theme), display(display), grid_m(grid_m), grid_n(grid_n), x_padding(1), y_padding(1), draw_requested(true), quit_requested(false), mouse_over_widget(NULL), mouse_down_widget(NULL), key_widget(NULL), event_handler(NULL) { this->event_queue = al_create_event_queue(); al_register_event_source(this->event_queue, al_get_keyboard_event_source()); al_register_event_source(this->event_queue, al_get_mouse_event_source()); al_register_event_source(this->event_queue, al_get_display_event_source(display)); } Dialog::~Dialog() { this->display = NULL; al_destroy_event_queue(this->event_queue); this->event_queue = NULL; } void Dialog::set_padding(int x_padding, int y_padding) { this->x_padding = x_padding; this->y_padding = y_padding; } void Dialog::add(Widget & widget, int grid_x, int grid_y, int grid_w, int grid_h) { widget.grid_x = grid_x; widget.grid_y = grid_y; widget.grid_w = grid_w; widget.grid_h = grid_h; this->all_widgets.push_back(&widget); widget.dialog = this; } void Dialog::prepare() { this->configure_all(); /* XXX this isn't working right in X. The mouse position is reported as * (0,0) initially, until the mouse pointer is moved. */ ALLEGRO_MOUSE_STATE mst; al_get_mouse_state(&mst); this->check_mouse_over(mst.x, mst.y); } void Dialog::configure_all() { const int xsize = al_get_display_width(display) / this->grid_m; const int ysize = al_get_display_height(display) / this->grid_n; for (std::list::iterator it = this->all_widgets.begin(); it != this->all_widgets.end(); ++it) { (*it)->configure(xsize, ysize, this->x_padding, this->y_padding); } } void Dialog::run_step(bool block) { ALLEGRO_EVENT event; if (block) { al_wait_for_event(event_queue, NULL); } while (al_get_next_event(event_queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: this->request_quit(); break; case ALLEGRO_EVENT_KEY_CHAR: on_key_down(event.keyboard); break; case ALLEGRO_EVENT_MOUSE_AXES: on_mouse_axes(event.mouse); break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: on_mouse_button_down(event.mouse); break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: on_mouse_button_up(event.mouse); break; case ALLEGRO_EVENT_DISPLAY_EXPOSE: this->request_draw(); break; default: if (event_handler) { event_handler->handle_event(event); } break; } } } void Dialog::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { if (event.display != this->display) { return; } // XXX think of something better when we need it if (event.keycode == ALLEGRO_KEY_ESCAPE) { this->request_quit(); } if (this->key_widget) { this->key_widget->on_key_down(event); } } void Dialog::on_mouse_axes(const ALLEGRO_MOUSE_EVENT & event) { const int mx = event.x; const int my = event.y; if (event.display != this->display) { return; } if (this->mouse_down_widget) { this->mouse_down_widget->on_mouse_button_hold(mx, my); return; } if (this->mouse_over_widget && this->mouse_over_widget->contains(mx, my)) { /* no change */ return; } this->check_mouse_over(mx, my); } void Dialog::check_mouse_over(int mx, int my) { for (std::list::iterator it = this->all_widgets.begin(); it != this->all_widgets.end(); ++it) { if ((*it)->contains(mx, my) && (*it)->want_mouse_focus()) { this->mouse_over_widget = (*it); this->mouse_over_widget->got_mouse_focus(); return; } } if (this->mouse_over_widget) { this->mouse_over_widget->lost_mouse_focus(); this->mouse_over_widget = NULL; } } void Dialog::on_mouse_button_down(const ALLEGRO_MOUSE_EVENT & event) { if (event.button != 1) return; if (!this->mouse_over_widget) return; this->mouse_down_widget = this->mouse_over_widget; this->mouse_down_widget->on_mouse_button_down(event.x, event.y); /* transfer key focus */ if (this->mouse_down_widget != this->key_widget) { if (this->key_widget) { this->key_widget->lost_key_focus(); this->key_widget = NULL; } if (this->mouse_down_widget->want_key_focus()) { this->key_widget = this->mouse_down_widget; this->key_widget->got_key_focus(); } } } void Dialog::on_mouse_button_up(const ALLEGRO_MOUSE_EVENT & event) { if (event.button != 1) return; if (!this->mouse_down_widget) return; this->mouse_down_widget->on_mouse_button_up(event.x, event.y); if (this->mouse_down_widget->contains(event.x, event.y)) { this->mouse_down_widget->on_click(event.x, event.y); } this->mouse_down_widget = NULL; } void Dialog::request_quit() { this->quit_requested = true; } bool Dialog::is_quit_requested() const { return this->quit_requested; } void Dialog::request_draw() { this->draw_requested = true; } bool Dialog::is_draw_requested() const { return this->draw_requested; } void Dialog::draw() { int cx, cy, cw, ch; al_get_clipping_rectangle(&cx, &cy, &cw, &ch); for (std::list::iterator it = this->all_widgets.begin(); it != this->all_widgets.end(); ++it) { Widget *wid = (*it); al_set_clipping_rectangle(wid->x1, wid->y1, wid->width(), wid->height()); wid->draw(); } al_set_clipping_rectangle(cx, cy, cw, ch); this->draw_requested = false; } const Theme & Dialog::get_theme() const { return this->theme; } void Dialog::register_event_source(ALLEGRO_EVENT_SOURCE *source) { al_register_event_source(this->event_queue, source); } void Dialog::set_event_handler(EventHandler *event_handler) { this->event_handler = event_handler; } /*---------------------------------------------------------------------------*/ Label::Label(std::string text, bool centred) : text(text), centred(centred) { } void Label::draw() { const Theme & theme = this->dialog->get_theme(); SaveState state; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (centred) { al_draw_text(theme.font, theme.fg, (this->x1 + this->x2 + 1)/2, this->y1, ALLEGRO_ALIGN_CENTRE, this->text.c_str()); } else { al_draw_text(theme.font, theme.fg, this->x1, this->y1, 0, this->text.c_str()); } } void Label::set_text(std::string new_text) { this->text = new_text; } bool Label::want_mouse_focus() { return false; } /*---------------------------------------------------------------------------*/ Button::Button(std::string text): text(text), pushed(false) { } void Button::on_mouse_button_down(int mx, int my) { (void)mx; (void)my; this->pushed = true; dialog->request_draw(); } void Button::on_mouse_button_up(int mx, int my) { (void)mx; (void)my; this->pushed = false; dialog->request_draw(); } void Button::draw() { const Theme & theme = this->dialog->get_theme(); ALLEGRO_COLOR fg; ALLEGRO_COLOR bg; SaveState state; if (this->pushed) { fg = theme.bg; bg = theme.fg; } else { fg = theme.fg; bg = theme.bg; } al_draw_filled_rectangle(this->x1, this->y1, this->x2, this->y2, bg); al_draw_rectangle(this->x1 + 0.5, this->y1 + 0.5, this->x2 - 0.5, this->y2 - 0.5, fg, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_text(theme.font, fg, (this->x1 + this->x2 + 1)/2, this->y1, ALLEGRO_ALIGN_CENTRE, this->text.c_str()); } bool Button::get_pushed() { return pushed; } /*---------------------------------------------------------------------------*/ ToggleButton::ToggleButton(std::string text) : Button(text) { } void ToggleButton::on_mouse_button_down(int mx, int my) { (void)mx; (void)my; set_pushed(!this->pushed); } void ToggleButton::on_mouse_button_up(int mx, int my) { (void)mx; (void)my; } void ToggleButton::set_pushed(bool pushed) { if (this->pushed != pushed) { this->pushed = pushed; if (dialog) dialog->request_draw(); } } /*---------------------------------------------------------------------------*/ const std::string List::empty_string; List::List(int initial_selection) : selected_item(initial_selection) { } bool List::want_key_focus() { return true; } void List::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { switch (event.keycode) { case ALLEGRO_KEY_DOWN: if (selected_item < items.size() - 1) { selected_item++; dialog->request_draw(); } break; case ALLEGRO_KEY_UP: if (selected_item > 0) { selected_item--; dialog->request_draw(); } break; } } void List::on_click(int mx, int my) { const Theme & theme = dialog->get_theme(); unsigned int i = (my - this->y1) / al_get_font_line_height(theme.font); if (i < this->items.size()) { this->selected_item = i; dialog->request_draw(); } (void)mx; (void)my; } void List::draw() { const Theme & theme = dialog->get_theme(); SaveState state; al_draw_filled_rectangle(x1 + 1, y1 + 1, x2 - 1, y2 - 1, theme.bg); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); const int font_height = al_get_font_line_height(theme.font); for (unsigned i = 0; i < items.size(); i++) { int yi = y1 + i * font_height; if (i == selected_item) { al_draw_filled_rectangle(x1 + 1, yi, x2 - 1, yi + font_height - 1, theme.highlight); } al_draw_text(theme.font, theme.fg, x1, yi, 0, items.at(i).c_str()); } } void List::clear_items() { this->items.clear(); this->selected_item = 0; } void List::append_item(std::string text) { this->items.push_back(text); } const std::string & List::get_selected_item_text() const { if (this->selected_item < this->items.size()) return this->items.at(this->selected_item); else return List::empty_string; } int List::get_cur_value() const { return this->selected_item; } /*---------------------------------------------------------------------------*/ VSlider::VSlider(int cur_value, int max_value) : cur_value(cur_value), max_value(max_value) { } void VSlider::on_mouse_button_down(int mx, int my) { this->on_mouse_button_hold(mx, my); } void VSlider::on_mouse_button_hold(int mx, int my) { double r = (double) (this->y2 - 1 - my) / (this->height() - 2); r = CLAMP(0.0, r, 1.0); cur_value = (int) (r * max_value); dialog->request_draw(); (void)mx; } void VSlider::draw() { const Theme & theme = dialog->get_theme(); float left = x1 + 0.5, top = y1 + 0.5; float right = x2 + 0.5, bottom = y2 + 0.5; SaveState state; al_draw_rectangle(left, top, right, bottom, theme.fg, 1); double ratio = (double) this->cur_value / (double) this->max_value; int ypos = (int) (bottom - 0.5 - (int) (ratio * (height() - 7))); al_draw_filled_rectangle(left + 0.5, ypos - 5, right - 0.5, ypos, theme.fg); } int VSlider::get_cur_value() const { return this->cur_value; } void VSlider::set_cur_value(int v) { this->cur_value = v; } /*---------------------------------------------------------------------------*/ HSlider::HSlider(int cur_value, int max_value) : cur_value(cur_value), max_value(max_value) { } void HSlider::on_mouse_button_down(int mx, int my) { this->on_mouse_button_hold(mx, my); } void HSlider::on_mouse_button_hold(int mx, int my) { double r = (double) (mx - 1 - this->x1) / (this->width() - 2); r = CLAMP(0.0, r, 1.0); cur_value = (int) (r * max_value); dialog->request_draw(); (void)my; } void HSlider::draw() { const Theme & theme = dialog->get_theme(); const int cy = (y1 + y2) / 2; SaveState state; al_draw_filled_rectangle(x1, y1, x2, y2, theme.bg); al_draw_line(x1, cy, x2, cy, theme.fg, 0); double ratio = (double) this->cur_value / (double) this->max_value; int xpos = x1 + (int) (ratio * (width() - 2)); al_draw_filled_rectangle(xpos - 2, y1, xpos + 2, y2, theme.fg); } int HSlider::get_cur_value() const { return this->cur_value; } void HSlider::set_cur_value(int v) { this->cur_value = v; } /*---------------------------------------------------------------------------*/ TextEntry::TextEntry(const char *initial_text) : focused(false), cursor_pos(0), left_pos(0) { text = al_ustr_new(initial_text); } TextEntry::~TextEntry() { al_ustr_free(text); } bool TextEntry::want_key_focus() { return true; } void TextEntry::got_key_focus() { this->focused = true; dialog->request_draw(); } void TextEntry::lost_key_focus() { this->focused = false; dialog->request_draw(); } void TextEntry::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { switch (event.keycode) { case ALLEGRO_KEY_LEFT: al_ustr_prev(text, &cursor_pos); break; case ALLEGRO_KEY_RIGHT: al_ustr_next(text, &cursor_pos); break; case ALLEGRO_KEY_HOME: cursor_pos = 0; break; case ALLEGRO_KEY_END: cursor_pos = al_ustr_size(text); break; case ALLEGRO_KEY_DELETE: al_ustr_remove_chr(text, cursor_pos); break; case ALLEGRO_KEY_BACKSPACE: if (al_ustr_prev(text, &cursor_pos)) al_ustr_remove_chr(text, cursor_pos); break; default: if (event.unichar >= ' ') { al_ustr_insert_chr(text, cursor_pos, event.unichar); cursor_pos += al_utf8_width(event.unichar); } break; } maybe_scroll(); dialog->request_draw(); } void TextEntry::maybe_scroll() { const Theme & theme = dialog->get_theme(); if (cursor_pos < left_pos + 3) { if (cursor_pos < 3) left_pos = 0; else left_pos = cursor_pos - 3; } else { for (;;) { const int tw = al_get_ustr_width(theme.font, UString(text, left_pos, cursor_pos)); if (x1 + tw + CURSOR_WIDTH < x2) { break; } al_ustr_next(text, &left_pos); } } } void TextEntry::draw() { const Theme & theme = dialog->get_theme(); SaveState state; al_draw_filled_rectangle(x1, y1, x2, y2, theme.bg); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (!focused) { al_draw_ustr(theme.font, theme.fg, x1, y1, 0, UString(text, left_pos)); } else { int x = x1; if (cursor_pos > 0) { UString sub(text, left_pos, cursor_pos); al_draw_ustr(theme.font, theme.fg, x1, y1, 0, sub); x += al_get_ustr_width(theme.font, sub); } if ((unsigned) cursor_pos == al_ustr_size(text)) { al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH, y1 + al_get_font_line_height(theme.font), theme.fg); } else { int post_cursor = cursor_pos; al_ustr_next(text, &post_cursor); UString sub(text, cursor_pos, post_cursor); int subw = al_get_ustr_width(theme.font, sub); al_draw_filled_rectangle(x, y1, x + subw, y1 + al_get_font_line_height(theme.font), theme.fg); al_draw_ustr(theme.font, theme.bg, x, y1, 0, sub); x += subw; al_draw_ustr(theme.font, theme.fg, x, y1, 0, UString(text, post_cursor)); } } } const char *TextEntry::get_text() { return al_cstr(text); } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/data/0000755000175000001440000000000012157230747015145 5ustar tjadenusersallegro-5.0.10/examples/data/fixed_font.tga0000644000175000001440000006235711057522251017774 0ustar tjadenusers a TRUEVISION-XFILE.allegro-5.0.10/examples/data/ex_physfs.zip0000644000175000001440000000522211173335030017666 0ustar tjadenusersPK:x "02.bmpUT 8I8IUxd՘mlGb`ݶQ"_BJݙ[Qݸ!65Tvor.Shj 5 ɮ[!Z"UU| ҭr==)$XomaoEOUwUw}7;/}@]~}=Ai(3H&rH]R \{oP7x̫Bi4WQo~;;RΞAfog+Soo 9W 2&څ(ԃP/&2BC0 Z~f0j[*5M+2ЁLS3W_ 4a&- u~ ϡJ-!M`>j k 1vm0WY4͓0Chϡ:S&kQºFU'_S2[fHD2Z ԰ndnd/1X 6N|IFy t&ߟIs]g}c+&^0o^]~\c: \燨vc{̼i7[1wsWUghݟ+PeTc3wM\%--XHWk:kUq m,ǯB.FvЉj~7534Z2[S?xvgpI4n׉j^kzA[0eGtQ5J|F(K{'tDނ -p%@r60Qut t3g&$U2Q(.=ܤ_ 5jn-B0 Fh7^, |6\Sf)Ӭ9]-HR67ߝ/1kV0oAB822KLۥl&wOs!cbVZȅeK錔_ք8;!aIlZNzꏲ ̟ߺLǹqK8l"q{&pm,LZ5.(ߡRH*78)I V ^V*ԃ6UKXXc0o wh&cK)cCp݂3%.R/;n純)pYlf4 :}$}n/i8|(݀IӮgUfA)R(zTu/F4:.w0ue |H"9w(]6M[4]]3gAգĒ/m2E~A։=|VU&݋:FthO`m4O8VwhP8ƻ · *=Rc:{ih:uS wҳc xsai"T+J~OSSX, 0'q+Փӡ*ICh=,( 3Pci}҅c|}en%=_щ^&NJLc̒ ~>#e0uwíZz)YBg}c;LGز93ْ:uyӺ7M<5L}1353NE5<0!gfsՀf~ --%bH#cw2m."<6{ҷB/)ߟ͔"`A#X$F_e7{|&d:ԑԡ^9e`mZb1rQL Q)ש{?Yno:uX/ro¶"o3Ufn 9k]Ī4%gJcF N#֌cL.֧ufV#,ۿy{nSNn OrwÊĸF< > 6g|\ ϬPK:x " 02.bmpUT8IUxPKA; allegro-5.0.10/examples/data/allegro.pcx0000644000175000001440000012540611057522251017306 0ustar tjadenusers ? Yesph`XxH@h@@hHHpXX``hhppxx@(00``0PP(888HH@PP@HHHPP0ph@xp@phHph8p`@`XPp@hXHXP@xXX Ĕè»꧓ú »Ú °oFš®” ûû“Ѯє˺  ù˺”Ôºú ºєƔúº ܹºƔºĺº ߹o”ѺǺº Moʮº“  ߹Įºúº 仨Óm̺ ùºѮڔ”ѮѺ Ч“ºƓѓē”  o꺧Ómm“ד­ѺÔ §úѓím׭­”˺ M o¨ºѮĭwmím“¶w“úє M FçºíĐwím“¶šź M8M §öÐwÐm­m“׶ȃѺѺ M¹M ŶwÐmºĶ” MM oܹ趚Đw­wmѺz› MMMo¹ܹ¦¶šwíwm®Û M¹MxMooךѮmÐwíwm MùRÌRMM8oד®­ȐĎkwޛ ¹FRRR™RMoדºwjkwmƮ”  oùFRșRŒܹדѮw֐wØjwm“®®Ô Ĺìl¬¬RRRl¶­׮Ѯ­w¶ÐȘwm“”Ý  ¹FŬǬ™l¬°®íwƐwmÓԝ  oF۬řƬl™ùoðךw®íwÐŐmœº”  o¹¬™ìĬlìĨאwmmИȭšmšÓº˧ o¬¬™Ĭ¹ìŦl¦ꧺѮmw…ʛm·ÎЭ׶šÐЧº¹¬¦¦Ĭ¹¬l¦“Ѯm®׶wm›m®ַjiȐ֭Ѯƶš¨˻ùæÏħÚw“דm®ݮwm…yʛݮ·j^i֮Ѻ׶קק軺Úöק“ēúmšmímmݛʮַÎyśݮ֐^i֭®Ú¨»®mw­­׭Ůݛʮšmmm…bmíÛ·Ďyz­ȃ^ÐÓק§ݮwŭ®Ѯ·mmb·yʷŽ·Îʛ֐i­§¨§mwĐwmʮmb·yʮ·mbk÷ʛmi^ק˨§mwj÷ymb…·…·›÷kķym÷i^öק˺ޛmƎ·Žk·…·›·kk÷yʷÃĶקѺޛmb…ŽmݮvivĎk…yʷÎk÷ym֐Ãȶד”ºޛy…b…mʷv£i‰vŽvk·yķ·ʛym֐^îޛy…mʛʷkv^iÉivkʛ·kk·ʅb÷i֮­ÛݛʛzʷkiÉiŽk·ʷkvkvkŷk…÷͝wRyx{zޛzmviʼniÎķʷkvkŷkb···ŽwRyxx{zޛzm÷£ĉivbķʛ÷…kηk·Ʒz{wRbyxzx{{z{zzm…i£˜v·yɷŽkÎbkvk·ŷśzwRbyxzxz{z{{z{zzʷkķƣiŷ÷vŽk^ikķyʛy›wR5ybyxyzxz{{zzzʷjm·v£i·ķmm÷iv^i^^vybƷąʛw5EybP]byxyz:zxzz{zޛޛzʷk÷m·ȘģȎ·mޛy÷vi^iG…bkvkb›{{wR5P]byxP]:|zxz{ޛޛmkjƷȘ£¾ķ…Ûy·vi£i^iÉivbvkb…ʛz{{{wmR5P]byxP]:|]zxÛÛݛ{z››ʷŎķŽ˜֮ybm÷v^v^i·Žkb…byz{{wm5EPbyx]:zxƛyb{zޛʷĎk÷m÷k^vk…kviv·…yz{{wm5E`]byx]:zxyyb{zyŎwm֐ŽŽ֮®֮·bkjk…bk÷ʷmyz{z{{{Øwm5E`]byx;:zxyyby{zŎwmַȾȎȾȷ÷Ѯ֮ĎjŽkb·ʅzz{z{{lØw5E`¤ubyx:zxyby›yby{zʅŽmÎȎþ¾¾Øַ֮ÎkjŽ…ʮ®mzzzz{{{lØw5E`uǝbyxzxbyzʅĎȣ¾àiȎ֐˜jĎm÷Žzzz{lØwE`„u_ĝybxzxbyz{z{ʷmŽw£ȣâĩ߉ȷƎ·֮ѮȎi^izz{l|Øw`u_bybxzxy›z{z·y·m£ȣ Ġe‰i֐Ʒȃi֮z{z{lˆ|˜l˜wÄu_u_Ȩmbyxyzxy›zz݅mmâ q~qŸeŸ~ĉ֐÷ȣiȎ·›z{z{lˆ|lŘl„u_Ǩ»mbyxyzx›yÛyzzm··~ĉqqeƟe~âȷ֮֐Ȏmmśzz{z{z{{lĈ|lu_¨»èû°mxyzx›zzzmw֐Ȣ~q~q Ɵe~âַ֐ַ֮˜ַmymzz{z{z{{lÈP|lu_èmx>xyzxzzݷ¾eGqeà©Ɵ~m˜m…b…mzz{z{lÈP|lu_Qoomx>yzx›zzʅȾĠeGq~àŸ© mjmbz›zz{{lP|lu_QùFoomx>yzxַ¾qeGqàq UmwÎ֮ʷmb›z|zz{lˆPÈlu_Q¹Fomx>yxPĈ֣ ~eGe |€U®·mw›dzcd|{lPDĈl_QoFo¹mxyx˺“]PˆÀUȢeGeŸŸ UÀUÀĮcˆÛ|Sd|:|{lPJgPl`_QoFʬF¹ܹǬmx yx§P]ˆ€DUeGAGeDUU€Uˆ›|Sdc;P;:|:{{lCgJgDgPPl`QoFìlFŬ™lmE  °yEꧨºP]PÀDDeAGAGAGeGeĕĞUĞDU]ž||ˆSc:P¯];:|:]PP{{lgCgJDgPˆl`QKFŬFì™lŋmE yEl¶JĈDCDeAGeGeGeОUžUiÕ]|UVPUScPˆPP]:]:]PPU{lgCgJPPˆl`QK`oùFFìċlm`E`y`EܹЧll\JÀ菶CCDAGeGeGPeGÆÕCeĆPUUĈˆy€ÈˆPĈP]PUUUlgCgPÈll`QKhoܹRFĬR‹[™Rm`hy`¬¹Z\JgDNjVCDAeGeGeĠȆGWVÕC՞ÀÈP]ݯȀˆP]PPÈUlgDCgPˆPlæl`Q`Kho¹F¬R¬ċ۬¹mh`hMyh‹ܹ_Kg\ÂZÂZ~ZeCgDAeGUeAGe© W†VAGWq¢iWņ•DÀUcɀUÈP]P€UlˆgDgPlæl`hBho¹FřÙ۬mhKhRyhĂê鬏KguZ}àe\gßeGeVeAGeşWVWVWVAėWVWVÆDDJDŀUˆPˆUlĈgPlhBoFș¬۹mh`hό[yhġÿz`\鿪łZŠC eGeVGAeßWVAeŸep‡WVwDDÀˆĈ€UÈlDĈgJPl`hBĹFìFì۬m`h`hܿy`h¡Ϊz`h\ۙƪ³ZĩeCeAGeGeWpWAGŸNp‡WVŽCDÀP]€UUĀUlDĈgPlhBhBƹ¬m`h`y`hǿΡzĠğWCeAGeŸpWNpWAGeNpW££ĞDžˆPĀUUlDJÈgCgPlwlBè¹ܹìm`h`۫yh`ǪyzĽéCgeGAGeŸNWpANpW¢ľ\•CÈňÀUÀUlDJˆCgPwBǨ۬¬m`h`ǿy`鿡yzCPĀDž˕CCg¼†CAGeNWpGANp ¢Kņ•žˆPˆ€UÀUlwBŻìm`h`y`یګ髂yzJDDdžCȆÕCĽ¼†CGAGeNpNeGANpNeàľWVC†C†PȀUVlwBhB°oìÙm`y`ی«ygګýàĽAGe½¼†\GAGNpNeGNpNGeߢpWVCÆVˆPĈUVlwhBhBhB°o¹F¬lm`h`Ρy`hڿڡZygΫß ľGAGeӽنVeGAGNWV©eNpNpGeq~NpWpWVWňUV†lwhthBŰoF¹l‹m`h`hαy`hΡygųŠ©êĩeAGeŸ̼ÆeGAGApWVŸeGeGeNppWeGeqqNpWňÀU†ÕlJP]P|:|:|:|lwtLhBðo¹Ëmh`hγybyhګyh~eŠé GAe¼ĽeVWVeGepWVeGeNpWVe ~NW†ǀUžžUlJ]PȈ|:|:lwLtBðoooܹËmh`hγybhBhοyheǠĂĠeAe½ŸeAGWVC~qeeßWVàećpWVWŸeŸqNpWVǀUƞlJ]PɈwB°oܦ‹mh`hnjδybhBhŸery\eşŠĽAGĽeŸeVC~ĠWV âqećWVÆVWeŸqNpWVWVƀUĞlgJgJPɈlwLBܬlmh`KNBŒybNBHGAGeryeß½ ĽeAGĩeßeğeVCUĢWV̾~e~ĆVņVeq~NpWV•{ŀUĕUlgJPˆPPĈwlwLBH‹m`K`KNŒ¡³bybNHeýyŸý ĽeGAGĠe©qĠ~qCVCžU¢ľi~qĆŕŸeqNpWVŀU•ƞlJDgJgPlwLhBH¬ËmKh鿡f³bNHà±óyVéý}³½ğĩVyƉ~qCU¾¾þi~~eƕee£p‡WVCJÀUĞUÞUlJgJPlwlwLBHBFF¬ËmK`h«ÿΡrbNhHfZfr}yb©½©éeŸeĩy¢É¢qeWzVÆVWƾ˜ȃ¢~edž•epWV†•€DƀJŀUlJ]PwlwLBHBoF¦‹mKNK`h¿¡³rbNhf¡r}ybNɩeӾğyĢ~‰¢~eWVzeGeŸeŸq¾ȎȾĠqeŸeGĆWV†eGeȎpWV•JDJ€J€DlJ]PwLBHBFًm`K`h[«ÿ³rbhÂ~ebyb¼©eeGe¾Uyq~~KWVzeGeßeGeľ¾ȣ¾ĠeG†•WV†ŸG¾NpWVVV•JDJD RlJ]P lwLBHB¬یm`K`h뿳rbhÿóeGyb©eGeGeày ~q~pVzŸeŸeGeľȃ£¾ĠeGeŕVeGe¢pWVC†VžJJÀÀU RgJPlwlwBHBH¹ڿm`KhB¡ámbhο¿ó}eyb}ŸeGAGeŸebyâʼnWVzqeq eqľ¢ĠqeGeޕVeGe iWV†VÕUΈ RglwBHBHomNhBġ«ΪmbBhgƿó}bybeeGebyľ¢þ¢WCz~eq~qeqqľq qeGAGe•WVeAGeÉipWVWVĆVP] R\g\glwHDHomBNhB«ΫêmbBhgΪZbGeGeGebþ£ľVz‰ľþeq~eGAGÕV†GAG~^iWV†ÞÕ: RNKpK\K  lwXHHhHomBhB¿ο«mbHBhgl¶Ū‚bľȘÃWVz~qeGeGƆAGeivivWVCDU€: Rt`QhBN  lwlwBHXHBHۙmBH¿¿ګmbHgö¶łb¾Ȏ˜ȃ†CzeƆAivkvVCU;@į@Ư RKaR   whBhLF¬™mXګªmbHgך¶Z¢‚ĶbȎV†zŸeĕCCAvjŽ·CDDˆPP@;@¯d] RK` lwKLlmWN¦ڋmbKBJ¶ƒĂ֐bkbȾȣ~ŸVCz†\ĀCAivjހJPJP]:] Rh`hlwmDmC`mbhg¾ȘַȎbkb£¾ľ¢qeU€CUDzi^{JP];:] cc `hcJcܹ¹Dcc€J‚ĦC`c¸¥SÂlhgȾ˜ŽȎvkbĉȾ¢e\UzDJUDUGAGeŸpNpWV£v{{JcP;|:|:'('0(%0?01=0<0<0=?<=<=8E`Q`_M‘x0,0,41Mx539343E3584E53E_QMxn0=?0=?=102%(=601=194MMFtRÒxa`RhsZYf—ՌësŒhI}´³rñó´r³ýeer}~}r[Yf}~e}Ÿ}fZfYRM10''#'00'+#'#"&!$#'#"!"'!#'#"#"&"#!"#&'#&#%#%#012010?01?1o(01=0163106389M49484’9<@=12=0n7?=daQata58496x7x‘x1dd=nM3979=?@<@?=>Ea`Q`Q`Q3896’‘1ndn¸@##=@=9dSdn=@>nEua83M=2=<2'%#<<=M8x’x8M1M13MaRsI[Yf}fr³¡fY[´Ľ³}rY¡[sssILa8M0'#$#'#$"'#'#"$'#"#'#"%#'#'#%'%#'!#"!&'&#%<36n49345`REME85R5RE9M7n9716M46n149‘xnxdx9SEdn97nd99777n@<22@<201’xSxu5xuExn0=<><=<#%?=xEaLR=0M1M8RLŒs¡[áYYr}~eZf}r³š[sIsILRx0(#'#$#'#"'#'#"#'#'"'#"#'#'#'#'#'&#"&'#'%364M9xME5x45`R5R`585FR5M79=@>2#0<=<22<=<==9xExnnx81M8RF8R8Rs[fZr[IªªôƳ–ſ[IsI[IIaM10%+'##'$#'#'"'"'#"#'#"#'#'#'#"'#'#"&#&'#'%'4143Ex85E85R`5R`F5RQ_E96d7x96M4396n79n7d7n7xM„‘EE1cn7xSEuEd<><@<@=@=<@#'26n799d9’9SxEd<???#'==xEaEx9n0M301M8RLŌsªRsŊsê[–ár}rfrY¡[IRMo'0+#'#'#'#'#'$'"#'#"'#'"#'#"#"#'#'#"'"'#'#9M5`F5RE`5`aRaEEM8`uEɸ=64M’xax4M4d79d79d779ua„7S9x7Sx_`Kt_uMn<<=>@<@'###21x9uauEx’Sdn=@<@2<<><<(0(0(%'#0'010141453435x460oxMRŒI[sR¿rfrfáY‚RFM8310#'#'#"#'#'#'#'#'"#'#"#%'#'#'#"'"#'#48`Ra5R`aR5xE8xaxM=1n946M6=6M45E9x96M989Mn=(=6<0=0o=16=1=39E358499n491n<0?o1(01'0=9dSESdd=@<2<0((0'0#'#,',#',0,0,0614343410+#'0MaRŒIÌLRR[[RFaM13o13o/,10#'#'#'#'#'"#'#'#"#'#"#"#'#6M9Mx8E`R5RaE8M9M916=01n16M49Mn6M9M9MxM4n6nMnME’9Mn==01641n=6<01=8989nMER5EMn1<1=3>2>2%=?269=2(60(%'('#'#'%'%'%'%'%%'%'%'#'%'%'#'#'#'#'#'#%'((=610=643631=(%%%(=6<969E9nĜ>2>2%2=62=960=(610('#'%'#'%%'%'%%'%'%'%'%'#'#'#'%'#'#'#'%(=0106413616=(%%%2=<969n9nœ>2>%(=2=62=2060%(0(%(','%'%'%'%'%'%'%'%'#'#'#'#'#'#%'010601610=%%%(2?=?=Ɯ>7>œ222(=(%6?26=(1961%(%(0'%'#'%'#%'%'%''%'%'%%'#'%'%#'#'%#'%'#'#'#%'0(0=(010160=(2=2=?=?=?2?22>Ɯ>77222%(%=0626206(%=(060(%(0('%'%'%'%'%'%'%''%'%'#'#'#'#'#'#'#'#'%%'0=0(=0=(=(222>Ĝ>7222%(=2=12%01%=0(%(0(%(0(,'%'#'%'%'%'%'%'%'%%'%%'#'#'#'#'#'#'#'#'%'(0=(222>2u7222%26=020((1(%=1((10(0(','%'#'%'%#%%'%'%'#'%'#'#'#'#'#'#'#%#'#'%'%((0=(=(277>2>222%(=26=0%110(%(0('(0('#'%#%'%'#'%'%'%'%%'%'#'#%'#'#'%'#'#'#'#%'#%(0=((=(227œ7>22222(2(06=2(0%1%10(%0'%,#%'#'#'%#%'%'%'%'%'%'%'%'%#'#'#%'#'#'#'#'#'#%((22>7œ>2722222%((0(6161(%(0(=10(0(0(0('#'%'#%'%#'%'%'%'%'%'%'#'#%'#'#'#'#'#'#'#'#'%(((2>œ>2>œ7œ>272222=(('(=021(201(01(010(0,'%#%'%#%%'%'%'%'%'#'%'%'#'%'#'#'%'#'#'#%'#'#'#'#'#%%((2>2œ2>2>œ2>Ɯ7222((('(202?6=101=0=010(0%0,'#'%#%#%'%#%'#'%'%'%'#'#'%#'#%'#'%#'#'#'#'%%%2>2œ>Ü2>2Ɯ222=%=0(0(0((2062<=0=0=0=101=0('#'#%'#%#%'%'#%','%'%'%'#'#'%'#'#'#'#'#'#'#%%%%2>>Ĝ22?œ722722=?=((0(%(0=0(2?0?<60=0=0(10('%'#%'%#'%'%#'%%,#'%'%'#'%'#'#'%'#'#%#%%%222ǜ2227?227?27?22?=(0((0=0?7<7<101?0=0=0(10=0('%#'#,#%'#'%#'%'%,%%'#,#%'%'#'#'#'%'#'#'#'#%'#% s[ccSc{s[Skskc[{KCkCCkKKs[[cckkss{{3;C#+33cc3SS+;;;KKCSSCKKKSS3skC{sCskKsk;scCc[SsCk[K[SC{[[s[kS[KSSS[[[kSc{KCK;sCk{C{3ckC[[+Kkk;++33#SS;[[CCC3KK;33+c[ SK {s3K#SK{k+{K{;3 {k#;SK#+++SC{ck ǧk[3+ ;sc#s+{3cKC#SK+ׯcS{#;KSC׿cc[;{[kק#{+k[#K߿S{k;{Ǘǯ# K; ߯#Ck[+csScC3 +#ǟ33s3SC߷ScS+sc;ǯkkKϗKCϯc׿KC3cCϗ#+Cs[+SC#Kckϗ+3KׯcϯsC;+{k χߗLJk+קScSC+{Ssk ;3[cS;߇ {#s#c#s3Ks[;߷{s sχ+c3[ǧ{c#[k#ߧcϟcSsK#{;sCsSׯ׷{k[ǯ{c{kϿǿSk;s{cSCsc[scǷkcsc{cc{{ǿallegro-5.0.10/examples/data/green.png0000644000175000001440000004426511436107177016765 0ustar tjadenusersPNG  IHDR~qȝH|IDATxw$G&qGF In稧գՏ}ov'Ho4c5GO4f(Xp&w},283q%P`=/D矙 r|BLUPAADN< %{ﺶk:hnun0]CXgSAyg Zfih{bTUtO;`%VBs/pBx,(HGp[uWs\CJ)"*I,9t9㘠[Mz[=3βߑ@iiHJ&GSjQ-Y9˧4*U@E*e@<۳蝦DзV2u5mͬ4Jaر弜OE9'9T2A$~Gs4}(o}E^b=TdNFQA j!K{>ŧYTfe"#y.YGnm9 U*_g5 b{`3zRcprX)91#f:G$P1u7AuTeo+JII}h+h^Nh[p@&zr׃/;xr\G"_94M (a6- @^nѭ^O00|?P$Df23O+#ʈP \!:DRx? *0G@>@[ ܚSq*&躹/'' P|-$Hb{Q hiĽtfZSa~ɀ)lȾ!^{v.[%dSic QY2Ke?cɱk׊׋SEqVe'ɠpXuOAmOeؐq 8/1<:'ʉbKoԾ}SsjE^zj1֡5>4>l!|{&)UaXZOK3 A:H{'9!hiЭ!O-ҢݰU:N׎L4lzV&qn&p9N}}"B# Q܀W~\ XԔcN?I?i=l=loܯ[Ʌyڋ =0I\vnȍyNi2JFqEWD}Yd_UWjJMuCH>M>M-k_Ծ@ZֆoxE`3qwnVt]LSnhơ;`+;93bD df&%~q/pdM8ܿ2CR[>+'<8_J;r/IWdL{9/gཤ33l΄btXR2rsfZ暴 -:ILb3vCu" rqq>WɯjMTc{}ƹ㷇A v^R@/܆ s3/ˏG5 ➶-u>PGaɻ㯏VwiŢeL' ~_B+U>h3^ >2aREi}bͳ:Af7qgNh;;<3ogoJh)vTx a.2o@6מ%rS03NBp#8a9#TGtD: Mr1(ݐnW+ǕO*`:,H؞sH#dA俗w:-%M:U;pƈQ.SөiatLo_6k4?NX ˟̏{F5AcO*{ҫS ;B_//N"˟}sѷG^B.GpI?OCuh%h؃Gr4S驉W&^2w3w`;yӷ#<:rb|HpC aB(_~E {޸=QLM6;$;Nҭ4F G|rl>[8C"MDƧ֪z/4g6{Zk5- #{8i ">d%ERRC8YeDFj}]KTuv_ `FͿ5sGp ]0]9[}{`_/pco)"bcH(r%!]Tcpl1; sY?l>3Np-\Z粳?9Sow;Ƙ1[|'IؿLR.\O'ҩ@ Gv15vO4n]s6UdaH2X{#K2x] }AQ1a||הvPNC/,sL7Y=a.#j20/YPJsν;;uz+JZ uRS%K$}P|r!*@D7 `g~|/[J,hT=Yd~Jj6]o-gT; ?6̅Pzx{n.qShM@ ۶p&XM "nG"QZNܪz-!?sNlO Ea­wo /dW푚\jL UP 'n/d'wr8 B+8w|g< Bw´0o \?Oͥs؞1@R|>w+-0;?NWD=[S;z`+ N8!^OaZ.zy*__ 3ņCC f%Ӂ&|oŚp@fSƁ1I縡[鷜MПLS *h aT@&w~^qZru.f9թ8펭yvlرBÿ>ϕtpD1Q +ʿ˼y۞RCn`0f13;V,Z,xSu,9p?r0DSN|gVOy{꫞qp-okLfI؞`Z Vc_L-21ځuညs>`STcHXkYꀧдX|q(+Zչy^{sw۬|dL>o5k[QG}7Pd`&(ϥ98)% R_R~gۨ;5y"f-򆨊f@E~t yAǤԉ#zW\#n G` l[Mw5ݖk3Y6rUҜ$AV䫲 ,s)"#4CoB-Uw|b`]3оҚ06ӂӎ:6 "cST`9<߉<;wyc!6^~X P76Rekϴ: _oa:=;Yy \S\c8"~~ha1]=cUl8*2]<~86?*Nwh:s}9 b β] @lE'`P3kj*RBH!0&H[I_gk>@R2&ޚxlr@00WͿ٬ l0 \Ύ|ECm. G-dp>BфSra6G3UoCˆ פiIa);#0{=&?/&_VS $@ M`?Z5뙅6F#~ k;ه5x<M_ϒ## /L"}H[-̽3NLbpfm׭ ^Lg(a7M^+$8Ww_ix dgcN%& AN˄ ̦~~Wi،3؞s#@cVXGdڛI@jSo4> \g0mچDSdol!˼N@I($mS/ʴWOU"} )_%M'3x&4 #.VlVYX4x 't^0`^,ڏSX>;F5b:tPr2-ڦ W X` |Ũ6E y5/ v:I'}!bmg^yw]{4҂Ȝ0 _oj[U `9tXlAL IwG;x#&knD6EqJT0qh7IYRPU_QǍΦYUlsҌwlܨ:b`vp0U!ZȂ-*i__ˉ\ߔb O8IY}?b-CjOړf>uf]ˏ僳Yn]F;C]fzc` h ZFRĥ \݀Yp︇:` :Mw_/CdET`r|3QaJHx~V^3|>g*"~7*]wp4C-~)dkТi3z$G0Q1  $*(LK*h秡HعCX#7:ٺ aiob,Fnp9,B V@kZlϏδEԎ TX~|b>K"as."BBL1쇇G+ŕ*Ty Fs~f|1t̑9nƾwXsÕY=B<Պ.b{7^1uYMUgxQ&\@/{ /?1% jeKn'b9nw:">tZ͏x߆ o>|~/V9}}:`Q{D"fDA|Y%`yN7k}tnPN^:tlӵIњ6VZkF>W?*gd`+הa*EES'yj/l M:s>5~NңNLu_U4s sOk'x78Z9yDN1Lu:̣QFdp>(:N% I7:w1z2qWw[aJ1C/[xfKaG:,wVt'xo% `ń:K8w`&<,ie\ͮ~lSIVJMb#= eG}nk@ 7gfUgմ8!e9"L*THev6*@̳,t'ܑgecn*eroB 8ȩ;ˍ/3_r%,QUw r%`#V#O0]lZX!ep`^*\h~y@GG8z_}fx[c5#䤟sa+ nrV):"9ۏy<6rjF \uQX6);I|DtI~[m/gO \3FJوiM^w'&m唜cFDFyjO}} m2#N.=2pEA l5jv΂p. 8;0Bą(}@?t㾁.>QTՙLɖDւR/!:-yy<L+R*GmwT6Y[ֺ@z`}:U-"?%`-d-R/lK14~@Y]LLvS)?ַ=SZԾߞC6o6H]>"XxƓOIOgp nm?׽*^zkoUQtW'.Ӟjo?p+f%/ >˧@c>BlvbjZ/udkbnEk-ĵ'@0k 3rr`%c'acYDœtz`k6:D>M@@Fǭ}+Vɋzs_'+`g}b3b&չlnVţ{EƢO9 dƮٵַCkZ^,i'=ߞ'aWz%.BJ`@ Q(mQ⮺˜P,ȥ8I-Dl [LFyP<(ޛVSk@(S C̽l_ 4ϼ+X||l<23<E}a|C脕N*mi!!|"&c nFVXsVdͧͧSӃYaA-mĂC!{b{ƞ'{ʄԇQ3򚜖2KftN'xa/Qѓ;35բZdAz*1z=N2g4[Msxj<ڏ!4Xp;WrcϘ3}SqeF{TZxd}쉮V\35wYW$BԕKc{=Otk@hԴaP ;Y1+{EO|@dD!QA)hG([LnP8:ף6]xڊb*eu78~ƫQ.w qyj$5)?+B 4EQ'Z}58lm;FJ4sI؞kc,CY󡉑T#2(ʪ[ufm@ے# dy“@;) y'(\I(Wxj; '6 4(%_ -W꛽1TZG>|r$9‚3B7m ;SUߤ<fvU{1+y !%E@g-y쁪2֊>V0ݛV-Edk*{De Ӣ^XFQ6R<Ă*a֢^w<%}Sfelo[(üx"&D-j{sV<ߘ10Qq%{r{^-f ʁ 2+!u/fՙD/"hRlq'vUj]i=yt~!KRlbaENi}tCM);aM]3trbjfWiP{͏c9aTƈc*<5䀝Hd{>J>އ~: b@{2+<6͊gx3sl|k4Oeu|OlD{ ;%HEM@^~ۓh*\IљDcc{֞'s@lv#]bGxH@?hUo:T J@9>4NSfl)6rAq2Ƌvb>n4n;@"mEٌȝd0IyKJKbS=LO¯צ_F^>&s\P1+ ty=x>YHv.\²1}!/2T)Swt{7p:Ctރ*vE6x#F5!]-%NZGOa0SŨPuO/̒΋^%(kź qRuYT=Oמ{}@;!e9uQ@(8%,^Z)ty_7H4d֎V7u<;w Q[~lsg,}kEp`/Bp%Kȉ,(\NOQ>1p)xb7(KicTlӵg,}ctM4? su*(P NtZ9)Ϥ9([0g,1ڏa(. N'Q%$ (~nX/XXŲƏy);skmiEU 1غ{镡@ C]?  e5AtKߩ[x(W".RJJtWg@>h"P%Y,/x*s'(؞kXf[}~6qJ4,%罭Q@.e?8'DQ(Bϐ JrNP 4](uh_uvasBT{λҶJVzN/.(=S Xc]8>T%g,9Lg` <֯HɝAN!rN%  R7 ]sAMb\⸘t%g,90Qҷ,P 7 $'T zX1Srz I$GdPnb?=A`T 4ȋeqma.; iz\"k$ I6& b_Gxf\ǂ`E;dEch~~(7Xj_ ؞|gߪZUcذ@Y+ܔ%^BQȀ#&"!EV(L+ꢗn;xrEy9x9؞=c0ښfho͏piQ_SS.euQ;<#dgRY:A',bgKoV]_,PQoiqR̰I6Cb{e1e]uWM/ yaTYx9530~d?baa&A*|-9&NG7t#7A_y^W ِgS,,V_/iފYM|G<(b/#Yc{e0[V~~4}%} ^ku(7DZ^+x>nQgJgJ̛3o&$EDi|&NLF7[uܦ?)O_4>؞ c]ƃƃԽ=|r9w{l$KWՌS/X7oEw&`^?Оg4Nb?`7WW5MҔ=k5qyQkXϬ c=glX!06j>W*Wӓ)2NƀN 5O(Y$^6-pT d%VBПgOؿ_ӓzW;u#Ԟij>EuT#R(HaZ L4/2KE! tٌy1kcGGqA\!O׋B:Bxrx=,.E )!_/̿=ğO9EnrW@ l,Yjm)*s<|*Έ37A|}l"u75ODkqJ28}RgQ7ߘ~fFpo5.]{ƴPYQ*Ӹ~ə~&0VL!3α3>{. AYRS,/X>{# Js]\RZwûQQ؞؞иIa*NBN*uBJK<&'S\j~ȸSH)srQSǙuf[V 's;y}2oZ° PBEgO`ؼ߼/N5IS*pRNƽMkdXC`1#fR,|n>Ov-J?hvc{^|{'8RSO0? @>*$MbD0Db.1Z4_ό'ƚf2nUDzYxVrJ.=J/ 2O捂Qxǜ~gxo fg[U>IN* <_w[V?.Y(ߕLЀp#ʬ8$ʄM~h|V*5`:LӉĬ8/ΓI2 9C:+b|Ï3>'sY? $IMMо :$EU^'gk[vxz`!R9QH t`,9qD)nr^AN' A`*_ѶfkYWJiBdD&3`ɏ4T%M_9„Pʜ2\Կ?זO ĕ0bUJYZT:8%NqA1(ڪԤX})9 \cVGXO-PB#8Dk|U%{W.X|8-BZn 7D)3[A=3:?HC&@Ӡ96'{Ntaݩ}kbƪ[sPVe&!"\q ˁ"_3 |#9x}ϱIRR&SR7%|bZf ŚUCrt'}5N$$IEI11ќʐ2pUPF1viKzI97L#ļ{4\QK'T=Oמ p{{0Ҭ4H%A& 8 13<|$w@%\fNT] ^lwdu'O5/.P2nhoF(˾@?ŗԚꮸ%䔝2X+`0$#GS@$BO)$7OjRz͠6v5@1Ե؞Ӟ (nխ>o})zgμ%-J|?jpð\26L<0ʯ*~I#JaL(R?5}2 }}@eɼGx~ؼ<ͱy6]aI15< S"vPNx*Rd%&$Iy8w&`Y h&"-gG[q멷℈Q;Ce)](e1 z5ow. "m%r"ڿRu=h&^NLISA XHVvqP7yq_c=( | $Ծ>6i>3L}/5%KI` "}I>i_T-=C_ ܢ{Dz9#N 2ժHe=N~?9#/isc!3?ا4YA A*g,Wֿ?tiX-2V,sC9w8qc.l߰˿(Z6GK*~ ٝ2}a  U>SrZƒfĭDN$6ŒS`/3vɎy QBEݯkz0x]6\Uu9\Q$>S<$=nB7f߯743Up5ڱ$Y@y?|^|z)o xg8N|b|,&&GrJE621p_1€3#+mU~^5œj؞ G|-n4% SbZaLp).,!Kc oo3*Nh_k ,Ms8:n?/1tVd}NL*R?5 g?j@9iN= :~^`7H(rCIa!$zZF:}`RM7!l(' b{^{4}_M[s&[Tڗ0OsInKpYN KXBYpF pJLA >ñ7m^-k2ͧ5˅@ A>0qj^NvMvV9M3sm0nE`<XIFb4`@vYxQ 1-`@.=El)9!C 7AK_)L0LXf  9 Ҟ lhﵺ|Tc{^.{O%z^=eoE;LʛHr$ʍrF8|23a!kpYIc0ViFϸ0RtdCJTfgoƮTZ^/ cu/Wu=R1ߌx_CIfK&: N>BAo(@䨉hQ"?t^rq'O񳃀jوB2cy@~<&I7yX\i-[vK僋,>\DTV 祰esǺKuB 8g34;:{X~넘LKGw2:L,-nWDp@Չ&؞=/\*OE<^ Yh_i}4;;F'2\<d,=c9r#ʫkk÷o !a8qkdZan)ݡiVb%/tR<ӯOUEhn)9f8PÊAޢwXb%/ pKOf~879oN4aI4OFUI ƈ:uEb%X. RY5Msӷ qj)LhG? Io62?8;5i]E.O%X{HOd2s\m~esdy)C3C3?Ops7lSmcn_Zgj\kyϻޏ,S66؍%X{_]~E~E.^o}yd<JV••7f{w]zjF4C Ljfu9̥;kcK,IgEV'72y%}q뱶u;yGbS;7Go:j{W+l3 fX_r=p,߼l7kQK,MoqdGi~ 'Rzxl<65}M6]L)bJG)dfw毦nn ׅ֘5f(Qz0_65+Wg%X<[*0;^Woyf+֚fo&hڰ;gy HMlA!dNTARRJ*Y5:Nʳ .Ԓ1VwlٱGVgf˨OwW9r4O,Mi)n[b+6@7MThmV!i RbVbie~aر duYcZ琓,,loG!'OV`c%X$c= i$Gru4PFc4_ud e\#o"LT)6E34+. #Gqoo[0-O%vCqSW[7Xb Bh@2,.%""5 +C`f?Kxhܞ=F,#h  cCٱ&NnlnU#~֠DF,spFq~n6DchO#M|SsK q2ȅ_=#/uw%x2*~m ![o.K,Rۨm K3R,b‘Ӻ#}N"÷-ƸoOZV7zMd!S`Ap—iۏ3K,^pxtoBuV^iQAp G%"cްjkFfM0qrv3,Dn@!OK,1zOxVaD$ q.↸+" 24J C%p&y)Pf{*'f; AqܦuJo=a-[ ԩAT[?sD=Xb%֠&nYy= :Y`lX<$ڵLJ?߁!ÆW-i`jG_x~,z(hhcRВ =ïG,{7bK,L_i71.܃1f+k߉%Xb95 f#pORs W6DZ5?jn]_^~,"?7>Xbe@aᴁz1K,'?p:IENDB`allegro-5.0.10/examples/data/sample.cfg0000644000175000001440000000340711163702321017077 0ustar tjadenusers# Comments and blank lines should be preserved when this file is written back # out. # Whoa. old_var = old global value # a long value mysha.xpm = /* XPM */ static char * mysha_xpm[] = { "40 25 16 1", " c #0B0B0C", ". c #302837", "+ c #362D47", "@ c #38303F", "# c #402E46", "$ c #323345", "% c #453335", "& c #3A3A43", "* c #443B4B", "= c #57525A", "- c #7E6676", "; c #6F6B71", "> c #938C97", ", c #B6B0C0", "' c #C9CBDA", ") c #DEE1EE", "$@@@$$@+@@@@@+@@@@+@@@@@@#@@$&$@$+++....", "$@@@@@+@@@$$+$@@@+++@@@@@$@@@@@@+@++.++.", "@@@@@@@+&@@&$+@@@@@@@@+++++@@@+@+$$$++..", "@@+@+@+##++++@$#++$@+@@@@++@#@@@$@$++@..", "++++@@$#+&@*#*#**###@@+++++@@@@@@++.#++.", "+@@@@@&#&&***;,,,,>;=,->;@+@@@@@@@#@+##+", "+++#+$***,,>'))))))',;;->+@@+$@@@$$+#.++", "+++$+$*#>,,>'))')'',>-->>*#@@@$@@@@@++++", "*#*$$***',,>''))))),>-->>>=*@@@@+###@+$+", "$*&$**;)',>,')))))''>-->>>>*@@@@+@$$$$.+", "+$#$*=))',,')))))',,>-;>>>>>*+@&@@$@@.+$", "****=,)))','))))',>>;;;;>;;;*++@+@@+@@++", "$***;')))'')'')',-@>-==;;;;==&@++++@$$&$", "***=;'))))''%''',% ;;===;;&==&##+@@@++@$", "****>'')))''''',,>>>;==&;;=&%&+@++#@@+@@", "**#*;,')''',,,,>>>;;===;;=%%&&@@@+@@@#@$", "*****,'''',>,,>>=;*=======*=&@@@@@@@@++$", "=;>*&>,',>,,>>-*--=========%%@+++++@@@@@", ">>>=*=>,,>,,>--;*=;=======& %@+@+++@@+@@", " ..;->>>>;-==;==== == @@@++@@+@+$", " & =>-;;==& ** ", " *;==&. @ ", " =&% . ", " *% ", " "}; [section] # Comment inside the section. old_var = old section value # UTF8 in section names, key names and values. [adição] €=¿ # The following line contains spaces but will probably be trimmed when # written back out. # Final line. allegro-5.0.10/examples/data/mysha256x256.png0000644000175000001440000020005311253526740017653 0ustar tjadenusersPNG  IHDR\rfsRGB IDATxٓ׵[;3kyF HA ERD:;7ۏ'nሒ( 3ЍsWe^~9nġ+]}Z !B_',Cp <3pF3)A#>{Ѽ0pId5S<#k-s PmtN>]UZ"Igm1Uyos XcgHt5:Cph+tdcSkw KX˲k=`Y3g |[#}3TfGqjz3J)Opw$d}87RoO8F$33s{H](3}?Z$3pM5s2Zd |39j%ҟNr<'&x<Ʀ͍[K{Fo} 񨏄;L]%]cw{F>3P.y&Ngaˏ@ŐMoz;ja~>aS E_^Se~G?|7B;]xcf|J37K 5m<Տ` 8uU^ձQΖ)~)Ns \SD+)8:s_ >C+߳@G؜yb~0'Ϲ _YC <66> $+ ʂS6wŠLXʹ4 zSʹU"͟> v3M`C 06 8,*DžC5pq Hl*Z5?YY =>'\o}aee䐿7__x̛~,?Α9~ 7eq|G ߧΪ/f7TQFZܽC^ o&KV+dl;Zxy|p :|xa+'yOcwm$D.ߟx7>釼q}e; Y6^6;d75[`@[YԟWMrN ?t-~G_qjCLA21iN|ppFߏ{mvz- qk nË/o=xđ)~73]f.QB9# ~>;&ta?~:.[ =||?OdVd7_]cv ʄB]noSw7_k|zeB.\gX[ PT{hBrJF!y:(?PV_򷿧@_I7&|:?KSܸ6#("J lg7y PX۔'=$u~+@m4~U bܙ'Y~KwFXw> -8m Y!gיײ$ ]v:fY?O*Bp <] Qn^c Q_/v~HdD;'XU_+#v!y +KV:oЕ,zT~y _=rlw}"|M~F"gSϕSrH U- ]鲼r(?>ٗ6@y[Hm )cWD§cI~<7.?1kk>,:k'~~NN42Tr+}9u?&66$(^8[` ɿL\N-p(V,JoXu䉌__QckRj49ڳK{&OQW6|6.\JW6W>2̴6uYW}7hsz27?|0ͿwW"6, iH f=̅D"%ͨWVQ iy^q676NUV/: WjܿfpDY3zz9mф#_?EP>8LqŦ5Qc!f#[#u=&U7ڙPYs}JҘP){8>7S:HY€K!uN /3 ?8,'?u~Vo0.~,7?"̇&SfׯmV`0T"@`O;=VwЌ@Q?;̐ h2\ts=ʉa?W=xـ׍{lYˍ{Od4!|n)'2ok! wfupE4ޡBnZK+MW+0&Qҿ5S" v9f'0Ȑ; $gER=Hܴʍ !#9GH'M:YK/|h/aw3O%N$uH!=# %Rs`?/%i_(貪QsunyJag/'.O_nWvnؔO=Q^;¹7ϯ=/:~߼O.e7g_w<h*HPP6ԛ% ֹ2% U1z9c)vA{/@xIY?D2mw3ܸ: {VFm2װ{R Yh)amL3đa9 ;xl* PpFabLOl*vޟ]4ߌk" .\ƽqv|:i\65Mї(UզJN 7jTV<>2ʍ}L'ӈ KjՌdŀG&`JgE6w J+vdxYvC]8:Q9|j =JL&:B/)fg8Θg82K#luO'9>x{Z*(2.vf+%R&"/h)(_FÀ'Za fɐ)_ZVr)4@C u~S12`l`9=i>@g3P~y4K2 A6hrwY8aM ~@G368|4o_g6ͪѯ qh LSK3~ҐSh!,Ae)=*T7 3dFP dHT.&iyup >FvH:]+U a(k 1ޟvgVXBtXa.6)*p{Z겝 !ZpɉQE n)[fR:,]L&̿-DDnP.5 M^2v/ {wɕL5x9WJe! EI^PFa0k`2 Բk='k0\!p*M?_WH•_\joqT̎]?_H? .\6v-t jǥt15ϣ2<"֨Z7E[V\q>CGEHZMp*Aj4N *O%zzTsʁU(kdStpc ȹWWiS[F/ :zjt]X54{Wjƭ5NgdV2 IU$v0g" ABIrBbPӐ{ؓ"ېZlArvbgƙ?˳Qy>DUy,]KhpjR m|9 u *՛X<K-k)f|G>¥qn\bkMC;lf4"OiuZ E,=-A㽮_J~S﵄Bi\ Z |LD٫iv?*y A!mdWEIf8mٻM _͖ uQbAf4UQ<0;Y4IV^]Aj-7`bllsmƪ:7& pOx݁6MKY+חFtis/~\>eU O9.oML(.Gd{[j*278ZkRε2~\" IDATpvkκbPEARJ6*@ntvՋT,ٸ BA:Oc-B ݝJFV }z:Oa@؎0Si`7SLV]ԥnzO(b*Z#S-rz؍Z j]')cH)ilQDXtMifO[_,g'(Zhah~9@VSCp{ Lbʙ 2:9 y}bB_so.LqΌۤixDbGoQ(-O8j9[眇"I\/5dd1 Ll9 &0Ƹl1vqqnGӢ6t:HGowTigWAZ-$D'cz=ꓪ7Y 6QTT(uJ!ʍxxH*hjG&G%}m, VE}XBj@w1pt(2vXt,uC}K{f1vk\9eqqW@fWdYSFQ8#3;^ʭ wڶ ?J\*jIA*]ث6zni!G}/.e;nZsm1HMO$B n!hiwtDVi@1.ov؂M-q)6#JN0C;(Wh{[!Iچ\wb?.t7麗X)bdDlGkfN~_I7 ~;1ZRUlfN p Vnwn _,;0\v%)DU%{3hQUpvkS_Ly:;3zKaEx:`G5gg(\2;nI65Amj.!5>ieZ&T,pwQW][/0eq!v.#n[M$.ttGt:Qev0@SaHl-;iJ$ZXHXM\VQQ=FOIӔ~Ȯ*5E࢑quvMz.nБ"0k:( b\( c&~bbRkI-Rc1vwwagg~O M2=K-e}lkz6"˜*'mz;Xm1 )G_=?aŤqϕdb0լ@[Hyu2;D\xQ>>?GJ]-إVkIH-a'^% |5~l-uze4P@@"Iv:6^}%t@"N\0vD& lu02.n-ks1P6Ż$>oy^J 0c4% Vl@ҏف($)0&aHcئMvaC*j,/M~1V Fm$MI~Ӹ 9Q1Ꜣ]xi(i5_cd70݀p~H!If{d:5_>pzS+ν>d[]cx6400C4u^7UH] -p)=9-D`3R4odj>47"t5t"H V"@F L.c609 CFF[-D Nv[03;H@;+~ne*ۈ!Jڀv/.B$]:)q?dg!۽bl+/}Ko+f@~'wB?cbm~l宫S r9U4I&(-?{ե/fsJi4MuPS(VzsY!ׁPVtˎ tc(ok#gWgrm1LuU$[j,K*-)yv5'٭Y/dD4".u7jIb1:tC{ ]AFC# 9vӎZtGt]a+T2ZJJ*ЎJN= 5{;cTۭ6~ ]W.,sZ%݁~$WM\`>y?u.-Ԧ5FVFpU$cE M Fݢ\:0fӛN#BjDĻ5S@l-` W߾ݱ1LPj Lإ+u~v:1[t]S,;Ñ#DVY@hE!&@ʆ,U %Wf]mS3Bx CԦ$UD-Q'+ܗvH0l;'hh1.ocm&ORGYkq?%pJ9_eH"S/|.VS6h6n8yX/vmҋ"zbA9>2K 4 K7^Wˣ (Auș* (%5{A7ϽLd~bIśH'@F߽4X_z@c 35J6@ tD#cSS,!贺G:GhB"!FyFhYAsQե"ZM7F-: IH_I0S'L#GXX84D¶0@+02BZPBL(`3M@O3PUHVm4 e'#s]) j,\x|ղ IN7ˎ$4 р;Ý5ԇt3f{x#b  ۔ 'nTENnmucM+ƣ̒G1gJP`߫3AڿiCCV {-"J. vcS'7xE2$=Og/gWzu[Ke-E>5eVR>WU>Odih+{(lTdLT-j\"ׯkh7Z|f_, ׯ051G0-,N/ؐF(ʺi3@ /{ ^I)'T)8Kj6kQ xEZ364k O'ā4fwN=o[q8Zw6 16P!J F!)$+$Z LEh@4a$B6?u Av 꾂a8Z­/\9ʧ^>FfǁAArZkԤذE`[_kO 5Q/&DgUV<ΞbE(նyGkQ*ܨ3+ƣ^8alscD m;3akVZH-0q.I9gP2/_lOU.j\Re& tIGKFOZ`:DQl-lS@5FRYEo g"$2Nh ABґb r"ìYJ ̄]ʺwf=Ww-7( olJ֥au5b.op`00Zc)+aT\#^E%pӅ_E$vggQVۻ+eL7uVz `. Xjy i ֲգNbd3&0ꔊEn/>I{h!A1U 2 B #7d 1qWH;.ʾʄO-Ӧ*X,3\4 O,A9`wF&UdžՇ]=n$ϡ|\lnO(vEiRl-\k5RIWL5 .U-r<@FWxsF 1K6S`q?tBC؊fP`T .ݦ%JE ^;47ƔNCL>W*I3*}:I14SiM OYm%M\{NJ?Ѐi/Aqæx]ylii؇=tӕ\TLÐPƣYlDW@ 1&pg3"AjУKWXͤ~ ;G-rA6UΉkyjpf }Enr8T-WfI1m ޞqiZWJck2* yYc*k3ZZU^nqYg"A>-f#9U~.mOPa6LR"lJxgj;GYĂL{=Ԙu]ETf~$E!Jh t8Y'Y4S% i dF%WdVAPЁܙҼ-B7l3M-Sj/נoj_iFåFypō[9=+gV̓4׮Ot6n=0MYw@?/4E~XH#sO,?;c\Cj&znM0jHfs/wcO9g拞 \ڭ+?S0v`Ķ(r`3V,SdT`HF`WEzVHS7j,tKSe*݉If c eWVRjk-n2NK@HOFVR AKb>-HL0 r%Eb+t;GF]؍ %5 _- uȐjV[[_pyz 6ࡰQL맧R3Vt+~DV.&g, XgTiVb7Oc*Xd*͖ԘDmD4!ĀQ"sHW?g3;>!UfeytԠAuڼwBGwn,R$ mp,tfo[j~h!jIEw YSUn& )+qBWFF]l&o!U/G!q !N!X'}D¨epXz:0PcdN/o -7Z· @ډφ+j1JY*TqVN$im[7#ך98Uۍ5J_]8QeDj'luc);}%l07O`EmȆ΍xjwL 3L͜SFLttfrŦY'F8$i&n@tVjYϋZǷUbUꢳSjLK@DIl- ,b*"c4v2ew[c ~@lq To츟47,a1lOon!qL-'nYؚT ʧQ甌jeI7+ +-AV߉ZxwgtʙuTy8.˩G853<\ X<}RUW#i#uU Ʌ*Œrb;XDzo0()\Y Ab+"FR IDAT dC=bE1iB@D:Q1DD!vǢ}#Ft:]0" iQbuy?0C^&S3+}"詙xfe-$6)!--ʞzrJѹ}&.ʙOJulEzxv{٨-l*ym̪etvmK;B]XI ba]J-ES Bl3.[}FkF1 &qrvF{E43/j{)3hM A>+1 AH!b52"iW$NMё.$J*B]RIXrU):a04FA4IS!6AYV(G1HX}bјv7loGu:+<vh;DG%%vKj:T(bd7lVܾ|f,bg½N=ܖfƕGk+w;X뤘ZRJ f WeZRCTj ߞZIibR-сwp-Qyި.g%0:$;?Og 6.,gËB/bc/p3 4cm:>{ ̙a8Hy`etlu mLͧ5Eډa%w{j :@AmK,7˟)~xn M9WhE\pSrTηЫ\<ѿ5)d7چOO(@(˖/_o.m@ٷ?; Dcq N~YIme9 x>B֩,4sӈ! m%G"r41<ϙfEFrXǏ`Ӊlu{{ˣG(PN8!;eej:'`彗̽y8G@lub+qRcZȉq~g_o[ڻ=M@ q0(O ŜP5t󑧏huSޗQ_&=4adx#8!<dU4]K37ww0L0PwV 1/e~F{~ gcA)`3q*RyiB"b& tȍ"l xAQd"Q֎U|x ?eu:޾|m|PJIn6HNVSM}mI\kVDBCX J@A\e,|)|ez KNM`gg%o^u+>]3v]((ny ޜo6;ꋯW춥m-8y\f{:v~rnC w|c$L# 8Op"?GZ) OG|wtifB7;ahNy: S +dN)ޫ.I GDž0 2.Frhjó5>T>1?ʩwp/L%֬EW?ƗxKČL$w*tu )MK6Dcd>j[m(Gs, `,{x=A|cB"hɞ֑w(z#QmΒIڏ{Fx5Z..gwі~~s5{{E\}9{}Âz#)ss6'!ݭ|2WyW<*Z5YxAB<`Kɰ٩U@I| <=Oins].Y;b1D1])6 G\daזJoW#(`*|B&zu?@.嚝djI)e@1jqzM?p>4J~t->^0])\lptFm ?y?JpD\t& vAIOjzU-h6#1c98k 8mE΄+ # lw="A$2i\C~z )p{븾O/~S-c =)`lzDhOH8^y׿⫓'ȓS8;%sqzg{G8rK&# RH\ui>%vJGPdBN+oCg/`:W]vx)vSkV7gۮ{pUXh`eCnDi'=yzFFrN)ќ<&v=nmO^2<ڜж--ڷWa'YC";P 5x,a:H%B*>k8un]ҿ1Z%O9`*~ x(Aӕu}-~{myß%s1c,:9Vy, UWxOW_6-e!9k,}XՑ4!jHwTbmlNx!ݻxO_Rt%Z<8kpRgUN1f0cFoy챝 N1.f)q?2ȎO29`tОt>5r;Fw#lG enVu' L3'(Psey2q.{ҿsBCۆ >c144 $s1-vq7p_%>|A67<7)ӜszpO}< R瑦[D,9/xr mp7nSW@!U^hҮey4}+ʭf89kJMngi6,Μm iE&zU|4E\PזiÚ8xĭVmh !VɍL**أ2ҠгC ᄡ&Tw-yZ>'Wn@"xK Je:,jRI#ڌNTO!BpBht۽z}`xJ5H^2/t ȃ܋Ip9 Ϯ.86']a o {! 1T8m~"K2S;xnU/ӯꊳMG\8-lB{hTI@K9MC! l|C;Dvq [lȽLpD^Tryar!.|ЅB`ūc`ZٍO&ux( BlE#YB#82#5nǏvVvb4W1~$Ь>E%pk͕yH#c>j;_*_%W.18- j nomTJ مSեKf-E_T{!i}i8}P+E95}¹ _n a,X{H99gp~5\> HswXkp×fr^ksyJuR,xH YS7p㫝 EZ3t["El*B>Wi*2x8k'a]v]y #ĂA8<9ETac7Dڣ@~ލD%n¾rޫ0|myIW9TiNOqh =N`Ȋ, UY^2O>[kIK`8a'lݎ}&QKДCeAϻeXkh?@`$N-Og ^U@ׅdV-Uj?Dh g^=G. Wt 5μ %N{)6u$y*M'/r<汙obD*&P@Q?݂(|Q|[xf].T³g.3 C8$M 1dб/\ Ohsuqco+h{742Z?^#4ޢյ[*=tmx-䥦iKTH ch܄26ayɧЉ"+P=0~ MVmsrzgAU}LC6n'0c$W?s~~@ -I IăXZ3EOrtٗzƗ/N 'P +m8|m[)GP#FY]PxZ"Gk<#tQNGdjiHQ[k Lηg0Ne\7Qbu)$]Z^2Sє34=qo`j?[ƘfhPW q-_&= p=s7U1I H1i!_Zrijlu=/:u?B*6[:@2GtĜfqgef|NN!gN& L#^Ӭր%b%SO0K v G[\`ȁ0S)C3n_~ K!A*츎‡}_`,KuK" bklJ@@@tlDy#=b"ex+]UTcd|UgJģIQO(1"]gBadX)(AW*26_P*HZ\:͉ķbcD2c !yo-$+c3< nMFԣ>%5{*92D3C#3sgiio`C4.))Jj{d*׎ݲVN|j3Y`r#B*>[hi;HHͭ e:>L'RNlSrӜkP*xyl`0_\E NZڰesqy~yGw m?me4S.{Hp.5DVe$@0+|m*^uŚc4v`i*˙\8' >Q mqSҿV;̈́~m"j)jH1CȨm'WҐlcÎ;w ұH )F |t$ڨOʎ6nGEٟ.ۈOvj%5VG$YS.{*DcD'eA4MTN=qkA<rВ 8e<8PIx;[ l[B$Woxt~fû~b%K*)(J`(%9" 2.@.@߈U}TK4Yq?4~O,Zfغ⸝NDq!tbnܔ&{H3SP(nsr zr"OoBp(ԪXdJN49*λ$a9|kdJ.%_NX-'ޱ6X\Wݻkx1ï}e-Y2k "iG+wiK74;Af^ UTVZS][k#Xnª[-fgF`*} In+ȮTgəe*< xh](1b2WPŗ7W6 GerlYfܗ Q햓/| E:7N!&"kadYC_y5 3NR.aK^xISmיgNyLC pn%&ϷK,"dBQɬSΌ5><"!ۼ'ȠKY~{H{{Qƨ1o,D2 Q7-y#/qm۸3c)lOެf2qm@LBnԀ@"辬J0 |kڬbDM#P Uܨ~JqCoNPȒKxɜW~x>clK>53nß_'&N`7 .$-/6זToD8[,-SOq.N!I@Ͽ|A4GcJE*..Xl6mK۶%0Wb%_M!0Thdya>.j-S)a)wbeJ;Kr11@mDLGRA8&}&FZj|(he|3}\KbL&y!:ﵛ6%Gj329L+C $p T\%DD Ȟ3Gc*XGTS֟YZI%Oq '+n2VfFR;ojnN~ 9_{^~{ dR,=(dB5ko89^n9 p/ l}m! ^1ӦitQy&La*Ο?%x?X(64+ʄ: 0d9OXj|uUt %" rDR^'hV7[s>&Qm:ٌ;Ѳ!u$z3G8PqH8# xLyV=-lR"vޛlφs-!{KV]X(i N[9 qTMV4e}thx'|E =MH}qM3\)'pnlן/,w]?kw]~&hsɆ'SJ8WNvs%ҕX* Um/qS9\i&x#6 "c7Т]" "&w!~`"pWH9"HۖlVXځ0dT>FskGR+s9~x{cH+!H {n@R-7{% V%!"@@K{jG!_&&;Cl&.iq?,;4I^Orpd`W7һgF9d]3WgtV'-}YfЉknfG/ë"T&9iwc<*RhHkmTI3>YϠCB|8hlTD3@% c[5ҫZ0fݠ?~Gv÷69?CzR*%@r;i-3ƊYبի]-tQ#=czKDf^O-Y- L3y{4^hyZhmC$bR*MްʡЃA 6qy!s.+b9Kji[d6.&%^?ϖoX_/v2'HaPv^#/=dGwXۣ"w<=|4Aj\vBV|Y@ R7CFA4{ُv/3kRؔy K+s"n.#)qG\!م1$BoKBAFl?O&1}&d6QqhsMH㖍ӫgG"lM'Ps'oHf6'"Mcgkh8n>!`N p8 ?yFRyO*4@YT43y&40ǑL Sr4T\a9%44ڶ_ZC8[ƸCQjݎ0K#ow9KZt vm %oEq>MWQV޽1Z*Q6>QF4÷{ xM!Ҏt'T k Fc:d8)!8Ao;G/'OiV.$sڈ-l6ǀtЂ:,`0H?{EsKw@uV&Ԉ,y&(&_sw{{˛xӏ\g<K.<¤E' O;%{˜tdAZdGTfkw'B{*_«`׿G E oa,G"č BTbU-4.n4C(1^59YTt9BЕDc@C>jBt]W‹" )-EXX hUxDy+e뽨em`&XLs-$ ]%ءr8пh}Kw;zA1XaL^xu)M`W t;_k~?#\n6h^X@D"f/H9r )2{r$ܺ-㧌ooZ[~o(=G-aGO5(}s$EV)3=wUN8e5r.nAGw%%?w-\ x3zUO_O yaVlӈc^T5t ˟? q3gbpϪï/?ϒqs?r/υ%hF;X ޻Ix 3kv&-]Ρnn rC{僭6]*h ??="G'ʸi+BˊXڎ&exlAϣrs;J" vV7{}|7~K_%"?AFڿ|wt9; -uHVT%ñB:Q&31LM^N]J)!J~_Pe 9)ixe,{U#g%mXM1ͬy! (T҉B%hI_i 09/*-JSׁ>EfB᝘q는=0{ i1J&_ƭ mcŞ0~"fMw8X_(2ڱJ&N1Zvη?o[{/B nG<-WA^ê`fͶzw6.E+0=H&pݓ߼99b(©k.N}~24Umr!bPBTK ڏ ĬS䤤~MLe>lB$Znla嬤4R+^r(ʁs"%˟ ' d#c%*+alUyЉ['; * XZz~zZF0e$}<;'K &݀8$"MM $}+Z6S-n>Dc(^gIfxeS5feUo' տ;Bnl#*Z&', :%@2bÔFnP7pٟΎ_7?zآB ^ xZGZdJB789M u06KϦz萴$Tm { ;@ cy ,T2 q,@ʭnS>IPpJ<(,Ӭy\ qaeݛLVH oeL|jıfk=ز#k C<][YdW8qSJV߄y'+t?Iě81+G *g4eRxݏog>Fx3j.BA[ 4SHlw.:Tw0"Bd IDATdW 4d{)oͿX֑7Wt[T"wS,4M'2dU*e I.|UѢI6-4ghe)i8e0R%33$"r: 9-iqKW]"h"-'yW aĆI+>[{^gN_e Dmem[/MYGZ.JK^Y-ڗPG:;{*-0+yd`O@Q ocIq_)٘oa3ʯOi5o_W<-ZS{#k7A'99m0=vj~mOӎ?o%?]<8lOrS>?0<^!#Ok(cJbNjWcl[7?iAh:tWѶ-%EwsS@SX2 ig_&SzJ5,5IL\o018&)qaD ܂'0#K'Cd&<])&^SC:MHP.-3.t.TT}8Hi2Ȑ"N4>~u[rYe=v47Ǖ_?Ro?W_4ŴyBeʜt&IdYz)a@Y0;v=q.= ^?8ޔ:/ O?p_s7l6l-mhab#=GgM|-nɌwݺR 2ěuyXvW~~v@ޤek;PyzN2BFEѣ -alQFhE5C/UmGb20dd13)y UXsjZEЄP<=23Lbd/* a!D\?_ byg[?Qƕ0f ;Y/82CuyDAZ5"wtۡXl,[n`kl>lv؍t=&b>yP @=vh}֫m#t azql&`*U&Mrj܇cMDVetAc[6CNH0FJ Cқ\WDh}ĒR/_Ϳs~ʯ~;v]Ȼl/5ze* h]tQ-hOԒbtqR\ }KWԍy>CW97VU<܆d|[tټT vw2qcXb,7@>D\g0| 9 Bc~߱ۿn[iTD8rGTxwO*_~͉ wN)G%gmׯ6."HP.ӟO=ZL#JKC 99~ۑfJ PRFo?9Hcbݳu>zu3ߐ)yNԤXv+%ֆ8Ei 闄_Wagd]ٝt "e3O;I'PXFhfwH |퉣mCf"u$:(6>k?9_"JwΡmkbI)=߄ʿ+@i>aN8z'-H wT(йF:=9}ҲX1Cd ~ lZ_zDZOR&H-\NV@qzi`]VDxfg_&~iC7o?ȷ_OK4!.SmaHsFJgF 䔮kx+}]KYA2ovɩ#Τԅ1Ban?Pf5Vf2*áp W%7⤫9M_ qv91a/M"XtFMy|k$]xUe&tFUI>#urjĞítTb$4^5kaM7#ꑱT >~GbX!i[&shPQP?w ;F;3Vg8b'LW\]8!f&@* pk!V% x1gPW! } \Ùƃ,B$%%9ِuE| P/!3|%߀+TwO W;3tv9JX)Ԕ+Ao Q?{jUԑ}zʘWGCq$\a+dEsD\^P[ ņ/s\lؓExְD%k'Oj0X!eS#ECEV y-/r_뱟@%Vuʩ;h?q a|Be۬D9bwi͓@F rK<z~&y4 k9i Dۆ߿&*p,6*8i青&#tݮ YHpvժטR# 4\Ȝ1.(C2)%rt% 6noA$Y´TWFrdNҊx|wg4T s AU$ƙ3KLg;XK~H::s):ʘJl;qМ򑬅re$@Hy(z13î@.`$;uۙPF B[A#fo8rӛbL:QFa^bߨܽ@v;\Kw)TrUM~.'XA8"Gzb hfS 6"'{EmM:" (֜[rS̓? _*Xh7e\л7,@Ez姏ݦl *.1Vwvi4sOSG6{pjPFT.WLͰIۆFt"KƠu1֫ZHG9]5-tfՕ1KԴ[2]]0$EuK?&! vVNƈ/ZŅɉr}3r~p:OZ2qۢNiU(X`[P#EWSY&&.HkjY[%{ R0ۧލIJ=Wg)9Sr4Z1R*:.'{Rߛ|DJX}6Cc=Ҵ ׸8% ]+^ yU-ʪ[V~G^ T DxV_2"͊OPS[sUPZ3Su{DFa]s,utXL|*ꀦ)C՚37ڼ(iһJ.v] e0^A}K3㣖)8fUHΐm$眫r?BӢ83cRDaX8y9#RҀr&ӑhYEwph찫JqsU5}(YlX"ue5'[qvw.#\EgGNͶ[Mo8Uha[&:*'B^~t˧OEgȣ糯RphӞ7/@(ܪY- `EJ 5 3Pf|!u=E;١A.K^8`BJLQݦ_[7n:#7o* % TSԖ6inidUr Ljw<'qBZ?uj-uX]r! fDDc2~\ ʠUj!^_b}n$Wߘ0k:Ɔf;j젠Ca܏h`(1/H6UjMğ^k0{wb蚪[LzCM:oՠkzb;)ujdLnr)9 Pynz=@&~ HӘo?j r |#7Qą%LMMKqV$+>ܵ n5۪ey(֢fBԙ ݂<{Z'T0:*5jL Yg1NAYG>h͌+a@{[Ԯ!ޜT BR nTƒIIXҮ(4=6 sD d(h/oy?@ɶ!Gg ]Jy6YZ?!&l/!ִs(y7oʚS7}j҄D- ,' (È#:fr0Ǫj[(2 "l$SubgLf!bMcxuaǬDo7&=`S}]SNN<7i;`LAw׌x eg5":]JAչ?6($WC eN2oZ*Nra֮^޹{kfq-, gH?5űqޙ>럔ޱbO8dҘ/8Dȅ~.y 1!2b%798#%ى2Mt5Bb %-lW];_C[1VR0"UEs5s۪t U%~.zDkPgڸ.Xhj.S7&'N6lY&s*}JՄ?<|n  }7`zy?<6kjQׅ;UjcU~\}+h\z=Ͱ$&GAϕQYv*jL:+] U߄,F(=պXM""Ƒ3y ~T= '/"YQ:i9G@J(2jȳ.J .q2G% 0d>|4^;Տ |/_?{`^#otʛ7_ ?^WZj9~*tw0spv/+Y:5D%zʣR͕:2\%TcܽϵU 1pY*v]gT-#:*ZqDME֊I:FL_ӈlLhs:m)&%xp0A8z𾃒LV )tySU˜/w{:׵89 1"^κ흳@4#wǞ-$UD\}ٛ/uU[Є:o)XdO1%MD0I=iv-Jہo8FMS.X C1lԑ"OڄP6W/ٰѴsd_$2\D?냷mD zޘ>FDz"'p}sox0.xEM+hTP=T"cFu_`g>1978 5MF`eH2!Wyg!xHMx4uXZT9\\GhUnCw4<;a8{Jcm뷌GDZ\ixT 9A>ox6K=]XF}_"JhP̺\:SBQƢypTQQn NGrw$ߠX !8*$TYhRRzYdQU0C4Z^C Fg_i r/@WU4tq_cC۹S7Ņ48.n[Ҭ>12Zkjd=jfr/B@Nz%vBqy{EӢqbR % "drR ehpMØ n.;xA^~N9Ƙ8ps}x(7zrRp^;a"5}x넍5Ai2VyMGPˍRS{\M2Q[3AlӮ^ WU_d j,w\tdm1墅z6_"L(c:ZvK8/'q*r*?n}5E'6U#?NxE][!>m$Pu:Q"5 rY$[MU*S ~*(fYWMRVi]NM'UQu(G }#qT0]ך9eRQӟ:˘eXxFVM)8-4guGU#}$A{9B_W WǙާZ:)dhm[&s~֎b:Rƪ=-gAqģ>Nx[V>k%z xZMSQȉt,h8h ;@kyI 2U+>(bN&'n3ӷ IGITQOhha'yL~ЏiL^>MjسlNյ-IeTѱä&٥ˊBg3}Y{>jJ(#<-j@~cpnn7u]p0сTd('ʋ|7 9/͑!m.B1Knp {_U{Ñ}S{x˦D><8t覩2QVW8塚/ `ت,O }pIwJ4DV׎=kR֎!FG]|2!>9jjvʦȐjGTśA{nn>B lƢGSHuI9!bS$W20SvXN&YSt\+xOL袕@l])L KhbIl&.X`S̆dcS#Q n\܎p^O@7@MF?r;..Q.P|W'cO:=Tq.x;Q$xQ^pCǗxMBR %ELE&j=k5kTݷ .W9iwIV\%b4N#;W+]<8x94c?໎?RGN+qhN/YRukff % ڀ9bPF)zCQKNvWO4c&a,h?.Gt(cY2078E 5U*>לWjQلpN :MU@)VS!:Wt\"';8W^;V%2r?T:sU8'>}KJVA?o.:?$ ٳ/>/\8qG<ii*@h:Ov@DFИȣy셀]3Rzeh zhx*wd![eN~ec[9z)蜼ªW3w:RMt!2.@f)#UDKO'b@-Ácdg:L)QHʍ{蔗?"g݇/9\p8Qr`?cUc9 @{=w.v4duDHxu85A}kZfE׋l~̺eY?9W#GRuL6쁬=mLh1u)Fk8Jq_" dlΌ/04P:f/Vm'R pqG.9'rWHaqiDkOY;mN ɷdvDԯ`"l /_WZMCxDvzn9<'L>U6 F.po ?: R_0A->{$SjhHƁXOǾ[jddp>ێJUˮ+1HXcj8l=rbzut5%f.u0"ڝ4G6a mXD׋&,$Lɕmι+i'>OM_0R,0hL2TnBW7j[,|MWKa!%M K197KY!R OTpZ5cAeɚr:0=nʼnygwU7[_|srN.9;;ǝE94=\]0)=ǣ5d[ԅS sz>\ㅾ$sWz mD #)ekíeERsr]u`(rT!Υ~Ӵ"6.WYEM0$ qzzR1(#".4ԟPP.H26Fo2?]P=.ӑgƔIHp=8ir)@Ga03&6 6˕@LlyE9 + ʺW3d祄ܦ2-t(R@R*.Oov՚}sqqcIqqN p ^.=N,wa*kS{Vxsu7Guҧtn5#‹<34 wG#:<]Z 2 %BH/hcDJjj݌U鴘Km."չ,- Y~=*V)L'~M⎒J'DӜ"S4ـN.d1 +JYGoG{ZY8E/yoWLu!`ZJ$hTkS$eV- t %$*%\gn&a<}ɔ󞮽9!q`Z>X> ܮqE3BRapͱSK- ZGnT<SN"[j}Ƃx("g/<j_*_| '|—/ć/5,ѡEBW{SL:*[@Qoܡp«0LچD59VG-MZ*<{`e㑮p ^R:+uSK>8tYrR6l9 y\\XpN XE>iH 6{O(|:,6sҜ[ʭ ͉rw)x/iRM`Lu+DzV"KVK5ˊ0ӭNyfQ;Gi>۪d5t CN0C}5VL2QxWbSf'*w=1Qi]nuW_'\uY;{:rg9T}s/Nk|uڙZ`` z]'gn*{hN}t }3U:dLÓ`R s$L`6^^q=FTm8{$r9׮W|ޭJZP7 iDmȳK tv*p5 s<_"ɥ"*BL^ic5n;Ui"*"eJ<xtg=Vqj U5Gk/* X}~4\n?_r@_nY۴uTLt9k6蘹;q B n`n|{6ܽ}Al\g?7]:_?; ׼x\*J188==2'q\4 /AN(1r³ahJJ쬮2٦R'J?shy+{,奬f.WMLaIؐk-&Dvm~ !>3cɌet¨J~χco)R("n# &eG/;+L5󡠄'Ӭ0qfZ0nBI*`(8[(g&RMWs}Feeczh)ܧC-r$5[Feՠ#4 S\^|eztL#ăr^O:3׊y2*WӃ&Om/~{"Ϟ&X<{_/BVK2U AWȍҜP<<pwKw)M_[ΙcMSЈFMFBK>ŧ̩mH2K~{ *YT ~gė9) JzPlE/kcɃ7>W9NB71è|7 q{9q߻Zq$O_P>Dh˗gOmru-|w0MTGGO nan!EX2AXFIs7 GҡX6[U)mKzd[eu] h V >8ul2m+U241rɔ2V-z9E^?tuE٣3{K"&pϯi!'9BBw\A+[w0 {=Nc؅'^_P SLX,DkG3Le5,zP-Jn%l9n0V21Gquܦ+Cդ'эd2GEt7P0@^cZ+E?#| _/?oyQOlcf_k>{uEϸ%"#>1x$l**eA'XQAzs{} a2q:xO~@c Kt]:.7&)%R!gSˉJ-}gO88X9XJjI5y4kɯ7ieHq9%A|wO\t%UQw{\\oRFϣT]}^,*hrUȂ>yv25/C^//ѧn3s:dW]'+}J3ILHH;k[Lֻv}"&rI'zী[A/a䷿~[ *&y|gO{B)x9 ޿ j&;o-O+X #:^A# G;^ɔRp{#8GԸT_Qf$*yFnm?SWC= y]gEVݞ=5Zk%)E.YN9"ѦEm QJLL,q0krr4ΙjMqP~.s22h#dn6ҹ tdWݠL h/vZ> Y#TXS|7:O%m-3U7*JNoG?zpoOo)}PJTTOwW tP0-{tsS{7r %\S6&~)\^3edp=@VifМ-uL\["B̿:4 'Ôm j,t4+jOL*aO6-S*XEư'3tnS&ނn/&GeŬ,S6Te.j|W}m U'1{X*qrnk*Tʇ<.-w6֭ÙW>8k =#@Bڣ^an=}xc@/u;xVrF-u:v~;oA.!е^L3aI# a"rj|uH\lSn"iMcDx0ncT<]Ed%!Vk( ]5(eXNۻR74֧;sNj̽o[%lx $Et6?q'jWP_ SB{dlMat'ffv`ۆ>C򢁫Sy r SYhwn ^v%v"]0ŬM>jf-*XgG\eahsa@զj5\uIʺѽTl3#O>~0 ]Sޣ%}4_}%ީ"fs v濎^ȫ*~l3m Ǟ4rBþ w~ǀtԣnO<˔9zϯIC*Nc`+Q\S'P>zv -f|K f?լxyᗿ7y@05? O_յpyU:Lq*fݾ_tn8rnͬ"۟{W|9p/#f}}4oɫ i@ yF8;8jPPƅ1-Yj5AD͂!Ç{>M-1$k>JmqZ'Վt"?jܤ2K5$5pX1aٿ^ӻ"p6<?U/n{ Lm2SS<xRWj$@uўM\BV\3rFl@o2'wH]s.uLAf{v۠Bs$(Uuoj_ "T 4B^:\[t-!@%fsd&4Pא-PbͶAs̼%"bd+ξH~RylodNPjcaNB=XE*_1h%F ӵWHy>FC]6hqO܍laO-<LjT@㜑|Qȕ~81*]D$DaJ"c! 'TQ ]tU0AL3P)ZZ%N }ή | 7cv-)xi)' -wrح``4;@X0O,mtfсA5`0 Е.Tf.mҸGwHgPkP/ѩnd(#U0zgN'G]k+WU${ F G6-"ƕ|V(U-R$3ޔf.ږ&DECb褏4h_YzaZjvS7n'c1i9WBͫ8Ij\B$1&S&BФis+ɉ AݤB0Af$.۫z2dAE;遣Od9> ӳZƒ-xl7>9^n3H=./Wy2/ϯIqNCJ2+wI fE[DOTuiDt5©~rh!(fs{,.ܼi*6k5iTЩHj4֐:ZTh~=ƙ&+Qp9IIMs h~El3F`d {̀\r^Q}y@Jwe~ 1~BDtMFY%n&IBu!4"RG5A SHMQfʯeeN’0%J<  jxL;H1ADޱbrZ =.T{{g3Ԥĩ]FSԪFo ^No֛z@b YI@fҒ7 x~.߄&YbA{~By){ fEff .>>e @-QJgE"TׄZ0nn;m7uHHP om3ի L= ]TԘJаˮ3S̱xVɒjHP0}79F=ˆ M(1Qj2f=g쇹]қ55 >nLF=($3i'ÈxJEtNjQ[-Et >ae֦{%)xQSyPs1k} Ǿ-[MK_::1q` cIFdΘlyd]sX8+=E{|rFvB03ó(__|| )U:aa֓lu$NC‰#4RiS!32CmYVӏ Q-<ϚmT݊sjP˃>\j/iQ“\R.?c}E wz^6t:~(*C|2K0s=XY}Z-'wy2QM(N8;3rN2EcZZ "%-tvsfb㨤,uXR=S{yCQ3SB P&j8ݘOvwU(vI]TA$7IJeNNx#G?'^AVi*#T)xKhj1\="{]ڕ^K\w]5È `jBI⮡ |kVK}R2w11[>sAģWGtѴ>`+߃UBsfSp xg 6l _|5G+OdC1Ж>oQ|ATY$:ɲ]dJD_8Qd3%AfVX.RR«ھEX>|}Z.^p TlP E܀rO2D?&RM6)[M4jKA6/+Xnr_K\\J{5%!FB<#$IuZN~尨Nѕ~YbC7̰g ]zp +tjs/\z~Y}EoA( \xp&|ڂmO0qY/U=Faa#K:mB*RH j P6.x )f#R, R!F,0:~\ pk]f FܒIr݃`K0/U@Aׄ0"#כ.n@,)dHf^a >!Cc!(̄ӤF3ev-/qHרq\TpKԤqɢ}&MzWdQ*UG5rxww>AsO@ PVlpnmE< <8|vMv`I]Ai<o4طFA@KsuI 1ITr522,B,4f8PEky6V %$^ YiIؔzڣHRÁ&D](%9 'o_ n/e#qeaPD REa2}o593o3*BG,x*b Dz%t$uSYiDMӄL IU#>:wFyqC2Bg9:By<׿>UbIgke&NQS,dpݶY!_4FyLOc3~ \;.9#| œ>k*-;bQ DoVHE$ `a !D7[{l 8,-l<:mddQ扽'rnoR`ZnY~l@9ݙ鑥\/jR8e3nް*$ -VKMO??pH3ҁѨ@:v( !!MR5UϿ:c:=Kmׯ@]Xjk dq ʄ0LO< tR_[\[}gg[7L "0ǻ<3oMR 77'e=|d%*mg:׮o2uIܬ,Zr]*d/Z2sPf g)A!ޡ%֣|}Y5 ]WGh ͻiῊݭ-+ٞn}\xL!`jQ\# Ӂ34Klk掩*]uQ;\\dOYfmMn&9| a;(<\}Yyx~o@=Ve8aw7 sdG->XGϲr:B0~-~a7{ROj۠50Q\P2~cE2ڰ?7e/gS(*t59]j Oz\?(r>9$wq&fJL5֘> gN#x5+땖2eO31D{. `.{Q85^e)LO+/> pUMo<dyٱ[",7ۜY^ԳTfe{8ۻ #=LVZ_Zlt^ Z6A-N?ZK{,3?_LM _2(v|~\l,!w"0ЫVq*b3 שy]_UYV2G ZVı6x2Pc4H#LW9@Շ:,O-4ٮNjXؖU*nCD]2R6M Z,ӡjF T6'S^~Ax~f[K [׾[w酮F"3^+0ێ2&mOudcRNUVK{ X^Ղz[;7nqܸiܢ*IL/J&M=YmMJ R0 V".*Pn,cMjBzݹM6 bPN~|R.LW7MjK<*^2)Qɗhٴc>%gɾy?</_UqE~m7(5?ioϽvo ۻBcdxx?qa_̀8eyw ˭= O!c<6tLHY"nqcw _^aRIU[};s{ӆހ)9.peo*(j:QStK%iJ ڡqJm+bסG.!^=oʑ8-ңgY\*`EZ[V4Sjn۶,r%:VuZnk~7|ǔ.+]8{ 4ZcbŖW^qqaas_ߨơ0Lɚ)IL oJR޽U{`a8R ݅U}.,VLBm* M0 %PI׼K:AzxM㧈cAd,괈k "tPJ|1(D3`@p gCcj 2N$&jU8sZY$F+%cnv8EVA'I4>޴Rۙ'(T (3^l4 |U6)^"#^q@A3̡ЊYh6d@AJ bo%@HWSN0Z8IDATceڠVB$@OJKXKJP4-*^ j]P!ZC tDW;ŞTք6! CAݞemy]ij~PLOTgNh*Eໍ5|[~(Vje;-mw@ESZ/v^_ 0 iq82AR_BNhJZѕ[L< sWI+5p@1f,)L2Bh{s6UTv%VI*N q%,Y'3\׋rK]]b*8CO+U3F͵7ɠ9bi?3IGWHͳ"Ա4 Axr >g0U3)^٩FŃDY.Lj h*hmGW.נ5-P- F r$5{ &ݰR06JJ⑑a'RSO|<LBϘ§K&O\K'xSW ϵ8:Y-*(I -CW v\J/a 9FabsFQz%|=I5UqR $%BԄ(ɚhfHhw ROn A\S[gL0;AfX㫇F ^%FK~HC kl׬L[tP)UB3S|hq\=-a+h5wrxTuJ TH1]`j~*W#3.U OXU $ (̇N͠hn7hfz\|l_|'9Y!ՍXMU;C`+<{)sP)9 = 5*a|x>>W_ !K˭TF1T+gX@P5bc܁jBgUP$K5 uQ߻sCQf7&Ѿ!u*8#Ԡ;(n2!#P-/\ɠW?YIc@!?0DȱT4U cN]j&sDW@HrptTn2BAo{JkDLkguB3qAhzgǞ|LU|My:|+& zz]FdD3#MFd$˙AoNTEUc|FiB+UVN/`ӎĤ.".255M +I+L4-VŮ2:!'[d̵-]2-轪9D=x$S {pהW^9FV?fߛ ,Z9ƅ^R7aa!W`1h01855 u}LB#2$ʔ߃"^JeW8^fL' i]$Y[q."p[h]ce"GK˰A)$< L39d?[ apHYuޘll\G13M1%{uY/"lGUs' ']nsb1:UHa8h//Q#c)}LSgPSsJާρNH{VA.R|wKgt1?5,S-R fߙU~4A;x񲣛BE3ak;Rc!8<.U7:"qÖ*"[lGzQVfAwhod<8k5ZZtk6]dlZh䱰xz59C{kjVЯuF$ (L'DܬU7_x1;Bat/_<慏>/od٨z&Q#qYm'E.p2o.0D1Da̝6fF%SYGҺb,/И ,:O 67bNeN(4TvZM4 =cF=qFug|̖|p tA! ?(XGppCJQAeT*/#qŘ}0M0 GthelVithEܺYoJ6s"t.TّBgagAjw%A4R_bf?AFrt2ݑU91e$;en_xe^Y}J%%aui7g& #!0~Ch=B`7_b\/3~Hu9tn^oάk/㾰:nhq4;.jQQrd#Fj&8I LU{Et-C-23 Z@W=(d]'Аv^e|2hO'LA;2Q r#1efx~ƫW^q w\` |3|}̪^xrrIFw&Qj2&:Mh$ѤTWLײV0sqV'vKՕQD8kwy';mث8y7B<' gG|G-u&]6hĎ3 ߾tٮfw k¾?NϼtYDNoP먫zJ&D`=9:ۻ[>Nh1$@|IzT=o@{2PRG1jc_<)xˆ =mG=mi9_칟r`aæ\(~Ke~<ϕmJ%r(FFuR?XcpR|S#jFPcKDD[HU@f-4H=w/fW3^{oD5|ž_98EX ;[0^{ *A煏>FcuH=:,2zC8o|c j,g;# #anz| )Ho\;3ʈkV7׽?dTM_,o{5c>KX칫}z3@8 < r >]ϗ_l@Z=N ZIKdo+C 2-()$ԩVp!!d(ƥC]qN~ W>wxށ2`s(^7(]:i%xU~ly(9H D'ᱼ?sC˗slmi;ckPru`xL%ۿ;߾ nݶ-mp`N'2JIwT-=ۀ;8:q zϏn+Q<8{Fy x%xyWo_1J!%AyL%A+zo^ӧ9xוNǓWv/;Q\o>EɅ)^WKcsOZ^"?ldO.(ơխޘ; y?k_畓OSS=]s ~a5M^_Y,>^lZ'S3Gc6ZYw.꿅/}?y0*h/K\g=|7a{盖'Aw'}4.WjݭK ?wCzW9{?|%=q?.:?~.? >lz[K.ˏ;d@_6.P^U8%cT>|~}x'e5*\x^{J5⢾O  /4;<81yC,hI6pFYXY/^W{iu4ϻ(o!.O8'+< <{gV8'W|1 8q.#'Hч{;^[-RuBYGfV^Gy]">vLޟOf<>i+}G-OE,⩼kG;{Ng} ?Uat_\D @yd8,3y~>|Uݙ;݋h/ 8g;]>95~polYpQ:9}:wo?Ϯ y$+w~4,-2; < .{|r9.GpG b*yzf'ˎ 6ǥM3q,,O2,-OO`|8́fUK\gw8+X߰Π:qwkWW̊C\vg>k"c8{T"<m42{p3Fx+K&WO* _O,kπGExjkKs5DlVX WĪ4M2[g |"6p=^N2z"K.\N)naM?;ùQNmH d?"w;:~jT =3oknYX](K)}w~ Ps@CXP8MVTY]]a 2Ȏ#3p2|~ } Fn._We[M8?q'9:crݣÌ*sҹq^ϯo%ak4{f3:]tϻ'Nn)РᆲR-mw2c?q') t7e#y81pr>o%:{r2DQpIENDB`allegro-5.0.10/examples/data/font.tga0000644000175000001440000010727111057522251016610 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/examples/data/bmpfont.tga0000644000175000001440000016351111057522251017306 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/examples/data/icon.tga0000644000175000001440000002205411057522251016565 0ustar tjadenusers00 ((`H(`H4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX(`H(`H(`H4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX(`H4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX(`H(`H4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX(`H4xX4xX4xX4xX(`H4xX4xX|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX4xX(`H(`H(`H(`H4xX4xX4xX4xX(`H4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX(`H4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX(`H4xX4xX4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX4xX4xX4xX4xX4xX(`H(`H|Ĥ|Ĥ4xX4xX(`H(`H|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX(`H(`H|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ|Ĥ4xX4xX(`H(`H4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX(`H(`H4xX4xX4xX4xX4xX(`H(`H4xX4xX4xX(`H(`HTRUEVISION-XFILE.allegro-5.0.10/examples/data/haiku/0000755000175000001440000000000012157230720016235 5ustar tjadenusersallegro-5.0.10/examples/data/haiku/air_0.ogg0000644000175000001440000002627311421044442017734 0ustar tjadenusersOggSaZNxPvorbis}OggSaZNṮ-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVڥ ޠE5LAO šd(($Hd` S"* 6 `?` (bC?,b-x/^p:͆WJFTVd[C1H?:֬@ 2+58 gO;,HV A߻3>$` zH+b\ވ/M)-`(6KAY!Z>5P!A2 "A8! _Z*"~;](7E >jIpMDV"UZw[c=)$HD$kDD/"9r¦z g @' @O_ @Kz҂Kp n+` *UA%]'48@O DA2@DDDqrǓ_]2f!` *]p VmGBHDD>??>P1U bqr}H BꪗU%E0SuiPO  H?ao`!'pD`[C>*] @#U8MJtO E!"@z`1C |g\-F#Ї>*] cM ̏,NXO P!"@@yfY 3F…S}H /*C A`O  "ADD@9Q_Kpo#vB!*C $"DDDxvqG\ ("~[*Cp A婜 >IQDDjm p@xpq pA"Kd~*C% HEg !HDDv\mHHh*m($D$D^*C %l$<@ шHD)e 6 Z(QBe@%B^.|f2U<ogcxÿ9$@  mn r"*P *>ij*| 3zoPGD'@"@"DDCtZ V. (DH**|G # kCp%[0DDD.7>2v#0 P.,8"( `ވ*m6?|20oPGD2nxR@" CB!l.u{*׷@*"nEHj*]|v[a:W7( !"!Y-~.(*(TT HHj*x  .[r ޠd<"q32$!"! Ѭ@'7pa*Q`AAH"m|SyjU%yFc&'x/d  Qp_| H"\8gWBHj*.>x0@ (LO 0  ^]Vp(HD T$Hj*xyڱabT]. 3 `BDDD$$37(T@,CFHj*{64Ԏ]!yG+&'x?@H0"!|@$cq* \Hj*1h$}|ށ13mO D#F"$$"B`xև ?<w Dӑ!a]*AAވ.6+VI9 V6'x/"d 1b""DDFK|q X#*T Hj*8Vh$MYv4<)0aB1"!!rEǗ+0Hܼ' U ,(@ D$**H"10NG#i>'p qx Bq@HDiLP_ x%(  B.*HY70Hh$-Q|W'x; D"DDD""զ_p{T,T7T T(E>Ba b "qHY 4h$Q;0 5/"2HD# W?3~~D*t+  *\DHZQ464((s 4 ng0 XE$@ ݻo І)b\JT"BEV Bb%H.(q3@#iݎ" DHHDD <!l]"j!@DppaAH!bH:M;Pf Fz cO^""!a;hcQ-IRFÂ*AD@E %HU7 Fz7ЏG` .aLHD (P$ 4Q/F E@` P˅(A`HIpq Fr7П1@xGW9 *t, 0>`ax*] E,P(HQpE@#i9G#0@x7!BJ#""!RӝU  B\ ;F"!0Pa( " HzNp\I9  yOc"" VcWՆa$ߵ`*L H8s h$(0&w !b"$"-@%i#ĵݬ@7 " ,)pA  HJ0@#6@[`O Tp RBBBB$ k-pLEm` 0za$ZX\ ; ,@  H<xI۳ ހ?7cOpyxN)aDB$"w<K0AqDm@rEMpE,$H HzosA4g܁<܌'K $B$D""D` @BU@jMX0,[I@' THzNp\8 Hor16 ĄDDDֻ(DB,Ƃ\7] Iu_ T+b1,OggSSaZN26(SYW\WSU[YU[VXTVYXWSSUUSTMLIPOOMSMPPHHIB"Hop16@#qz)!!!"KwW3`A (B  b BG%Hor16@#㔂;b  tBDH.C@ 5" @W*0"DGU!FAmHor16@#;@Gx PBHDc@ۙ1F@An-`)( (H,"E\Hop16@#d&'KD EJ0!VJ/k40_̑Q $fч c%p)Hzos14~s [ aEHDkE@@(}@0ʐc (3p GGK b`H}` Gm_[*$p  c@ WZ,Pw\`Jg$@B"BHuPM: 4~ZpFC ' pV@R0܄  ,C" .H}`M4a* TA$$BB"$DaDOkPX/0ȧ!8`@EAEaeH}`,P~@#7O?63"@""BB""B@_[K`\EWF o~J& TH", ,H}`(H}`@} 40@Ha Pɣ P(` G.G\PYT$P(HuP|nI?cN_ধr"@JHR~m@b`1bbj ѷA7 ^D $, HuPM|Iʾ)Y~f?/@H7 RM@E"H}`4~{@Q HDHHӉ ~q-v RG€*H9v@ h$:(P( !HDP@!vEX XB A…H9h$:({V( "? /WP=XͰF@"9XnEA HuP4~[4*QB$$DB>aTOA BBHuPP>'_+'M "*tx68,Q.cD"Z#D (.HD*H}bn FsSMTX# LDHHHY Fc,@s ..*H?+F'O5B ԰wb˽J-* ;Pj€ b(HuRnY@#IeM?@JDD5π x(`2 D "pHbn &MG@08"!!!74j쒊@@, X XHcn &w`9(""BBC@ $ֿ  $pk#^UTYD\\p+H}`nܦA ЈDx*k?À(bpݦ`;PI"!.H 2H}`n<t*"""'7!!. TԊH}`n@#IeM[@)"~9- B5 ވ(H(ZDT""THuPn@# x9Di2 j "ÍaAA$bD.HuPn:@#Iip ƈD?S@LпP0 *P\aFDJD@Ċ$(* $H}`n {[# /T@R!UX"H}bn 4ি@FH!""|l,~Ps Y"ʅ5 @%+HuRn@# -`A@A$D$BBDm I ) ```AApuaaHuRn:@#)@`*"0 "0D  H}`n@#)` 6DHH(Pg]MEJ0p @@\hsPn:@allegro-5.0.10/examples/data/haiku/healthy_glow.png0000644000175000001440000007455011421044442021441 0ustar tjadenusersPNG  IHDRwmH pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FnIDATx]ے&94Ids-Kl ^@3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=2 „qTmS8*AvG@ݢ߿g[^Om-g;qA ٗ!=UЂ ᥔ!_^,YZ?=]ATt/)[9!܀ \A^h2qS@kť//g׮]u[ ˸0MY~ڡ_C(p-A\i3"?w7#_5ch/ ^`yx%ò=y? ^ jھlKd_ۇ^pqÓNϟ?5ߖ2e].K{ \Scy:xn ~p~? K=(̖8D1ۇҌr9el7/=])y /J^iժ{yFڿoUs 1)c +m,Qo&ބ]H *ÚnS)p:0ZHJt3d>@-2Dt3SfXIM_? rXٷ-Y Ro,aέ3&(S[.鏑1%pˀ,KuQU]֠ -X6׆tIˈV5"ZRlxgt)??hAl³t6&~X9P "`A&27#n gaÔ-%rKo7.{((-ʻXzãp.^`艊 ˬ9>!gPn{!i2<3 +mw^醄eEx|4ӵ_CL"J`dhX,_[Oaa R)OP@1z&(+eD,3K n %o9~S%a,TTS%fQ)[ӄ-bTEӘ62n(f'dYUuDE94{90uaL7THd_rɩbIRV,%r 2+3 ""`APf KCR!ޝYQN[Ẅ䝼: [,)*&Ud"$"` cU<0gƵ]IOXO;+uɉwm&𚏟؊[TE1Xw"> 51sPIE%_Dyy*dZ&:rs`r%Qr³6:tK( S,2"S*  %--![xl.2>yu;țH2}|o,Zhk>_- ?t[F~qlLxNZ:Eb],^naAFr=LA+ݮN/BvxCo ,g/Ĺd$˒v):RwW6Oy"I0MGZ䤰/s[.ȋCO419׿ Jܸ;d7bbmxFVגu.L^aiC>K-ӮqfT53n #佥J& Urä>Ʃ[ _S_،dZ4]h]4C$w.<$t0Zmf֯i Yn[~ׯ_`&d\@9ahTFGKSZ^D|}G6并eq.|6o Hƶ=t;t[Ai#|׵( _zA6R¹ٴ|̨js(ݬ-Ak`yx zيNH6e%f$2V6$}=eql&s [m{&+8^CoH N$řɢh(oyF/I4%mʖuB܏v', G er̦[Q lV#P,K3ODy.x׻ 2CsgZ,i&y9t(77}|ULeQk Z~^lUv2+ 8;xa+lokܰ㙽%I֩oϻa V`ed*6ϬYr'/ʫJC{ctOr&[:.nyR5Xdؙ,¢ܥ0O3da)#s yÍpcF ) iX ceiPYw2Àsx1jmfת09FZռ hvN ; gn>a-&g%8x 8-eOU4bzEK)`l15`e,uyV J)C͌ҵf5ueU6Fo\=^әH}%[^l"%(gnjm ~I%]V6 7mEyk_k}WX[ZSqɯ[$\f/{oEJ fVq~dpfMc[ۇY峤=%΂ۥa QR=~0[z=@ `v񳌘#h&ˇͪi^e.;D788FfȧrKݼjA=dw&¹-mus@d 6˚kyi.+J9 -nM"-o@hkVuyRgf/l{9XToI\n9J2 7ȦKR3YzńJ2cJ*~{0,,0h?؆jf\RYYw}/!1c5ܚl8S,rn&v/oQV]lzq)r64nt0۬tok;W2ܥ|ro`E5VP3ApmCo)`Y`aCn%6ڗd_^ÅX]L1Ѹĉ'rYp!(g8DUMv6B 6}K歩2ܲȹ<\XA0 dJCg.}:3ư"py.{IY4*oU],Iܢ1p.ꦇU=HU)6λNwUgP1&)E;aLҘ}vg [R8,<+3P!ce>+;U(qvb0ezjǼ Y&[ơf:*$,Oiڌ2G:##Wf4N|f$V[mKk :k焣E_zP=ˡb&)(?f1Ӵc_ܲqVY5cs BHo;'vIռɆg0mOp3Ibq67 xfcD'y/ֳb΢l[*/-vyRi$[1ZT5.YS$Yě$! *n%ܪVTV!:@ 7m(?EcvS#@[-qFYہŲ+]~eK8ZNQgdlLٓ_#۳o8uL%XxH`Ʋ?_Uڒ>%/F"v<Պ8hldyV+ % g~hfQruFа%Rc<w-a\4z;O 9K&1:X,FbVN}xlȠL^,!g!!wLjOɳIYFz|;Ĩ_ns80eĖ39]x~˷?!18ȥf;r v Ƞ4H<6bg[g1mHUKk4wİo6萃 $+#WagK{gP`o&g0 JƟT4$E24+7Rk֟d/n!C!GCG8eU6Obf=)a pU36h4 c˭"O] JrYE彿!Qa9kŞF{k~}P`{ &=faد3Fg1j!A.VaQU&"K[*AJ@7^@76[sBk/)fu3RaG&켭BGdV-Ƒg3哚^ByKgpיr-<ʮb~P2NɒlMD/Y5įeFҷpOrp~瘙̀kNҙF,U+ dvS7<-(nip39}xa2,L͘Heg ժޤ}ʵkUCn'˗0 ǼŦ"93!d尀!l!htisrœnn[Yg0٪1 3/4̘E89~t9k.雩a> LJ$eepn`)'Jk~xY6eY^6LȚҐq׵c_hƺ50@)⢭Pْ eQp.-jPS;[\ =HfÛl1 uRU,A~Dت:6?el1*T({QĥyXֲq"Zㄳfl%O>v"%z720,;`, $v.S]c^  =eSUVʀb[Yj:nm0Щ;L6$`[K+]I]':}/xkpþ3<.Z謉Jx[r ]i H;ߞ>ul+㻥3#@Ԛb%I&; 5qӖ حF/,~.c}Og O4VNZϟ?ooo gު w 6x gA3w 1 M*YkyԢ( r)1e_L 2JWIvTgwƲ<$cf!—t &C& [d <4c_@ː+dT6ò'rQȻ8[??gZ-3Ag~Ȥ)Np_n0>{v_h3efhu;mP &$2.%/Ƴ(6)jYF~lI6ۃ^aR󾥟^02Z*[1׳tbDK 2cș <gX`hۥےG8pa8y$!sȯ_%bTDۈ"'/ξ a^M9TYq|8[4ڷ<(̬k.*qtC.9<8Qڗ%=R #Ͱ$9W5^9x}ELf _f],YV8^F29W`C <yAOdD:ӸAdbf2|D[3ApIC.##إd# :08P,h_{j[w6C=&%̳$xjHAwfll"8V%7-v{!#Z87oYQ-NI08-q3(:յ+8X<^R~j6DYT9)[l2Ӕ[qU&_G FeX6PWYڒO@ 먙#wZV\jHgj,4MUzFfC09p߿NϸYeu^YV5[g1Hv˩ls6a@3-54&ڒwq3s&Af&Deh[ax)&3̕ H>(DCk+xoDn6X <2c_K[ԛ-͒ketŇM*_H؍rR6no}3Brc%CeM6 k`nR8SUD'UTu/sVs,=·Ur .+)&q%Wl݀Sy=7xQNeAOi3LhʩH:fAX{c)R[d2u00,h_F+]pF T FZdv፾m>xO<-D݁q@ t[~}'ZLL׾|3/Ɉ4h%c]!`m{Do<II;Y\8!e%3?qssFN'lXfgP=ԝ]8Bxn+f6?>>b',ٞkZE MDJN V$=̴__o `tf$4&Bqy [b,[wz.zxi[CK3SL'(z )Ve8c­j粤$Dj+l};kZoW &1Rj8RmDp+̸0 䭌 ?ت'Hׯ_[UN1. f_E d4Nلk3vkĢĚmNVMR-'eDY5 8h2|Kٸl1VuJ[{R["o~\!b#mpʸe.ox-(3D*'`}'K0XԻ8ekwxfYsٗ2nR6"GdY}(yYܵ\gkD8`{OL}u6mI._Z*S$P6ߗ\Ƒg^z >3vVH&KșeAgglf-_蒛C w̆z$"ai1nRpWAlLZO,f8bLeE^f!/"`r\aWI7|YS!QhKX+/Ȕu,n[n.>emPh(oLE8X)#꟱]3kLrTҷ"L.G7XYI۲ĤV1gqu4n dq3_?F yJV,ϨzMD7ljDD7!ĨDyc fCyUu-.O tX)?dK˜?2%lMfYՕuf؁۳uZee0Ody6ΚDeǑE5B,*Z2w2UCN* "$XbvDZ셳n4O`ĸFwl9B0Oy=E9!s &Zw{| Pf&&1FFTxe~7?/ hbRfD HSþ$@SkuN;Mݯpzࠈ 3ۇߢ22h11m*%ZL,i-[p5/9[nG.g5e,J͏j X]#~Y [ ey 9a408n]|6&퀥yFƭ7AQIXƵY;ڷ U|9'u0mkeDM} 'Z&kVeSt,&-*jd+A $mTRgna\feSq&,"Ό>!W+gkyV fmH yعU%c9,ȾUQ7XY"VWsW׎]4/ϻ1֛W[ʚN B2iJƜ6ە..ؼ |<j,jB"thU)cY c6U&0 L9<~p-%,|67|m~+ 4о|߰تKe9R؈$bB3<2.W@HIBRn|0vd<L&.ХGʴC xFaj瘪+[E|qV2u+uM(5p)V?06"3a!nƝ@.SCe0cYeC[Ӽud>r*PvL,   ,~AU6ڭlaJ}7SxٞI }ղNe҃P&`}pLd[,uWe?@fmHp4Ͼd)V&d"YeqU.%͇!sh F*uI>ԣVXӺ]u'x+&fϾ86 v\ b-}.>^%r5 biЌka+#Ն7[sW= oٛz-n=~pD>'X~]<.쥉jMllg~"Je{viʳ^f/IJF#r[~XcnzP# kAF,tǛY'BPeds|U%]O8)[9/t_܁w휜Xƙqύ 3kOJhT+\Ⱦ۲t`ݦ@!t"f&,3RH|#Qc]5lS7+;3#4Ma fyD+{]$,䶨'fh(;LZgeïy;ڠ['^ ,FۤsIb p1Gc}* Y%V .lw+Nҭ`2I6ueJك =G ƾL-4ӭ䳶.6x#֩#3νEq:sg*Y!gﶔ4,bFHw#$%G,h3ylB+|m}iv+z<~tҰ; H 3t#ìȍ\[|TRz;geɺ-0* 0˻Ȱ3 Lx宓(`Iny7Lff[*L2u0fP٢^FSΆi˝FoA7 <[e11P$7nI"+/n#}xke$oVQ5cC1-#pe%M[quKb'j;{.nE, w1fA;fOQ⪌3gh >JXcxZC>Ƒ㟗g_#3||s7E>[ nRIZѾ7ڮqRX[|c~6s673"xP22fj 6چ}ʼ/iŵBALvd,wd'F_ :Mf-ԝ!ZTk?͖ 42qU{ +R n}+dC60k^O?eb+| UaBt!0Ukm`~dLeIm5I =Fn ;̭i*'gdH߬K-H{$ P4grPWcKm^8dK vEInCu0řq\MCMnS{u53|4CWLJPTtԪjcrvp$MXJN,4u= +sD!YLJwo1i*2f\KUJ*[f\bmKxj0t#+"%MYQHzİ\r!ӌ;WEa9qLYpَl61˓@-ż"gܞIG_es0ߘY_=[MidJcl -¶d%n-ښ79;v`4c8lgS.0n4kDCXl2kţ0O68CI e⒞B6=Lbyf r%d7Đ@N_2 _^+R^фY/.oq:L'Fw-:̒Pg-iΖ}^ɒ\7f+UT~vd5a+=| x:IouXc,$tl/y/3ߛ⭠r _Vبk2瞱} 3|tܖAe^w =Yеuzlef',x&3BZ5S]*lHp@k?RFuqP{5S-C9HߛØ~Mn6׳̚Ʋp=h/& D^Y^`'}N~[2vѦ|1noOj/B2=^g,N )P_mHa̿py*ZlK F>+_^bzJ[oiفn۷ 132)del~V08Lfr„ښQ8xw|)ʸL#,C؆RbAZ%Z qX|m"pk&t Of]9aQ2`U' ׂ̻VH/ә;efC˖߫*Ļs7V̀ge^Ғ 5n#.H%1RE8m0kΛiѭ=V;sm'cȦ-JJ {>E80Fx67um>1Mo%@L;4S:a8&yor55t_jX?婂6k7L6.ʬ6@:.%g-8m|9_)kKz.:j|u4 ܵзuO.c)Y5g)mQdd,` f{c#Ӹ^\V{IJ]7k8-+R? E\fLC/@zEo ?5 XWA=Q)I FŪ>[.vs(:HW9m2ǒI.}/!&:?aUxkXUbe/SikSzA. |nkXb`$VnQye[=^c-o-ԙcFWi0ntD98,͸ٌ;ӝ 9٘=y^e2a0ˈBXJr|3yPazӔ8O6O$lu cj U]7"6"v|Ta9N o;VXΥƸa :\XVboUl(ZԝR؟|).×dۗ. 0{Ͳs+OП$;I/*r1v7^\~`6Em/o+ k<"k%,sC'iF^_#cH6at1R{}ut[I\4~oL,njY,ђv8PzUKV \^z_xuY>uȷ)oi0o[!oC[~#k}\D?()<w}܈s';s/ Wu`0?xlw{~.zRgmH0'⟭Z ^.%oF-xƽ˸]d`rlR}{D{AgVa̟筟8]Ǜ %嚗]} F/ϙޖeЩ5}:)<,.w9(bY`ncIG%#Lo6'-}TY]o̔ۙ[s8Di`ߌs#2)l3aj<.+)J*B MamDO[g@۴Dkpـnlv㮪õBO_ɒe(Ʈbf<=6tR~v/9`k5ؘʹi4YȽ= ;dOEX(d`rM TW&Oa ϖ[U5eЪMAf0}%%Yl1+e]UrPUX@DHpuϸV"2q2hܥAH _rćZiLOvohu^}Y_ȰuX#)\G_ Fe~PVUzFD` 햌(ҦR?r$20_D}u4`i~du2jdp<`]–]G-iYl,0beՑ# A(G6\+UC㍳)rPD ɭ?s8`ͬh  EJP@[G7iwR*ҭ*x8OYU)y'$YJGY 3iֹƴ"۸ky 3C kj-KmL9=a@Rj4z,'A3v<͢Ǡ7C:fSylܽDcH!.26+a%۝x+Hȿ$Wp[wg4y VLm:uߦk\ZZ+Ǿm&qK'7*Zkb~lppzOoO]{pnN)7Jw֏{W==]b椱8 l6S֬>r<0na.>b&gU[_]-+4#*e 7->>۽[s9!kw ?PQyP eop/-,Mݶ]s̙ U5kD_;%YfK]+sx&MjIfiW**g#&\QUvWh &ͺB2bR̗Vzremv> ïhxY@WS8n!2fQbbfښYgd-Jwn)] \~M < ~$IuLO#ԥ6αy-n2X>RxVp1'+3^e^}K~L35 ab+P*?t8!& ߭|r)N]eyw:̣|. դP&15= ,OxUح! pf<,=YRڒ r΢̕ 9.k57|]V[O&WIW/ٍP1ISl7 Fr;fg3ݳ-5drW877-sRKF.%>،ؘSmN- _3Dm(gAؒ`-&/ܯSa&Ba1@ᨑ%|}3zPYR3Re|6ƩYFܺe7ʻsM= GZVYFx}L.-)iƁ4K'NLF_zSbYfq QWq ;ylMܯ~lBq!Z.32yL^|֗\j8eT񇘑,g}K-|FF|%.eݻRVpݶK1}SkǍ@t-zt7;iw-X'm N(;/9+ LȬn4^X#}][Rؑ ޲ ;0}YnsW}ۏ1LK+v ls;2'`sLr"@<nI 3ڗgYĜOd׍񥑥7r M T/2L6<3 #/=MD`I \^7Jґ$k.|)yQ)f,DʙqEJƌ8%ưxQ{ 0Y'`M!²j37V]edK*+ogl_%A_vY_,n(~|]Džu3wj{9efr]t/`1App7n:{> Z?hU?'亼\gOrAIW.W|Ξ(L^|~@V7j浍H*{Jװb<\s!t<݈7LKCY-@ԉtNd%]:{cXs0:ۏ ,Wue2n%`2ZxL.+k(x $5P)bL=͔H*;h 33񅵎K_ᗅR E x;E )ʚ ƂYmdi =Hi5 0^ݑ+?rm/yCgȁJY#܂zc% 2Q''d5j\.d 5'<.v~}IE􀿍F៟gxIGZ>B4&:sҞѼU_ 4 cs"AuQ>xV8Xj*9j7,dbu-;[pYyϾؙ)D&a8ypwr/ust3D(*?2?W*s3l}^W!=ofeBKٍ4`?<)C[˂$3n+_ֵYAxRVЩd0aλϛma ښ־x(Be`@iK2b~ժ{nEK;tŸ9⇥ԃǚׂl)X}θ +2lt<+˶6g᪈1x}ȷx2)Ky]k0kl!nxATi˂p) :e~riB6پ d8oKGHXxL8 t": t^9KIUċ ~UF\.?p{_KF3R ݟ+q_r|9&! Y(u\ ʈv~rṔvkowgHJްkV=/Npҵe/1d}3LqkMs%ﷀg0,o]ĶBy1)=VUG)U/)ׄD%\!]!_lc!H.oiZsפoeߺPܺ=Vfuk7ICWލK^-/z䞙 e?QiW놎{䀫ӗEk0jz,5Slw eI11gVF1:3 {fzɷV:6gk(˲U#c@,SR.__".Cٷ -pL6k[`LFqu=3z)`Қ߽p!ÆraO[foqAgjfï hL< [dƬ=/ IJ*Gs]"7N5ˉefR&lNp8Ըwr"gu63^"n5^ oRU3FT~jDX[G)::vN F;>p9xSRgDj+Խe[OdMn+21 ǶqV&%X%5l*H.a[fS|;dJs"M> U3vc 85$Y̴"w S| 8 ̓D,NE3`^= Ȩ:s_?~ꖖ!fy80,'.aEZP<>|]XX<ǎT.q9|~6Vy:sdgwvvž ZxRnkR8ޘob/~7yW5XkfLux}{Yq ay*,}E~J$[T 9|bkE|Sg15E>x!%gfJ\vXeIN&,V쭭n M>a9/K#%o©xzeX;e#ܵ*kc4scJMd)X.8;KuڊBTg>fxi*yxi[#3쩲1k V&!h0/OB0S(;%*2jLyIq:3\I8I+d0Jl }c^1g@hP2eW.eV5R,fPWZ[M&ض:W.<`_ܝRbCnF.dK?j3=AZq ?o9I>:_cc_-g-j=MpqJu!N7#7_|dw5N髣S.Ms>i) :y\ax#+e|MM0+rޢqsv,kC0 dE/9r͞opwHBQFiĆLG:M^$sXNBf؛Iw`*Zwi}q`C!`ݸA:Agg~-_J/*_<^߄m̗I7j+?ʪַ|;Cm%X%r[b8Mmo<;wUc}"0Kݳ|EhAL#ۥSǀ<ŸT.yTymKL 75jJVOVz|IMR lJv%4.p`~aȚ^LJ؛P48zע{#\ClpFFC[uCeY#_*{@the)P>-N|B{f.6>^Ud!K𪅡^l"Wo03X^ߐWAo3Ku}ͤ3%Ե-; 2snikkN<u Oxss9;PZ-,^u߇ܠHAm:]Ŏ(ZX"f棸&EY7XCʾ@=5pIX.o{>iZXX+g0tyG4%#Sn%<}HCnZ&e9l$adq6!ԩp\~mfw|u^~%fQdıɼx>Pr+sIENDB`allegro-5.0.10/examples/data/haiku/earth_3.ogg0000644000175000001440000002347611421044442020271 0ustar tjadenusersOggSi<\Lvorbis}OggSi<DG-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,m@v9h~Pd@c`{0y߃ **"VУNl'AħZb*202s)x u" 3:x.ksUxI"Y?(7 p1`7ꁵ&ۿ#/::΄K8)a޹*P*<_"FV65 s!R((!dpx@.U#J{U nK-yU÷օ7a>G1&(?,_Ѿ2a>싁*H""ԡx;6~*I22;tZ H~1@G60` H&Fp&DzV'sU`FrGOԹ 33 ^88N1P QY!"" Z<H>@˞<=Ѵ, 0(@^*`Zcxn>ls{[ltJY݁=1Zy蜣k鰙fc!@~Y.PEQYJ*HdpA8W_45,p`"}Q2sC'R " BP ".~ cĦ2Z|G<5 Eכo6?^Aj?lvKd01Kmnr+ch< 4 6 @>Y.FpŒHNd=xuD\}L8oED|Pa\BPB$@(7C]x~>@>om"Σg>h9 \HPAm]SdbW| PGw\ 4y7cxƃBdd#!!)0:( ^YE``v\|T]L;HT^\(Ǚ9:A$%$Q=_P' ͗?y[ {k} +0L菐Yaj ;՚ܗD 6 L  I{YYL{QGYX]UDv2v2hs-y% BP((~h_fWo.Q^qy?1qg^{=9˧2؄X.@r臨+@1 n' ,h NM@>E]GBETz2hb,MQP$]Tno G\dGh&2$T1JQ(D$!`f C'vd)[W@Fnkoǫ8l|__uJo_? c̉րRABtIC>YQ|;wQZA؝ˈ| {2' %8OvԀ0PWP( +2 =xsO|xb+on>v)ԧ/^ A{?aXؽ s~`labCD hH&:tLZAAa7ZZ`.`!  {7]nR|m@fk vW\dDt-ԅQB$"@LWHk auTt#/ ~HF=u/ /;;tLЃۑ`$T 06x4HIi`+@P ۣ1ufiu9kq ͹ь|($D  J0ߵV7fƢz٠`O +/yH 8L _.@i: x :CC*H 0;4hZH-.J"K\>JhȀ<&\dW\( #P(DD\{ 3Oc;Gts`mc`ޏRv?{ЗW|AEgn"t6baS;aY:$@`v4rVuH I 7Z ''@.Q($I @Lbno-)&*6 L9F>{@Σ߷)ɠ(vzC#y1Qģh@0LX:$~4H:IAVlI`? nNyrt&* (" %q{+o~-ݘ/fc ym_U>|U.t} ֹyI|5DU`@0!) l $4AA@CY _AP*hcD(Z&!<d[gWJB %N[wqV@?}[t IWÿ<^×!  .o~сg M`+x ;ttX!'@\XVȉ}Xz0N 9OE̅B"P (IB K _^9B7/_lwY!3AՃ!\/F/)Hh:L4  I$!`Yw A|@³boL篁aMfCr# Q(""""9 Lt7} A_g;ڭ@g |]oD6~{s (0HDN :DIB@qB_:,}!OH?+ 0!6g'MBFDPB@>pW~M ؽ@!^ύ_oFxc,]BM+-z@6Ht+cN  f" %DDIm:P|*zs`?`/('dM̖6 Iwc5q& 3!@Hxh$Y`iXx$$}T h$!$ \hcI(  Q" ^$p^')%6yh 0[ ?ow\Ćl{('`u$ģAсb`J0&:<6;<&OggS=i<ث{ztcenhgb]\W@IɔG;=ˏRHN 4d zSqCgWPI(D!"JBPNʮ.|0Py@4D{"zCkb¤ [hmC)L`&$t:$ Y _`i\w, d  "R)%D BIio XbxoWmD_E_<%(lt&4Kƒ[Fǃ&Φ$0Y^0O`!@i"K,' E`e9rFD!(!"J([f?yxÆx??ACACXmK ҃@`! I _`PHwnd t*r4ƒBDI(IB3d:qذ?;<}+ ئPǤ;l&4JGOC0ЁGhؘ(Y1O`TQ ;DO`X䴅%! Q(J( }V 6$?rFFNsL$d6 : :NCǃg"ӡ$6Y1wH"K? Ybu((! {' r{:>'@$6mh6]!)B|PHxt1$6lH6t:lI5Aq!}|P Dd5  D$$B BAxQe<d!1;}I 66:Ĥ [&i2YY(7t,$;  F.QPJB g] @xO;l7 t рDoAtx I(7t$$7;8H0"%DB Uy^֏yhl16<-Ц@@AHt( DYanY`n@"xfD  (DD (Ps Xx %ؼ l RbCAIGIanYan@DLsDhIB$$! %I$S~U?>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCV0|{qzVooc*8H:M1N4.*xΡ k$?Y3HG܌(02k@恀J"x.*Pp+H шUCAሔ oU7Kǟ)rcxUʰpD KHI&&Ħ埻=(?ȔEA/0 X"!"Rg=rV `d%"*H0\,rE/i3 dVp,'.n(XC`  Hd   ll|sB@3p ~Z Y*^rS7mҀ`f}ON h@k`@$  ! Ɣ;?\Op >"">2]p7eЀt"S?ws pA k {/w. D8b!!!qqrEp'Ѐϖy]Al@ P@$` ! Rϟ_5?~HHHrY œmUp,A@x;7`5H0@@ s*g@` ڗᇁ6rE䓛4h01 E !  o@gUo8q ==@ HG >rUp- ރ7g0 ߽- !B `/@{G r] .=ii S[}›SxP5H! $xwٷGS+c( ވYO* ALdɼN{'XA"%B"Ĉ;ѶytN X~\B0ވ*I8AYhD",5ᑩ~ J  d(FB"`I8~N] >N(ЧPeT R ވ]pt{悒iD. nLX!0@2@$HD7,v"\> xO#ЦBH .ވo]=iHrSpc%z ԐHH"dPw ?B@ڰ y(Q-.L€ވU;A QɊSp7?/NU k #"!uh SHpXH .0,.ވ=hH6[{Olr?Ћ&kXC !"_$ I(ވJS 0*Y܇zF%@$DHDH@e n:CmXI,T,$H*dT,ވSpGd&Wh!, $` $$B$D""~3ZYt* Z(G  ވJ> Lb"Uu C=xP/NU "  Jb 1X8D QP,paHJSp@FT|8Ȳ?* "!Ǚk0. -XT,n .E H*]Ca09I ރ^(DH~ ^N7 DDvP_[ ,)h@CRbX ) HjUsàVIk@>@&  "z %H ,vy2@"HPBDH AA(o;j4-|$`Ԝ0"!!a 38c@p {,\ rqUndY`@ dHwp HEaS9D?y Aj$$ z}Mן S 0+q#"BT@PHno0 hD*|bhxy`D ?a8 z@Y؟"Q EB`R ,$$DD\Ho RIuxP_n8M|²RCkp E.+pa ^0, 2HE7hAFRz;:˟.XL%$BBDB+/RU cRIP\~!b]P`!X Ho0 h$.{C!aLD&%"B$"GP T pCUa D! THo0 FR}:4 u?io" 1s|mPhDq[B1UVBU *8#H@e"*HZno7I@)!%"$""޸N@ ;R;*yh0HODD*`aa% P$ BȢH^ V54eE4(4Ó'%k|D"$D WЏ)]arRa.يVe) ("$(TH^ D3U@#7N'w/K !"!!3 fR E, .DX( T"HHzl IkA0h | $`0!uP[:u•7 `K'Uł Uk@H_ I*4(M3j1"!""0BO7[.K~)@C̗[P2XPEBa!qH_ C*4$a@ I$`JE""$D$7m*ZεÐ`뽂{ !PJBWH_ I} Fa3gqDHD@.HM\g\| "BE H] 6 p/izBD""޴~* 5kߛ2.@n<Y"%%Fp!^D  H^ DSI} F`3gu،EB$h\شd~ePA;Rqݖ[a2\PTPE"HuPHAlYh$}RqU DDDxWa,V~Zc0 ܣU9()RPUp!`P0TH> C@#u7 k^lDHDHHh`%3%!ת`Tv L@`D¥ @cH>  `8 ,A (!Xpw1ٿEPå@$@d+`R-`PXH: l Fco<5"1QtRpPh8 q*.nP0P . H> FcoP7& b8TPn0 .2\ Ċ HP`@tB@H9 Fkko < W!jDCiO`Ld$B\C .TPqqU$ \HHuPhAlih$}R~x`R5DDDf__H4Kqp4{C%\,tE \* \ HuPh@54~T03 3_`@1"!0P C=WE kNEFJR" HuP#XHuPm`^@W؈5 &"B"$$3e5*  _# !JMEuMB&Ds L @Ht@m$ELHn|KrͯU@uT@ Cֲ   "" Hu&_v@5/+&N@"{(ЏtØݞAC߬dT!"Ȁ%bAA$˅HuPM@#d7 7pEB$BBBtp==2+8]e)(nRH(DA QHuPNC&<PBBLA4(*CadDEeۄO JHuP v}2x'g`}s ^_] ! lR b D(u0F *HuPNI'Nn">~A1 I (@>!P@HuPkfh$:  %pJDDDDHppƭ5 U' g2XE=)HXD(A$rA HuPsHuP jG"$$"$8#UTr2︸v.* 3\ Dq5(H_0'3~#)HDHHw<sNu2'VD5 X+ Hcn 4\$D"BB""yܷ|(P$`0njt"H}`n4~{`ͤ ~SpP#(QR=JY`8- p` "&$0`1 XPHcn xGP p XPy_e 6I^0pXHBn@GI}P%@B$B$$"@%}`@ٺ cݚ%w$W'_ \${aH &`6( Q$""x<+՟-B,K@5" X.XHuba@#A*;@?]@Y"B,}7DEK  H &_澚0TO&$$BJHgJG\DFH  ** XˀHbn ܗ 74tn  HDHO-V[z%bIz$XH새B Hbn:@FNFүr4g`WdHDDxi0@}٢r2@U`)"i!R,HuPn@#NixJPh@!!s@NOR.^XF ZP$D0 !AEHuRn:@#I 0*"! ~B@`e)пBballegro-5.0.10/examples/data/haiku/air_5.ogg0000644000175000001440000002007511421044442017733 0ustar tjadenusersOggSi<{Qvorbis}OggSi<O-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCV rb{UنP @ ! [HppTA,F$X~ɢ Rszr茉})6H@Fգ Ua> Vep:2|k^}U< D@s `YM/C_:`ވ2UeBl 1Z*4k2X `kˣ3 P<DXވ}aZkr6e1E_z O@?5 ` !"@A@HE7_D,0:nވs6 ~sJS,O} 25 H(aԶxq|p HmPчō*3ވbשִG(\wY# !%g1d k@P}L-)*p 9 oL{-,/>DވS%ڡ PшQxvݐJԨWaD F1!X[.gv67 \".ވ+wRS Hn#w>\l='GXPAHDDHHP( G6+(h7 SpCbB(p)Hb-wTLIpJbO   !"y@80|f @HTB!@!Hb-woTj\4r%3xR`@""!!!!M]oz@T" ""$ވwRT$$8wG4i ?dDHD ^8`a( Q(J@KHϭJ6=c䞇 23x "dD""!e(H"@2"@⢀+ވr RD#<PX@AB$DD"Dп'\3_H*ވQ)j\b5gWM]|O D4%B"sJ@kp  EB HE0ވSxwJQJ6q܃zV<2@H(2'Y)lFBz`@aRވJSxw AԳHnnAxx@$B$"D$"3@/q pEQ0PA0ޘCxOIX4"Q5'l {0d%$D""kChB>QUckKv.\$ވZn4H#i»Ө G 'J"_Su7z@)Ex J*$HXDHHoH1F=6 )A uN">uXDv5U`"DXP) X$H` DHnLinԃFZO1uDDDJn>VƠ?\keͨ""܊&PZ IJHnnB6A#vQ'2@M*p`H)BB(ڱ@\)j I_,DOzQ  BPP!HnnL 2tH^ wq*&( D0""ljFa|*v|UX"nr#Vs#$* HnLiB'IK䎗&<>[`x"ED`/[(J &HQ+%B P1m- \XX ,XHnD1O"@#VܸTxEBB$B$"@ 5,`ݗ*<񉉈BUab`B HDA.i$&R &> "|GD$B$g?Ba*p#ZI|@R! 21 @EHDiΠJ8H:FFx47h,v88zAbDžA@.. HZo2x"rO <M`~oKՏ)ˢ4h+ATT+H H:~J,\FZwsp, ` P"""!"!!!Vb$g)Vq . P]0 \Hznw0p54[ \4&~HDD#!@ )>Z^ H7O$*UT0"YHHzl#w4q44OƭMt!""< '4"V{*a*ń*^b ]bP%Hzl=w=3p-oh$:(vY&!bBB$DBظֲi`;' ˂e` R`U*`aXH<%7@#`:'ȖnW‰ w 0nm81L%%Z. E ". . HuPnH9. fh1(E$B$D40,DaiD+J* .HuPn 4~[4p&B$@7@4Ē_ABPDp\$ CK.HuPn4~[;` `~"BDBDBB"Sj# z# *R p1HuRn:@#I@>  s`MH T,.OggS_i<5@$Hu2n@#IB H> 8 FKꅂ AEEHuRn&@#I@ Dallegro-5.0.10/examples/data/haiku/earth4.png0000644000175000001440000001162411421044442020133 0ustar tjadenusersPNG  IHDR66EjtEXtSoftwareAdobe ImageReadyqe<6IDATxZ[$U>UuuWwt}{8,y,Fk‰ "!6RdCD@-(Jdc։=k.׎wx;ٹO߫~sKU 0ꮮ/E:Q_lu;OT#I=>XӈZnv6 P_wg3ܚ> >S>[o&0 I+C?~0P1giF-bkAPG$ /@~l|~\q0 P,00AYf,R|۝Υj3%1Gg&&߭1FQ)A`Pd)鴫ȰSiJiZ;vO=?Y'*doӒJ)i7ScKqDqA1`JRnbA{^?˫/ ѯ=.%GR@-@Ѕ7I\."Xk]UX@En&L$1t2'怺jlz??}JQHiZj+-sp`fwj2@0-ȝYD) TMHT$RwZG^V:׆PRD JJ 8*lq7Wv pw3s3cUŧJxPhT:} ŁX.pLhy.q*?IATd(;.iI\.):>H/?sWƺF]J;!~TZd 08RCdT iO7V dh&g6 3(~G6h{0gATNAeCՉ)C,::o/cyfcg?u|zt="PO Ohֺ֢D"U0 P)acNR1Up]y X@|ڊŤ$%J9Tj=O+]?ps2?V(D?$ခRP-PMS.u#Բ1܂rŐ'aKNԀi[G&uPS P@"MSjZe,3X}X*|R7>?bѦ,geX)(t >N>ݗsR,[ i!* ql~G~]#<4Vr@ᵖZ.>ZZw6]6SE?/kcιqOl}6N%R*[ovu~pw$'uejvc54OJJ& JZGzCKZ]Z]ޤ-@|$%aBlgSfNUiԄ$~~[>CnvakjT1֘ eˍ/3Qy|Y @mmJVqk)oAXӫoxFᄑJ{Qj x$Z)LA9>z<*%%jlȤc`Z*'ko^ʈPYpVIià٦EXHSN06z*=եmUs*iQMlrw^]ִCs}$U7hpLǕs[ri?1 >g1f񹊵W{/o |\;_w 5Z[١-Pn&|G2=U[V(L=_ߑtt=^O$|s$Z$d=T]2`8}֒S%8 ;wנՁ_6ҧ٪]R7)4==Z*m(i4Wa!Se&&ڦ(j?[m~{Bv hu&쫂¹L3H;5u*W"DźZ Vgr}nNq 9"D-xe6 f!aC.S(3I A2;7Pzʂ`sSc>ypǝWvL)ɯ WbbTKpsiWd|X=(9p BGb70(IkUNpE:JZme 3,s fur jXFh]@h|QBq]IB nM®TYTۨIVc; /ymovb(&ӈ[J?hih%4-K0-"33QyΗ @7io.tEO;PE8:OTmtifYp<Ȉ"s""AA(,팯(Xεi{c#ppt伥G\*k3|%jL&Ԇɪ7c|QnLFn} zG! ,]0ayƵNL|EUmEn1%3{E{e,vP#ޤ[hqb 'љ(:I-nNrbVkȺG itבe7$JmTg (AO۩[?my ؈.5|hTt:)2&ig˜%6h eWv fY;_`W]20֧ݧʈ3=2]H?b/Goݛ~.RK}hB9(tԴ>ŲgF@F 0Ll`c1#-l(+/.^qJ\9#^0J\wV&rpMdd% xEd`GKn11:@ A)LS;B&śMξZvASNqf_:qɄ[Q3TaiϮ%n"8$]({}Rq-*V}>4NߙS\[Y?}a2qMq ?eZ|- i'j.gqߧ"p|:/lDZ9'D1Bsj/+'вe60uq`"3\bkM Y置l>VpcZ/ `ygd|nM4-I_5K 2+:UɏŸlձ3Cu:|i,t4U@kuٙ﫲 ʴexܬ[ 0M3$"uyś Dò ((\=ԸNRMQḢq$'Q/ EKՊ( =E/gR1p|*<ރ=ظ1ŷnrQ OLef9HQ>@o_3S lb&n㤆KȮ:\e"P+̇@4#\T1ںdkN['~q|v-I]kN0^z]vj[мeiCy^D}9/o k[B 6k\9^v`ȼH GK}s8 J]9✏\HL3Gp(MaMeK5<bb.J]콬y= U@{\ z)@HIENDB`allegro-5.0.10/examples/data/haiku/wind3.png0000644000175000001440000001050011421044442017760 0ustar tjadenusersPNG  IHDR66EjtEXtSoftwareAdobe ImageReadyqe<IDATxZiG~s̞nKCH!6$  ! CEB8 $$HB:1qzo{ٙݝUWYBrVW{;ՒG/M~pXB鷗 W,u~'@k0_'GfO8pԩ!OTkQ z{nBMKg JdF,ySON仿\XW(@w[ ܝ DR[r* 6[ZСM~VVZwYXo>A}WXwg{0 P}6pe-G c)!&p8Zg?^zrk{xi`ܪ}o.ՙ G0dP[&?˥w2瘭$@cI/9o-W?@1ך\A\JJ³J|Μ r$pDM8Кx nypɹZ Hpree(L:׀HAb$V kHdEbTW @1GbiKAM)VRS,)YIqn4j * M' }KFBkцm71'[$ZK\K@K D6(\-"ZY\k1nmItن:<rM= ym)=M ;cH-C|7~+fVI#"e@e@j"0B!¡gR@BmnAoP'406qloYDz##N R긳 ~Qoa#Io)PBk"FJM7ZЊ]ӌ %LE-J]-5\4ά}Վ5["?ڿ&T[ˁƸ&%x&AX7!38N!^eX4DӋGv`\D0p1QhA,8/Ѱhț,[ =8fPF&'9`-T$XdwJy'a#ot~yoVṆ,JBPfw ؈9"DW-]F~HQR…B|k.cB=aZ$ҿ2KLf q nRMhAv~{m(0>E> V4W P V C~~v\gv㍑(;ϒCZ_q \kp|4 -8u@N^Iuͱf=]!B~;&zh:.0dꭞ~+[z3RYfS 㤲t"YLXČӮY"d37p|gpmwrS<$BKCe7 Wm&*fb >ȴ 2DZ`FTpO2k#3*֛Aqu6uw;>y&Mg#]!gɪ(=&@_g/Q_X[P cyJp!`c<ćJ"8)6Xb@kvΆfb4b{?;/0JEgv5a]૱L[ܱXh ew.ltdOTvʁʆ -PC5{{dS鿑:yH|w:++vYtSƗb3@e-~8\xcmxi{hY o78gϝY_Gتb[f}d[`gtc70 Y%-a=Ew?2`୬0DoL (60e]f|q 1e]mIA5=Z̾eK7#Xs;meNg'[R+ݱ`LCȉYpw@n.M~ޯ JYhK/j6t=ݩA~\1(a JnGx?/~ҧaNN/N,4ҠjĢp4c]l"GtI4y$1eK) {}c|%hˠdSFA(ZĂ~'{j4W78r_X LUBt $j&h0XKj{ˉqt|ɇ븫;2R9qEָbm/crv^ӆv`tR|TX'1br:(WTZ$a,sٷw|_Oz7ِ`oεUpx){`MCw傞k d:#vmFt m'- OzՅ7]vnR jW؀xҋ{^?/0v|M}` 2KsE0JˎByWi]&XK{u"/7HE۔I$1e$%I[]+ٔ+\Ay6)!]ԉW s[&q84o(*! E p~oʩ+U}(l I`(yU9±c'K}xӓR۬Z{lϸ5 `ٗX^ieby;(4s*[8|j`t|q֊uFޔf.F8r@2 UJ?I}[ؑ$NՄ}ز*#˭';Cmp2j' GK,{o g^ ׶k|#GwV ONjM!-~OCdrKTuTAPo[{s )y5RB~GA& pmѩPp=}MΔ$![Ч|isXJxQT{?2^m#$(DMJJ6av=Hk;*}&4G#M@@W&Xpc@[{toSo CRyu ]r,FYUdE?o]1'] ٸnF4X3opk2. >1i*vy,i'gNf?[Pލۂ;|U-=}/{؍^lܯ&\܋.<鳕ٹ8AF,xތV: OA*p{jcBf|(bodAר|KXɤOkXIENDB`allegro-5.0.10/examples/data/haiku/water.png0000644000175000001440000001205211421044442020062 0ustar tjadenusersPNG  IHDR66EjtEXtSoftwareAdobe ImageReadyqe<IDATxZ \u>}k]5``LyL Y+AIQbM@ 6"JE#i4%))(&54.0Y1yGsw޵ Y]ٹ4M{7'qrB?Nޛ$7|/9&D&q≘Q4šn:nbQݣD[&^[Q9f<=}ǠƓ7y >tO<~1-O1kGl۱R ƴR1nf@My>i H'Ō߁skM{ҙ3VLn/w`/ ->Q( (kɉ%8LNfjmdԤKŵZ&F:/Kj,?_{rYĄ9!jjO[~s"P7Mk.]B u5B/97$``i^6]".K+{o(]Zj{v*K\K\:,ЛLw$`+؀QY B+94v@)i>V:  @(Zfӣ|S½~[ UҶY}u뿗;j0Մ|IF# O% :4R̙5峉ր7B:i6@PZU a2 ?]%Lj-#ďb ԚY>'(~$UsqODc0NF|]H= Ρ'.r(щ[J8'Ds~;U`;w3/d^ X"Ѝ?{ ̀|O2RYݓ+`h$P6VRXhO֕{r[3KdL>Wb:%2W @&i ,ܦϜg >h>$2_tXgKqa0'T`$|KN'(n[~t.On_0W~K>CۅPPO.ܘ]QSZ ȹ[{35Ui j†UՖɺJj׾O8rf`?S`@ وEcQZM V"D6 #01:A/Gۥe~n+i% 7w^DoiH,e1f' f6&ĆЮQ6ND3J4\DdC\FtMDρCF4q"<>=fd,ɧtzѩ 4B|2=O( L[eIY'l +F!1@r"ϡ.BJlQSL4}"x7o?FQf} 6cm8p& !g?lcT[CX^Qy9v<=q˟2˘7a8_|-v2@E|sAz"i{KZsNb9DO'm9:v*2r=)x=GG. 7ۀP[/VmY`eBF1-R s`ВD+jojf1*t0B|e9Sp,\^tyDjBf(`\3L P͸&f2Yc-Ϸ̝h"H:ln*`ǃDQ{ 4eD$)ȁh*~oPA+ n2S=Gbqpeg#h\~J~$|WѠ 2Ԙm㞺۶ 9E,D 􂱜 sA˺!3/\X?MUvX6F`sO%dہmQn]9LAqr,B9aQV;"lH@{XQ0Y0usQ>\s~h(>cb1O]|_{,оb55-3'[Gx%KUW>!f ƜH8Pq\Jk3`) f^PFhJpE[I<ۍ뜮TC|D1[cn^s#@5DXNYkVъk@~(,:]bhnl񻎜h,Lldg?/,`k/QmfM Y3< j . u`G$ij !H_1P'q$ '%^qdͦpӓBǴ yfar*xa`Mv 'Ӝ'Z&/VK:vvN3A˥Vσ NãHO|D!jD _&:\VRg?P4j贶jh)%at{h_}讻[DKL 8`ME_&.~N9RSq5p䨄=!%y6?^*j> 6m,X8`J{@)PKnKq _beg`]T@Y3fCL# =D(3e˼ZyS487E[J%gaO~Q.\ h ֗e:^ VZV0W17HnT6K#0uIlTsfőc6%_'6U[sơ8)Q!'BɰZBCqs\D.iMx%GlZ<&&QC+Kh9'|p]eIojxƺbV!qO54pՙ.{SDI_CIrM/D8}85xVSM&)k sü~6t/tǪT[Sgbcɵǎ"qQ IaC|8t¿Rqѐ S@1VhXڒH-w"gGi՞ƿx`*i_`ׂ)5\lV͎jqM C=VW-&UGV͍ٳ)~\$p20$}Őn}o ETYyEiPDz6]e0xO \K>{2%,%ǽdUO$ĉmӅMW)Prc;֏ͦq0 U6ߕusPd%36T=d<ٕʂJƮ^sgiE T7qZd |ԴҌ~ɍfTUNW!f[ЩPa/X ʙ ltI_m4~+_&8IENDB`allegro-5.0.10/examples/data/haiku/air_1.ogg0000644000175000001440000002505011421044442017725 0ustar tjadenusersOggSaZNxPvorbis}OggSaZNṮ-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVI ~9l  XPD"DD"D" @x r( ^yJU>: 4[ǍI$8$""""!`%@Z<8Co @~U }j, Z#/J@ŲJE>:hD(x/¬O !!@oC-UFt-@ +?7 0TpU ޹JE>&M>03@@" !DD0Rq&z#+-W.Xnk JEp~aS 30I$pk /2 , >*E = `"A[ mR i >JU>:\.x  B@Z7;fz@0,p-JC~MUz;XxRBH@DD"L[ʲ~ZO6n@bJ]~T;8\LxRD L[گ3>ˍ"~9F n޹J].Q `O "D2H@1O neXvJUp  O @@% :U KJ]p C<}i*U 34}AɘIdH@$a >DK9x{ m TX`aP\XJUX@#FId D"!"D{J#}h?. H(DވJU7h7f$0o/CD@F4kDDD[{=rH,D),\ H*EIx\AxR0PHHDxRzď-" Ҁ‚HJUpI 'HDs@hZ B`!`!1T$H*U 34c A S 7 7hX@.HS;hfFR{A#C"O #8!"N@| э Tb+_$*T.H*]7eFRA3#Id@6QS$B" ]ObxDUŠ"} VDV"b b%`aH];hb!I} '7i2$4s$!!!)z(ndV4AG}J:HX@` Hj];hF||$`0c op|PEjpA(C DTTHo4[ 7&xkTHiHDkބ|4˚ Ǵ֔Ȣ7@U D4 DX Ho̐H:U;H30  '2yHHDH;|~E%ox7Qm(:AR !-"D\$$Hno t&30  2@'  pC ֍9JpF69PPB" pY.$TDHZnot& '@?2R<HH]oHN?"RAw  ֈT,-,P\. HZo,tF h?[- c"{,ۛ,zG.Wp]P]h%@H:n]74['xz 'dЦ"cBD$$yK8U@@7$ yA4b0\H:]o$dIK+<)m'zBD$D":W|x@EU#P%e`%  $ H:oU704"xy7&xR&HHlWLcTigJ #լ,d -PkE"Q@H:oUoL!h$=Qro41vT9E pM304On0q@5 JeKK  W"H^ hHz] <xH8!"PkOR%6&Vy0U DŨx#$D,T*0H\ O64'xy7OKȠ )DD9k5eZ1wu@p\ZB K$"`p!PH\ ߘHz^ _7dPF"B""$|zg3)ڬxy]E?9*H|aa!‚(EH^ _ <SUP$JH);.Wq)ӗg%B[@$-pIAp-eHpAeH^ _44^#x'>< DJHD`)Wt.ne@g .  .$ *.H_ _4h$/Z,xO21"!@0=ԲHbպ#!Q(0K,ԈA$BłCHzm o`S >'g20"! `{W5cpM8,Ed# s3D p p*Hzm o` I澶g2hЉ S(T)JEHץh!zE$""nB@@HJ'X@# @~O:{ 4qJ ۏ\-uTyY ;% , u +Pq"H:` I?;㾘1a5'ߚdPHHDH6X=`}a"SW *jXD@#X OggSw=aZNؒ![UW[ZUWTYRUVQQONTQHNQMNPJKODMFJG-H> /_|4X &*DDxY0 P&Ϩ.\@jA@ŠBE`QH>/?| [px+ AHH4ND /?m [_HB(!ϔaDD 0{?e@pY\V\tB%BEHs@70Fүso:lp 2D#!"j0z{S>p B6ɪ?SE1Q BՈ,\HuPk~X*Hs`TnxW$("" J `ZU)@#)w\H pW ADDDnY /"G e!YTD,,DXH}PQjM#ISM\ Ia"HqH?g-`uXTNC `* DTHs@ ͚+z4&FJH @;ȿנ̀xjA Aŀ DD ".H}P h$17Lf B"B$$D";GvVtua:0*,T* H}Pp% h$7AHD"qLHη@~X,t`ұ+ IABEE"HuRTA#IM P!!!!6~$QwJK@PQ\HHRn4 P@$"D$"Dd A̿U$^DXT !@+eADHcnINM"!$("!"!`E~E~w H*,Xn"J0LSaP`AH}`n)C! 'INMn/0@D$$BB"DAo n.@z.zAG@qaAB Hbn@4~|(_`AEQn-LĀͨ$,$BBB% Hs@nh$:7 4G@ +0ϿT!ͦ Ӆ-":JxFHH R*HuPn@#)` @a!"!!! _AEekur3#kdADHuPn:@#IMl\ $$B$H@ .:W  Hr_Y@"@T 0@HuPn:@#A!"*P:t^cGD?`h "x`ႵH}bn 4` @h"%$$D@dN? cDq$hq  @U@-@HuRn:@#IUHD"""6 *E W T X #[; \ \0HuRn:@#ɸi HDDD@\f OEP;D, qX`) 1P!HuRn:@#IMDDDoE4WZ<@uω9 F (P Z0HuRn@#Ij"!"@| 7ZxIկDϲVߥ$^ Pp aHuRn&@#I " B+ˊ{Bpallegro-5.0.10/examples/data/haiku/air_3.ogg0000644000175000001440000002325511421044442017734 0ustar tjadenusersOggSaZNxPvorbis}OggSaZNṮ-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVɒ}%VB[y lDkD@@`Zz"$ү]}مhIP|o`)@d@HDh`D2-X@>w<@ G?p#J{5 .2z5x_&> @$4 H6| <PIpTeRyl.xa?( $.?@) PF@ ""}AJ. *ϛ Be'RlM!FVH)H@n|vt/cЊ% >Y(H3# \$ү DNQɒ\e"Z@"D@FD"ߋ)^ 䩈 \* pE(`@ү Rj'dM!$  HHD@X zX 7@DMbAވBsT+ >LD}h FDH?-X"\D (HүoPce,\Mps8`   A4?\ (E.<"XH2ϋo {U?I>* ޠ"x^D $ @#"""\KD@ }V;D"DT PAH2o s?HS) #8hV$G"B$D$H#7t.>TrÅEDBudIRPHose!҈2ϛ <"&@ &"JHb _u ׀p fp!@J @CB$H變wPcA#=AUH,@VxB$$DBzUf nBA A3@ą€H2oP s!aIq pV"( %H  #;@`u8ōܧLp@XX  $(.H2o sU"8|s" VY&"&B"BB"د ^?qݎ#,>%,TTH2ϋo {$8|+ hydG$"B$B9U`d2c k  . H2o s@#ɽ7$ZCYԯElrաRyGV V`mpP($HPHrϭo` C#ɽ76ia:yҰ 난  . HS7ЄtHrϭo {zv c""$B$F x|J:Mt <"nEH*]7{0Hro` {O&@ A%XdN G)T(X*,T.".HjU7p@F-K@DHIjO0V1"bD7f , pPn.WĀHﳀoO@#)>N@ a@ ~8Q"$D"VI/b=a;( 45 *X/)HZno  FRz=H  +$ $讵<st4EzRePFap"\0i Hگ]70g T變o *"F V 7#!]0)b^\ր*";\uE(`aI ZDHZoo` #eI  W Z*@D ߹ @>Q1ݞ*(3 ED$ָD!`U0D `]HZoo ꍑv_|1x."% Bo4!!Ht 0LԓnRt&PXi\( Hگ]70g 4g @+6`h NyC~!V Ae H,(THZoo` #eIm \M )U%L  xCU{Ky=ئ@V8@EB@BY肋"pkHگ]7PgTi$Q7pw ~?JMHDDH@U`fUnfjdmHT  *$Hگ]70g J4(]}(BH. vEV+pi`Tz#IB.Eŀ H:M7Pg%I  {b" HD3@]?`@5hw3h)%ET%P, $X "H:UnEH:U7΍/%@ PvP@=LC} ,P(p* +D *H:/UYXVguVlI  @pp§Zb(PG" #"\*,OggSPaZN^]_\SWVVSLTTSPINJIHG.H^ ]#h$].E9@+A+@1"!8kro=mSzo0BL@+4VH:Uh'H^ g-͕[*@"$DBB"$IT4bqWFnkE@[Fd{YࢬJ..,H^ @ ^_0`eV2,Aa`@LE%q H^+NuQih$/Q]M,_l*.k@d0B4H]Ng#Z @nxV@ <\@&$BDDD$@e!k5)@HdMB 7Hzl 3Xzw6$.?*ND7I3qڗ)t[ݣbX  . .HuPýHzm óZ" DDDxH~ |D P!!et-6TRR0 \ $|HP 0P1HH}`I}è 4hE"$B"BɄ$L9,%t/%1  55Hs@ H}`MA@"!""{0hKKO|Ԑ)C'@B\` 2THs@ACxy #@DDH՝g]i:VY-XXT#^T\. H}`4~;u-zi""!",l(Ҹ1^`H$ɅB EDH}`nIm @H5n)B 4^XH}bn@#I bD"BD$DAP ? @?KPAJ pH`H}bn@#i ("!" ©WXQ@%ą@RHuRn&@#I0""D$Bp `   allegro-5.0.10/examples/data/haiku/water_1.ogg0000644000175000001440000002261311421044442020276 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,/OԖnmDߩq;Ac'cajj=v'[wH~Mr5v"M3F6Xp@_lӂXX ??_7йHI)Ѡ'|nab М u.8t&8CRfAaH xҾM4<0?$XDž8OcUAjoc_eIlha", nY^2֢?~RmZ^~߳MX,mv?)֗ȵyԠRhF=ۼkr*c~8g/ @Su3VnLI ͻceska+^m Zi霕d!$k(@xC&IL6|^r`pqHcQju-υ8OkIyŃ ]?=_r7YO\ڽV[]sBi_|q r'DtԘVKͨh,iu8Kse^,j}7tCCkvSYӜ)8z 'wy[ߞC>m?1(Gv(E ;)15aГS&m'ODlJ^ry|2uDƒNUφK/бy(:xIJx zD:DC%'d Bx?.!""JB! %" @xybyƳ߿w?߬>/.ݺ{~w痌W%Dз31 !W>3ƫ 5r\39/Osck >ױeuy;+ Tzumo>;9lk"Bft&D+@QIjp ]= p"K+]7.7]s=b$ B%@0|m_4}߹RGG>]GZ×uFkW˘9_Ylv9ڢag^y-1lv"jh! L$xh $Y$x8 p "ID R px(^<BQBD!xp{ɵ/G ?Y++?kc[@ jY4 ٿ(Äy@ry}[  !OΛNi(t mx|9 ~O˶(?>7~Z܌E 6ؓ0ޕC5 I!O ;GlM"Ĥ0C)I Z!HAo9Q QBB@H~qq0sq8; /cY5AQ=֒y@= f7[)лmI&:h( &l CIU-tH.7X 4Z4" p iޗ0(ziQ$D PB|o2{&bw. 7Wxe+> |df'fgLHF@ÁZ<^x)x@Б &  I)PY]-z &7 @$i ] .^@'дQQ(IJB$D_g+O㹺󿞽3.e6og-wf@<f|G\@;SN%ڃC tHh B@Y]-84 YZc @w*Y tg34ǂ1Jt ބGREACׁ&A4OggS3 Ǘer ~|ysql1Y` r;@ODž/@\ BDI ZQ#~=Ճ6.i4$7mĽ7OnNP&ߛ}%7$6u4O@ ٔ.QF#hl u:LD*OF3 & &M  3H1I(\$}1Jxܼ!@ QBP((DD> c{yYh=EBy}?ݜ?h7܉F ^/M!hxtH0y:4(Pl < $A YB%IkH PBJ(H?noix1?OwtKsF41(^ۙXEhxOBB oS?[\iv͓ NЉGC@QAOPacQ$6yQNyQN'allegro-5.0.10/examples/data/haiku/air_7.ogg0000644000175000001440000002442611421044442017741 0ustar tjadenusersOggSi<{Qvorbis}OggSi<O-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVQ5RWQUQLMRLKPPNOMSQJPORHFJGIQKLONQQSROILOOTPSQVIMOMMKH&j1 21b:uC$Hzl=w{kh$].ExƩd@D`BD$B"Isu<> _bAcrG)]\P $aRUHB~$z!h"$ Gp"DB"DMpfMSZD@9.?\TX , *ވOY/GHR7JzYdPPBB""bpވ >|Cl6X &=mD)!Xh*p : Y0 P\! pވͰ9STN;^ @ """"@x_ `*T*0ވ|~ uבT#1 ?H@ w!@ (_$*\" ޘ~ O8X|# ?'@""""~K&.t@|TP *J*f؉mE8R|˒UPZ2PH u}/+B*pPވxg؉_[p"<|IBǑ4( <_)T"H(@ވ}7HLwб !@ (Ho.C!BeAAވ~~ &lįsjC*G濈_6J@8G@DBDDNh`@6$$Kވ ?~o ?FTkop$D(Ĉ#y B*X. ވ ?oA-42ocNm,H[N `  " ވ|MTNu|?m d( AF< @*hE ވ owN\| ⟭:Q2d H $jy'Aވ>|C)]8uFTo"9/$ )SDB.S_ TP1H@X2B@H ?&u g+/߄E 1""p] R0@`&e"@@H >|#Ʃ #s% rB 9 DH >oNmhDY?!ܜm@g  HC""!!(6 qB>)HH >o 8H ?!N]Q TT$QqIK@.( H ?~ C1z64_!Rt@$ )1B$DDBQ`AR*Qb?EJKAEH|مFR% Fp'$FD"D""( IRKda!qA$H|?.4_G8'p>@ ` `XH .y$(H ?~|#BF#2?gsvG cD$DD$OBJ@qb@!  D.D H?~ ){N݉F޿_. s'DD$B8(-@PAL2`@tEĊĀH>~:=ӈ_ 8_VG>Ƒ D 4-"P !QH`%ވ_r64$9[h# )S|E(hDPUPX\B@bXH^W5gICxg|DbБ#EDa Q&pXaAa@"!2H"ULN3$~ ?L H x-.CHt-0 W <\H"oNWWIy6d@#""!<T J(crA H~gC# @pDX `Q` 0pH'牳IO;rR2H z HӋG  WQ ɠ@DAE@ Hb8^h$Kx?ٙ `LH#%BD$B_`XbACE-a_. ,*B H QH¯~|:H¯~8d !)!!~+i`H@XVICpY hL@UH~'q\^7}/qd( @6V%h BK**PAPH~wήF{݄L,FF$$JHHCVu+2 Ve%QY)`(Q@H"u]8H|ml U駈  0hB"HEHB~ wN>Iul- $8Ḧ́*7\! Z$  VH~wgF}݅} @(@f7(Q@`Y.n XTQ,pH~&gC#n R$BBBD FXcAU 1DU,> XPH'gh$WO'P$*鈄w 5" R?A2XQV *.Hb'q\7@Ha::8:=<=<77HCx_?85H P H(MOȨZ ,œR%FJHJCxo_B#W=O;0!@BD"$DD>|ƍ\i ,{"Hz]477aF)@$(1"-Ѐ⭭9\T , *D Hzm5w݀54[]`` @ @DDBDB|THTk!Bn.H**T"Hz_ 7;]i$v2 @fVBPd V .K]D`Hzmw퀶vHzn w=5C %"N#*YB `a)Hzmwֳ8Hznw[28@HHDuʖTg pyb!B!$ D(Hzn=w݀uHzm w=5 @BB$_VjX(@@EGv.H*@`Hzm5w݀IP <""!FBBOHJkج5}/`TP PHHz_$7;` Spda"!!"^)+J\ \>pX‚Hzm w݀54(XpKpUWBh+TH(DHzm w=54O` N8!eD~H$`PA€H<%w_'f!"!""Xm!BߔJX. " DHJnv@ 'b"""BBkw&EӪ\XS'"$$ , HPv@#@N0  Tj "X߷`aD" "H}`n:@#IN Qj]]!E,RaH bT,H pHuRn&@#@BBDB$BE X^~ IE @X`AU"HuRn&@#I@"""!E!;Q B@E4 HuRn&@#Ix""""!ƭOq7"BA1PA`QH QH}bn:@#I!"!!"W1FI%% T $ H}bn:@#IDDJcs`WRKB`1b`PHuRn&@#Ix%9#iNiL  T.܈ HuRn&@#AJDD.{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVz''G `bLDHXBW_,#)p5!"@%H~tZ&WOT^zp#!"!!`l7KE)` a7BAHtZ&,G#O'Xl GJHDDU؎Ѡ,TaI%P2% HϫF M#)>N},6rCJ&D$"B"Pv.c %֑TR0dq"@kH2ϋtZ$W7 T>V:HO@Tk+7\R ,*DTHSx Qɥ'cT>z`Ev0&DH7  qx wNHSxѓ#HUx\] S#">g*iWO@~0TFT "C. WR@HSxё%HEx/\_` @T"\8#`T$THJCx\H^ ztlGD 1!! ^S-eڰS-J0v;". @"H*]x/ܾRImޝAFn` QDHHؿF(-?VCh*+Q`*?P`(0HExO\)6 z"*nA"$"$D"?N.k}UI R@qܠ* \* Hn :HZon'rsWnDL!!/XŸs&XEB\X\E-x"`Ho yFt!)cB(""g`m!Z !0X%\ixрj eHo\h$]?8n !!~*k0y>2 JĀVEHZn h$.;^F^ hEH 1(PEP/'ʂ.,/.HZon'rsqJn? iȥhc &HH`s^q 4}"R- &! BHFࢠ$Hگ]x7I\v0A$$BB$$|_( Hh:\PPHoT,"*UHگ]x77rutDxZMDD_OvG\?tJ5|1R (Pq/TD H:Mx7^H_"w| x J"!FD$"K8P4g EX>Qj^L}4 U#;OG<#EBC 04dI /"ύa I&S9 4@A̧i:J T%D  @<{vᲝF)v H|E߭xvOhiml~\h8kcS\ݱCY_5 0+L 0Y4($ mX^" . `$2x/27$ycQӦwX,D?̜)M*z{}xeꇧj{T7ϣmZ,C]e~a/ShĶoW`_}K}_;@̾'WhFḽFoe_"vM؊趮0MGkb{&^x6EhjmMѱI4yx)D|"-0<=O ?%172;X݌ڲLL+yJ; Bf#Yd [O>X{ǖs4"Qoz;1>>c>VޮW[杇宽0Pj7+7o~-ǾѨ5^>K+4qcfO,OFioO(s5)om>V,1VP%eLi (K( RS2?EN|"` @y~!ԿT(!(Pu7Pv;, 5>L^[VW-3# _==x`t!}^;)(;I4RV6cj!C3)6<&:BbomZfbopW O7h#JB" BDt&_";^Kh΂a=3eEvp\/΁I^gΚ\c`3 0)P 6l6 t446L LBȉ8,V"S9m $ytZ(P("  @OOe)[cm^M $D QB!BDs8|k¼=o4co[`8+/s]>KVĎ 󉷟JAl$@-I6<th68Ί7tD$c' @y I%D %I(DDD QB{Ӱ覿KnG31 fJ`&Q?f/_6N@Ƀ&(xذAGHP 6 r3kb_@6)8`q b<J$%I(DI(IO`A;'%10uyh>cs_wZݢyr6Lz%mgQPfA (6Lă a"@`l 5l A @y%""J($zx,w`so5.zhj@`( _Ccf/8x$L [gCBBAl`ztgc/H@2l 4@ED%DDDD $ zhUhJ]3Fk)T sXy Y(Z ؃Alߺ] B l lRJ.R/E|88Y@iiJJ(I ;Z'E{eMNm6,6OBf O @{F\ն`ӭR1ݠ <D CäύB%Rs^ѱYyBQBDDI(! B}#e[X[h}@3s`5[>N@&\Xxb 5Wc^<)ƣ3nBh0SH 7(Z#Z5gSG|,L-厳7%$9XQB" B @{ ?cO5Y3mxNYd'jwL>`.ek/I᝭|{ȖG:I`6($L  G G@yOggSe ǗXEoYZϝS 3yvDs\"` ;H< Lj"of~W;ګgqð| 0pwT)sv#=  e6сmbQ`I:N@n;"KǩpH <p!("%7=n1MgC 76_@lp lAY+Cxb,>Wil^#ؘ:hx:4(:(CY:2'9*N͆H8 ݀bRO*\QB!$@,^m[b4y$ nE{sߵ( 者rQ6 ^2RD66!`cz`CaBl`b6Y{&t:eΣlܠ^B$D _=#&Yi+} hڽ].* A'- /(9u%'ZA<Ѱ!yS0#mLy;L4=O Z¾RmcYk XWTȒ\]Yt@:}gYEo allegro-5.0.10/examples/data/haiku/black_bead_opaque_A.png0000644000175000001440000000530511421044442022604 0ustar tjadenusersPNG  IHDR66'tEXtSoftwareAdobe ImageReadyqe< gIDATxԚَbqmv"Kc yW]DgzkU?uFc'HK**?T*)ꫬXU]TkjI֎;m:kKJENB%:RQS:fG4 3֌Ow??}{]^,4+'Zg*G΍cpf(pO{>~w.-KE30&YgYF ;@9mNX?>fCuuS _QjZd~ p[|v->x_SrˇwߕWiUB?7D<+rbˍ%Dݫnk sE+O}x!pl˷~_ZoW뺮>EE,%[aQSq ͓( `v*I\o8tg#~ջoɸUڬ7W8v+@P=9/ۜk,c;v>=wT[&g0I30p !/0l^xوaqb\C:$ =%E_?(!-t~'|dk?M8u^HOZC4/%oْ配P uܸaȍdZ$BBuW#g[N)YIOJ@ q# .8y(|Xj*w<3Kt>a.B"?̈́89,uSe >lKCs &xX%}G5(,Qh,L *HKsAH'q; "0 ($!" x7$W@jy0*֡ |: _m_>YR0=G&FB_zl-ޯ/ֿ7P=owA&t<$4l l^Iҙ9@GxG}nË;$+vP_e]!3\g@^ -pcBqPKPJJBDziS"@ï{6m~ׄO`t lhz|oLkaefrs@_ >4vv([}m|tЍߟ9:qX_ZAx0(`"u<$^Y2?vkT2Sŷ r/DPV:L&dB[ vA\6PXB1J(IQ@Id8g`3t ~3lH 卋$ 鿱Z 3z@Ӄ*Y`jC0v&#@(@i$~YE=dqr'BuȄy-< x#h ZRB$_d<;@]__. .v=??T߬n/iwDX=,`Ll HDoRDN)@k`CLx.5n Y$5" _,84yG4@ƅB %! QB)SK'|'ZԻ3A`ҿY-0wJX}δokg n5׀Ħ M):  t Pn`XjpR-+M [ 0 , &"" Q(DIB@g lݗ t(@/l<6P? 3[eɱǸE+u}*pqitXAOeFAAёh@XxP'P)l"`;K548]s2a;)sJp(\GDIP"?=Hկ Jy3 p@X+#__'F9 >#D`Q`+<44HI[B@ƃb$Y( 2x%Q>D8 h.2qH!0r&.(DJBIPֵp XL 1@7\i (xL~zjW>{%_z k x6 xx  ҀYI@wp 8cj@և2wh},PBPBD!%!P)ȣ\' @OGQ ?_Itx?fO(%DP m@G8,tvIf"A HvA2(@GZ '"&,3cjƒ:MD,pXz 7xA<%Ta!" (!""  hVNП~H^1Ek( }-BC} (`ޡ|6^o^Dq Xli.`#PA[B@FLH  Ll ]% 8SjS9~ 9>@;xC "  Q(!$_6!^'~gZ@ @^5/06S@~ `z yEz{tDGFD#Ai{0`#(&x:T`Wi D I=a~Ł;z \ QB!@q܇࿇ >ߤ V<7? x(o]1wIu?-޽ۂ! (+?!` \o:  <<:GDRzr+#u 9mYC;Yj@ ) @J$I( _< d5 Z0vHxQ 4.op СX9i taVI#`#$0H::tIz:e@:H+ $tKAg`MUŽ7:37y!(%Q |Xe {)ğ϶B BLƑ|tt EVә)aNABP`akOggSEi<==9cxtnkha`Y[ZO[UW;Yzϊ'hHҽ(\Y8h _;7Nn!DDD %$!"l5N <> |Ppװa.n%P 䟮B~AxA? xllɘ0m&Hx †IaQ@@I_\D>!^%A؄M @ QB!@?G;{EP@ooA L?PLPt$ 4  EG&^I_ !tH0x7B@@y_t6l@iUx)ת/  & @aY>bn>@QB %I( %I{p7a;~tjHPM :@`ӱ%M0:<4Y`nYbn>%`,"(DQ×;nR`%&3w&uRA&&@/& t 6YaNYanZ@ !b  (!<$4rxliQS@Gޡy@##<6LH YcvI>cnB.""Q(JB!%@ O@Wz6R)O<:xl DH`oYcvI>cnH (IB!" QB!"hn%zb . I< } BFSPN`BGQ!@6IaNY`nWDF,PJB Ez Ƅ'1anhЙh&$ DAIaNYan.PE%I$ x5/KN [P#x "aChH(`xL <<YcvYcvfVA )<((SQH R)@v`x %:6YcvYcvf"cBDQJB@4ar v@džw@)hAfb{x`Kt&YaNIcvN(. BP(ЫxOoq4mu>xؠ!I4MAIcvYcvL!]( oP}n0]th::yDCC1`𠐐tPh YcvYcv@!HB! #\L<tallegro-5.0.10/examples/data/haiku/earth_2.ogg0000644000175000001440000002277011421044442020264 0ustar tjadenusersOggSi<\Lvorbis}OggSi<DG-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,Bԟ.4)~bG =pu\Y)HEa҉S"@UJw̯:YUbW3 bF]!!Jrć iӳS9aR&3c"-4=RjC!٣䖓(YX% gSL_;[J& N&B XR %Ÿ 22HtO V3\T0{R1E;װìFp=Kx@CN&fN Рɪ6vK0^H*}ox _|oݨ'\Y0} ƫ@ j{Q*@GH`~C)XZ;e dg@ڙ,9p') %@@tO Y~HMdWwl v_? u8obSN( e6 SWL4C{\WY֎ Y i-స,H< -LI(D 9N 7%Dm@} 2j$m_^à {}؞j*sIhpZ^2!]?+0-v0d )`i S (jPj~>l:,fQ5og+d)X9X$!) %Dh']f! Oܿ70r&Y"M_U}:chei:+-%W',5/, 062pIB" $:K @[[[͞.`׳@O2%$_4ް3zF8MDϬ11{x[El@:<~yM*;B̖6g,: da~e39lP(BD A(@Qrr{o3`࿿ /z-I굟 3AI§O#|px[5{AА@@P dC^YCƲ@Tl¤JWA)N2oY<-8r`JB,D$D$ Qt}? | {>?4Phm[hq$Y6?RsU`Gِi@*4P^JItQ6U}w92,4h'~| WDP(I(IB^;2,'6_k^ǰ `l`@iDN?p|{hxZt8&&<&F#@JMl &4 ^*.:) QKkeؓ` _z*dW1 ttr`JB(D$B""|(j~%ps Zo@a=.@cG bgo; $Yb~|(sӵ؀Ll&h ƒ„ [I$^&:,"L9 v.ecT XO^4Y %$D|қ O *φw}nwc>l5,@WS#`J;נ)|ϏM+,.^T}|6x 6(x6h&F)nA  Iv(;Luvl?,6@Y|%Τ (P(I(!ug_3Ni˞;.J~`@ 44 ~x.嶗]W*gBgbJ &6B 4!y;6/Uܟs#lWkOA"3c$ %DQ!or x`R>^Ogd1`XluՔ?5vI0с0A#Hx( DEG**8ƉMg!2Eq ʲBce#HNGIBI(!$I( ^3^/@epzP%O}e]?}NC^QFoBL9`zG}+ZFF(x01ia4t$l&IJ*0s#I"S,Zl d<<~ l\acD!P(DDDPBDjQp_N > 6ybF~}]0AʇSjFcVfĤcа)Ih &t tSY,=$Ce ,hMNa ? Yo %DD @@3ʹ@|^\ <-(jw 4hMgOY+ 6t]M0uCH 64L <4t:?t*|%`.*F`w7jH:DC٠IHtxAI pPHFhЉ@gY ;% YQ(PBI(Q 8@uoGp|C`׷?:::JF`&(<IoC!YZi4 (kעGèL4X$(!JB!JBD!Gv1z^o?OkK(<)}DCt+2Im&<IAC@3 H&I:x !iWI(ͩ~3€ ͕хH8" ( " Q G?. xďh70~>aRx:%+ LX_O.P($D! A @w\k @o} !{n&`}h~ޝn݊RhM!O 6$C0CaYzp'м)D>`_fh>^ܴ2,"DzI""JQ `z`Kxlppo )[nGn[A fOF$)xСS`Czx&:4Y @ $ !7@&Q`(D$DDDDĸB:pn(I0.CS`66&ۃɃ6vYRҽs7 @6@0B$D@(?/3)<,hޝg$ܢFzPt(}CFPFCM#cYR`ҧ' @pxRPB$IB y4z@O\ {Kzᕧ`6MM: 6DQ Y`@' (NPñ\\R QBD!"Jț% 80q6yVA@$=0h& t Iq`W| i%QB! %D%}r tpuK`SlT$]4a"i`k$6<& 6&Y o`O|k  X ( ("J(  PLmMt9``>aaB0 $ :J Yɔg`Ob>Y>c@ ""BPDDI$D Qm|#鈍F}C]aă0HPl lI>a>Y>c@`B$PBB$@_^s"$JGM!uP4<&LDCI`Y>c@X@(BB %DOS'P@WP֠A$t:$$@džDCQSYanIannD$I&*d!uPQl!u$Hallegro-5.0.10/examples/data/haiku/fire_4.ogg0000644000175000001440000003030111421044442020075 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,nI\:.pۮч]j2|}9c1c|||G0y<'&1]Tڭo#+,$i݆"h=^%_]}++Fj[)Élxt+hi7Sڮ={?_Ge]C[F;U߱00F1,) ڸw;?!u@Ҵ.̲ }bë[js>łX|{W^o fck(JA$-k}nЊ"wZ߭>r(#nnصm?tޕ0N` J[Xg64\]{,妩"+7qFݱ9hё/>6T=li)Gr6n8mnQyC>UcǏ?~?Q<)2HXJ(\opubG|$Son~wӆƏXh~苯7#wT,+lNn:@.Vd"Elfف~?٨wtuew3_7N2w蔟4;ż9b6썭ϾX<87~G)pF~Uk_܇_v[\)D-lxƽ/>f=|Zk?|䯗ן&10tֶ QNQw7$;,=-r3M3[]îWSn;1.~mzX?s￟}-Pv-NGqDxf"D5yD12O1F隆9֦s}.|-/)k7$:O*ET?~=պC&~ۿg+$ek>Rʃ'*3J']12/C@p> ߽~>\׿]gkA7rZΉk~ԣ(]`dYg5@^rβwн #dr>|!O3.+omŏ\tlht{??  @> W?Tw x?ċӖ3N{T%_ +vA}cI;PI_(YPzZڇ_'+W*&5:;yBz</SCN15ؼch獏@?.99/HB.@u]5@/™W^ѻpSx# ] aa (| 8Ob @@MJAЧ  gy1x 6۾1+ǻN;x Yu2^Tq + (^: OLLP|Pb؀ @ Se>47xxyr _u'\T}˿s୏xj<߂w>O`'5 ?_C&_?Llk(@1L/,.zơ8W׭R01 {̨G7.o4L.Ø>Fqk45EC)D8K/(t o>ْI.w(%כ8**\I/ ?wX?…鴑iDǫ gw~$k_̟,v7O???+fOXœsF7*L u2D'.wT.yqv3q^oDx;^zY(;(o7Zjp8SXfbj(Ae:^@(^`fAwClumBxIh^b">d!e OUsK%n+<Ӂ/Qe0$k"VxV >G}vQAsw_Y$9 Fu@π/? $}1 ) v룷(5/s;=MR&WX3~pn+oYA^eM׵뵝m-vi~O0H-c/dO㣩5RA^0`#'+ jxMU>2iR4f2Q| i[ xß 4(ri79S?JG XQȜ:ׁ;Fq{~}P og 7 > 5Z{n~:WAph>z?#%ftubӀmz4}ꭘ-GvvSi^pD4}yQBF%EhhP)愦lb*1QLAFhsd%_s.<9/^,E +bjdι@n^ _)}?Z,~Z@~SD޽ C&%_ ; @~`ɖٛ8=NTxRlu)4gQ]KQ}MJ( %|77=9έvn@#Xt?hրZ æMA !@T7830+%ca->#*&yؠUEmh6M($l]Cx x:LrxAU `N„ƔF3^|+  ~(Ѡ͠ix$"ԯ"J(I($h߇?2ǃ /h\oq{ π3 Ps@`=h2UPO>>{~(]aسޣ->fysC ]`΄)P<&hI|/ HE$)~PQi.~7<&HXq}$$G} xԑsOCѧ@w (XAy_j9`@8?И@5JPRdvet[L GՁ4hf+j!e IJt". JC)L_YڌA!~|x<6a5" Q D_Nu{C65__U8Qq/xA}U'  0`$x8!۷%T&:e"~^2`ha=̰J(tLt OggSA-*+b{l`^I vcM @\!Lh W 1? r.0bEDI@xW7D6dq -@/ ugt' c_h?\ H(l2u?+Xm{=L?^+!#KcdãAHb,QݢG1!l0 BI\iv"BGt9#Yq!P($)K#¯7B ?^n[!p3󏟁 /<.A $cic詩c3`_yu,a)MPU@{P l6HIJnH( $A$)=1Kx˃,;?^ WyyDc$D ~jgV;8.?z:<_) { ~/ ~&Dg&P%J` 1᷻-`kیG! <FA]i>LLr@f-1BO4B $ (^W3!ϓ*'zJ(!" QBI(@݈6M;sn_Ο? -4 Pc`4Avb'P,;Mx2).FۺƦM`{`hh蠣ujvZC&4L vb-)kȎ+SO.xg."X(D"J Oo~*͝h~_G h{;?\C`_ B~ p &0>8'iJ'?My'u 0L$>]M/\Uj b#2ځ) Hi?J[=BIB QPe"vz}^n8|rDO].X yn  Lg ń9U ѐ& :DhQР DO%ȁB<844' =oǁxAӢyRdG( (D$!$J*@q^и<6@7Ϸ-+ כ3!I g}O @uSFѱ>L^Ґ&hHtd [Ӡ`z QRJj $Z =(J4 ~P4&&H %!" %" d[! %"J(!J(J  lz/DB"ͧ_cL@?..Χ070_   O&cn@R H tD̓dDjDAY-n0"K`@p\ȧBDD Q@.Eh\«ep(a~v Xo1pyw|SOF@Dǣ{ؠ`R@!HDG&Iz;<LfH{Qe B>mpK BD (>߁HwG6Ox` Bt`?uCG9nPh 3I*@h :LI Izov צ 0= WAэCD! B B  T~ '3p|*o p/>bU[3 ߿? V8B NicS0I/>EO U0;Y(:A& BIdCO+ =(I{Wt' ^ƠF"W,$IQ\/@@{fHjN//x5/Q)y7|ݳ=&'&4>(6D'5l:6t 4 $2I'* "I 1F7+ %""J(!PP.@ .@O`8ADu lxСLPiLxt$hLx: x(<:hI(N3HF9 MW@ %"JQB @p[( ^?vR!~ `+r ?i#Ul < А`C@hu0yhlI(7vG &7zU $P I@?  >Ȁ4$-?}Zx=nB(H4ӘPGNgF$h$Y(7t$l:xi.! % %PΟ |mupx.=#?ٓq:XlA݈fs_0 „$ $Ll!Y(7t,l:t Q( %JB >?Qv_~L桃/F 31A#)@GP($6YanIanF(DPBacR&&KP@!dF`aKL``=tOggSE-*,n.yqnyqnallegro-5.0.10/examples/data/haiku/water_0.ogg0000644000175000001440000002430611421044442020276 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,mYyA"2^J{ Z{}[Y^ʱ^Yw4vYk^n/ntJ=[ʾk\M2jv+>M|''006 ^㠫D6h7'06yC!Pl` \|tñWv}uKNj'~~j,eh`mV;ra}'m-"e_3?t6>o &`nt?B*oRf٠1ab#v=% FG̠}+ne Xh^ ȇ IPAG@DÛYU-Z"K E:D~.QBDDB  v/Wt.ȞCӳ;7n62ҝp>4r=Vλ}~ܮuCoo2aJS>įezY&U;7AфFt<<:viCIx DVE+?Wۥ3cjB$!`3_6//'f?o~qXMרO]hĆwҁrT` x1|u" -? {boxI@1 L 0AYt |YZy zpBEIBBDD QBIbvJs1pj+c7g7YlP"ß^]nGDd~Òߩ׃uWV@+-;f3*l"K6e!0)`C3`Y:t ΢ `px " QP( Q 0FY=i^>|wg4qyfdf 朑`^ߒ}*{<` afo{Þt@/cxc0Lt't:I:,cA$b@K 1B (!WN^|śU!6߅c`(ē~T(1_e֕w!z شLh(B4c: @@/lh<0=(`HI(P D..>yi '݌fi ,s)FDDD"@`\kׯzV?b0.n7G/?Ǐ] ,hL=@A9, JM&h2ajx&&:I бM$6PY R N !  pi"`@(DBDISfM|syiO1/%],m,KC.n_ l 6uL)aKHx< II@ HN $A.? օ K"%DB!,s4(bvW޿J7MaiLj 6J7<afi-ti`ChlL6t BBЁ YO 6!BD$DDDD .ͮlmuYx8vD[4ֿ">jh`⯭vڃ2!x 0OgN ! &644II=Y\ + B)JBIPB %D(txrhHH2 Q1Un$ acM4 :< @„G`(H:Y纂E~` ?6xBIJ(!PB!w_ٿd.&En o1740#63?iKR4^Nf{$:^FaMA!OggSO ǗM|y}qnik`fZXPL.Y5Ck:@hs0X%DD$@ j١zԺލt}nTNv`&A@+/ip{@hvVDAQРA$ t $Iak Y>bKC N(FPBBD\kKnk{Kڿ׫~6ںU'AۯA`@CyģaAK I&t6(Y`pJYb oD!P Q(J'vRK:nvOQ?u|+,${UzY.|?cFӀ :N Px(I(@D~v*rc DPBI (IMvnRcɥ]ez^o\=hýA NՑXNu64݁`DxС?Y(9"K?tGtz6 (`!" B% k2@;?_s{ۏCx|n7uSx`Y/,mqM1cl6 6τ$ 1yu((t(Y(w.tAdgGdUx\h"JBI%}~\DhϺ WQQKd77I Cƒ"g`@` t(< xY(wrg`s<P% B @Z[)mi9y$RĆ PLysvysvallegro-5.0.10/examples/data/haiku/earth_0.ogg0000644000175000001440000002413411421044442020256 0ustar tjadenusersOggSi<\Lvorbis}OggSi<DG-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,6 FAf W{NZk:\Tpi6u |_["\Y݆͕^OdƈϘ7<:G:˞1PVDF|M,- j3 E#% k ` n0l7b4`,x F!fR|!n{AiOg1hq x>Ts&PX oX|ٲ #7lnaķg%p]p\DKZ6XC˗&,Bhd_/7?؈"~ٹ0z`rBV&2b( ҅74W^a<@7ָfLݳ8v5lm9p AbPJB @"X;_d|Il܏5<&0-szV>߯=I'$O1 ktZιZ>4hx(L(lX#v7~IxJ@g~x\'w"YX(Ģ" %I(DDD!"J˻=tSg@5 o@  r@8祟\ytLF!IKIRnDC\; ,k-4`KH$l tL6$YJ&g*hSxL9p;}N8ȴ?.':B@WFD!""""JBDDAlPx g͖rNPh|58p[E3?b`[U4OVX~5[ p.dy(o۸] l&@jAH4J.AFZ#M@'^LO-y" *~,D!(D Qh,QW_!s 0?<To& 6}~]x}mh{>wU@q&L +]G/ 菲!&L`C0`P@j*C*PCp,^p&d}ZW* E@ WtP(Q ~jf]"4%Dk/F|x<s_/~gA' im[xиӖRqq?D@궇Ʉ2a 4h0)h t[ZOhEȊo6M^ː!c26ǎlA\^KBIBDDI( Q(D8WEt7|go@y7H{'K_0W'tYI4ۧGKhDì{;ʢf̀}KFBH:(h tJ͕1"DFvݐY|m |rɁ l(-Q$DDD!"@@f]3'Qn Om}vwI[;<[Pxm`@ !~Jiq!]`y !z) `P(  4<: 4a-܃9ȝԌj>U7U}2+S\|rf`*T! QBD$ LY/3kɂ{@@?1 ~Ћ~dn u}=|-B>N]zY% H6 Ac@t;YN}xLMdGB3d=Uwfc`%IB! QJBx*,p~_>Dz}1 ޻Lе3`?-`3iIѠt &0+&&H 6E[OF^ibd"( AvZC[s tIw5$!^>x\Xr` 9K`~(qjTzG0miHy?F0_?"HM$>NJ&t$zaBĶ!AڠxY9OYqTw  < P(DB :lO@ `x50k ^c朆@T( &P$l: ^OYJHO<;G`+CD"TBDI(] _?_7@Y?@FڦCGpy<( {† B@IjoY锯w rS@%DPB"" Qm/ ~@h|)WԐڦ`P`ã :<  IY(7t,}17T 3Wb!"$""Q!Ȳ[ Ƌ z@yS&nb@@bo<$ (hh Y('t,}17T },. QBDI2b5('\> &64&oGҁ@F/4HxYanI>bn@^@ TB$ (DP(hc/s 4EBPh@6Pl6YbnI`n'@AQQP(D@DgP 0`'-,K&I" A hYaNYcvQB!PPB QP };P{0G(l@!% OC!PP(<6h xH@HYcvYcv $P(D [A=Ezٱ C(E7a($t4xut <YcvYcv]Z( B!"Q L_qmb,GAW2@3aSP(LP(xlؐ$IcvYcvc % B! _9O_S&& 9C jx < l@ƒF7FCYcvYcvN@B %Dĩ4`.OꊎPE'11aRaCjБPysvysvallegro-5.0.10/examples/data/haiku/fire_7.ogg0000644000175000001440000002645111421044442020113 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,ÿVki3R7IvzXj:42bF,248%-lܰ|CýϿ&+M3_]S~_qD*ynx"@~ >쿞\ MLWxpc e\4rQ(Jk@?;%Pn&C^uݓˌ+.e`~d(_ 0^D#=٬.m1OVMzhU G: P G `~: ?F/ɯ&ШA:ńM. Kģj=v< NUxhS):vr/`Sxe.>*B,r 2?8>#{ @/|rUB.h`( uP8 , p5}_hPQPpp~t-$HN4궢ilttD5 ْh A*Ø& K#PWCM-"J u8{/,,@Z K+P1k# E<? &/Z*9!ׯ^`f-,NepOH6SL t't>:hl$  2K]8 ǔd.X“xɛh44ˏ ygMB1#3A.B!J( /R⺇oxrwI|@ ~D^(o!xf {o1p{SXg灪`ݥJK 0};)4U]&Lcv'x IAB0YF@-^O1Ř!JoqD{`<4o<:Did[%DI QBynnD4@l~Yl_D{υm`0jl0@o`DK _0xZ ^WC9e0 XZfk}'RJ&fz@HldB A HQ`$i<c +$Eۧ>σ@(eP*! #JK ?$R;@3>-~>~ћ +Џ Ώ{| $³SFf fVưA-yۯ&]8ϫC < ! :$B@Ʀ NI`!R),X_#> >e @D@.bn㯟Xy{C4'wNo1{mmѦ4f" J@ 54 60: R 0EJS\* xq>x1p2h#r!2bQ(IB!!G=yy4}\< >@}}D@NO_h]7@ x[O)~Η@L $g$'֬Й)7(y$t::h<< H&l:t$ IL&F# g >x3o?6<7x9 (I((@l5VDy 1|zBʹ^> h~#蜙XLd*Bܹί+zAg;r*t  𐰡H䠓i0/#I3Q W' 9OyJ$%P(D `s(;*,~=,|~\)'}No }?{x(l?4 xO`& g%36.`ӫ3"`Ȍ(o &rB^IrDEA@dI*2mJ6{__o4dBI(! %@~Mխ# !ps ~|`2`P=#@~+~q>n&%0C N d N.< %/)4(`3(h ih<&YJh)rCD9A"|2 |/d\nBxzEPB$I u㽗3t@:t X? @|Hxo7^` }Os{!OrL{U+y <S?AcvP :M6h$& &h 'w$1D"کHԂ<=ss4O7h (I( B@pSHOO|?iP td xNP7|~b0(HUcUtL:^k4h5^hAoAxx)< L=P<jx!w["|>T;ԭ(w Cd3T7Os +>9s/3JJ(DDIB(!>ג@^\~3m_~C;_? '6

    d\Ҩ\($DD$D"Pਲ< pu`8@_ 9}rx]p|^dY`xƀĆD(@dL$0%x :LI~̍յ;3f25I6p^p˅7h.4٨J(DIB$IGg~ z |o@+gU9 ,?4 gubR D£ %0h: &h:46^Y:TTPa5diSXc l78& ,B[J(""%_>N7@~OKO O}lE|XB>S@ZcE:gBAa!yx@:?4o!PZ+ *@/~_;;-1PBDI(! %D@.w0y xSc @OF 3@aLr"6&#0J>P<(ht$:L  1@W@aCCAa>Y&XeTV[/4p />@bODȬ" % B@` ;.b  tAtݿ#P O@ރioCj\FAi2QC0!I&^:o FP:GIT5M7(PB Q(DQ(DDo L@=&AxWL"Mx@7Gh~07Fw5+ IAY:G )!T(Ql ;F.A4^Q % @pٓ3[L/ le{] vS 8%4J&  :& %!(@:ƇL+F:^0.\.|$"BdFEPB! QBD AqH F +p Q~ O>,`E$+;B.؏TGP:OA0az`ٰa( PP<((Yf%"K 65^\ pb Q" %P0 _|/n>  PXO3t~ৠ/ X-nIa^CPP0Aaj֑[&8$Ld2_ B / @$\<FE! %(!Jx8۳A` `?0?K;_;~ ?_%7Z>Ɏ)0 P 7(yLl0:(x:LuhYNs& x#̖'88-/0ܾq!OJPB @@U o~Mvַ Aw ?A@?8mɍ`7LH< L&Y֑lwy% Hҭ-e />@ σE1J" %D!J(P)z @|/  1A=6gIFTXpnb .Cbc@`б$&Yd $Y9@0t / @tg".D.|P @߫.3t0 l@|ic??1h4Z`U{ {0_LС &LlN I_!1,}stT+5[& #J(I $@8\v +/!}OC@'0G`t{<6$ † `Ax5IZ(",gˀ~Ux'"2SBI$D!%I7|P$? 7h?0`k( o $:A݆g„DBaIZ)g4."K3\& ?q!rGQ(D%DPDÆ(S>@#@~HqȠ)D x4 MYY(trh 'X|\(IB%QBI]Z np&<K*lĀFoT(& J0$6 &&DŽiBmbCPYY)'u,3t @1,@R"" %I( (&?_6@SIPAt` A@L<YaNY(g <܈K," %IB!"p oW?]?H4flDMfw4(:t(@&xh:YcvI(g 2\<= 0H0FD$ J  C8>`]h$<:l&ZiÃAh YaNY('t;7b *JBI(![@x&zلAQn„@xlH&6 yqnyQn P: &P<allegro-5.0.10/examples/data/haiku/select.ogg0000644000175000001440000002027311421044442020213 0ustar tjadenusersOggSu,W҈vorbis}OggSu,WXR-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVn&sW1٬iܜTqsSm, ¥@(0 3sm+c$Qܠܠ TAM$ѰlYi g m̦yg6c>z(A= ֻWܠ7hi JrC'łxo|Ӂ旺w9v}.\q:+suH#717<ˤ1qwbۭ'9{O Ӻތ}({-H${n!I[h3I(LDz{#3dJ=5<\usQ͟~Bį|5=X4}]=ϯ q~/mw퍳 2$w#6 -aO"}&r20lJzzrW7 r$f=7\$s'27T 9#O\cϻ),P0iНnbJ<5gQ/EnU^'xs7Q ?"zcjN[^=u?<[FGwFF+~eDh`tdbc/I+,sY8й7n8j/ :HoX4꘍H:R?ŭWݔeSYA ryմ,Cr|A !U>'$ mQDv۷4gūϾ=7wϛ^WUA_u7 :FIr @$l䝃z7;2ӿnL}%F#z=LsΖc4 :I#X?cq&/ 1ɑ޴$"9][GTzJ#_Ds Lֻ2NMrnN=]CU%]xai\'fC5- $dJz(xާG rYpryA. !Qא^ ]խC #Y!Y~wO0>\V68qD952H@x8$Za9$d:;DHtނmsfJH8J3*Rx~9|NfNᲈ(ވjwý%Q8'NS7!9^9EZg 7.M?þV%i;og=؅ &).M$ؐfrB nfPqU)eߤ"@vʳ>63TnQ?cD ވJ¾XD{d?r  l1r> M{HS?ZU:$ӒD`!kCXٛM8Ή ëv1\ԎCltpl'0F;kܾ3?e+C}4" ވwǾAWPFT'c siDx6i/E$7io_קuu&#qz<;~fo-bZM7]Eъ8ǐFsz޿,*F{L3zc׿afձçgw>8tlZ,jrk|}g n3W,-rMQ;4xz|BDDm=}UlU>yT6xk4ȑa@ 領CN֫[w1@UV=6.>ƞ0Z/kT:I=NQj}Q.ވ}+pӈ}eŨDŽ<6i\dwY]ƭ%HrPScW4^ԑwKŮȨMV'uJI;C_H~7 FIo^?"^7VH F"6`I(ވ bBD5"4 Eߐp*#!!"^GEDtCc6k"M랆 (ǩK-D-n|BFJ| $,7"|z\a{YL&81nӤ |-ʅ ވZo/FrKL4ˀ3\8W #K ȝB9(A?ȵ>5K0{ ' >ZH< ?D`"G~lό(PWxgm@"?mYyԩrD&BVbmXn=8ZnK0 4[t AԦs]ӄDH9z$>El 1zknz2YdJly*kFȆొKgA1 b&;eFlbrQ9 0 " 8Zn[0A9H3 r(IZNh_-{èu[ L֛=Ӑ^F߂J D^t $0Ft`-nJSV8'.-3nTKX@%@e0bOggSiu,W<3tm5H] w0t 4.]LuljNU:"FP~aY:w(s מݓD9,i%Sǝu1>Up[W`rPu!FҀd%H_wX0-^IK.8)uU"RDDD""kqwYL[&G M FU.P]g@<-! :!WF XƐP *TD(h}Rn@IJ8.ž\6==vYallegro-5.0.10/examples/data/haiku/overlay_pretty.png0000644000175000001440000011253111421044442022033 0ustar tjadenusersPNG  IHDRX{tEXtSoftwareAdobe ImageReadyqe<IDATxkMR4\]FF BhFig}?|̌Z^v۵goˇnGT)z,RZQno 4g\Kuצ?t |ImZ>#&\0f{o! &2/S #*W'Ro\8x8;oï'w'R_X!SȱݨOjaSMRSJ e==.~LUo"@A.М/&F6U@Y)HS3iepMtmQt~'no5x Jp.oh 199MjXyѿn ' h[hWQw?z[ M2F^_D0R@oC;3W (SJԼph?>Kx;rK Q%m>ܧ`QF]d Qz 3BQw1`$IZ2p{8տ@?۬^N 'Q!Pqb%PF vabGB, 2A ڷ nu[5d7Q'|a9ُ_[{0'O2ނ2l #|b8_ܜ|뿞M|7P/-ўvU NQ~].h GGd\;JM& ܛ.<7V?=ୱV0с\Vf 5 0%@आ|E$Bj)N y$s\N &Y|M<0w,o+@?{+5}Z 2mkze5`&+ǁ@p&T!Óg7;s|<+:o;Ɯ&-iINVEҁ' % bI@p"fLHCPF߂o9[ p[,g.  7Qpmo;V}i.KLDg'/=Jޓqg@u t"zhA|s43SO5|Pw:цAQz {x+NޟJtodd]ߥs釚 ´bb8|X hq;s=wN4jyq8&'r˚#<6FRL녁KX*} JZTw6 -d97V*DQ97-X+ $]=3}\ g1;bQH3D5?¹JxkG(IȉW( 5h8p<@sI'qSs,#r|m#ݦ =("$hTڡ] A9[n+ | &-pw V|?I8=xpsƣ܆ਠˠ? iT 罦~?A`O笴?q)c,N%s:!Jm(9J@ 'Χ@@`cQu~/5< RN8ghC`Ov5)S) uAtpǓ E+0&xӝRO*-0YN t闝4xfL88ML2L6kp`>HJ~񯳢Ӣ:(T8 Emnoi 1` %# 3>s{@V#7Ӹ$3ȇ6P8~1xymׯFrc؟Kvl 8{2™?2Q Z߇;fB㟇AJ5:7E-eCWg!Dwƴ|B]Utip^: N7$пϓ;\9Q9\pc?sKc:-5}PkGL /;,t?efx*yz\GgR^(2O$>SD}x_̫0D@TaR3J;C#!.ٷ;}~`rA a<<s>= x xBZmJE6(H['.@53 yU{4Q[ՍWL}|t`, 4Ǔ-LK|2u4ݳ99S@<bl@qVx8@ A=B(b3HB:Zŗ;|@Nr+R{27\˛1K|76o} 2Q|@dfd:3NHdJ?Uq=uq[('` |皟c,O  TSݫɈ? 5r 21|F=NDfx̺n JhhӃZZ~w;naROs6 aD3s r#;.9Of h̒ pe1M*0>l ɂp1El0#\s5>׏}kp8I2Mic\So>VXS? iWY( hߏmB0аMBA n5?IeC7S< 1;+\hxN6<8:''15?X+fm _3lc ޼cEYwو?;H }ѻDAn|5,@cBJ Y)V7Mww>H7SE4P&Ze f 92X f*0sC6 9>p N TR\.7 `MnP[ǧ:#G?NF{&DwCN?$:=&u?CIX ?L$H*b{B!ñS yo׎6 v@'!rΠ?<"'o JSuI;L ៏aElL6:a U _<Ě8JŽp[ewZB4"\/P{i/V ;"{OP1RV698s>/!,6gG2 )? u*O)? :؀ɀ`>'d, 3 i4fF$sj PD+<]3zp &O!KIye{~DȟҭͿS@epubD,0l="G^P/P`+ oYy@^>So ZTx%.eܔ'uLOۈ|WFlog)s%~=vV'`<.,R)m`@0eXE davpށn\@տh@'tzs#@d]ùq~+yC;zcQRb Kj/\8Sz [Cy>K(4Cc_C_}bژKki r1 ߠl@8-x5ЯΑ lAsPCĀ 88?<{9aOX<3UhaQ/9ʽÿ!LxT>?w.^9#`?t*N{OM)$ |Hh?@S'e=ӷa_{0KNy\)(4R v`R~L2A <5(4c'([ķX<Wp'x3DGp2`S?{4RP)"̋JрJ*<& @u +] ~y#8g^pzCQp]W<w&H)rzyG0̸#.p[e ^\? q%7Ξt_9vFacNx@I($m" \r&?^įև-NNҍydf/ Fz<^{Yӫ:pD.V]/!= @*x!ff_;l3,6oi{87 A#S9HwN(~{.7+)$c j \6I㬻'.Ѥ$Uu> g:|6l+N%Ew )z2#8xw?tpw zt+ V/xm?Uz:tV~dk#c_1?TkLjs^+~@dL^rfC @U{ 0G^nJ' >ۆ^@y꣎ž-ʕ>c Otg72t[o$|:!GShpޛV:=ʼD97#0,l$?  ^P"2*hq Z뿉6^AB_ U̖F! ϤOސĮ9{Ϳ(xdOo`0@:rVڒBIGt|q2 8 @{1Z e11J2~le|ZJ1sn7p\IZ0@fp)9!"7M6 ¨W} z(ooϥ jc<i؞Rz~m. \wH|oMwGpQ"/ HIS PRN@:\ >ʼn (-RegdfH "!+%f'h%'?H? p9' О4}G `T@ۥRJ,˳q@!pa0^E> 9 Co* 7A6⣥z p}J d#6 '`&n,e$I>@ls8hfiryGm{wT':7W8 wD;۔x3T~|0>v/ɚXp]KQ*``!^Mkc{ChWH̎qKs6b4 h8o2Bys)"!I6 6BCա$iL֫÷_vXCoD}#׿/q qz`ge竐0j9F Hf?'a'xfJ!2'hOﰵ/qh5$\"i ˃)hz]ctГ*`_d7_czp aFDE{]xd,xxr>lp:V{^3ҏ~a }/5;)苋q|?Ug2>`*Ŝfe&,Lq߾X L@B (^-C0%lZt+~rO5 8bO==O0e 쪆{gJ2ďϓ@x p_DhQ(`!'J)JGт gh%;[-:zql=5Sf.P%J'#KndT&0bPL0R~}93ޟL({ʼ~|gFx}*2h ]A^I/1h N8=R_sc:=lM\e&'~ʧ3 6ϣ[?Q `/ 53Qy@: P*>8 &%7879g`=9][aG1Ovˢ%w6*% J*=Yv+➶[⼓ A%&iIzw %b]#0NA@"K6jutBlMZMz!ױ;DKk U}?4c+8d<[D0p% VIrm6_MZl_y/ʩMV WŞ8Tӻ@oz-nA/Y&h;`sk^c}.'lzx3&p~_`kB/ܭ#}(ǁ{5*.``Ƹl`shquw b~dՑߛ\!= \\7S W2h$sXvxf@kUf0O{} Ybщm܏̵.0F[:;G8?6͡/pj栜׫? wa 52@-4@C`om)Fz`Zs4$P݀gyzo !AA &``@ &ic ftBk2J+b@" @px8@ "v3i(/RM@qOt%%71u}/ HhtYQ8y8?Ps?jo3Ko>R>?S4!wҷ4ix0 s31"m?^ZjD_wF%vo)K.Ql^rhE?N_XGІpeD_o:KgcaA;Usa-C0@h40B1Xrz𸺗k/y>e} $2Gl%M輇 Vأz3hiYt#Qjv@.?ʊspI !( eޢJJԼVŷFGCwnQ{IlT=㎠vJ1Z GkEg=?4E\qppB@Fs5:ɭrt]ҧ4ɒmNgXtjЇKrGPk \ܕs#ACo6PT7Z>}k rI .4`$h俰e6pVK;&FKPu/(( }p1OǷͿ*g/yi~ Hr#D{~_ ĖP(u5x<)^Zi>Q@^K2BHP;_eNB;E?,{$n8OB34n2%'@2Q] wR7&v|BoPĀ2jNDy:͗ONNC!" w6w@y54c_G7 ?khkOi`[XP6$쨃G?%_J(l{?0a;`k3vV &`mJ3'S4Dss|_<12lU5l&& XNk?c DL!BHʏB ^Z(|Tp!X -gP# bZ^W//zo9g693wyM" '30@#Tx%`MA/@ωÿMeSkZ<  )^!F!'<ΟfRCML-s!~2   t걇?H_ZI0C%.eQW?zzX$Fș/QPzlt;'<#+_=-ۂ}gl d!!B\@F[MO6+;?*WwQ|  S ҆R=2(fw6|_E&ŠbMB/Ue*4`p_@f5X!A0ЊMv!=8q{ׂh yyAQC(LhŴ)@;lV(Ц}ωn- ?OS~@Y<?ˀ#p L@ٟqФwR|O >̋ d@)\(A A7C> \fb 0@ޯ c  u%c!kv$xFKh5 vz[ZM/h ^$?tv #Ogq0 0TN)Rfc6L ?')n{0sVo #w@t]~џ[ПP_T!`^vӿ GByUY?gxlh t𩞄cgo,Ցn3E$!-Yfn6ipBG-X)MCΡY WM|03=?PXE!F1 X56?$l?HSy]aJ5 \6P2FBU`#}J. %Oo >TbTv4Οvnٕ~N /G3@-t@n 4irPQ v Yq% ([Y0Kq"VBI `k:sca, @~C?ӂϔ[ v]pd 0-ẁ} n{ڸ@u00l_K\? ou[<n@Wpr H\Kw҆"+НO;tIbB``<nMDu^ue32zOlY__\NH$x@J :@"J5@$?%=Ӏ A>g)8MEs\Jw?_~,O1@<G iJ+ Y2FM {%q Gn0S+$F 86qiߦEJ1`B§A6[T >LB ,%XAIg*^r%"< d[~G25<>ӽx-?P(3@d@bP:2|   1Ad柅^[V}G\07sH"CHН[)@& cN+Ь焱,UBKI rG^7"R{?%Gz.@NsY_hjQX<Hep\.7 Nd9[` {v my?^1^BG;nQ7^J񊖣gY3 n#?Ջ^,ĭϐ2䶗0$RWNeߌtsL)8j4\o9#?~ Z@=To`gn@ d3%i]hQ;9ꇰ UM瀊cr!Ze?n_ N hQ,.0bk@" 0z66۽L Z`c8nՋ^! '%ƹ`^*cznN]ClDV`-֛I <3 $_!3uX8wsX  * Oi(9]OG&2Bd`$@)8#P`כ{Xm^fl ? ,@-e p /W۲gLiF``MW/7pgur^;hc7$Bh3^ocp01B{ +(~#^>K^ 1 N`$$Ȥ t󀿎*m~(5lЙ& H!ݤ ) 3*~N@3XzMǼ{3=K/o 9{ Νad T@6;/C~^x/ c  kE= @S{%7pN/$?6}Ὺ w]z i -@{.oි+<}OD)EM}.2(HC2~%WeޏqXx]F4"~C$4/t2Q^B/mCv:W2?VEh "6- 0Ķ2uk2؀\`i&{`}Գ-@ K/繹%(Yٱ*N?0\l{4eoCGl73ٱ1^ 813_Jq:tA@q^ClS _)__n *Oz88I@  D] _xWqWes0mf%{@]vJ$^>>m'wM1 /pf@"/ ?⅟`|f5t O/gpw@`2?`Eoa[@"`v!t&Џ!Evs+kѿ_'%?GQ f5~6pߚ{S h G+_yǿD Ԃ*n!wha٬>k@^C3d/d?B/tI@sA$0PfnOAD>U0t.\57;?kp xwcu/j?8)z&<#J(E"Xjx&; %'G6cH||ߝz;z'(%@09@\//UG;gq@7o9@DX݀]˰чGOC}lo|Azso 0} VVp6K^2:_Fo|AzԓzJ-4N! A@?Kowz?W?< >nWt#@E=upyQGD<yɓsp0?3vCݏ/uG @%IF* A/>U`fcDW`ɰxYʒKߋՃgXeٝwhwšp"(7Hxx &*YlrU{S' B`C~ L5Kd4t_V __? gΠVX0|'R=\փk}?@V At#ѽ}ro$Z % s -HJ}  2bl'Kz } B?@  R @TRػsK~Z+PWAѡkYsfM5x5껀1??~Y0;?>||6{l9V'h-ZHp`ٌa P , @dhޕ>Mz$|vOtq"ѿ Woߎup?-OR|0f>rkj}Mп_שN?5 zuܝ^ ҫ\!Y X_=0@DD1[6b̄d5_̯2w  p&7t~`)pcc˃fxA%7?*L sYC[#|Dv 7\@8"~^p`UV^vAyB7t2@8svdx@_ /!x" mбl r\_}Q)`d QPf{leZ "}.%N2@@T% Vb),W OFR$1hOpH->Df`b஠u];*TJ9F06+@X_ghL(KJ}7 t!U[|ȄGQ,q AQ"^x@X?K//E%$;t]%lEIV`M a3'xM-4d&0XQ^%920zG KN\A`$&E[? ??gJ@7:NꗂA`>[/0=zWJG4)XMʢg0X_`^u3U( j㫳aLRhWxGVZO1 @W0K hS`PЮ2  _(S '87գRvE}:V8 -Y,SA( xCj"XqAG ?# PI[@O@*`ETG7m%%wJh; ]df}QPV .ZP֠w o ,]4V`.!KpK*C/]>hkg@<{?@jE8 x%C`H!0 <,_/3OvՌ 'd/ w*@LOOo1pVJ}/śApIKM?5>_V"/nqp?X*JtPP9@Ye) ^__@N+xA&C@&x U3_]H՗;E2@&x Q3xO\ɋ!Ɔ>MD qÿ(yzP1 pW`UvzU{yf=&xp"h+,v ȝ:_~+1\Y$\U@@5 K/]puBN#@44Z __xu@6efUpπAn l ~G> `vK:'f__7x u!ի`5`$;O}_o5;Эh/@:?(_+w/Ж@b`DW뀷_N@~%O@tlMOmD$]^+ Wnh=h1<: >k[?XOmAj[z|A,uWT{{w  `  C~+W|";?堜i/0EWYcMh%B@=_#\uN0K%h.)lX7o= @7z"XO  ~IX7`HY@c֠`O8&BN4 U$g&Q@;%;ǿHB c QP"W]!*d vs<_߆d/\ `y]A <~WG/¨#( X$ ,o" "u@ic374 >t>r0DXA32Gd4w!/x 7à4c \GT?Wo^P2[ Xf`Iޏ@R' Zv Z-$0܇^#@ ]ANd>3[7)vt@@{+@@OqT` `dyCK!=smoRPn# t @)->7 @VF@,h&ɖ'!m@ NK/Nٙ^eU[)%Hñᷢ&A` `_ @@W(pMC N{u@%" ̄M: # vE+_; ;-p9w9$_XA+kf 67@!BK{HJl@+WK_"uLp3=SOӿ1oлMA!2+`5w.;1\.Ea /i2Gj'^^F@;- \]wp6G qo-'MT@31`P}"!(X+4"8IĐ.1c:ޖH6=`3z{ 5 @{+W% ?޽wիjpMM|J.FR`]Ao闱n <Rfo>>/Ma^{s`5EW "Lі/g }%݀ F{;p@/R0~ `n V_2n7!/XLf=3 `UU? Y7RnBF/`rdl%D/ˮ 5_Xc%koCS¿ b(#&-r _n<m`i i*>]3I 5 2Vun"­9@ 'i _~6O/0L?!4 p.@ ` oӿ`vf &}8!%K?[n`Wxn%$_l" R 2@)..2`Tׯ]~;<ٖE݇cq&   :{PJ@yPd p "g jh%$9h{ Ԧ nڃ_9@!~& =q@L:WZ[o|ͿH97^=T` &%fHo gM}wZ"\Bƀ@w_E,3PD3@+c @` ߤgOf2m, =<VêȋC<@o dXk$_Kǿ{\A. wO,gH@ ,u湂@ l"U[1?+>@ ~()"-+_9#0@i--$@,ZRr;e3ϩ_0 @`-;p@rIh) _W? ?Y@E @1@PD`lA67,-m?AO[5$I`$p/X_)iY}|/P2| lASsAp#`g$SӤ{p~=H+T@> S`UJP?YZ "M@(|] t;qOjF%  <(K!E Oa0hx0_hp  ;{$I+_+UC`d 8h(xk` ?׼Bd Ruoe@w":2Ԣ!O `:hD(d7\@PM\LPv`|5.7vCP V-^jJ 6"mG̩?B/l?MQ|0h(L`+_ۅV/P XFr:aV7H "A|l} H'XU<m~HTP\[ E=_LA@X)RLK#z]q@\A 맸{-p@G O&cd=䚃>=ⷾ+ t:6@%_V葖tp5츓̖p H ,/ƿM;Ph dإ%[Za_ߒTKqF+ m=zrFV_߆" [(_Gu@T_\/{{zr8ֿo=NefI[-,j >wy*:3p8- Pt7쳁po.o9QcTQoSqF"7eguPKIq _RhP@i_pnڻ#C((n 6, ='?B~oFzGP1qL~ xXտ d1NS6H[|Ș @WWdOLpE%۳I]\Ap3pixϬ-ИP wyoHzY[$RLvU[+'\Q7<_ @-ln@puq7ѓ_V2<  LYqLK/A-|pO]!PD]AƒaLXտ _R{ `$v?|f(n( Iu@ [D\يn YΨnP@=i&p _O 3- 2pysl-ȃ `o%yS9C@x: &+%Bޠu/7. pq>(t#=PJ?Wñ__H*b-9C!O |D(tRxX `:{kU_.Ch0w0iz|(4x-=:M ?@Bg v{= O<~nPS \BvE* |D  +iբ[  kH%2`_H/{11,E}&!+H}R֠x mz%B 7!Lbuy9#Y .$E0BHJh1bFwLP|8'@H.Y_/8( r%lojpPm T BU[#O[_:y]<-աVptCGEh3 ?m{3';J !*# a$2@Gݙ \)h~73A@5B XI ` d3[5`/(p£( @%R@Trп%+?m{ ogE IbЫYZ|A1>[ Z _",Ӷ wp% ݁' M VLS9F@ ^=WPAn @/-$C7Ctg7Ъق>'90T8?"r-& ق$l\:i') Ld)M~߅n!%TW@A(z[?W[.kܞ6`g `V򟶽 h@( >n`+b5< Sa{?2}?5(UV O:+ˇ>; 1 R\@a= $4M+_Ҷp;%T#@7Mđ-H?KM⟲p `]NZ$t;DPӀ=.7y3: P,]圡{H" ؅p׹HD%`-̡3|p{pgtcpF{!Ȁ%a;Oɐ!?gj)\7v˻q$-{#\A8 B-4  d |@w"$O 6Vu3@I05|\E E.:4pM#Rҳ&zT{@L ?3L|?68P fXyMsGT`L hG;]O6u`I^H퀧ZeE)p 73nOpA?Ԑ"$,)4%w{BMסA@΍'3lҀdA{?$BH_?{ߩ=Uwp1=\#N8&iSF$`R˽/{wܨBr 뛃JCcpfo@n% `U_X ** |W D~ @n9Kt'ZƛD)^ b];CaqoNKWOtwk3Y7qJ ,' `U k) *vur#m t[̈́VmL%B hwENjaDG`/ c(5?x<{^ s,>(wpH2N+?%56ɑ /LApf@ @ o`UigIL_@a$t.WE91Ibd#mA,mgmԘJ4 V(Y^,S:I@+%w?mz  ,zXE1n ,|p7 "U]u  _o hWMspD@&Kn8apLꖤ+A W4k&?I< &w? :7 Gs\u]o P " ]P //`Y VSGFfp?6h7,5WۅV+jSGI꼨  07}`@ `u篨 셯3dCF_Щ(n(&Wk,!/E&4@X_O^Q7s-([$ZYZ 1@cx9 x!N,D85Y@rj?ۅȯV8/TXpd4(omE|o1"x+O]BKJ3!("oƂ t`]0o !&L?mEN`] Z[8pƂ?mq9w}`~ ,/Ÿ+.az$r1қBD&Y}@VoY*f ;N7(16#֯QZ C`"yv `\qziYw!$OWs_Geg~e$a.q>=ns +Qi_X4h屇c׏߄F7p&zM! #F=h'94cכ#P1l, w&a@+:cA_{ 4ij?\a$o7@F 9е* p:FhXމ'?@ߩ:hL"eƿHW(%Gk`^_ D֊Qji;( /4?Od  =%  KL&N lXp ',oWE}!u oZ-em_?i?DóNOG.0%f)  v]f -A|ԇ`f}\گ }{8@ñXb~<*l ? !|yX:?hGg["? S'`Z`w] A2yI%74RЎL! /_ϭˎj,Doۂd>츐gGE]FO-?&Ar >>c lJpG`/I% 2MW`w/_\[9ւ]")`xj30 4E@+`?M cOX |W_#"v8KDMޠmwuÑ fW{M}Oh,H:UqZ kκ9 dA]F6$`pdɹ0@WcbW (eLZ Z. pQ8*ɟYb*O϶p{xO&q"!e>OnF Ǣ5 zQ@7~Ϲ_8\n8a5i7gn!.?X7˞_H$6@`+-B^:gl<4R Z8cA܏H^P ~TXO9m?M#G]^/Z'U3^X5S >T.0,%Rȯk#{Wyo{!.nñSW. Ub f-|Q[k}-?gz7wl &s{߾!nG]f0P4c;U*(|acm-.ٿ 瓧lE-Ypw8T>7lC{)\ZkCe9]C梮hlE8n-{l|"w p ! <hhd0\A (zHy?mOz{ÿL/J2x4лe 2 t۽t&P yP?9DbUXlHN3wn^p>d?qT@k_5B#_XhqᲫ5S8S0N\jA *RxTp8?w Ώf]E8ÁA Cfw9@[橡.F"479*:A/,0@Av̷o>JPp."A"xnΆT|w‹ncڈ:a.9N7%ɽ-BX/`\f hK_S{Gu-@!X ߈!(&@: ]#?y =!vPu q`*w,$:x^@GaC=\wg=Qa.~#X3{xQ\Mx r|?~03О)7K9e_$ב}s+{<4R1x~\ >%|D.*0`Xs©XksT<3 6Ʀȯ;Q'џHs?c*"LPv[c@A։0 pLflmT|zx:%/w򙻳n^s.Gej&~8/`=e^MuO`_ =>Dt޹K#b@~wmG{|$}RvMG# ,4y89M;iu:fmc`s0m(ߺ1g֟g;i'PW8o KXW ?'g2sgO< s?47\ Xp8L: Њz:P 1<2z}^ d?ofM)nk54P]'?Ɠ{?O5 BED T`.XwpW?s;gF Sgho HߚWیV{-㿎IЏg HG|pskB#@J0@UOKvAEr` ]~F /OE/ӠLٴO'H`0 %.Ofu0V G+u5H]ƨ믯$@` ?LyyA_  _کP8BKC?hŠ`+x-@=OЭ˾amN{?GSOPBP*ƨc; |k2Zs#;?d}c3{ofׄwSԉOIy{B0Go/p8xȓ]&֐h [@" )`Dh?Prk^qЁ,Ro5J`aˣK%x/ `B{]CO({CM?Z hX luy_P *@to~+ kKZ~r-4ALm&IOWvlH8N@hmp!1  on+ͳOo>Bz^sY2pрd3!P 6/wIK@q)PEJAYGnbڈ3gP..W{,y6?hD/law ؃_p"@ClCʧPy("'pN .3T#׈_APmHTᛑl˃N`~+U-*-9C$d GM~??Jbd6 M0=OʍHC. օ|FFPm.QZ"<)GPVfb;쒿hbA+O$^ҫ8?lNIRJuz:/X}T{b#X77sa?U[u19/v4(p8jm:V @B6 Aڥ\m@.[):" 5][V{Aw M`\@.K`oJ =N1VX_mLķ?e3@=a/Y dS?tuITF=&qahRb]BhLXAPO ╂ ^,2`\C7DA?C_޵-9r?kqرե [uk/qѨ[Y$8߯ 1^`GM}r!Yxys筝5: Z?%gB&='PC=t1xp+vp]㮟s{8?u $7?h! : g;Fw_,_?rT~t˜~V!N=u[X I,]q_Hf69odW8_*m-P( V{[ǁNK2b &Α%@_O_ >`o r+6(dIs]S:v Yc'?=k̋M5Lok<. '3ӕ5)O.79=^ Cx~}:t aAS/50 0i::WpA qRi t/w]͵+AvSZrs:[!Y!f1}PQ!;|ffoҴqXF^fs}ffd4/G(,ul@bTP($d3%lq =ċr=M7F`/UO ?xLg@ߔ9y>OgRGo2Vt9~Q_d 휀|}#Splȷq0˶ A.un`5[{UM ^~<| ݄a36G1jFZn8{IB:oK-7x_,XA9퀐̀£41$5BOm\7O,HŽ0gR7g0ŝ؜ш~!8 ? @P`o9d x,,`N\j@^ZigB#~F/LQ~] Kl}NQsbg?4^1Wocav?5"x4 H7b[6\ | (TU(;j^q p%TzW* Oap 2x P"pXӼHb_h,Dy`>GU9^e/Q>cRI7`4f~`/\DN0C,+X}!=L ~v Y>h›~El#Űl)D_AWǿcqhm:hy0$,ǶK5Di kٷ_L A.S.>̽+RQ(š xl =?838N_3Tv3C$2 RȓFYA%o(ɩuq}v5P-CkL6vi( 4^ ^6>֙׃AA@x}) "n"]T>A]OF2K4*4 m T㰑͕m hFo8= pc`M8Td]2:*d )4wu$!jcto~oS-YwF1hX=Af>lCNeAAq"b5{jwѹJbk¾%nJNz1x; @\xMӐSFDlG3ćE0П)E;Y6ßMRr'׿$ja++) _0\W`\ٿct?#گ^ zwb֗ U 8'm;Es3r!3QϬ2OFi)s=~T0[8j傩cItH1#M+||(_n N1DוF1PyΑQ?f!Ϯg o/ѬiZϷ$`^ `"%,RV^Q/50]iS Δ;(kwo~@@N9ĝx:!j ש+]hH9Ï<ȗk#xj^>3 f*iʖ@]O' Yts8b`X*A;4E#} \ώWX!Y&-ʛd*6TD0x ><` Auk0~ThŁ'P_;"N?nÉ}Pyz.H*7?u/D!vpM_Et#kƬXp<@4&[v֌} Q<{dԿń \3;/ɣ^q@vDdpC6Y{ `Ts%h+} pD턖 lH'z}4u!ӚO 67xqw'++E@IIy AB-i|Eͭ'SCj2gu^!?GA[*{ |NqbBd4@.6ܟ$GHY =` ؋doxEʤD'zs*6KmGZpQ綵`|3H)Wt'nwBwwL;]NEb.8,c#U'-EVybsnFra* kh!1n H{kGN_݀Hw x"#}CA\9FJʍ Gwu9%7Ÿ7.SܽPQt9'MrqǶϘg@#8X`f D' gBKr"t~;]+?"27><P!t aNY#{B_Th:| 7eŘw*-t1iG?v"|9n#鸠% x`@xC#'&iJ@ LV./g@zx2;oe*(2wP?zA~&{FOcd̟o:jXW-r6W@|[4`/aq@7epN+&^bhl|?8LN=p79Ra IN#61||v>z/ djL@|Xp"\c J5-)W )~JVV+嗻q<" W*, Y^0txC 4M_9 "9VR?m⏙A_O :7[ R A+_3;fD7ܶN޲޹׬YwPXU!1`oqv BpG9@VP4>x7"4IJM XfZǟmP*0`׉*cFiS`_  C7s&,pG?!όLir1tXlٸM;)m!N?rA箩7qםy?=\@'gโ!;/Bil!xxTAi8C\ўT8ewM!i( vN*yx4H@{,jBq' p(a =.`. @2r#%ϊ|;y/ͩ$3T{gqr3A4n?,E]IENDB`allegro-5.0.10/examples/data/haiku/earth_7.ogg0000644000175000001440000002206311421044442020264 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,fwZmZ 1)Q>crIhJB rI3>? av-NUh~#ZK!h?fπ)C)!(YмSt{e?@G2{HQQ1.0?7.>j:U^*u: 6&4(< Ɔ^*MеvOWSZOff S@=  (Dt =G»l~5:uޅVO;@j$\vW9SU:c{Bg8 f[(hf48& Q" +Q˟[< q4e4 )4*sE`ѷLjj ,h7gO$bQ""л~ 5?!xJɛqo\?V%!EBńEFh3Grm6]N kt7qffu  =NB(!J@ fAgܗ;0U'X(4{ 0ݒˮlt0PL [A&h@~rYPx;s*mCּl9,Ywd}%I\Ig4DP(!$ @) ;yyc_Hh5 5:wL6&6} xId Ee>UP8]o,f=&UBNwG+:0-1 xq@3p!JBD" %D B/e^~+:6+/qHr}|n  P$*ʃcB&$&66$l<<>It{Ŵu1rIа\uYs9&5 :"%D %B͆4`ij}$o/`c78ĝCIyPFGĤ@䁍x```cJ(4L >J!./\LE$=Ŵ~r+)@-\Hiy@3 "$DP( (@g.D cL`6D+W-n2IC2$)HxF !I:4l:x^EP?ݓy㤋d*1 yq;~|&.4$BD!JB % )D>_x^{+/ntѣhCB&aq$t&((4lDVD+@Ht60mJ&p܉\8{Ŕc*J@{4ߍݻ `H\bBPB!B Q 4@g}[`/m?jNGj6ry/?PlX&i` 4ot!7lx  F^*d߅7OF_2Uv՚!= ,1 ":"J(I(DD$  k @N=g ?$OAyãa@d(Aؠ tt BI`s7Jkj"7^:p+X(" Q(DDJy}:[>~QWl@{n`U6es4D״u$ &  f30C0k Y*Fku#Idjd&gJg>XV B!"(IB9D|l+(tFl~mNBWz@аmH&xIBgYI4 al*"KldsCl|8  % Q(zW78%֦WPdm>`%O lb5&AKP 6 4:6t44Y(bΆ78 4Q4&N(/`I\>~6H (D$D#~ x Wl="0P֭_OXzBb&: =h4: &6IP(G]g"S+EC&kh@3*"$I($B nygZ ~`Nl Cu|* ߂ [ h($tlR"D 4 YP a68{5HkѐxAE71 Q( B %I"`]M@?_Nh4A5=Tٯl[I:tI 6R@@xӘ(@&(6I` eOwE,ؠ}_ r Q(I(D$$ d6= R8I$:LP^4ۨV@(t6( 6DYZi FEt cp儲b.( K" QBIλS=Y6O<6lf pbO& 20ࡣ1A@'?*@˜xےmb a?m$IVM[+~*<\ P($(P  bWy?]ǺW>腾m(6& IcB 001YҜ'8 3DlV X%TPP?υ <Y0QF`c3yd+ % L h 4OggS B-*8Rh mkljegf`]Z4IpVnGI oLZnT$.% S,/@!x Igc Ŧ$SY :.@$3p2+ MW A8""  %I@M#[ʄݐR!@H HDz.QFaY;Xn"K_ FY$P X(D  Oy)VhdJɂE`NP@Px 6 lYɔ'w",cjMB BQ\,.6(&:&6t$ۄ†SC`I)vhOb>>FX($Q ļ'oaY 6SdӀYY(7t,}17T0J(B"@ z>saۤfcAAc3Q.hP(yl$ÆYY(7t,}_07TWK.F! B$` نh@:`SG`AA Q(0QyqnyQn< v?%allegro-5.0.10/examples/data/haiku/water_4.ogg0000644000175000001440000002224111421044442020276 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM, o +5C"~| Zn$ t8P1BhG:'[m8gm۶*W(7m6p~ZU^ k4^zI"tZȃ5{Z>ⶕl*]r4+V4h*e%RT*k&Vsf VWW(W(ݍag7EA 9x^x=5&:|Siߨ/])z yCnߖ˙Cvi߫C뷢rܼRv5KՕUa+wl_~NbMjsc=/0nR5ٲ{sFizLRo`' ]Go (lIOѠK"K>#tQJCÍDA2n4OcPB('gC߱۱mߌQ-3g,?YɻM}z\r6x@'>;D9aP1|}޷=|v&Bs v.e ˪7sE]ut>kRM h ʳĤؠLH >m RF AC/ѠKE߀ДD%Z!Hnt8 Y7\ ~;_(B!J(@={uи/C6 c9s8>sҴh_͏o1R`_\ zWJ\3R_CUP:&&τ fY2h7Ȕ\>D/ W4$DQ(""" ?{k=zE!miൃ9j0 X>2m>]E4gF孵b|15cDnJT4Y P t 4LY 7znܜE6roPhIb UBDP""~_܋;}>c!x>Q7h ђ5ˈO[f{?z:ҿ|Fҗ mu`{pZzqvwO~; %~7}hO+^K/&_DGGv`-ACIQY")x4-tgI$ h0v%mBDD QmO?{9ۺ5^Lmt7fsKksWoK׋,Q<А:wV>#0}挿%=91sԕgC@AayP t<4LY&4| pS"I, h%=/ z@AbC(4 yYM7H(%@aeP(!JBDP~TjyͿ,s?B̼8]y/Z/՝֪W_})C<">|MؚJIAK(3f6/ COLwjxB TGفdcK%t4L YQfA$o>4`)4l7pQ(DI$! ;;~|Ѵ,+] +M @կ1e҆>56 ܚ8$ u< BH`2(6xl:6 :YY|np,,%Mx!.! %(P ?aoV{.O/D0e<7ߞ^WzI{c_-X+hă M0C౱F@A@"<:lt&Y/ N@|IQ|oh4@>7`TEQBAZW~3еƞhOSL|nʞwokeJ>f,{ϹP<惢G(o#@i@3A<4Lh4PH Yx? .D /p.4ABD QB Q ^ۺn5eӒoOop~=S s^LlەS5&s 7-t5} HLt6 &a2AFc3Ix ' .D(l  EA @BD$JDI_gwCIѲ"A">|v 6SND'hw/k_@G(@aCGeCAC!DOggS: ǗrM }m$IZ]|6 8 mM ,DI($!(_{[W*w2kdnk. C#l1"_P26 EM#@ P YZ]7Rp' vnB!PBIBIy|"Jn>w_r9^7mW2+.$_PJ6b45$:6BR)@+Y:E'"Kǩ pb#7 ` %DDPB Q @e-L} ʨ֨kа}÷^xGfIy=aG^@c# Q4 RIzN$=Oi*o@b,D!$ (PDUܾmt-!B8~o^WkLme3` B:0ĄBAhR'cCx& I?;I?;h|@PQBI(@WC ah{}鍏?K`^NL0$ADlPPб.kPallegro-5.0.10/examples/data/haiku/earth_5.ogg0000644000175000001440000002241311421044442020261 0ustar tjadenusersOggSi<\Lvorbis}OggSi<DG-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,N>qp 7ML % Q(@`( G0^0O aKSrre<,1Wv/v|5ҶѕE hfwL;s=z2B׸RHB\i3͸0pJzp E&&$vB j :X'a 6zAr,kgpIJPrܸ*@X"R@cײ~ě0$ا^}Uu%|c+}=A1A@w2)Hu * ɕ5 ԞO,J= VɔidHDqIyҼ @7 ػ x^;-kg@ӱ <%:$=~.j~}v*XٰS'S@aSb&p %946z'A&IJPaOdk\K'O <*IPyOf+  n ~ؖT&@޽f|k4fn;{wn` l8Dg}7A6:mHHj* p!r{g|hẓ>ĿU߁32 P_]o`9z@+/؆Od_(BW W>yGimsI<&JmOdZO\4&$K"Y |Dٍ!y>|yd'O \$EIJW.[ÉWʶ)@(a͝@iiØaT@]B"ݡ0BH!&$(Lؘ~٪Gp.S/@d<ϓY PP( Շ 0L:ۀ7 N3ZmF/~lc%G);MhllH&,0Dy@`b5<L::X*pleչqEA KX^8 @>\+əiH$QBI(Id??1#NeX_C0P|lv~q[(FѨ@ 6 gRoFCM[K7t)@ hH&$l6)@Q`Gqڦ61U3@y'`|>5p2IY 7s L:b pˁW8>w ] |G⁕߿Vmע!:)`H :5h( Q0T A&&i64x4(H6L4Q j%tS< .r?~#ّOo'Y Rx B$ QBD!""p/^>d`0?3@((cV'8aVܒ{4#;@Lt4(l::&[MFR@@( _Dt 4ȣ@Bpp53g 3p*J(!P(J(D@\|>8>^'>qaEr9X;@X3T@%NHv-& L 6 AĆ t(hq{bDf0 H}p'"%i4lsSB" Q$ BEmkx_q} g zjJE6G/ȲEtv3kESuڴ(41c>MmF6l=m::"#: 2u.pɖJB %I$DI0g-m@zcGMg1%|el}Y ~X{UhM8D_%l6 &:ƃv }рI4a{uq ]GҤDNLH_Ds2|n5nHl(!J%!"JP >$] O~8ėŠFD wxT6H(:xh <6:(xl  6:,P@94"K) ׶\p5h[XG ( QBDI G/ĸ&'^@P\; Db"ĺ_wnqڑgZGG]4 4F {$lP4HX:$@`ݸv9+ .֛\%pvrӉ%" %4=R<ѓ)nLclǬ|F~0u,OT(&~|mhAWtDaA)L$ :LY$@p7&tI@y2?1|BƓ'vF@QBI(I(D=%prp16yLpPFhLyO (ԗa$:@.t!0wA{[Plxx( daF$`dYz% `J;gŚH jGM v{N+{D)HGTа'x  b"@ؠLL&YJQ̉,p(8ٛy8s:h.1/a J6bv[]K(zB#@((kP:h&4IY\CB4#D,DNN%DZX(PB"" P_/m  xz00W!11)})nBa3!yH$1QCgIš"X/ڍՈ"%%PBB"  ֟@#9L@2* ͳxgc&+ Dё`khP@ Mt0)tl<$OggS.i<8qslcpg_c^_^SI=bđ  3 @G^$^BX(!P" !{/"CpИlhy) hx  MÄAa#!СuY0fGDY1?g@4@,>a|pv@(!% AWW @6 ׏+c@@Ht&H6EͤCY0T@GBdQjO-Ƃ/B QB{d%]ڂ>CGԑlDF6: I0?f@@Y ; .@,89@P(PBIJe?.-@Ogo^o:0a%0) tL xh4Y1V@/X!)_y~p0 D$DI(@(48 ~Y^ؘb h4<h<&(&GI>cnXN@4 `DD!"J(" %!7+ٽt}-"= ΄k`b (&LhLH:::6 [@!aYbnY>b I,I( B$WS40*)H`ϩCm <46 6YЁYan _@pSרIA*JBD$ Q @Apt6<aH<(($lthDŽ Aæ!hIbn_ 3k<f@,@iD$IJ M4 u_eR(M%ИNAƒxH$& x(6tY`nIcN 5%D %IB@\-z., UD = bä "A<`IaNYaNNfpDI($"J `O7w<6@뉆m6$ BäIAG`!x$ : YaNYanY(%Q"qnL6;҄fJ&B-`CH:&$YanIanf3H @D%D$+o &6t<:&6 tIallegro-5.0.10/examples/data/haiku/water_5.ogg0000644000175000001440000002211711421044442020301 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,Ўz󰣃C-utv:ɯ'Nxǫ ;1ȃ*Z*#< ;@27r$Gd|/r{@?M;- %!S,F$! BD9=+|UӌFCrV*YlZ9Hf;nY7"p[{; С4abdNA=4С'tv ;Mz—(+b{:NT?݋s6ey2 N?J~uU,NtnXsK~mhrwC+6i/32-[L|YS!>a-0CGe.B=Nb_v-e|{++/rUKfR5rtf@̓!o*+)Ae|v(iӣcll( icあF2/rTi"K~OsrD9xg*D<&n=k 铇BP~v9ײQ[m}l:ܶcھF;[h;]σ`3Ҵv#..+r޳,)Z{DD/o^_oVth>yZю/[BlMo =3]_ʌx>F8nEl]W2ڛUvn3 0φaM Y>~D(P.rD P 7oW|6R){]f5j<{|Kk5^aW×`=B|QLmr|:#rZ'Ff}H"#bC>@Px07&PP6"''z ;Lɯs8ǁ paP\B! %D! o#7x=cKn+e}vw ϟqY9ЖM3U;iE %AA@ѡ@AA+H64 44"'%>})y/rx/|`M<n<^PB!QJ~XjH^MS_ ýk9kmOhƻd(N5wnlZtz(0((6h:4t$b^oc!2<"'P~<@.OOP"BQ(DF7Ѡٷ䴁D!c[^n>0]lG =ŝzn<<66ڄiCAGAA@hϧȍ{:LKw;^( P>g$I$DDDP's!51ߦs׵{;AH} vSyy67sG(Jhll]$0y@/@) &@ χȍsF\js"SOǥ @]4acD$ B" ( pO.=}lg2!& o5O1xK/d^6=>uy>QR0-3ʗ˶`c ^0AF7l¯ȍ8hӗD&r>?2@?m""JBI(PdWOӜM4mZY,ͧ˷sN]cb{w:_ d|7[iБL`PP$̄-݀YРC(ϛȍ9~лLMݎLWQϳ<cQBP(!  {$ <̛[->u;o1͚ o¾~?_ l wװDg*#4t((l0ux&L  OYRȍ}.i"Ky1 غg:? @zD Q  x{*NG^i#izևGU;/E`n=N@ذ=e߇_!6<ƒdAӡAQxh HYC+xI7D$ro7U@ .0J( BD ytyxZCSfg$}p?aWGW>jY~`OlƮ&(&P:6:6 t :Ir]XGNȒ}";< zo|@ F~+ %D GB3/xK!7'7?4s_Hai_O/kk}1,i RA/A YrC|6 "Kᶋ d}O\$ BD!JD! pyFKy7_kz33!غl^Ͽ W] __!?w <'biRmlc*L`o$4iBIM ,MwY .'9\'BD" % %;a^cUyT9z}:ǫgy)Fú;eؚ@$0غahP0%<AGِ@!MLYJ]phURz-<di\gBDD!JBI" ?B}55lfyU=|ս:['?GL(l:  :D@CmRDAY*E| 'x `>I2\(I($P$ ܾ7F{طٌ} #M_@$S\Hf~ZD|g B&^A:C@@iĖIoxpUYR.0<Mc:B %D QP+s!m~3lAqiom8 `s1-;k†P(@`c`h01&:$Yx a>HYY|. Ydp6 %DIQB ^ Ai7$I( 49Xɗ΁sYDM;}]j/2֏|&.!5&& 6<<CYZ.xo 8@!:& r+yAUB%(Bه@|$B25-G>{Ax e;|4_M@ICA @(hLMCɄIZ/]< M6 @\ JBI(I _#sg%qa[ao">v#5G;t 468p6 $2V0Q@GG!aBx`SOggS@  Ǘ,5 }uiIE|6@4DK:fU4`@8JB Q( Q( ^5o_8b紏($tM&g<tؒ&`d;AC tLt YM|"Is 6 opQBDI(I(!" dow$HJ<)})vy[9͝[(ן#_=w3 Ll ulH xlPxhhxlhIE| @dt  3ip\(P%"@fbVY1߫i~m˃@ dsOPMN6iҐ44 $Z@EgE[cb*I"}S:@49 U@Dql4o %B!"@v YT"8C`BM U p"za"A")40DSHL666xHS݄6Ćl@JY:8h@! PB P(@ _]F 3 8?L 1 h=` 6sz`(v] č|Et<(6 &tZ^  Iz;Yzvp ZiD!$P(Da pk`|y ~ !yb2VoXMԙMѡA 64h&:H2I);L,}&8O P( B @C KlOTc~~VK{W_W22 ރSGĆAƣMallegro-5.0.10/examples/data/haiku/earth_6.ogg0000644000175000001440000002240111421044442020257 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,%}=jBba{AN<'jYy`uMW[37AѴ=jP$j oXD IBV kF y?=dC>U`C~:ӇOϏ}sΖQ#@\G5Wؘ_րk|*xxn|@@1:{H] z+~`&*HADߵɀj[Y"!9ߗ }U[p=_m'0X*~M`iMEc{X A 8@\ʝ +6Oj>13oT (D8noͽˍrKm@C(/wc%qIL @ov􁽰 Lg]uڀY3\ y̦yk N.C{NCv5ܧ`;NW4& 6vIYj@7[1dF$p_"s`~n`f`*Q(/G@loG[*}WH|={,[:0w.4};׮LKh:&hh&FB@Ac*-໰';т ͘bpbI`Pg%Q@ `lk@?GC0w}!] `]n_$uS`4n@MFt: ldM"`B+@I@8]{ai o؛-z?gts lX KB!$J(H6@@w gM(?#cA|gkHZH|S;WSj^u4oy7 ?7L Z)h@udF@GI /mxL jQZ#Xp 9&EDDDDQ$PY9dy2>uK.8D2W@d{ 5>u3mAJ/8k`qăڃfIMP4!H`P1_Nb2Q`).%*Sp %hf@UK"" PB3TQ埿K/gT^F{:83B}m_g!HJA@GQp%L FۄAfH4`PI@\(˩A,<R H=oSP\cC"y( UB QQB@%VNÏ~(? ϕ\%n%Dh$6 :   &Eyx`zLH6(MLl$D`Czr'\G߈4G) 2BV O>m$4O6%!J(PBJ@zZyAlkak$ ;'sŠѕNM vDG"!L<`c۠)``&Њ#`=)C YzQ-@ ֍Hs 3(`X( %DJP@ HƯcw}a`'ySbŅ)=r[b9)P3^E"A hС ؐ:x6ROY\DS,@ Dc\SMLLK/I(D!$ %@0pxx7^~uKۡ%|=Gt9~~D~/P`tSm: L<_[zcUl?q c+MH-`ӡ$&hA@A6 &4lL  Y\ @IG)LdS b/+7b"UB!JB %!a ]ǝWl⌰7]JI?`ؑ~짰| q Lx6L҆FRG<4OggS?-*nMokgfdeab^]\YRY`nQ#,}5 5;1rI" QB!B! 8@/{8yEc@ wT<i rCLul 4:Y/UnXO|VQ\CMBx% %DP( @x},T_62' `@:$x< 66Ll6Y/uHү 8=D(b*BQ` .j^h'.f&GC/PFlw0%hPH$Y(v "K?#0d'J QBD%!Q }|/_:69"[pF!h`2a?$P@YanIY(tPMRDB!JB A ;;!t<4dADCla4 DdYbNI)ODV@XQBD ( ?o@WPx{ qcmL&IJ Q aBx(4xw H ]I('urY>bP#J$DDDD %@!@Xk]CD x$H IA# 4I(t ,}0T'7Q%D( H׮x.}  !d&&6x4$I0 @#1uIaNIanNRTBDI@!㧢XٰѲ(,C0٩( P(DYaNYcvf `QQJJB @{y:S*RҮ;|7=N6  6 YaNYaNNv%$I(DDD A6|Llt&kxH,&L M }Bǣ @@CYaNYaNfr4BD!Q{ ਇ t&4BGxH(Hh<$<6l6 HYaNIcv\A(D$D Ppv~ P 42[ΣC{@allegro-5.0.10/examples/data/haiku/fire.png0000644000175000001440000001115111421044442017664 0ustar tjadenusersPNG  IHDR88;tEXtSoftwareAdobe ImageReadyqe< IDATxZ{]U}}In D"<Xk#iuZ#DhQ iؚqlii1@MmP#!!ko{m$I??[1aSo~X 7>Ύ.`r|Xh]g+g|8BXylqy/>Zz>͹̒FSr>|J߷୆q>n3e-j̀dh }!*v7?qkem^\(j,``QWdfെ9|j=PYF>e>l>qTa9SmXQGYy??9M TF%5rEGSl9d>jd kʒP}祟7*:7 pa<@1YA,YQQ8=ܼYI# DOY66T7M7 !3' j5 -m0P(`RA݅Dr] ?MuPl%ZRJm%˚٧ezpEpe8'Dzc--qgF 5e͔Zk*1%$ceA&5r 9p6vW]-0؀GC7\}1I.1=7m$enPXBR- *'j"LS?:.x1rz,'GV]H3`IC+8 Ly.rC"ûF1)GG!"E9 ,-ԍſE_ܪK>TyY+kJf(GLy=O ZTUkF(Т#uVHFlM+I7x͂qaz(Qk$ hkqtrW\֜Z*G?(v x5.-xӟGDTƸS'& 0Eh" }iA˶$pVux}p[_C+hqp6柌óz2tuKs|ISiŒqB% JB-yފep..q +-FyZE{elGiYSr L ܪ ׮^ ~( @O ]IK3ʾva"-Έ XThNf0w("c]_C/FyN? \-f BomZ6v=׎6Ѥ J: Gk5_ű~AnttbBe΢(d%|m@j^Z_2JU,^}}:閄$%,HC`>T-9 š' e,r1o @K'gC͊}2 bZUThq'/.UP<ԏ%k=G@EbQa8Dy(S:"Rb+W=込f'ZI{x2Y秖ƣm u HMonCSR^I)ձ?g ]l>|NiqK(+pu7מ|GGAw u*J1H2&8btYEp6n WS"wȀPdo V(sxdz;J A*:J[Y'Q]ȹt. 7ǁ'FG| 0VD_VkeVc1DS?C Kl /9{иxyJM{ar>",DkN99B VKȆ8Jd4[‰]c7&0R6}=raL ]#JlRB5Y~%]9+9n|^<ȟp[H(v">/T^9q12@/bw_~;Q6Z,H3u1-TlE{ւq0)ȳ_G^"1ʋؕx+^)*sDn`$AZ:ADhA:ZԐ%2o{jGVMo,ӶJR/tؿ#iIr]y)b@ imo !Cgf&;gvrj$˔`IWz ;Qx2IT,]sC*b?xkKˇm! eT cUE̞+I&jTڥjY);ZO]"H*48AK4n5c?ށJI!7i?JC+kHi,ݒ{>M5d܆Z: ϟ΂j͝@:Mov91q"P;uD.Y[Ifגd_nsʽ=5+arfۤ3̫Uw~Lι[\Kz"D 8'2O?.vݸ+Fy *,v&+/v"B/JܚO?kzi5p,\o:$@Ӝ Zʧ'C+n`_kViJY^`݃08i!N/` n d8EAQ_z˪0V<>dh\с$6.=ytNIXԊ rDŽ$KD/FFkC!WORObtXh߱ ]O6܇ʹr864y֧K}\Q]+k 'M4 "d }}PˑƋ̑RUfdM44򨓂S5z }"I>u^OiURԞMyIY.0YeN +Hj"oZ:RIKExo%QJT=VM; c5w\7pO825JyNUo7 nSB{A@0t/+*<>H0[r41xv!&8=60=`! EUnx\7jڟ]76FPf<7E 'b~C16NT؛y YQIENDB`allegro-5.0.10/examples/data/haiku/water_3.ogg0000644000175000001440000002254611421044442020305 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,%{_^5f}eRͽ(+Kk9jm+8VyȜf^GcƂ`7(pLECہw-6hy`~D/iHl4WE^ڨIvB3̆ch39G5I,ycT6o_Q]Js-<~6 5&L86l[108ub[ؐY|C7s~e"QʩRn. CkNՅ*E90rLYVFBݔKr6 MXC՚ %L1uth%poD%T h~$gl4G}D5GK3>}OlFZ Ɯ}m2)TپXsn[]]֗FcB`kya}r__Ǣsղq=Gcr6L㕻+Un\ w[ sjsAum9U4GGl'WTL/LoΌhţPH1;Ft+֟wZ|?gj? _- hۚޜ { ۹ׯtҽl~EST֫/+ߦ;G筩-?C\l9;}+mS%%ɭ]QAC#TAGx t t4Ypװ"@$ɋDa tF$k.41FJ(DDD w6؅!F_o~k~?Nx-LF_K?#/C# __y(TG{nbϚKyo <  x i(l`i<Y2h5"C$ɄC 2qQ$!J(tt=mffF4s嚃n[?UTR2z6>hK6!V.D-pB<E5YW]׌BQ,t$<6EbHY2h8?h,^4<&/h Ddp6~@ҏ(DBD2&t#GKhqk쯙0as.m7}M^>o jߐΚ\ܿefd囻ᕭ%Yߋ:V#m<4QB Q" }g#ɨ8t][_~ i2 LfoޚʝUc_ƬP$ >+~m5w$|4ZG.L4l :@31IbK4p`"BdA@l|QBDI  ؖY8_ w}>mKV)?Cm%C{ ^V~-{)նlW`YfW^ٗ2W'e1:"h : 6z-dYB)4۰!C4d_ױ BT2N bIQ"J(!W"O68|UIs楡mZ(N]43>dPl[Sw?W =4Klk$zAǃMC3xhx( L Y!ؾ! C4}O s2x&F;kb^f6"% +us k n{) VA2Ebj  JFCB#C &IR$nDHOLpdp p|Kx$( %$S7ǿ3=*"z^<yjcwɏRW&+}ƜЈ)+$JG D1a#y 4t(  :HLI!'x$7`6zUxDPBDDBD|֧wo/G/0e`)e~W<ܽYF˧iAy(OC!@cѱao mMYrCY }Ƞ|BDD$ %DI wM~)vҟ׾;:7O)XpO̴Z-hk?(n[C6NWPf[o|o/CF/oEP6l&=`w mhQCP5` $Y/ ހYI|v*%DI P(0vqmz+nC_ ! 63Ͽ<{zv[J rK=n3$HJL6:V<$vFP@(AGQY.@hҰg3x"~%BDD!?W;#/xȈ4؛@9e5o|z9`G|2MLx Æf@CRAOggS ǗRN zz|wqp.YON @{A$>O{|a .xBIBI(J+ a1^c|Y[>(0`wA/ڶW]|L۳auhx4(H$: f#рYx/@1 4j~<Htp$! @X~?S'{C⎣K޴it^[Re2j/rF><<0m(HBCP L&&$$(`IZ/]݀hY/Eo6 "iM aDPBDD _>w8buS|Kph~`ot0I N!%h $^}f YZ/]' "K`"h@4 Q(P z}lҸIu+˶?>a~}`~A߅~)7 lo%$:6a=aB ` 'P(LhC`OC Y:L Ds0 P$C( A 1{1'5Oo Mz/^|O9塓7j%%N"(S<0M`nlMLx̆ I/Em@ {  @Q(BIBDr?$~>zҮEjw,ڇci k|Sx$iCR)Ac2I`*LY:'01 t$ Pی, (T % % غzSm1K>>et/=~_ aԠ lLDN&ɄC7ABY";}hI=P CBJ"J(I(C3h_;@܆zE 0ʓ Sh|10x=Lx$t tD 0C"YzOH t;v{(BH60JPJ /ۂ$neϋ0bwON ~ Rol&< D OЁ@I'Yz,\H V @IP( %! % O X;3ddwFg6Et7ƃM6FЀGNI9;L,}V(DQBI(D,f&*1 s_z]0! k=5lHh<hbBEAذyysvySvallegro-5.0.10/examples/data/haiku/water_6.ogg0000644000175000001440000002237611421044442020311 0ustar tjadenusersOggS Ǘ, vorbis}OggS ǗOs-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,= pߟ9 mTGWc `"m,Y_cFkoe}lvc~yY (􂍆=K|>1tq>>ϡ nK2{ƎowV[ /W dE랢c{cRc躢ãF }ԡI2O{ `Y?D+` 7( @^Q7j>w9rJn]W#*}mUڿҏNg*,TZ.%aoTM;+X/ڼͷ9>\]vVrk;byiV_'Fog*ge,S/N[1y䋩ybHa"Ll&YCV@O{Id{%r=U 0I4Q(@}&Oi!Fw"[7,f禖g.8}C;Ν- k\\U= #xl]krQ$[`*͠M: =HC6D :ĤS h  "b"Ձr(t4op(I("JBPBHX߅<3 qŜoہ5C-͌^riٴ wjllts?ӐR!CDh91慱mߗV 5B?fie0^5Xlq4gK ]AGF hPt9;P/)~Wn(ȓO4-Œ% %I(I^F8m_S-܋ߙ,3Z?y(_0 >fyfkeq9d,M&h &LɄƃ-#AhO Ϳ D)r <ГOs~ P(DD(!etu %W.7w`cB72_{M<\bZGa߆s(UPp0F4H cIgi@NǦF¯ȍ:nz)N6@FtI( Q(D QB`uB!:XR]R T/7teá9XSV_>Jbk =I (CM`CQ@cB.@1, `cj⯫ȉw:&3!I*)x#T\pI(!J($Pwy+5'_;s n|%nzZlc3N ~ qRN4$ 46&$PRȉ98ހ*OdJ/"'QE }zC(  % _i# vc}^7Rb=ޱ}ьmOko4`YYb υ ~6L ƄDC `*4$Ll[rȎs;'2gwD71 tޠy.%DPBD$ Q"8T*w":Sa` c`AיŌixͲlpu"􀍂dFCSP#x@+@b%L$ ϓh9'HLIMo@}`$"JBP" dj8`l1+/Zbu b~` > (V Bdb#yؐ&x$ CMzRx"'ezDT2%PBDD$!  կ y7c0I `Oimw(py |%ak_W&+ B(@%.:?jx|ٯ_X'ůM݂b^ k؅jG&4&&::6 $FKly(lIʯUd~ڴT`"KEPl<,IBD(DDp;D{Q3jynŝ8{VQ@˾_~[ ~0NL2mq1INI$60P$L& I*E|^!`/E"I屈6<.(D! Az޽ir{ vK^-݌,&3Tm 566 ݡS.毾2c7z ^ ^`RQé'@`C4((* 6!" Q"" Q ;@gOnOEfNsk؊F&ԾWAVAаIE:RE@ǃNRY.\*s<2+P0niQ(!""JBI`]%o7XN a?4V*kIAUnax(]GB!yaDa)a|YZ]|nд@EYZε2` YYz-{ n 3 % ?? ޺k`:s`J-g/3LC  NBi(Ht & Yz,{ D'(d1ĪQ(I%`믕Xeبk?D4wx @(@ c¾>35<<E@.CI4IdžCYzv(bD''0xE T Q (DPx^@!ﯣ/7@<ƹ;i7|(u a!A!LH&lCʃ&Y?;Y?;`z  ED!"$DIBD"6Rz{(9uVgo ,6lS#R+ؿPFC:LFBPH6H< $I9;t,v | K(QBArI(iZ,~.+s@Zw72٘C4& @cCSchI);t$}:JB$DPB gC0`j\VNw6wCh;7c8U֠tG1;D@aMykySvallegro-5.0.10/examples/data/haiku/main_flame2.png0000644000175000001440000000764211421044442021123 0ustar tjadenusersPNG  IHDRMstEXtSoftwareAdobe ImageReadyqe<DIDATx\۸D^7 (wm=g3y̮{uz+$=61IM8qx5m03}^.N=htOkE}PLPiUԎ@"No] ZQkI֭,!wkrϡqVܩ0F @LOg>n f/8o`HC wKhܥMd<8wYHZ+ٙ 71ŀ\٤? Wu&X2ZGFKtZf*O0_'(kT3c1)|$De=F(hhw. 5zų d Fqj1pR '-&[+yL:F~lߌ3:v0mЂ.'[+ P vI'ciЀQm8ʐAmt96 W?E} . nMիg;#&5& ΉM< &Ry\\M0DѺS?ލ4nqohAŝT0JaVm.8NTQO]S"/'3 PB@21kzJXQDHU3nx*eWci HRdFhMGaVgkm*_Ԩ]ήxOߴ;fNI"ahEϴ`%J3O.edv(B r˦0e"U5P#sPʟiuV^E6'L5͉<3B✮9cYc`݂;LBmDwIJ;- H/ԁa݊3(%Ohmu6J4ZZTFz\ЂIzjB^,ar6~̥[$6F>O~(ᧄ?c 0=nJLu~J.SJ בF ,!Riz* a7\y۪Z/>WDP62)2H<Ƹɦ00Zˆ o ԷN5K$)֣JOl 9όIع*5`&Sb>s!ϩ4,;Ӎ*;iɜihO~,G$sl݊NZMH~ <9{FV:^M&}nJ5`QZm[yXa 5P;f 8 [b -2Y/iw\&8z t.L!DޥB4Z7'w! #i Fm0p Wa-+uS޻O_SKwvF' U"e'#N4P-a$@=V+HD=5ǜ"+Pd{V%"7v_#ۯ=dCш WJ`^UYj5+ɲf&vcb'p㎾GXq 6|lZ.(U0Q"m10>OvөEސ[)9fPzm O=Gٖ^d0Rs.A6ӾRهS,vFG-1Ÿ}q`I8wWܺIox57ݗC}-0fɖzRos*lncNޭ*j]Y_lǧF]GT\L|i^yV]<΋z4qS1*'<4oKJo;<+ol (G ]̊ri? ׳":ze i,'õըI Ppgoi2Zg2o2j4={e6w$w"a6 (y ʮu\vVKw*X@'oq+4i,iy Ly?kFfGWtSj\u A;im9f3p^[6+vG}'/wtŮoNùo\ȫzi'o秶z}m#L#0'y,63IENDB`allegro-5.0.10/examples/data/haiku/fire_0.ogg0000644000175000001440000003023011421044442020072 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,Ӄq\ܞk/oW is{O/ļG=~_/m{8z"?Ha_p,""z_ھ}v~SV%-f@ S6,&ќzd.Hߒ\$IGWo٬)7wZ -D)eG_Sn\ wVy[y7|Ǜ'ג2Qٵ^W,7sI<<@?Z}7^_Oļ$s 0߹=rqY.n+U~Sw3Ѥ<7zI=uY}OZ^fZߟ\ǕEǜ[hY?WLY{`g734L\ۼf_W˱;@^{WZ_)٪>J]#>+뗳ϡbO?߯%11?ZT6Ż[g xKIRԓBW?`s;/~N9a_,ZC@ #KDpLvT|!v sl|sp1n'qrޠ1*_($~!Nٞ?|RҼl(ɰ$%q~ [3!jAfqK@>7q*[x8<~Fs]؏>Bą<6?m129Z O!援yh]V]0mmY;끱>+ wENg|!;Ld'kQuO^1 Cb~x~9KƂȩLJ3%d (+zC0wxpC01M< % ewxARB |dil0ie%৉/_C MD':{VQB^eNTj˴] H |DAyA 6`C~ЀO0hKL~S`7ۤń>+; k9)}GĕCx+O_DAF)^Fi.@a"(Ě's  z $:a 3#0gJTpKGĵ|@]”[`P3urLҥE[Ez=M,8-"2C 0|spUEeCU,xwNM- 0Ïbzo.tYnn'i|,Tgf2Ft.` @´@Bb|҈~JCx*]bҐLJJ$Q!,as_ Zr h|e?# 2fw;o]G|^g94{d`RL5`C h̋xLa Wj(cwl[3(L8s9c>KUO\W1־ZX͓ Mb$Pϛ;A@!BD)yfA0*E8  ~(]+q7 QX=xu|{Kox0?ُq? l~X ӥ8|_3:AApx X򕲮^/ga`)dHT趧76 (Q$^DJq`2J)e>fKg4['i ZI$!$P nw ףtZ_>[z=4nAyO誋~H6`n9w9N<ńc]S#I3 zfr=૊)ڈ/9䓻ۃY.gix-ŘcRIS@Aјixx0> g#Sِ0l4z9` )o4 (`YU( M~OLgQw&幇'%#kc~gP|C3:_"@43@?7 l`Qv9]Y|vW|K1wWk2l|ܱJivëXJ%d&L :lllh> 2Ad @8#]oߓ*r䉸$A UMQtJp+d&' .`pa~8`wG00@'M&h?jUb/Fw_U]X 9XόWWDK  BFE>Y $ @D8<@Zi @cAsC">tB B@6226,w/WLM\Qx;`筐A@˿+@x}K~A ? ~z oKc7 pơrT6ő:i_gH9Iq2bn/ t I+`kh#IB HGz4s"I @hj  %@BFⴁFTB B %@D¸_2h_R?է  Lc= WԄTuM4^>o]C Ƙnc-2 ^!׳L^MՊ6S)F@S  $FIL +># mXRLNBۈ?y{W>C^7O .di !W %( xpj:\~uv5œ0Ć>[?'"x @ZOvHƃƄѾ? @&Bx[MADmWK$Hl :6&) 4OggSB-**zxkmi]HD BP!Πd #߯{>O5ӈ8%BDQ*3=D: __FƜ6GHL]ArOT|wxȟ`0y ӥ Ɨl&rח)7O୒J[V3I J3iP0% :&@S~YJ`% }KRS{BPXo{K|@.D4 Do_x [fKEMh xtxA  yxh@XH@k4T5S%DA9S~i%  ="""J($!"|~֕SFd% 8#~%G? x^?0pd+%P0\n7p aBK"zP,T $IɆݑ`B>Yn0bT tpe<dw ~xVàxXQ( Q(I( )ivnsqo2B~Wû.}'3 'tbnW{ `4_pӹ1ؤWtJХZi@!$(lI@"IO+dmȆGTj# h*pOND@p (P [+sg]Cđ9"4xu5w/Ϗv}' ޿- ;@AOh==eO6D(@tt` (<$[&YJKP fI<"K`5BdGA'<&NxP(IB QB!p|ө~Dr|u uߵlo@&Wɟs xxF>ĿMN0 Mj +l:$:FS'I:J $@di+/#,Ǣ~`4|]QB qPVY~,h-{|y\pOw?'(<3 <(t-' 6tt4$ < L$J-Y:r* tnOnuWn#MD4PBDD$!@Gd3"/DC ~I$a@cR@y hlt`?~[ZĜPx& &4[D$YC(,=0 Nd'-3HB!"(%!{ ^?BO{?@h8 ! xU0X@ςI]l/*]YQ dP4L H&l<4l:6YzԎo&ECfIzw&  (j4 BBp+^mf^qeAn/C:֥&0? NhJ?{VMF4t֓BƄɄ IA1-Y@$]+ ~fi B QB!P(/B$\= *<qA ?@tbNx ǘ' 10?3? N,h6['@CCɆ&!0Iz3 MXz= f2GpFVDD%J r󇈼>ܚN@n)gAwǞbvEh3a!OIxF4 sæGBQh Yz/v, @$ Oo(ZՇOp?E o3!P,&}~i#H5$6&φBG#љYX'"N"KN@? H$@BI((ėiv x^^?]^ nz9&r`MaGAdo-@6( 4Y(u IZ)MD~xy8s"(HBDQ(D 0/ÝF||[߀x s>~fX4E8@x'P<t:ll;ցDYZ97L$:@&50("`@QB"$I <\"/@ _px I[7):fONnYaNYY)'t@.B %$"Kde=@r3~, ʟ؉xHln~po @aD#LPh$ IaNYan@+P ) %D%I Xؠ_T \14% vpAH((6Ll |Iа1YbnIaN@*P @*IBI(B!Q8>L)| 8$|  t: aCC CYanYcv@d8PPP(PB!1޿OYA ߠDKl<x4BbAMǃ  $C YanIaN@,0"H%DDI(H wFxՂINgImik%ņdOggSI-* q5iaNYaN P @ allegro-5.0.10/examples/data/haiku/earth_4.ogg0000644000175000001440000002307011421044442020260 0ustar tjadenusersOggSi<\Lvorbis}OggSi<DG-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,DFb+C3>[,`>qy5 ꃸQG @d8 &!t.B(@oxkX];-h~v{@s̞릆As \: Jt\J|E//n}:aTCIPJ:W(T,@ ۵3_1y9O#G\ @I5Pt'mpZ +g] 0k%æk|P >4sT "nL`| pF7ZP D=5/bX{ =8@`h֠6S?}t'64]lp[@>t81.3_Lu g0L|צ!2`|*@L43p! * |Pn,$H lذ| O?>b^?#!zPz&K. ~y*,h0pKG-M窳`⚑}moh^@(B>PB%|X0k͋`]&ۧ{ z^1j eF  QMUډU <>Y** x`A!:2S< , ׄԨ[@@sDf &N *%BIS Y(P!b6(Mdi`F%#nH20ko &FZJ8 p cD QB!@ ;ر/0$S} WWG@?-d]KVWƾ;ABSGx-QmmCIP H tlIA VdEO#D&f̈njs:!" (#{f%T(I$D G#؄P ]46h_&NN8 jY`ʻo,SΦPCAl4h^YZI-VUGŁ Q)n#߆0?Ȁ7Hnt!*JB$DDp ~Or5e* ^xlW|`AFɟA @/f_V.=6oИcڲ8lk`:͆ƃ֡c3XZ& T0D%72(5L:1)U7h׸P$%!QR?bqx{h#@)6j@8U>Kߧ6?l2MxhzݿKL(ȍJFAa¶Pt<j9T?0233hy&(PJ(I(P 2[q+ !y@c~'qO/ vrzWYdB|& &Ah h&YUT`"c摴"@@1TA2u 11q$(DP(@5nt{p{8C&@C 8惘`{%$v : J@!FAH:$@&x$ݠ*pdMe xP^ DHpG % %JBI( @׽V< @0<8 /^0WxPh1`JCe͔pjtlt 6$NAeT0Q0aXz- ? <#= Xd[~%QwtqJBJ Qק 8H7~{ .]f'~ ǿ(AZ &iFk N#"Ä@ACC!@C(`LYzpǏ+xGw&Xzr͇+X H C X%!JB"" 떟AO~w6KG5x` %L=< `)x@*PIzq-@?4 "Io;ص8 P df#bRZ~pD! B Q( x +HIJ̷[x4@؟O ~ti@_1g\PK0%(=WeȜh-iPDlx(L`( &IwOТ eY׊Wj Y*ddVH3 JP(J -O ?|_D9xm#m/@|mtK3)D#Al0iH6HA1 =YzwŃ;`L "a?`UT2d{h(D!"""J qpr@w?xHnFo@78Cqw~%l(bRv=L>0 ݃Jnƒ h`u`Y`:.ň$}&·4LL2$'&F= \G( Q77^6ϡZ&G[~6>y˫:@װ; dw$ &AMB3!(`J=(4L0I&YZ97Ed'R>a*@ Y/* BD$D (@[ @4>| PBL@߹gN=4srxmofa^]_\TS2YG;U@d "K I@Dith%PP" %D k5S֪@<@ۿ?%pI|?*7Mj$F4l)&:66MY ;X+U2'b4x tIA$J( Q @@]c@9 4Lg#ӤlZL0:4tm h6H4@l8x 60ܖv ï< Mt$FZ $a2 HY)w*"Kk+h4 = HD3% %P B+O$oǓ 3@Ci{((x 6<<&tYbnY(wEv(! $@~K][lgn_bd;4t< LIA@GSIanYbn@L&旿t  ,DB BDI(@,`%`[O_ H'9vϤII@ `)Hh$ $Y)'t$}07T u Q((" j%P(T~y ICyi66uhQJ#!(EI?0mhYcNYcN@"@P@BI(P(ooL&F{=P6ظf@A:x41hZ6YanYcN@"|0Q" %͢=(\C!ix@7ӳFDALLLt(4 YcvYcNd;Q$!"JWD;164 0o Bm#(YcvIcNP:QPBD %L>, &CVВ?ۂ dGƙt6 YcvYcNDBP % t%VtK:h}& AAЁYcvIcNDQ(J'sÜDF5M'1ё $4BYSNyqN " `callegro-5.0.10/examples/data/haiku/fire_2.ogg0000644000175000001440000002653311421044442020107 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,aQtǘŐߺQO.TZRT7?wSƱѧQG4L9J3P| rUp7kÿ#MFO->߿]\rJNr ,%K\mJ9t@s,9`Mi_OrzJ:H^ÅnC /#aP~ZխinI<'{srhzG?7OoX ~"%?_|{+bocq!N4)rl'*;>JGp 'b㪬H=; 8~uEcqLU׫D)Mm\coZ i{aWIq""֡W29\w닯GVL)<'Z7?.*|xiNK/__UMl!|y[b<:}Y}x[h jcC, ${sa2Lqs;ڼF(P3vǃ ͋GKc$ @a7x]=kǣ?v) p*@pIZQ"YWpA5 auΓ?Dno<#+n[+ wG !NU:¬tD% f2_fۈ)\+.v0a9ƘDM+qUأJs^fM5xIe/gK1fGQ`£!j%7&"2Cu,$je* gއvMڿ0g2m&0(L;[ ~:#L H&HEvǷ2`u~4>P2X4Jԏ "JBŶ d!bUȞo~FsozP 0 -+#lA0dӧn l sIL3Z1YN{XVL|nyVo€a.hʣԺG'j!V]ِ.5HЋ@Z㤑|fI'Xӕk3`P@1-^* 4rIJ^g]Egn[l@9SzU{x@[s ~߅ `МM,<<~$x::z@lVh;L{Es挋}Csٮ?l̥'J96" lIݼy `'-$1$ذu^*L#iy&W<^`?SiiUB*{a|yI~Y ~p[=Z}y 5a5Z])Z|Us_`ތ&ZBU)xn66X\ (^"fbU-E-,Tʧ+sg|plt"Ӵ…QB D?d:p)Ds!d7"/0 /иsy??x;|&x[Ia:q'^D510<}b(޻ ]'NQ*[itu`$`zܧm`D%t0C:]>쀦|Y6j<$V 3J{ ?߫E47x#("JBD?'ub14{ MK2 ҀJa䐈c9JXP[3P5G %DD!$86 @-AzfWwn @ O?c[ا?|Tt~ 9 /`'J*NF^{^4]+/ SiZ9@v4g?/l(lL&:6& hK*InSA:2EqRdC+=K9<цatƣP_?\F`|b2n* -|N+`?A,@_6?\h? 4`o1}@`^MAH} KƁߜD˃=8b2+kJyNu]V aB&t6 :$DG@@DNӦGJL f&uWNI8ay BDD!""1p~yRdRbhǂM#O`^O~ _nÇ%O O( םnA/OI&역AkS ^iʷÝ hxћM[~Yjbc DD j . Yĕ\0ﯡϽ/m2PmGI($@1~uV[ }?О3yjqI, ^_XK 8:b"6P|zٖh|`hTPv`C&!@ %hOggS"$-*'eB½źR~IjbFA C2IZxRSSvs$=UBI %IB{͙#.K0;MF4~M_jM 0{ 1P#4x `~`әs,z  er@+Dа쏉f;FD%@AaSбA^=602D:](hj)؉O" 9s~JBDI"$I/z? P S@ y /z(J11h('6sLL: *#`:<hL& $`>CfH1G*9@K\*?w_ :p3m"湸G< % BP1@$q/XVX=u <D1c%Pfl++[˃tNص [U0|4HHN&6gNm]@ TF5&h08o7sG-Ù6-Zg/(DJ(.p @ n0#_>#X>;O S`Z<`𑽹^f3n)$mv16ٽV@Q4:tH IA>Tq-.Bm2Ȁo7>><4XyB4=Q(!JB@ ;%zi#7 &c p ݫ@6qQn[po8 ]נ||O@?87`צ!o8LHl M(X:m@mМx$:q@oYe:k 0>`4hyqQ( ( %@g-b _3?@ m wNPOz0o4Ae;ݜ/p I BMa†IbAI:`8e>A/R\qq6h ">]p( %PP^3 ? 6A9pQT_<#??3?@V8Y^t vS#d/с$yБO SY'7X:btQ2mz rn@'Q(PPB*Ճs8KG`?=5ԁp6 ~N^3|>t:fN{``c`S`"6( Ll<X;:`Z Ka+d>77 G$DD!%D N  :`5 pet˨f /|(t7PC!MɜAGcB(xuH:(xh<&$YztǍ'`bDq ̆"p,t$ BDD (k pV?X(& L'C) j &o4` vA H 1a@%$MI9g`rDW%dwO@AT%Q(D QJ ,< `sú|x/4oЀ pd_~` tBd b1 l!m@AI[v 4BD  3 r)QJ" BI(a$xDR&PC?t%$'|)> +_`7 $ aD`oPPL H4 hYvi "I;8Jȸs"|X 7p.I% BQBDDDĭ@"V_i /8p@aS=h`23 [:t~!v(fFa$)KPlP6$Y87L"K2|Jx\\ %IBDD<,,ٶp1?v (|!|>& xhx0az(hxChHh<(hY\8'N 1 n]UdC_*XrڒF PBD d~Ϡ:w   0/7xt_|U:~7 ̎ EA3@YY(uV$}G&~`|DTKBI(JA?@4`uVhn cos @G?rʯ2׿>s]|[r?n#<&\xHNz›wԺ|3Fſ̓ي^;ۼIL'\ ZXߪCf sgRYB4B숟Y?b?IW/W_\i߿^SV;7 C m}YP?=h^ef?6W+;?p2az/rH=ve*Az\RG YhͶ{^Y]$EW)~ n9[ cson.||<>ɏh sn=|ճ(uaVVY,3r4?,gdIdV) ~ۈҪ'-e,9Lk>u{9eXU="5Z ʉ40G͜?LT0 r!M>^Yu4Q@s-7?o {D4(zhl˞q1WB?3w # }Y;ܪV"߳\3uEw~|*:W i-cW-,ʎ#R ߺ_ƒN6IBAΕ?ɬ@@hB|t/;.DrPU?B)ܳvG_oQ}?T-UO@o@q{w`=!=<c?7`\?:I *ɗ.UM1:}bNX|^TV؅KR;(c3gNF*ӯ" ]{# 59M>m`'|R1;)Mߥ^N쪂F2 7I2YIwm8dG?(4ByPOg9_ ,몳I\@n>h 6O|N y -`8]~҉fufOy٦÷6̀z@Vr5w/B}ȓ^UX)'h ˚E:yS3h|kxF$H2Haߘ InPD'݁FM2c>P4pKgM97йA}GH(N/.摀q`~|.~/3M?a x[1r::Dz֤\0/YyD$[bZ2u]ݫ}/;sj*?Ccs n!6zcUֺn3eޛG<7}W`rˇWN f>ETtLL!?Њ @6ࣞ`c~A|>RZ@/v ptj^  x0??>_w[K&D_l:v|n 'x+ 4i=# Za%{{E YIOmmKŮL,wɪّΘŬΚ?;A|}|)ϽgD+}BnX? aF1C~DhZ&1DA)iZ@<GwxC-;ۺ rEP? /~9@;)p~n`#`~)<3nf^3BNu3G+$Cnhc~ Gqٛ^ ^װ*n{I3]삂6o-o]g $IbDx10a2E)LH@6_@4 |7 G48#Rg 9 @G,_EqZ~ o{g @qѓ .G6. ~D,Q k C؄Bu47sʼΧQKv1ab4N2Mc "`v,: ѐG'4($>B`ej^AdA3xasp @?]%A |X `` T?j% %DnjA@+ q9+s  ]? =zc yq@UL4_#!7>a+U5 (B&nh2 Q$!Pjw>-׳W> O_j H=`W|"xO03S |.@cjӃI.ARHifB(aB : [#A >`B'20ziB)"ML?m\>>4~x m0Ӽ(bQB%@@N.y>(ʿPv@ ?,M(þ`p5?c\U;#ɾ89pqY';g**Rnn1fP1zN@Ɣ( s˷ 4(QwԧFTTB g|/glhj炙_ ~y:dkA @\$P޿^JI&f=|Sk4\<([yVMhKH"C7@Wl(x>IRv EL= @_;,μ{-?G7ݙ/#+p5%`?Irv I vc+( ߋ(ev*nD lD'OUD  yrm,u /g !጗ G / !&~l fzt{Mۈ<2L C@CCÃYR|Р89%N=X@d{J܀dp#)q aPBI$]vGOf+hw^g _~'1[~'@xin0Р3!A#2҇ࡠi(I(PH OggS-*JƷo>Ijv a&K%,|I# lpf'dpP{,#ONsy(PB %.n8hݙcpyOL~W~ H,? ߠۻ~``3P% 0Cٱ ^!fG{m ?L !@Rtv D0s,esLQL<.w^Q rL3@Jk %D@Nl~-O ~yg3(@tYB?%`?2<\~ kB^!@4(H<6&x4H(jeѵ蠨N"K--|A2;:yW|0 <-.LQ"" %$I(D T◚r&`` 2} ~q!x]RQu\l mv nU3eйQ솏E`O$ H `!a@A#̯3ޠm`7# W}709QJ/Q(Q(!_x ~+ ._%p%FЋ/`y/觍@&]..!Ol᩸p(o0}8Y i3$:,SHLP!h(P<l HɄ?E PBD~ľ ha xg <~ .?,oJB?hP  +vMd IDR0A@G@(ƗK &':̗ؕ8piݠxɅ &⒎B QBI$ %৿mWEy\6~G@Ui'?F 6:\ˮmz H < t: :AYƑPlY/LQA% ?P豹` PGD! P dz)p d㫝L oZTį?ps~ g/Ki?},F?Tgm~9>~kbj dDxPPx& IZ΃;X ,q"IV[P qȽ| bFҼ%IBD B A%[/r<@0gy yZG $34ׯڲ4sS@c`RH: $&GaY;F-AҺtc6* kO(àɉDBQ(I(I;@~ XI]  \Ŀ<^Kܣ FM LdQf>gAYږƝ*(/Mv"I-s^" S4~k.lDD@;K(J( ?8p{ (W@g@o~BIl kعM<A4;*:!t禘JNH`c` hHl&@IZC+Ӱ$mGl;ȇ 4+4xyP$GI% %@Gn ~W `?|7gWl0~74pR@Xxbih:c1L 6MGБhlH$Y[W0) u;ix V9@)`! 5^.n h'm%DBI  -\<+O@ `h~ OЋ/KE3= ?H (P4`۴o(/% }>~`3 =0@gi`&'IZ6CEsgBg1TA _pw"8=q®*d/18 Ȫ܋Cy;$ S4T`o}w;mLgOkYig(\=cLO~Ou}CϏp9d͑@+ߚ FmMj-4O_K,>&jб oe89΢TAf;2tMɛ^^a?^.RZ):28?+Z/{[S~s.Ae*\c;.LvPVpS5X0Kiuie+6"LfǬR:hLh%P\u,4Oб`W?1P\>^3k\2;ti7l/: k9?׳)6lͻIupX$I)!\S=ݗR-f{UEr~e ObPM~_.+3X1oQn:̗eX3}="3K fٟ5˳ sG暴xxtAdt< :z< YP;r %?]4xNi`uD(E6K>ު>^-~%|6e24[J{g[3pEvqoܤbA|[{4kZQ.ƈwE\Y(ޑĕoSRz>سOZĢOXR_z9,o6\8k\+P{>m$б!xAG!x@y`I2oLȒGm< o( zl\(]q=F,I Q:#[;:,Ҩޯ<Ngn?aqrO{ɏ4(;1>}1~M:7`rY {O Z /c뫔)8@(01  vimǣIŇh=pmOȒ)>ECAt\?x0]x(P(DP(Gߑ^]\IZ$>^?R?2>rXō_xuzo} 0Kbd`YhД״6MKLl&$"`M Yhx|]gD$ vJ~DJ$D$D QB@Oe13ͥף[?0RBW  BAMAǔYb[4}m~7&MdI ލIޚ+yVP(!J%z yz !??5#? }16pLHᾉ2*ʤ%`k̽yF+T)IgOaҁbBޘ@t4< yY")v"K$N`W7&S4h|mFZl@%JA|[Y>G_?mE{6~9S9E6͙sjW?+ceIn" i"֠@n(`&t&l6:Y&T좐/Md h' _<( B!@~o=Y_hm,ѧb3١}Gވw0 cpJO?VO$]wQo50_֘SzIhL(x4!6Px&xtY"1A$ h$Šy!%%D!J(I$ɳ7p5zP~,|P ~$e_ѐob!ޛ;|2KņL46 dF{gMg#YR,FpfA$?Fpy[2qυ80"J Q$ ,K[}A$<W㵟 70Cy6ֺ\is{)xtt{5aD1٤ƒ ]mbS''{ aa!6I"(4 zAI_(Q(I(D %!" @)O./hs=x<>ʻ kla7ϲ= [hH7҃& 0AhPt4( 6I!Ɓ ~ ]'b4W%B!JB %@wMO{n1]n}~n\h4Yl$6X~~RڻA^P@+*].`]F?Ά EӀ0aSH HhYr h!.c/ ~o F(EDD Q(!"ԧv1_L#j ooj[,X.̻Al:Et646&I e` !DB[7xxR(!%xy`[]M #u6 yGo1ewA0b#@ 1iI*~!DҸ`6r%Q%"@Xj |mYz/w.9_*_N/ABy]@@ =P$lx &d] IZ. 0'Hrt]9i @@XP(D" Q(D@[.._qXK>;F`[ԏ1^ 6Cegq hDŽ& s-A'/1! ahL0a*LtHLYZO]|Adi?bnq1\K"Ja}*A5;cU.O*}7ӵOT( t4x & : 4 I:Y @({|_lZ=Xku.allegro-5.0.10/examples/data/haiku/air_effect.png0000644000175000001440000001511111421044442021026 0ustar tjadenusersPNG  IHDRhh~"tEXtSoftwareAdobe ImageReadyqe<IDATx]vt{غ$+!P3Z cg-Rw7waGdDoS}sŻVW̿'^Q;d NbAXnѯBFyZ v聳;9JY)V /[u?>LHa/}YS,T?_8$0RywvYF 5Zz╦JfKZas|󆿋jrF+Z.`2/durmrDnI}DoaGoF-kO)Oޭ> g#p@fCV[^Sֲ!gHdZ߭&>:^b0XyM ~->a;z?jUN=(d>[@R?"N2rdJY.?ހ@ ;5 UmI,0RH}c 4AX6MA_a1~T5j%lRV'҈/ eXpβQ273>Ø߫swGjg=CB*D5[X:S^d]v1W·I ') ;8`5W5!h4@6RȀᣤNzs9oj 6 *vsUFF"skQ ~ܽY^;(QmV %̅2ٶLfs ZvI6PҹJ'/ܮ*N'U:b綯6;rPC v 6@ ^椺;B)>`Uk}*5^ \1M$ 0; BzQzZیaL^t"gW"85 7j8\dۘ+{Q̓D߉IQ,*u!=N\kZ66E "ðU{f+E*@$@0vjmԵyBvْo) W츀pCЁ()-´s wi(eNT*80?JO$,Yj>>55#Lj ďj/i RrVL t>Hvz:~ǼoqX#g n1A]=B𠈣q >>>*|vJuضTDIrmM@ ڒkzmUj#n9tc@&U\T=,F 2G-TZ!@0ff)6?eL1/Vc̤ɒE:sW,H:ۊ[5xlN4B㑨5qjs< ﯰ>s@W'^]͵,0ԍsOH" &G5ǧ r t3[aprjC?FM%\XI 웄9(8Mɕ*ܒ05|*ۋr**o558UmW BneTT/29'j\νhOqS^%ZzQTrRIi3l e^dViĘZ eM3׼-hlS<.\h7gL'Ṁ.CH7ioR|MUo@G :gҺ=*,9W"ЙI(Rwl3-GnfQWs6KT)E/'lz4yNSI|ԻWࡉNM57%UISLy4ig+4Q`Vm Ip%H ^Z&Y'TmMsv?ޖ9E׋ND&%0IͭwV7гp+SC D̽3&Xuk5$?`5Q YAΐ gM&%]>ؕkOD4uc,(Sea8T虚{jUs;Zt#[#zf4,vJ Pb)uAN3\vE o@DbjE|fGTzt-Adl"7k"ۙ bQX*ɻZ7LyO6P-t,ĔE߯9L~nN3!NJji[5oƒ-&v.XF2s@X$#s;j]\W|"sv8~ĿY/gqfku囪g 7QV@ >9P`hWzMM5ʻ̽%J~*jk7^9ZSOU2cZUoug,$?)ׇARx Ȩ@\EM;ޖRb:_~P&T !Kp> Sޱ`|ZU &<Ndz!)H(;J~r=\Qbt9"v# ޡðY)i3RUE^*C_X!k솎@gbEr'ӢقJ;NǴOw&zWЬJ~#ˢAz9~% %ZoLsš]pN!L札πq?fR <~VKb ACJN8)NLayݫ[.dLtN hr'st/yu:%SQhYEW&qm_ҒD%+]jdKq.@Y~MidN#T%ft6|/7^o 0FNjsQS==|-Ʀ@s~Iπ k $&$['~oGym5t/tI (-CHO;.pe1J 70<+cEJ{ұA;A(! |/ױOߥ{IaF/ũ{f"5F3\%\oCc . -8nMs^P袈k o#n8Kiԅ~ovTJa^%{=ߛ4ۥ^Z5BeZ5\ߋ2eA3:v}(Q76%!K8,GVyH!uR -v{tVHk$G4؉& Q)!^nE֡ OC0 R6e*(zlg@ ]yLK҈EJWCvƶ&6BZBAk.7J Q]熿;Y<88>{k8CˆxgР $.}e'Mk4'Qs7_ܔ)M1 .s(m_#Y1]W,63* Gk h I1I r'i\ m"=/s %a mF |D >J`q.{3W&|؈p)<U]ZMSd_M/I1i=Hxjm+,ødwj߄m7w=;N.' 8GIDh$/e8;D_ߵs^Raq$^kgRBE1lCZ Ad7t i7=wunkb>t9|]{2"kSˮi35oI9KiBa.KUeH D2nD\y3>޺;eFY=]wIZqMhMmFսM b:^v)~Y;}JR_dUM9h,XPڮ)j/vVw"csV^INlJ'6"Z'Ki\Zײ*`q'Ax7jfn6%=>QMfܮં0dz/UN Ax0B;S]徉&Q&J2(ZoJmo+g!(\w8Rw%gv7#xSp:T7]=V;ZF#.d|cHeq ,{\F]hJ-4wHHqz{%\x" v Nݢ^qgEjZJ 40ޛІyII:Ӵf!d%>*);bzUnGhZ ]z>d}q[.< _MdIg]$Wl__? g U{6$+$,5~@M〦o}ϐh*RDWt2c3#u(GX\-U|.ޯtFkJuY (c$>xa];6qqvҹ28R^۫5W{Y `c}wi#C;U]Jn^ޙ>Z|//;R* ]$5Ӑt{ ܙtF#Ok( B/I|O'\ґmGI2K$ithrQ]#r)TyS,Fn;J8;2 WÝqZ^Hg~><1V[Hz c:ݚ_g tڹd2}Y,ۊu̓ I+׾wߓ.X׋0-N `#޽}leE 6J2X&9(4{iNL/W6S,o74rX̪m'R{J2#Y`Y|z6qz1dZuY%TՆt~hH),){^,GQs;ЇJa  gw`UUlb`FzS9櫣)&Zw} wT[e6Vϊ/LJ`EКR0w@ODC?tɽ"zNL SɧF$ F< kGRhBf*62楪>uͥȃI)e̼,4`/T)_B=!~clD &ctoԻ RdN7NwV0ISw.DRHbZZ]-1YpFqL4Fӗfʌ+iJr1Mf.6PgE5E \zkLX)] [YY+ifr^IJHЭTOfBkHQbV(CހZ<ϰ;S/s*!'K*"Шޜ3-@h-R|^]7W.}&ͼ.g"qnA^,+q@'Ihh4*W'/Hh͹9<~+do񔘇r#{-h+{]qdWJg祏G)_1Eˉ}ˢ毞Vc˙t Vs?xO? @^(pWN̷ounko` B$v>IENDB`allegro-5.0.10/examples/data/haiku/air_4.ogg0000644000175000001440000002244311421044442017733 0ustar tjadenusersOggSi<{Qvorbis}OggSi<O-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcT)FRJs1FbJBHsS9לk SP)RRic)RKI%t:'c[I֘kA RL)ĔRBS)ŔRJB%t:SJ(AsctJ$dLBH)JSNBH5R)sRRjA B АU@ P2((#9cI pIɱ$K,KDQU}6UUu]u]u 4d@H d Y F(BCVb(9&|sf9h*tp"In*s9's8srf1h&sf)h&sAks9qFsAj6s9j.s"Im.s9s9sspN8sZnBs>{sB8s9s9sАUA6q HEiȤݣ$h r GR TI) 4d!RH!RH!R!b) *2,2,2밳:0C KMXckZiJ)RJ) YdAF!R!r)BCVy+7EQY2nۣf:@ OV"!A ""J ie@kхf.+7B#?wzmJ'J"-0"(P_7\*WX+7EA[Re[1Um0K(<d5 XC @SG0Zz9=m?<@Ca ¯+ԌL{]m@ 2@MpAPxg CZ?`/a^bD9l.DZx_@ր5@ >.NO`W0 ~ 2x{ZMp&QJa|-m%J-Z@"5 @P [*xr{3w$}=mQ3*Q6@M ADBB@2@SPx? cx8"@gFT `  ɡc?wIP.P9hJ{zmDT+6jJ Z " `[<{ `|X+JZ6W`QA jZ}  !"i!, @?@]`D>!^;w2L).zpMYrl0d 4@@Df /THE \07G* >~;QCMJ%YE͠D-s  D(BB@p"Ȧ@EP`G }~;Ԏ*+sg5@ / `_9NS *~¯MC҈bتfP,JY `  zDpm1eGE* [Ԍ Q:T9@כ0 "! "@{ od*pΰ\ ~\)h jGm!ʶHo p~فt-YPDBBDBB$@k)g] @UXHb(^Ԍl*>s/ADhc  eWY'F#᪰ B>y¯ujGc!J4 J}#@Pp : @_]D 5`PUJ0,>yMCCWKm#%@+ "$D{&@ @@a`p]A`0 @Y jDm%ui$ם;+je!J] #!ty@CQp &T 0p)X i TFxݹ)R5p MH+ 6rZ)*$ ,THb;wJzFx݅0'%2E|D$B"@U'~nKA $5@UġB$T. HPaވr Q?L#I>nܶQ;( h $DHH@3Noz诀G]KE*"D$ވ-wFD9 i4ΝuLRg`hDDDDDB;Y!Z@c}I$J\  HJ{oƗ)4.G;( @k7`D~ ‚AIcXB\ ވ*{QOF{^aN"J$ L#F,@J(.F* HJ;Sj=FwQJ6@ 뿾0`BD$$BD,-^-W0 $!RH A@`H;5Q#g(4c+;(ZX~20 i$"$D"0@ \$PP1`1 bH; jCΠ8H]xgHMQ"@ 3 d(MD<PNRT`PqD*"H;D)%6q?O_7x@ 0`-hnrD|@DE5ZDH-wVK+r/'@ EWd)!!!p;AU1 A] $ "*THJ;_DD\L#yv&%d"!o|m@)UL݂҇$@-.$*$H*;/8KODH<%w>xxP (4 LHDH^FQ1rUXTH{p~SޤWIm_Mbh`_*H cH_" WP^UD7,XDH;/j%;Im^/Q@ HDM /-+dn "`@@EH;uj&JďF|˿IVWP!!K!sG2E' H"pP@AH3wv.bѣ4&p@1""!!Rz@!6xh!Ϣ B$)ŅB%Hn3&I#i{dވq @Ƥ#"!!"  0$E  D,.*HZ#a&4]g=0O_0@I BJDD=ǟ@X@taa G"!RDtZHZo#>?5i-{a4b5@'FP^41QԵŠ@@pABH:;9D)᧑_;w~};Dy/ (䤈0""Vb=w B )at`A  \ H\ QH 6r?O? /0'D"BD$eŸ,HH]p#r@KK…$UH\ >bX4k^h4@ ~@IHD7~cJ#@@ TwbJee H^+ h{%BF{ڧ@"0VX;+BbBEAH:;;>;Dyi$:(~$W`HWFBBB$$m ^-s*Hw\K($"D,T "H:;k>bJ#AeAD)HP$zY`wX3 x]DA₈PH:hD4~4H(0 Q$$$"$"amPEaD!tB"7¸"ĂOggSi<bTZSSOUXQQPLKJIIB>#H:;M(61$>I-D)}a HD JI傀HAH*H( *HH\ !}x7bnImA-PW"!z5X`T5@H,b}E!ŕD P"*0H])lb^I-4hL0""!PrkUj\?`YX DC(0@eHH8%P~9Fүr~(*!%$D$" Q@XM+dPD"BhR"H>wި =h$:(i>A 5"!"!tWP`P0v}" .ZpaaAHuPn[TI?6 J j < 0R$DB$RǏhXIPRҀ`!`A l%\H, .$,( H}`n~@#AeAp@$"!!PiX;%\Ⱥ tn1HpXPT ,H}`n|(IMQ hA &DDBB$0@5L HRGBQ4%Z $H}`n |(I̭ R@ ^t D @BB$B""-x ]E0 .B@E **.HuPnTh$>0(hBHHDDp;0`_ ..p X.D#a ABH}`n4~[H4`J>`"$"$BB8Pw.^PpAP@# .TDHcntHcn @%1F"$$B 4s K?6HP  "(*P$(HuPn&@#) x 4DH YB/ X@ VHX0@!HuPn:@#i|K 5 R-.Ű.#H}`n ($$$"DB"/ժz[B 7w$"*HuRn&@#I "Є@oADg4˳HPr:H C.H}bn qt O"""!""IЯ``/ "(( ."Xs`n:@#@ $allegro-5.0.10/examples/data/haiku/fire_1.ogg0000644000175000001440000002756011421044442020107 0ustar tjadenusersOggS-*Cvorbis}OggS-*vB-vorbisXiph.Org libVorbis I 20090709vorbis!BCVcV)fR[s1gcZ%B(sV[)ZʹŜsΕbR)ERP[cR)S[i!Bs[iZj9sRN)SJRL)SJs9SJ5ZS1[K)tNBRKtJ%tP:k9S)cVBjSʭsАU@ P(2(("9c9 pIM,<4 SF[g1z?0$fY}_g?lLuW?~3m撻߹C%054,N Q+kۇ]ýy 08oѤgcM?6[ZhǾ3x}k1K%x ,})ݧ~/Ohr|pxY_|*:qǏ?~LJ 6^>~\},4S?@`JVc uzW^93_B9#]%O40~uuwzЗO>@x3ӣҾef?g}~}\l;D'[]B6eYMcҊoK'pkLnK,cmF%V*֏ َ ~l`<ݹl0@58_dz|u*y/_>G|9wij0$]X~yKkc B\ȧd{na 1\"us̜a:|賬qL-]fRyݧ\j }̺8h7sdlX[Wuε~CC7 4'{ymR6x +9Ad&ߎ.&~sZ oz||+Wrʷ1,"$T([M\qapXC?ռ}zf:±ӽ6TI}j\//Nlo~E\5xsF2;d*}sp^t:3Lj>-G[W,=L+;R6j͇\~ ƿUZ7[a=8瞱ȓGnzdpzaW`q笌jrz ihƟ{ˢfJ_g0wayF^K(0_zZ(k^u]ɜOuHs7r6?Q*Eipx/OT8A=)Jpq@}`p;(`N X_ lg({wzt;\;ݜ:Zђ\FxKf2h8:zc@ќ"ڤI H0?kY{\\x7r" dA|4~#Gh3GWcs!;o?E< O &.Dm#opiėB'و&޵++\͙m$-ֲ6{Zccy[\uckM 5ϖmŮS uJys^0gBÖJ0.WQ`U "'WE\ izѳ,+(AD}v_=ԛh4O/)wȿ`3~~b , л}QLO`t "x\Y0WpKk9|c4=v3q0K."Jnҽfߣ[$7$0-! & >: |KH:C|th\?A>Mb 4;89m<6bג%AN}V:!`#j0S /㫽Vz ?!9 (߳'qav_Z@#`txm 1?@x27<+h E;zK'cl9ޗ9E}AӻG+]8#kgFX,mYw?J߸4[16vBᅹ.-//@I޾m/Ut!4Nt~D( Fv7U'H Jp6 "%  6D>~x7"?'ݺ?{\ׯjF~{.$g@E`@;~V9% `?~`ZNmJWJߣAOl05&:^d -pp7&D-/xO~~1pqv<'(PB ~f>x=`m(]@ J'n 5l~~# gaK`oB~KG~ ~!@AA[eDv~z7ݮݏcXʘ3)*+[+ 4xg&Oj4^ihCPk6Pxlx& H::>h!2[d%'ST*&5Hww1]D?$$!JM~yH}nѫ'~>bG'x1p~@B`RmLL(l(y`_޶g~eO~R3Yc/s5?'< o'=a?{ȣ&ICSa>RxEt8ɔF3Ԡ$_wYwQڠyORpIBPBIa2enÈbjA^?H:%k)>R {`V o V ;}߰ @b't OalڿB͕5B@*olK5-*\dʸô{oua_X0HlX pC`(ॠxQáDQ/D B D4޺r_/a\/Q^;>OY3~R@~ @Oʏ&Ӷ/9h-'y^klvB^@P0ILht&&t6>Ya!'!JR+sd 6د~ M<$ٜSS^=@ã/|}Cxw? |Tg?A읺~^ d X hz.:猗,hK$CA3DO0 4&uxHze'M(H.(wEA$p6|1fDi>D\GP(DDIB<-+K|-]ya*#. .p// [~πR=L i%eWXv{Y"^G)C4&h664$ QjaC:3ӑc3:5 1?^EE*xhkQ(DI%/!V&.ZڈwM*0Z@wбfBц04KD%!J" ˋX/>xGׯUp_]4ns(@hc0? Mv>^P<~C)%(@/?~VE+]IoCP31`K40 ::ttYZSM PsVNYlH9^J?O^[3Os$!""JBټU'mVf=68"?i)A`M?/`?hxs|q~H]†|ؠ`#h@n{ܡ}t</cxc?j0M 0zh0ٲ^#A6ؠ3ѠP :l6XԑnM8Fx$]R dD4HW;ژ7B$DI(J""HMKe~ oOd /(c ~?g~FZZ>g0~

    7 ؀-MI1!@I &Y_gPYz ' ^pkt|zEIJ(PSBL'>՟o۾4[_@i/&G|)N@ϻpk›mnBQO < jd! LhHH$YXpY& dOM%DP(D">7($I(DmǞ2Ÿ6<~s< h&;0~҉ Fᡁ6CDB $ IXhH.8 $ xi\‚( B$Ŀ{rx~H݆?@}V{=s~h.0MW8d†f*AIR t:6Ll$L6:lY(u ϕs;xz!%$DI$!Ucqui~3) 6J`B& f RgI!NY9L,}-& E\@PP"JB@o@ )! M _?m,e)c*y @ƃ0(& L:Y('t,}&ٸ9 0"Q(I($I(g/G] |xL痩#1mHAɆ@HY('t$l:($$ o`!`aa;VBStEP` t0(LtI('t$l:щhZBIBBA Lwms~1e?GEE^)RxE():OscE63pG){o͜>Z~ /M6T/f_꾹K˵/nh,Iܖ ?}_{㡘߯55uĝ3[GHW _YR}GQyr{U9֮x4G?vc&?^\5 }8yJ~wJ-%hy9(MG[74G=C.O?\?_<4{9\:&ު/qS3_un|Gvm~QZʓ!$F1 Н ).xC1(?O+?\7 м^/6h"""Ht cxֲPsPCV1R")e З*V͏_37}GGWUnޣDo)V?G ׷Q[^~?5 M`9v {6.YXJ.P,[/J8OMQ#obJ\jsJ^]&P_ 5;J^DlǽnDfɑ~zqIeMf^O\"/~H= ?` -qOJ ͯT!y'P O+TJT}[EOOJ>vyAOX^4>E ;>hfS7)!=/LDL2kP#`Ix>Y2%KQ@=$%B qA6LJ@?nx0[pkir.r}Qx,KGEٝ_μMP<+{wF{c?x> w# p.vڒ]tɫ`)p0) H_'L],_!}uiUSbl.j܇S 85YEѦF -Ȣ.iqwCjf=i6x܀ >2HnuOݸ'U2M1SOCvG"~UTC6“n7...[s?E6C@Y<:l =X[xa'^{Ng7tF<+X܃])b=DW"-|.SϽG ~ uM}0ui' S(mS`700"!\ZB[yLEl@t# 4>77<3h.bDuZ(Dq5yNjGO/g!f67g~s /   | G`^ pȳեn~onln?Ra,ycmj xCƨάn%60ӛ̆(tj) ؎6`+~="7 J#U㊊?F ?@6Bj_as̄xR7 G`707g.7LΕԄ/aT\ Bؿ.??%X{*9O? pqEo^G'~ L+~@~: Mm}'|C߮ >S'M15+KadI%i,H=54$O^>bbn"+LL)9(MȜ [c+\J<7:g.IDUBZ(DD~+RD 7_!xW KMX a3 8?^A`l@=?5l_~)+їОJ1HXK 5+0٣˩A?6 /;Kd;ckKR!>R|b+R׵rRta$QYG7D5o2!z %5 /W%.<}¥6KD<_+FAo/ g?~F6*  E+߄?~vw3 a2y ^:Ͻ4 (f")wF +xnĐ( +(5rj C Pu&,P*ıZ2~^oL ^("H%JX(DIBJ9\h:ܢ3B Կ?n| O=@Wً`l~ ((^d R 1™dKslh Ja( l6 $m `M=l0a٤,JRqn9p,6w@>pc044"BcEE!" %(\G[w@{~$q[ '73~{x?k>`n f'@ ژNIiHř$978 )_/6`]ǀ+Txù@p%(I(D #S'HP$>vg?kx\,9foug(5Ku_@tɾ|Aa7K1%:愂I^Y*a/ Ns  ဂ@.<yb`\QBD l6@:s4p)6a~ܽrs ~߀zs `~ l? j6AL^lQ2bv &PhxYjn`KSps"Inwa[2_԰l 9"$¢ ׅB$ '=z.IK??e@Pv ! o Tp1H;@暑/1Q )yVfU(w1!t,Ô(`"ِ 4<t6Ya_DP EOBfX^1 !rLB(!"JBD!"b;\jt"WB| ~2L[Ƨܠ~R@1<3Wvt>vUX,$@T@<<<6 OggS<-* ]:zib\\2Yji Bmt*VD֝ [(qlD%@%( %!q=3/A{T~F/xx@?*qOҋ!23h @"/DoSeW[( D:LCЀC6xPY$& bhw"I4 Z l鏨 , BJ(DDDI" 9xo=/B| x ?x?<^~z? K0|0ŌWYlOG+`bjБ0H4t$:ׅ L&$ڠuBl0B !ѢP("J( % ~wb5ah@P`S??/@@k(")@<t/1?"""J(!"PBstI`>rx "P OC.(+^o?+x+ bSq3lxwk0ؙ:7&H t&6  LƳC 6Q Nd<$քސoPqpy MWDB % QB@ @8l<n4>jb^k?SccF$S4Q4^x hǃO$Ah`RLΉoC&h ,mC  iuxmtCdD2 rQP( %DDr3@<2ӗ$ S0x?k xlCp/\4ddžgxlYڷ7"% :<\A!*ti4MEE(IBD!J K@{a}u_pv[@ g~ ~ %}Aw P?Kx4 F0h4lI%`$I( '< LH:n{Cr e|-;p$p@q6&2p]B %!"$|h_,S~~ -[~藜<  v~Y$Ã<\bfi@ -&l:<RIL \>$W*`m$ y''"FG,Ē%B vy@8@o%]h?`> L>/ ($^f.;Məvoc9FtŇ^ i&x`Ô4lH4Y:;1 ",[hJ`!+Bo1q(D@_-.YA/oP+ I?ޒ 2?' o@3?^i_Lr3x<lhPP$$CYvP@dzNE,bt hjEED%BIb 8ο;~1 Ϗ@ 5hJB' ?g'9ҊN6C(L=h:D aYz*M"J%t;"7N8 H4c'R((D d- 6Pව243- ॢ|u?''.p&쉍7i6C @lС1YEN"IrC pBٸWtE5"bD! Q(%0#@\?%^`WN`gn~^a_ ۣ7AaO<6 M"!`tI)gc$Adc($p!@e&"R( QBD$7cÖU۟ W4v }`~"Ͽ`;@i/ ; ,`f` %CAAFY5d=D>6 y<Q D_|F@<( ~ }K<b::  vDY(7t$l:ɠ%V!"J B! 0/O~Glw\;~b/YYAbDx$L  6D7(D#I('t,l:EFE(BD QB!/.SO N؁ t-e `C@F<4666h0H&$ YcvIan"Z@B"" % vlu)`$,X)LZ--fq/H^l$xx~ApoN%6vJ,Jk=|pϞ_ +[P8{œ.sPk5ɨ- " >ؼ`ꥥF{Ӳ=oUxyלQ6 븿y{p[{'xž|d]v1,k(R~J)S0dk%pWS ռ^ý_ynAzqƝӿ;]<~82_ѯْs?32ׂvvz/D# /dϑ.]^(`u-AȽ]Iҍ#83fW~l2f־ L9x2*a)*׶yKI:M??Yv+qMhW 1gU1w?$?ÓGz |Cx!~#a^ytv_Jc:>?dhO+v`CI0IKk&I"xx?Q^_XjlmVxvNJP$s&(y/ Ȉh?= [r, jk"Q|sy$=䎂+"ˆE9ȵa^ꨦCz(X XϓߔYTRűq9aQvuʤn`-V/uNQCrCȥJ(UNM:d/3$L`yt.eA}6{T-^e;cWЊW.I>2\t⵭Ip嗓7B7|q{Uv Ը'k^ѶK]9Yx]\؃:kJ'AoVY6;ox׿'ӵ3oE^#ުڋ"QE5qX8,>}zkk>4dYTaxbA^W!I UZ^icֵ[>"FO>+M@wiٮ:}!J)^)iN6'=xȫ|/w^6be9:l2:1xKN+ъ~X4 =GDU| N=aꬑv~݄'/;9=:}*ϗolˎk9Ks) $O.U]0K? |8L{;>H?@ XJqS9l| L3{zE>{ ^PR6NJ3#A蹫pĠjY NŖ9]mRcbM[ț"s$3!6ј.u&)~rYOF(< pGk Ĉ=E)^ ?q:Gsk<>g2Y Y0&E0sdU8`o Ua`H,lؖVѝ,x+_X,ϊUBW<=$ au&{$ K/!tP&ѲTu i!'HOE$'& aOU뺀J;BP(UyIWF8l.Jf/,ioUא4hŪKIQ&B+ )30Q5(ټtRXL&||\%D-IL + ]y}ˇC^I:=Moj2FK*&f("VS'&/xy6n0k2eJXD|PQʪ)$.]Kwwlnid\i{zZ3"wm+O[l`$F<3>@f u6 R'3y5ngx1egr2u]Km)؍xVI$zCND懲ۉdG:O{-N- Pa ,Y̷/ VEyb1p#__dwﮥd\qRЅp@" b8pGX3Wr%gTN%5MVV 4%04Tl~lcL$[' מϯ3>)o{0peb䇁l|Xx0{LY޼~߯('[E!n-%E= {)zAN$CJ?!Z -\@Ug'I{7yvY{:ъU &yLtDU'D *(+*j8zٙ@AjBDB4'%YNu5 *ቀQxb)tl~Ɛk9Q߇<xe7Ҡƻd2n yDÜt&+m๤*+D/^] j,zĮZzl9kpKKG j,yE`,N%a@.1#2_ ;aD7B4RJhYVXZJ݂_EEf\%&p \#lѠᲮE Rnh .7қC؊-ƫ*?d];:{UZE$ K0Drj@yf sQPGvV朵^زx(T^yUDˬ+0,SU@;)H1"+|/"m(8$4.ZJ|ѶUu6ɲ| n E +Бb#N$F\ImGd+(fkY\;=q/ָ,?ə5(3kI)c%GU##,#P X Ò^!bD0)uoL??sE[0N$U;DE1*+C99d&֫P_| .ņ>*3 #M^٬ʸ"j;v[J87~Y'RE9V4hAxl.9P6:6,,@q 7sL@ ضLݹvdAGG< M\~Ȝ8  [rfDh[tH2CeN=U6iZ.[ިsz}ݪ?<F)D @V7k K^ j1#z4v-֑ Ia.4@5kl3Ko]_*ֿz!&eyG(Uዬχ(b Iqۑ1IPM@"=VI9ɇ֦> Y>@9yOɹD/Um',RQSIF NܼRdZЪݣnz;'8@zTcn# :\J{PX ~`TU.<Ǩw\BQ*̢񫛮X0`#?]Gw?{r6dzUANq!7vw 0S Aȁumiwrm uH4 %zUMWs{x<1,֏>wFE>9(lgY |': KF`{}w, fIV*x/ 5|sM&&M/'V~Lc#DnŭN'E t}] XN@5 R2K!QCRYRGs5[ͯRnY;#6TƲHh2.bC84G݄vl,oJL eZwbXͲ@~ǾV*"܎(V4alc>0A&#<*Hq#Q";T&(V~ , J *_NJ#04y#{9'2f!؋kS[uj/3pcA⮰*Hl+~\W|q *T.A'i (#):aPIخ͆qR1贮fɗCrL0* Pw bP fA?J=OU"`5f’MQJ,fB فVIx9i4ٳ %Y0g`1W3"OB}0 yU\Ɠ͍8ڛ8C܈@jڃay~iRh/lֵ4qg/rJ NJ\IUo&VT]>aEW:M瀑&RA(b 0ն'[?'- mU44ulrr7qÓfEΆ/ 4!`[K␲w׎$Rf1(#:sUU3nmn XO^WtE,'Fg9rrKhwa-}fVxEzKGIKpH8tl@kQx99shIK ^I˥$R9;Tsk֟ʔb6 )l$=Z@鯈'`%/LFQ#T4ac"ul^l>˖v ʌ }"q/@A(JgK|k vHz^!֚:=6Q10cr+gHMTa/*$U{ˈWglP4MriF> Sͥf'mJD!9Ʉxq$%UXE(~ܢkQ2,2%^8US V,ؾp$XU ރUd 9/% 2Aᛵ_% ؊$` NQQAm7Q>e "(32&#$qlw #Is~Mb4w~. RicD@S˰MW>rY6 Tn΍]oaE, |o H?P4AeF4Eb`COv7`r8& a "M8is&h;*f1j[`bu*s$^wW|ZD;U )1 $"1+e]ы7* b,Ta 3ugL Wu0HWGMx%]I mNV ;PJICtArټ qQ8Ƞ"T"V D Gn[Sѱ"vAQu~>" 2N|f<7gcAVHLp[hm#99/a3%VeTNSN`ao^w؛A>+W.\u7>, `hh YӐFٕ59\U4ً0N 8 SfDIFx8e?}3I<ΙhT?(G3言 [6K&>.G8gGۈ}ʝ_&AB^R8H@('Ɖ^;EH99=Z&7z)^Y$(Bј0gޕy}7o/2/+P\JΫ=xeEkpN6`e4G1bDҺ6)I(MGtEwm6LxB%: ᛾i=zx4:>Y/EࡻKNt4_KWã3XQڂBϥ1D ~^/GۈϜhymH*x0LN֣ϲcm0P~K*)H)DVD5{yme~Icn @ ʿ9ED2qWɝ裸3 若O 0uؿ$f70bH/NlQЁ|N?EvxM |<\d񓡌kkOdg"e(Ğy$ypvz?/'ϊ" -HJÈ4Lbͥ.gok*ٵ_cӳӳ (4vBEQk*E^2xtt訬*7%j-+!.F&ʛ - ݺ9ӽT=#%h[bSϏ>__?:{F,TEDILLF;qQbH+3 [2!|tt/[\jU z8Z\Ȁ\m=$`Dv6r:Q_7kDB"e8Wx6|ӢB% *s]mۀ;Ӳ< M *G pH@0&fҝG$9U-@_ kE9n0. 9<l}5QjkRT@ʡ,Q8I]Y_U=W^IJևrtU`*hYXnx=;OFYY2!,[ PX].a8[xdqS[B\gUL;k>ARtiPԊVyJtlVy[K؜ xسHWXԆ E&?`C~ RAA)'ȱRoN\:4ReohjAg% WW$fl4Ν ¡5jethxvZ{ƆyY@ q 49[Ge_ ps~%ekO?FF H W׿} bhH!@ѥl׻z6Sny϶~^/AԴUءӬq n #5lܐ(c'T薐cܚ{U׎\Q6-B0feFtWs}WR+Uʹ in-[z^o7Wg.LxU#y5R`硲6w"h.2עf:::HVo 5T{N7]^p̼+_Skp]&WIJa/bc>bieN%w|w-p nw^3ek- Q98mg/^(խ;ͬŷt~H}%9:~3/Nm^,H'eDғs+|oK}9!_vˋ_`'۫wuoIENDB`allegro-5.0.10/examples/data/haiku/dropshadow.png0000644000175000001440000000305111421264703021115 0ustar tjadenusersPNG  IHDR`0tEXtSoftwareAdobe ImageReadyqe<IDATx\ s:DI67fwc; 37b>;=pq,NLw#x(7~B,s^;8]螴s ZrZ,[CBED ,@lnIs%YVI"DYl= Wשּ!WqA{A@`)RZA"A /ТWx1n&[83Lb| - ޿(mK+eq"b%ܑG^=Iș!q*JYtz,H `Xd`RMȉHCUF̚4=K]c<ڿ$5{pw15!@wB3й}=> Dq$ "~鷚೫A3{=3VFKV?~mj_ROi\KBW Z,ɰMz `z [Å8 7tCA֙4ƺA gW'_}!櫀36Dp\8oVOĘYi, p=t"IherK ZCR+aW3f*]lhG[i\:(=wCs~(]D5 A\/ LVbK k r%2+Ɔ+)WޜR^X {펆0a3W#u>'0}-XABJI|"`[D6Cce,GW>nvTD&@YA X+S qVJ oC?I3?)t'4&Y*"x1+GdG_z7(M*G"~ 0&\H"7P۴|2gx֬G*ԸIBhQI#$9A}co2kQ`pՊG0j9 gƨE-eKhR^ b1,@v0yWߘVm]a6"` + YWٚXGtڛsc|+ o ӵ x,'!۩/Oq?z@"[}[UUُ_<'C}_9ZUdi~cO? htg|}Y R,'>%K<};;F1,M=>(ׯ^}تc{G=_ICoQ:4/-vW `׋JMVocllPW*sS^w:<1|9RrQ˟}ӯ*=X{mA3+|>f_R~Wd$1ׁD-:[Zw7Z:F^UE v^{=M.~s-{$8`4xP#(>=eFD :I&diG,ks|ɳtwCo_Fa7$̓c}JqKq=O/i6y] (>級BwCZH?i|[)ld![m6}^-~IwI\JCAU{DKͻt^\l(L6J3ZhIRZP@vZ ?uYHppRm/y'59 -E)(W\4πWBh~( ~voy pk|oZUW]UU^u+rP?"w]BOu~P<82bA')B"Ja:ONR%I5xˀ_C#ѼxY\gKGIQ}b~ǷC#<\'O@?qOZ؀6 s Q c$HS)Ƨ/lis8pFVY%"Jk} GрQ^H:P}.q-Mw>m[o ZvsYKG(~a; u ~0Aج4k07uwgћk+CjJgܟӛp/P`y9^U~-cR2*Am!Owj-jѥݡl D:>hX鋈͵1`焳%ͣFIB`0^"hb<Fdl3OZY @W |֬*ހt0Oޙ~F!JB$7^lO WJ ׯ.(~?P87_~Ϧ}~5߽J_^ "7CPMD۫W9JF)gVOQ(xv`$t 6h&>xE%(@D3w ep |GJ4bɉ4/PP+`V8fIb!3 [`} ? ~p?@?"A>\P: '>f3,1MJ yo2.s:* Ғ*>MIs>͵sSxX[JBrM$ak $$ @~RbcU )GgNҪ\*~>s3tq#"▞獯{IPBJ( b+WPUv. {8q%A5 _l x1_41Rhʒ~i:~ OE9< .AJr [t%{ IeAJ&t&E"0bj̪TkK')E(@(] 8MD< K($!\xCk<x,Q7_~PpQ`?` /?~ 9+>N ϴ??mę*Mt+36o'A-? Xb``ҀNAQ^IbcH@.T>qRp{IJbf8N%$6p '܁;9Msb? @@kW2A<ŷCk3zrn3 ؁x@?% ?.gy0 &.!Co<:Mԫ,+jbZw!' 70%< LDOggSD-*&Ŀǻ6>Yz p '{I*tK 8{/\40h:o (!""`-2 G/`6z!Px6qB9';?? / MI7S[1~~&B14P:>X-Lfm\C75>+Ulx6^JAhE"KxkZЈ~) 6x~9q Q %7a˷nS77k0` HY|A 1mZy4TmLZ0!: ix6 [P^*i 0Sn|;5" - ^*>\k849<"Q($!""/2 .7zGL=NKBsߟ?l ?~,{5~ӭGgç@@$=P5≔],h((Hhl ll$6<6l4CO>C:9ACT NG05޼+jզ?BNuI$J(DDIp\ؓyt?܁~I&b"E p=g63f» B`R1kP(dNwwH# Agb$ (&tx&xt6L&&jnop<0c3.QV ٳ99D|>MFĈ %P(!@~܄ kYXO>s  `x ~CsWv6=` `0fL50[T6PV %MH σD A7g.i`+hޘȧ6a*yHH<"oz".~) > Fm'G#g[p 1 {l< L<&!ؐ&6HH4XZC؆ldLA&h#x~iyW(D"$@dԦXy_|A<޸l9 u_nBÓ!~t`a('~QO@ SaJtV4F+5M0!6$6$`CGX[+h>cXZsC`_xp!rь0~D %IP_G6~P~uf$ {/7mF>tKd zb//?||m=/6U@  M!h` h!<4<L hHZ 7@P QS#is/w`{2"[B;d41#QPBDDDD @@c_TH$9 (з_^L> ~= S렰Q&h(ؘH l&t& H:0I:̟? ;6N kaMy @"  %@D 0 ?} ՝ckFO@@ ?@m0C'y<!&ll64<LL<:I@cYL310!t7~@ڽ8QB$IB Q^$?wNIb ߤ|@=~3π ~ zP?ŸE0x0y<& CYz,;&8@++^mИװPB$D("t~c"XM옺:qR/t=M ރm$Yʼ`FG LH̍ BF A0YmD "K%He )&bABBDI%P1nls1WVmDv~9~@ؼ(o|o}Oy(HDB.@t$&h&<LY'fD7!CLVKy($D`ޡ>s@Eh}*x~ 7NxkB PFց$ 4&< 4h6yqNyqN\-{_k allegro-5.0.10/examples/data/mask.pcx0000644000175000001440000003600511057522251016610 0ustar tjadenusers +,,allegro-5.0.10/examples/data/exconfig.ini0000644000175000001440000000103711057522251017441 0ustar tjadenusers# The ini file consists of sections # which are marked by [ NAME OF SECTION ] [graphics] # mode: # width height bits per pixel mode= 640 480 8 # Whether or not the program should run windowed windowed= TRUE # the actual content of the screen [content] # the header line headline= Welcome to Allegro # and it's color in RGB headercolor= 255 255 255 # the image to display image= mysha.pcx # kind of image display # - 0 : stretch the image to size of screen # - 1 : center the image on screen # - 2 : tile the image on screen display= 0 allegro-5.0.10/examples/data/obp.jpg0000644000175000001440000007144411436107114016427 0ustar tjadenusersJFIFHHC   %# , #&')*)-0-(0%()(C   ((((((((((((((((((((((((((((((((((((((((((((((((((("A!1A"Qaq2#BR3br$4C%Ds2!1A"Qa2qBRb ?),*'e.3aY*=?fݲt!/(nнۡQ!ޑ3!? =PRY),YII`5t74N^&G(|Kek?xZ1А$6Fτ@=|.[%+ᕮIrtIz<<=!n55'`.@)9tl#q`. =FAform, 7< ЇnLJzC4ډTHWG h7&< ނG~4nShלu_W$&?O&B XKۧOYfa`t9ptGΫ&g[-z#;A3:TyYH6P1oKc5,V]Rhzzf63@.{#3u"u䳸 / ,cCq ʒPveû(E'&w2ʶ}V cADQ4m6-}Zt$>H5Gl&2<.7@YpwCptwI:v.HFV8+'%2:'ĝ h`{FT6,&WT$^2G"'fÁA\-~#  JI;AR|'1ᤶrK0y5U'ttgA xŒtlnF{ڏ2L9M)b\4z}]8pY XOP2Blⱞ WCĒ5DI#oG&|V ݤ*ˡ 2p)KkILn_<ylߥ|eY[/w&=TM|ǪezҍJS1p͊A`663%e㹭]#Rc$<9x8vOo@,wWF $iC,Lܑ?8wTxlcUcN%}'rTDΚ tq~Jc?72`͵avvDw #nK桪NpK!wLxJ!!i.Bmo 4g_Ic{gt.$cu+CDrXVp'78OvL]G#Cu/#zWG&Xbx`cq'*!`xwm<.Ý^Ts9y^pv.dgu;{ȨG._Ggvh;7eu["w=>2`7\T}v#%eqo/+l:b/3sj¾HHkQ^Γ*Y@h}4&"A=CT6cGsL챭-P@P=,FyQIlO" S']Y h;s.=o>o3.g ڮbL[zGFLke+\Y`FP\}ӻ[ͫCBK%~=l=[J_R 4}vX+h&LpIpH- #9N O+.Z4DHmo5дmiH0IIÎmӇ . +p).Nm+D@7\m#)'⨝%h?WpoQu̱;saخG C;r Z7Il0Þ&M#oů弐tq{k] }i\R=KdDڶY7vs[U wRk L\r^幂b ț #cyxDPvF<Sv8>Ambz#\@_Vme)'2dŒi??eD X6Pw{Ƈ4i-.t%;I#tbZYT7J=ŚM{Ӽ7>CC}b5el.VI1 ktΙ5FJ55q6CDN,ͷPx)Č얘|*_唹YkdwB绛%tnmDԜ.ƢD(1!K4C8)In KmG!o&Z@(QLBP'Ӭpu {KXM`;UXa66]ۏ@`q'=1vLn!o֯{!g%m~i oi [yQ C)oIllVcКdd>.1Q.h!=F?3i7{F]2w/k ΛŅ 4E}BVꇬӥ!^C :MHQyNu9yW?jP6WlLHfn4%Pe ikS@q!U4&mNtb'YpUpiozT>uâ^fdQb X\Cˉ.S[A\ܩZ7Cnhen ` /E0H"{%ZrO"Œ6ǹۥ<B D'hix!u%)!j Kb`vGƽ#"v?&Îڕt^I{ܬ` ]~_Qlny2-[tt[wVpDj*t4(-J)tatbm5} pݑcѪRH],[qJ,Ҷ{-BS${i,1Hp4K[h!om%4vHe}DܤQZEp(u%tIYI@wH`};mha 4N+Wݠ'tzmGM`$)` ,&J[z-n#X-]GN蟲c')9r殢Ȏ8+sWBni չGl쓸ǃlPdDƵRqș6JCZ^H5jM2N/Ɂt$Y?e87A1=纴]2~$)4~EO>G\}|R:vk;^f繙K ٥' È*<)bېpDe nu.j?%nЎV?4(ÐMT1r+@4Y@r쎨!i ~(RBuG*XH(#EQ'AiZ,u",̡]r-ڊ|n%@KQI -XGD TϠ&!e-G;iڔPKpP&UHr$ j2 mtցhnLh-J BXIsT2D2qjK|jXz}@Q=CTVD[_^ Rc;w!(D9h/1t'w7KxkxSpd̝W+[|hrsg,%{/N^Itj{INn2e!-%Js ,@j&tamnA`CX?g!;&\[|ӛ Y4lW䕃<~ޕ_Sc{ھ~U#"l4]_<8kOxJ2'{<ɋ:BX'i#؜^2ͲR%c]tEȢE+q# 7%…Fw]#L%~BR{\ǷiM,sTrn>/RL+ýGCt{V?z~<<ōyn;~ dz|b?n?M[_ҡEV_akkcɶiVu0^ B6b6\3]!I#79Iy?Ц|Yr3)6Y; '+xe?DHoH?='dp7)0ںe;:t<2'_rRsECrk}ߩO>K.,8[eI{kaz*;Y qk㌴u+nnRʍLq[rGڭn$͍5;KAwR&GGᆺ2wh]N˪=U*~BZc-Fr#/HɮP]#:Bll2C[-l8T\R&UнòBZCN(VhP% R$nb԰qJ[=Mҩ:6x<񵲹;.N$3`nB[=]{kU5KXZZߧlh>bM?DpH5,R*dS_27U L6/dڰ!Gt{,-dW DP=H:!vF*I(AҞFKIrQqCC Oݩn$m(\omR??Rͭm><} &E_es 1`^fbrtǡ@lFmGeȔvE˞,s~Sfc /wbC.wnovб !r#%:ŰH깓}hVԧ 4Ľh܅;^ DҲ$jcEk萅9H\C@ifQAc̮|1L5 &+L\>xbLt6;rF)wg.$NƗ[kN.^Ǵcv n la;v23C# \emX,\8[t[FǷ*_50A5G=Ag~5y¢Dxrq !=֠H5sVSQvCpwkoWPkwt/'IcBInݮUyP^u+R4,֡dw[h-iޯeG3|p{E4j:&i9 L̊\MȞsiEҚO`iV;!ZhlpkRQ9Un;]8,Q`8lVJ9[uYIQH B-G (@BH4hqXNuGT-HlOIKiڽҲ){~+\?=򩲙2rmy/݅>D:͒AVL_*;{;]o FNCHۧVC-bv@Gu22;&K?Ul~ Di$E;):(in;_1;ꉥ `Hh A {#h-϶ 1E$py LvC$l?d״YCWT+EF\Hh9T[n\kreP!9A/Q})_44UH-kHq'^9a/ Wߚ5Mv4PHRt6LE0lU:Omrlʶ\R%|f\ZW?σkS]M繿?/Xt4{?/?N}edi v腑$FtnK\6PYnI 8jp/dX{PV>@Y>I\C+uzaG'x.LnI<3ЉD=]O}zNsD29V<~ة~-=G E >"N?U~+3 lDգDyGױ,.c潻q#G@;㢣.Mniwec][=oثj[a["|3acG&dn15K)lfNٽ?4Oe"EP$lVP3U#BJCBj +t [i pR&.-FLOfS.K\4A$Fl˚4uy1e%޸]H}2#.`5lTKqخt Gq&zh,>qD$yv[Cʁ^y"*Oᥠ(jzAtL$LҪzEHNij3Nox wJ%2NRN$HvtցW>ݸ@'&#|(@4q xY^R7c%<ݓ-tvvM`0>W{c {Q_꓀Je/LNpptv634aMpk3Y19lo`d . okYpْs}Oi gI{McNtPh+vTM[sAtǞV &h~u߶@CC':AEm.O 36ΒJd6l:cgq4زGs\䦹/׍ZZ}_+3ݍuT.v5D&"+&(9qitOP (-Ό-"Z<2`-k ޲&9lDiv$,EƒR0M@cfuX~v>Mش ,%o_HڊXuF6rR'H2;GM5` d伺=UUt2s3 tK.c$rH c ~/:t3,LKd&52PFo0rvn% sZ.\#cCA~\~Pio?Nԧ^H<9tv7߿)M,u)əτ|۱eEyp>0۵Cz뿖VOƶI#L'uؚT+DZÓ :\kpy ky^)]>lPt= `;~k|QCٳ}HIo%gQv#\ 24#7W4<cSC0{kTMmtqsG[-ULQj4T;w@FYhQjHY1dZ ;TeRY{E-0ࠖYK+,c~Kޔ6I![.4t3~lx|r88|5PTָضtΫLe9o{ZI Q1 rzR_+^lU7hPdz!5Ǻ,iZ%PSvV5ۅ'>!7]&Fb#1Hxc-Q 䥵H7^@&KùQ!IYS45e5r&1$e]Je8WSNCAmIdI$9^N]Cɗ%Lc@h7~<׺bCi4IϜ%۷5]cCM n?iK 7_#$i.WR;s1${{Nɞ~IcK z\9x;`ލӛ'kj?Ν34@8wx=.XswI:Coet 5{3k#sTӺkpkv7j>S$o~a"qѲkn) . 9Lipk[ L%D1@o\wů:IEF[|=cײ6lK#[龰v''0>@⿩ڲ0>#54Xs8ƪEG3OQ˜,R1R IGa{ =-3D!GymQ䮂) 8KϞ^Mgŏ4 {%ku\t&5:6Q`d ~}uPzvvN-7.}?kk m]Ob` 8Pmr|,{5^ULF٭k"`gfنY!|O3u}"_G.S}Ǻ?Pa0mch$OyF&_?U]^Dfg E#H }.or1t߸^p%npl)"ZIk3<ORW+.^[i|T[6?)# qIN{|,3YuA$ oVs_nW7u@ ۦF`DR7`t~9,Ly\~<+=wy]Cǂ z7]?9;4> |7NezL͉eL2R.c4 L†~?ĔӺ{ȲۺHe#&ӆȱw ue9ҞFКZ( RKrmK!A,ZŲ7Xs[tln !!&4lLJ9Ah['i (Ch[nS 5J3FI +Fm;o-U<e:7W!;ZH{}_4WJ+ Q7H Z&ھ3"nLYg0F\vI230I.sft[fL%sqq ۈ\X&3\[{TC2]<4jZJ Q;-]&HK=6ormWM#?/I;YM:3W~ەddf3I;XȚ5_EqY =8&2Km$WtICj$V7. .G:i(IZ+g\a"5^*H p AFKmxv:1ԣFM呑^8{A[ he 10XkaZQ|\tvI$lA4{EgTR1E[~{^V5%sdl:͏aiqOlU2Ldokxi#At4Ihq{~8 ;P܌i2k!YqEGO&\:FKꌷU;ۑ[#XߟI#$sY#ڑ+_Kubg&&@{I{ ˥䱔q^*Qpl;͉ b:WQ%} ֙fRf4VV!kHiDsDxDSM 8lsޓpPgMvFX݂ O#dIrIB!6 Eәs?X;ҫLZ .cGS mrۈ)'ˋ$misv<@QE'6,ƖZL8t*E{hq|)O$;oh[M 6Qe!ԞZzT{{)ʉ wM`&E{E)l&I a(me#vU7ԤLSV~U\QXN1%yWOĥMFk[:H|Vsbc;?:W1F7{[nY[:',n`~ [ h.':ŏI@8Dm7sot2yio"&XIp Sq0r[#Pm`w5,w0W'GM cI5HM`o32XcF}24?H-`-;{S&{H nw>e:pD=`wPv.32K ߚ h`ku Թy:l qs$u{$X v=Ÿ$S7!{͒h4ss*fr#c1)OsH NVEꭒMg㠞۪\̂Y] eܝrW _vm̧I￲n;bDz1|ǹ&\Tqb4mH|3I1Y$[GHuj|q2 Z ԱFi$2rŃCs9~{>͢GeU..${&,S?8%0LmŖ&CN=ʙ>d8-H $}4aD&t1N?v2Ng:l9,G&`~-F- dwDw݂-k8X5 /pI DUga3A;ˣwGd܇tynw5{,?Lu4Fz ~??RPI1 1*#a]ue;5hHSe4~Cm4x4:"#C }!fK\D6Nt?9K@$Iƥ#"s`Gm88AɯϥA"JRt,dZYk&K0ȕ_Dn2=G$E7=zGk㤒wGa46B6v{)Ŧ7V߲PLdos7ظ>%]:7ly"nd29BI+ >mBA`HNDO'"LV("8dQ5Q#mrUc%c8+I\IR>AL:}:S }'mHnV"y:h;IngCT3@ |BC!混pvg^G%&Z wK U) ; i6 wt@H?d2-FN@v@B[`FzS> ;졉{%87_trV$W"CI}\u6"ebo8l)#Gk6UD!;{C{^rp =DtSJ5 VF3oq&\Pt_)I_ڴ<`cOv-/ƥw##d1Fml&mb'`ܭ=& ŮĹF~G*M9Mղ A\?YT]VZ6+ƙ#\<_ %U7ռA !w$I͹>*SrEPaaOe;aG94qe&|IDSMZFw5kߪ5ZX9esŗ\Nv{*uqCfG<0CC3s.\@ٮ;y+ɾ8;bڤ"Yޜni̘ 1ʤnc4bI4v~68XF66m]ɺ1Hё%1fy7\b6&I;&ǝ#qq v(||Rwg{i$rEϺu\:iK@.#HD{a^dYU)GxoaOʊ(2HIkN[g*e&aEc1 m+3NKۈ4M_L-ӯU5o׵t:3nUkL;;ֲ-E$X60C-B'ip%d%&ś=prd}qx#H+6P+C^A'WwR8ԮoR$kg9$ Ct#lAQ3Cl i}Vn䥲6qہ[*; 9k_*7 >iW22'~XFĹ\xGI5CYsv.O_d:i4:Mץaǁyh.c8"=o1]uRJKxP? GP("W/˫_42=(^l O=ZaG>\N/Qu6Ia$I{nGjC+Ȍl)5l 9 ZP4t{ZYMʽ> F56ED_T䵡Rhm\D|CQ7MH6?T2U-:&[hi;,p2FgU6Kȳ{`8 n8dZq/gDDZ)?}49(.G~BkN~e @Ж9NhT [-+>|ZpZi[Af`9$ qIrk^;C#u 5²ٚZ,AjEad#b8JPL;'4aC؞vl{&['Ҕ +11r :q,cKܪ=#e~Iq̒9"K۞;{ޠeyv=KYٌ.sdEISΰ]4w8o7ܗg],c k h)pc&t-3qFzVDt28Xm],qI?k{~jFEs)nbpv3cp aγv::rP9#; LN \( +|\>HW#^\水вF>5*;.pC|ǀ8X纞IT6q+m7-|˗.GKlM3GHtƷ~ot:&LF0LCEA5Aʭy{IM#] R_Z@[ fG>By= QM;Y&9[ڹI˒h\ǵ3quzQCNILFSdcBwQbyM#bO_UT/7.]Ye2Wj'jK2(/o"dlGak 4DfG}Ã1Ŀk]рW>bnnɍne!!iD4~juo@"g(kS@` h.lnHz{ܐ N )KBŲ7XttƧ6X tcoشl쥔ψwUQJګZ+遵DNoOdQ| Ths/jm "W+\~o]_Wg5?lM5^q|sA9Egk/;r|V5elz$N^~4#F;Hڽ\e=1}6ΛSA TeN aye~9<YHz8I6GUM1W{/979m^;5C!YVk?/f9Oتd5{c멋Aa01oX^>Vv16v,я; tZwAFd͂&?'1 zw4۲ V;_QB{\% g?%ΜB/>WW ,n@a!10nb֏*DS7k*#IdW>:3soRqzPiX8V{m!ըۭ:vkLq88l&&8Z5͡ki!Q|H5gnTM6(s۲V@"0ob_TfNhUYC <}+s[$9ڶNn$Fih-["  zMrFzl4{M{ICޞa<ІB 2@KHt ylv csKOv߅KIQ"=Żۿ+#:,%]mChDE~ k|Go}ͧMѢVEӚ}6r,m`IN씟. V$-ΏGWr 7n;/s \|pW/iM4oU-R.VW4n f&R[-NO!!Kd8p|%=&R\RŇFwрY 0t/] LJjSZwX6H D <6HXPRWowX/tɡ쟠v*%wDC9KK&G^D81z{*( %-1|I]z˞3k4+۲'<R/%fvSG d._;%3"uuHAT0ֶx[ɕ9$ܚ}FMG>7-db6{@,T1һRIvqEEJ:|db' g.7To|1qgm˩~I_Fm{%sHKfpuQk#Yi"e,|vAbMj[e> ׆0r grnB($- VhXI{I >ˏrJ`ioH W\3-"5kwv\%P4w{)%U좽tV*EF4ۀP=Ԉ6bIEmH|momiM%|l_Kr<5sC%pk $Mܬne0 vd}͢Q0&8:ܙT-b=0{5AV{e#aHB4 BCEjG\m4U!}.hh[1060^ݷ '27Qn !IkI{F- m}XFM6JN\q-ﰮwXuw/bl]wo|#CFkF/ShmgK)^<9]COq^ʓ0nc_Wa<첹1Z wiew$fg.MV,V ޤV`v胶IFAaBw&;9KH䆌sV &Ա'uO+QkVỠ{7`mृkNH,"l$6Bhe%XM ;XFP9E+ M3?gG&ivh]ֹ4\5u9MBCeK9}YqS?x~.3ew0CI2e8)!r}w<5E}Oc9?͑4}-o\ ĽB/=9Gk]D~8dLZȷPx#̞V/fA+6vU~dI} 3?6IkM-{u cəٷG&5$lMoS4=ޝE!fp``Ӣ?_tSV ~yF_ i")=F%{|@u]PUiQ]DYԑ VKrX;>=AjQ%7. V$M=8>p#mz8 qvTQz^2AZ^iiFS{j]"I{Jϭ$nI_! .w9X.ZҊ)Ӱ62ơw'*G7$JQ=FȾ,8X]xj@i TUq7Yp$hCIitmEGj@3O`i[c%{P[p:wZ I+h[7Iƀ֑svhYH *\PUv&|EuOeQe[Uc7Q{_=Z0H$X]$W hvJLc]- ;%KzK/ZyiQCIHyF⣼4M;RJ ivRIQkȯvu"x%ɒٲ1ۤm4 *]uBMFl'NBlcYhRdE7CV#^?UxLΫIn"_㻊Ŏ0q'4AwcG}<#v6.pٿ q/nS߷eDs%kxq2?< 1q)?ݾW{չ= qr>ȧ?8+ue8%hTqDY딏T*縹丟u9A%܇ 6xd4sMˉeF47;.v^QsŸ̌ 4]mvS^uI#߅uiuGKifDVIw,/ӽ}LF6uZ܊NΜqWdE0P,H GL[D\:[QKkKpklJiߊX.KhK$YI-ؠ?TmǓAmi6htzl 1G ңG\ѥji&.i\MmUMm᫤F }3K{ Ge%G=6Z?r@آ<\ (nKejjm 'bE Q!ސ K`)ۭyX)bELJ8#(WEe>WXQyZfX Z,֭d8?p~IMʴ+-.g'UEҺ|ORBz= nTRސYa5W&UoFFll;?E_-.xF&g7훷e˕/,Ŗ"1ꌍ؀>\*<ƬYCPF͎{&P1[#LtMĂ$&{JB\94T :yq܅vHIŸʙKe}h..w6*,e~2$zBlo- rcD4K颙pb&XڵF.4{vuS@ɵҥDmM?'7[_6SDl9wjk@Yyos:\n4V_B䃩 BsݫrAָ2N] 4|B-Tw_X&<=-3# &)q,zˊힺ TUrIh(%;ypxj;/ n8poROŅ{uƹgstA76.ltbB)Q΄:n9IIyЂO+jbb|Mk8:c2yd8F_âP*vJ1TGVR8{cpx^dA'rIBzgC_RzR裾7 .{{kOoD.=W#;>7_?*3q$/>j -~ńZ/Gkb# n:FTi5H;] ׆NHMl}e\}&=gN:ZidŖ+~U?ዱiN𗅞ּ k{EIίQ-]W֧Ʊ"<6gkU>PAqM]7g[쾯w+^$U- 8S~푎ldVH{@ڗ1ÎrDŽynF 88vl.i< sbQVς<-NsqGeWz_k~g]@{6<0bGG{J8w= bgc~Eby / 4LxSb QrOS]*ߨ[5wENĄDX}J xsI Ì\Q3ܷ R_"fAo+Q:[Czv?zF/% ?a臖BHҺ3#_cھ% =7%E܄twlwrb<5?T|ק3Cz?Mhھ1 =/MwJn& t-{XEy΄%OK ҁQj< j#Һc,}QHWpYD^.zp}u)W?Ne!OwEi;[=d|XF?'-g{zN,>:G*Ayj %b)Õ{Z+YafA,|j~FBtX/1,lxߩ$"; \\ŋHuR얝`|9c.N7ŽBww *0yH'&xxC䤹:D)D$xݮ,iլu/c iicpJ,#w["wVCOkQ Sf<twp>Lf{`ۥJpDO/Cך0P^3zX/m'ο6P)6>] m{ !ɂ9 Zw(; "pQE&9^x6bO+@6E+$*AYuQn)k%9o0CHȫp*̙<[955=4=n[[Azկ[1e{}Fō5%q(/:k@ƗdͰ]R3cNK#X| eGu)ˏ_pot$e\ˇTLȐdm25߲cIC_bvZ8u5}-;*H̏ct9evu hdA$O$<]Ƌ:3P>YN.'dJd7{%,<. csi-WQ$3K dS%Phn_w67s5l\\9as,w[c<G^{QY1yO*ϭ>JdZxTO99G L\Jx4e(޷3FXxgd-];F %:,kI%; |ޫ֞Iĕ2OpǥskZu8lV_gsF@;N=`|7AqRM#Xֵ=;)j{ղc׻ufL  SGd*3i. p9(H36 <=丣s I9/kA}_#^ 's@f̗Yh<.{oޒ$~t[XuXV'lta֔Yhܧ9֐##5Ntnbcp,Muζbt]qJxdҶ2E\GCXCjd6- !Q'Fnmu j HPqljcV;`wRYD#h4IPY8v| i/&)!: $>KXIE/'@qDq&O`gUr3h]55~P1k`~i02`{O]. P^u i1lj6p%@pdhc$odFF!Hb 7h6Al#qsjE= H ji u*>ƋcM>B\n 貋#٬%ծ]*r͉G&ei܋9Wxwÿ f6{]sRc֦8($1G @G#HpFѪ':ۢ6h45nۓKL9g4|Jcۥ|-Mch1;nnag vC1Y50yR{]a 7Aj_B(yrYyR5\2l6ScAb6Mc6٤6;QBW7$0GnOZdI{+bKgB% G/j!*c0yR"O~1ҝq%56g9p,Lvp|h)-,Ѷ=Q[X>@O.C쉄>tMÂ/o;ݖ^K aV=pI9qEZm<и+3Y0\w?eJ1 8+i /HH,r>?15G"W94j)8s[mMňm$$Ms"ܔ~[f{.p:9InǺjAVKKKѦ1c]pCM&CtԔ\6 [ c2Y#K;XTDu0icYހZ3EGt; k7SEv2m=k{tcZKx6ӮM:FR27F=Qw$&:wcMqB3# gpĠ.t4ѧS63QHC\I=̈́- EO2<$iH$Ȓސ GV h88p5I5Ҥ;2\q$fF\푑3K5fQ>BIQddF^_СCQdE9 円v9ٯ-R1Daqd'K 6{$;Cdi\[\|˚_6yͻ Mlr7k|m2Kq%mгW죉AcNRI/{Lo'ἦG2A=to%6X /$J^Q>ipܒy #AlDoE!!ߕΗwMd5 $GP`,wFLs- ha=QVmLwOfv9 t&ljTQ};CqcK)pe6$Z]WAkZhLdr<&4>65z7oe)»{Y] MlPsM!-%snPXӥ L3`V:9ɧ>fQ>>䯯ÎةǢȎ^^^^^^^^^^^^^^^ Ǣȴ̯됐ԒĴ'''^^^^^^^^^^^^^^^+++___===Ԓ{{{޼ثܕ,,,^^^^^^^^^^^^^^^zzzggg''' ܕʞǥ۞߲___??????^^^^^^^^^^^^___~~~,,,߲ιڵ郃ڧ+++WWWooo^^^^^^^^^^^^^^^CCC>>>xxxڧ̓۷ljEEEkkk___^^^^^^^^^^^^ooo%%%ljΰϤٓܝѐ vvv~~~^^^^^^^^^^^^^^^ooo'''^^^^^^ܝѨ㼽∈·Ē,,,bbb^^^^^^^^^^^^^^^^^^^^^'''Ē𻻼԰沲֣JJJ///^^^^^^^^^^^^^^^^^^~~~LLL֣ϩАڎǐMMM222GGG^^^^^^^^^^^^^^^;;;BBB888ǐᶷш콽М//0___GGG^^^^^^^^^^^^ggg{{{ţƣδzzzsss'''???^^^^^^^^^^^^___bbboooرѥ˽nookkk??????^^^^^^^^^^^^rrrWWW'''<<<ٸ괴ŧ:;;VVV###??????^^^^^^^^^^^^{{{~~~(((xxxrssyzzΡ常>>>666??????^^^^^^^^^^^^^^^777CCCņkkkkkkuuu}~~乹ػ###OOO??????^^^^^^^^^^^^cccsssnnnpppmmmpppxxxppp칺ʸzzzbbb???^^^^^^^^^^^^~~~ccc|||ͧpppqqqrrroooqqqppp}}}Ψ޿WWWrrrnnn???^^^^^^^^^^^^rrrOOO'''[[[¢sssrrr~~~xxxnnnmmmvvvwwwzzz෷˺III[[[RRR^^^^^^^^^^^^___ KKKڳqqquuurrrlllnnnyyytttĩѼDEEBBB***^^^^^^^^^^^^^^^___///BBBBBBԢoooxxxooonnntttvvw{{{֯ǹ9::...>>>^^^^^^^^^^^^^^^^^^;;<徾vvvppprrrmmmooouuunnn:::OOO+++^^^^^^^^^^^^^^^FFFzzzCCCֺpppxxxqqqpppuuuoop{{{ͮuuu999 ^^^^^^^^^^^^^^^###???zzzGGG̣|||qqqxxxnnnlllwwwuuu}}}ỻrrrrrrGGG'''WWW^^^^^^^^^^^^^^^???>>>nnn###XXX྾ppprrrrrrmmmqqqqqqyyy츹tttsssDDDWWW'''^^^^^^^^^^^^^^^??????^^^...sssΩoooyyynnnmmmtttvvv|||ʥ}}}}}}~~~QRR ~~~~~~^^^^^^^^^^^^???OOO>>>ťsssqqqrrrmmmnnntttsssݼtttrrryyy~+++OOO~~~^^^^^^^^^^^^SSS???NNNڶooowwwĹqqqnnnttt|||{{{뼽}}}sss󸹹[[[###nnn^^^^^^^^^^^^^^^///^^^&&&թoooȿtttmmmpppvvwpppկ{{{www___^^^^^^^^^^^^^^^kkkGHHwwwqqqɿqqqoooqqqppp}~~蹹99:222GGG___^^^^^^^^^^^^fffvvvպpppyyyɿxxxpppvvvvvvttt{{|便pqrbbb___^^^^^^^^^^^^~~~zzz~~~̤|||qqqο~~~qqqȠ˷wwwooo^^^^^^^^^^^^kkk###;<<߽ppprrrοnnn~ԭ---666BBB~~~^^^^^^^^^^^^jjj[[[///yyyΨoooοklloooXYYfffggg^^^^^^^^^^^^vvvBBB>>>åssspppο|}}ooottt载nnn^^^^^^^^^^^^^^^222NNNYZZڶqqqsssοdzpppoooDDD;;;;;;^^^^^^^^^^^^^^^"""^^^#$$ըoooοmmmwwxnnn^^^^^^^^^^^^^^^fffkkkyyy濿wwwqqqοųrrrlll]]]ggg^^^^^^^^^^^^^^^~~~vvvwww001ֹpppyyyοǜooowww&&&CCC666zzz^^^^^^^^^^^^~~~jjj~~~ Ŝ|||uuuο̹xxxuvvxxxvvv^^^^^^^^^^^^^^^wwwZZZ###QQQ淸zzzο嵵ιnnn@AAbbb^^^^^^^^^^^^^^^vvvOOO///777һο۸ғnnn---FFFzzz^^^^^^^^^^^^>>>'((Ȩοsssxxx淺 !!^^^^^^^^^^^^߸οտmmm⊌^^^^^^^^^^^^vvvʧοԋppp\\\ ^^^^^^^^^^^^lmmοmmn{{{Z\\^^^^^^^^^^^^$$$٩ִحmnn刈 ^^^^^^^^^^^^444ě{{{www깺+++^^^^^^^^^^^^ KKK嶶̽Իoop@@@^^^^^^^^^^^^%&&ѧ̽޷Βnnnuvv!!!^^^^^^^^^^^^efgǘŠ̽tttwwxTUU^^^^^^^^^^^^*** KLL̴߯̐̽nnn=>> ^^^^^^^^^^^^:::iii222 )))]^^ˡʵ̽DŽqqr罽QQQ(((,,,^^^ʲ^^^^^^^^^^^^NNN 111}~~Û̝̽noo|}}yyy222000RRR^^^^^^^^^^^^sssϽwww}}}BBB--- &''233000FFFxxx٫Ł̽šooo{|}LMM999666//////$$$%%%(((GGGfffhhh ^^^^^^^^^^^^̽šoooġϰ̽üvvvwwx似򣣣^^^^^^^^^^^^̽üvvvwwx似̽弼lllթ׫ooo^^^^^^^^^^^^̽弼lllթ׫̽չnnnͯЛ...^^^^^^^^^^^^JJJ̽չnnnͯ̽dzqqqyyyģ޵ vvvfffvvvfff̽dzqqqyyyģΡ߽̽oooεУ ɩ߽̽oooεع̽ѱ~~~sssɩڻع̽ѱ~~~sssɩѦ̽ƥnnn||}ҺӨ鋋Ѧ̽ƥnnn||}Ͻ̽ιppp̶Īѿwww¨Ͻ̽ιppp̶ؿ˦̽vvvxxx϶sttnnn}~~áͨZZZxxxؿ˦̽vvvxxx϶sttnnn}~~ǭż̽qqqɩ~~~oookkkijjoopʰǾ{{{ǭż̽qqqɩ~~~oookkkijjoopƤ̽qqqɿuuummmnnnooommmȨ°ݎƤ̽qqqɿuuummmnnnooommmг̽qqqxxxڸ~~~pppmmmrrrrrrmmmҷ秧 г̽qqqxxxڸ~~~pppmmmrrrrrrmmm㾾̽{{|ʹ{{{uvvnnnqqqxxxmmmxxxª濿 㾾̽{{|ʹ{{{uvvnnnqqqxxxmmmxxx׿̽pqqε{{{mmmnnntttqqqppp 222JJJ׿̽pqqε{{{mmmnnntttqqqpppƫƽyzzƮzzzrrrmmmqqqwwwnnn}}}ʭuuuƫƽyzzƮzzzrrrmmmqqqwwwnnn}}}¡Ƿsss{||ɺuuummmnnnxxxnnnuuuţ̧ ¡Ƿsss{||ɺuuummmnnnxxxnnnuuu̳·jjjzzzpppmmmrrrrrrlll|}}ε___ppp̳·jjjzzzpppmmmrrrrrrlll|}}ʬwwwºuuunnnoooyyymmmwwwͮ''':::ʬwwwºuuunnnoooyyymmmwwwԽyyytttuuuѾ{||qqqmmmtttnnnrrrֿ ԽyyytttuuuѾ{||qqqmmmtttnnnrrr¨{{{ooorrrxyyƱ}}}qqqpppqqqrrrmmmūzzz¨{{{ooorrrxyyƱ}}}qqqpppqqqrrrmmmrrrwwwnnnƼyyymmmnnnwwwmmmuuuî~~~rrrwwwnnnƼyyymmmnnnwwwmmmuuuȲ}}}xxx|||oooħpppmmmrrrqqqppp˴zzz~~~'''Ȳ}}}xxx|||oooħpppmmmrrrqqqpppȴrrrtttllluuuؾuuunnnooo~~~yyynnn}}}ʷtttvvvjjj {{{ȴrrrtttllluuuؾuuunnnooo~~~yyynnn}}}д}}}nnnκ}}}ppqmmmrrrnnnuuuӷZZZdddlllsssд}}}nnnκ}}}ppqmmmrrrnnnuuu㾾}}}vvvȮsss|||wwwrrrlll|||³{{{ɟQQQYYY˒pppjjjzzz㾾}}}vvvȮsss|||wwwrrrlll|||׿tttıĴyyymmmvvvġuuuǸyyyKKK'''+++OOO{{{²wwwkkkuuu׿tttıĴyyymmmvvvǭӼvvvąnnnqqqͰο¿ƒlllpppǭӼvvvąnnnqqq¢çӭrrrmmmǨ˯ѫpppkkk¢çӭrrrmmmѷǸ|||ɒmmmuuuܼӼ}}}ǐ~~~kkksssѷǸ|||ɒmmmuuuڻ|||֡qqqpppƲ}}}ԟooonnnڻ|||֡qqqpppׯ͖Ęwwwnnn{||ӻ͖–uuulllzzzׯ͖Ęwwwnnn{||ƫz{{Ẻېmmmuuuβ}}}Ẻَkkksssƫz{{Ẻېmmmuuuӵ눈Εsssqqqܹ눈̓qqqoooӵ눈Εsssqqqڳ՜॥zzzxxx뼼՜ޣxxxwwwڳ՜॥zzzxxx㵶Ո{{{︸ӆzzz㵶Ո{{{ˠͪ縸Ϥͪ嶶~~~ˠͪ縸޹؞ݞ鼼؞ۜ޹؞ݞ컼ԴǢ ԴŠ컼ԴǢˬ麺yyyӱ縸xxxˬ麺yyy޷۷˯ܷɭ޷۷˯Ŧﭭߺ|||ʨﭭݸ{{{Ŧﭭߺ|||۳ۅܾḹ܅ڼ۳ۅܾ뵶ӸѲܴ\չҲڲ뵶ӸѲܴȢޥŸwwwˤݣöuuuȢޥŸwwwݻۙ䯯Í徾ݚ㮮ݻۙ䯯Í꼼ةǢȴŸڪơƲ꼼ةǢȴͮ됐Ԓ{{{α풒ԑzzzͮ됐Ԓ{{{໻ثܕʞ乺ڭܕɜ໻ثܕʞæ۞߲θ~~~ǧݠ߲͸}}}æ۞߲θ~~~ز郃ڧ͂ٶ녅ڧ́ز郃ڧ͂۷ljΰݹljί۷ljΰʣٓܝѨΣەܝѨʣٓܝѨ㼽∈·Ē޿䊊·Ē㼽∈·Ē鹹԰䰰ԡ뻻԰䰰Ԣ鹹԰䰰ԡΧА،ō½ҩА،ŎΧА،ō½බш껻Ιɿⷸш껻Ιබш껻Ιɿâƣޚ̲̹ȣƣޚ̲˷âƣޚ̲̹ٯϣɻ̱۱ϣɻصٯϣɻ̱;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwwwwQQQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@sssyyyBBB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GGGddd~~~sssXXX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GGGddd~~~sssXXX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<<>>qqqhhhDDDkkkhhhYYYwwwwwwwwwQQQooowwwwwwQQQEEEkkkuuuOOO;;;XXXwwwwwwwww```;;;XXXwwwwwwwwwiiiwwwwwwwwwooowwwwwwwwwooowwwwwwwwwQQQwwwkkkBBB;;;;;;;;;;;;XXXwwwwwwwwwQQQ;;;;;;;;;XXXwwwwwwwwwQQQ>>>qqqhhhDDDkkkhhh<<<;;;EEE>>>;;;;;;XXXwwwwwwwwwiiiwwwwwwwwwooowwwwwwwwwiiikkk<<>>;;;;;;;;;;;;;;;wwwooo;;;;;;```;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwwwwQQQ;;;;;;;;;XXXwwwwwwwwwiiiwwwwwwwwwiiiwwwwwwwwwooowwwwwwwwwQQQ;;;KKKuuuooo\\\wwwwwwQQQ;;;;;;;;;;;;;;;ZZZ|||yyyiii<<<;;;;;;BBBhhh|||ddd>>>;;;XXXwwwwwwwwwooowwwwwwwwwQQQ;;;EEE{{{VVVXXXwwwwwwwwwQQQ;;;;;;;;;BBBhhh|||ddd>>>;;;XXXwwwwwwwwwQQQ;;;;;;;;;www׹hhh;;;;;;;;;KKKԹ¶qqqwwwԺ;;;www̼ԹԹԹhhhwwwSSS;;;;;;;;;wwwӸhhh;;;;;;;;;wwwԹrrrhhh;;;;;;ooo;;;;;;wwwӹԹԹhhh|||BBBhhhXXX;;;;;;wwwԺ;;;www̼ԹԹhhhIII;;;|||{{{Ѹhhh;;;;;;\\\SSS;;;;;;;;;;;;@@@qqqBBB;;;;;;kkk;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;www׽hhhEEEvvv;;;wwwԸӹԹԹhhhiiihhh;;;;;;;;;DDD;;;\\\SSSwwwԹԹhhhEEEѸhhh;;;;;;\\\SSSwwwԹhhh;;;;;;;;;ZZZQQQ;;;;;;;;;|||kkk```;;;XXXkkk qqqqqqÝQQQwwwʰ<<<;;;;;;ZZZQQQ;;;;;;;;;ZZZãQQQ;;;>>>;;;;;;ZZZ kkk qqqßQQQqqqEEE;;;oooXXX;;;;;;ZZZ```;;;XXXkkkãkkkã[[[oooqqqEEEZZZQQQ;;;EEE;;;;;;;;;;;;QQQ~~~KKK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ZZZͬMMMzzz\\\ZZZkkk kkk qqqßVVVQQQ;;;;;;;;;MMMZZZ qqqßQQQssswwwkkkQQQ;;;EEEZZZãQQQ;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;iiidddhhh;;;www;;;qqq\\\mmmhhh;;;wwwhhh;;;wwwhhh;;;wwwhhh;;;wwwiii;;;;;;XXX;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;wwwhhhiiidddhhh;;;;;;iii^^^;;;;;;wwwhhh;;;wwwhhh;;;wwwhhh<<<;;;;;;<<>>hhh;;;www<<<;;;hhhBBB>>>;;;wwwhhh;;;wwwhhh;;;wwwhhh;;;wwwhhh;;;;;;qqq;;;;;;;;;wwwxxxhhhQQQ;;;wwwhhh>>>hhh;;;;;;www;;;;;;wwwhhh;;;wwwhhh;;;wwwhhh```ZZZ;;;;;;;;;;;;;;;;;;;;;;;;BBB>>>;;;wwwhhh;;;wwwhhhZZZ;;;wwwhhh;;;;;;mmm;;;;;;;;;ooo;;;;;;;;;www}}}mmmMMM;;;;;;;;;;;;wwwhhh;;;;;;;;;wwwhhh^^^KKKwwwhhh;;;wwwhhh;;;wwwhhh;;;wwwhhhooo;;;;;;wwwhhh;;;;;;;;;kkk;;;;;;;;;ZZZkkkmmm;;;;;;;;;ooowwwhhh;;;wwwhhh;;;wwwhhh;;;;;;wwwhhh;;;;;;mmm;;;;;;;;;ooowwwhhh;;;;;;;;;ooonnnwww;;;;;;wwwQQQ;;;;;;VVVhhh;;;www<<>>;;;;;;;;;wwwBBBwwwhhh;;;III~~~```UUUMMMhhhXXXï^^^iiiQQQoooXXX;;;;;;;;;;;;SSSEEEMMM;;;;;;wwwhhh;;;wwwhhhGGGpppiiiólll>>>;;;;;;;;;wwwQQQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwuuuKKK|||hhhwwwhhhXXXï^^^BBBhhh;;;;;;;;;|||rrr;;;;;;;;;;;;;;;BBB[[[ï^^^XXXiiiólll>>>wwwhhh;;;;;;;;;pppkkklllqqqppp;;;;;;wwwwwwwwwwwwQQQ;;;qqqDDD;;;wwwhhhͽhhhOOOvvv;;;;;;;;;;;;;;;www;;;wwwǴEEE;;;;;;;;;;;;wwwhhh;;;;;;```wwwhhh;;;qqqDDDwwwӴhhhռ{{{hhhwwwǴ<<<>>>ϴhhhhhhXXX;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;wwwhhh;;;OOOvvv>>>ϴDzXXXiii\\\;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;www{{{;;;hhhXXXhhhwwwǴ<<<;;;^^^hhh;;;;;;;;;hhh;;;;;;;;;\\\QQQiii\\\wwwǴ<<>>oooKKKXXXwwwwwwUUUmmmkkk;;;;;;;;;>>>fffwwwwwwwwwwwwQQQ<<>>fffwwwwwwwwwwwwiiiwwwwwwSSSssshhh;;;;;;BBBhhh~~~hhh>>>;;;;;;;;;;;;;;;XXXwwwwwwwwwwwwwwwwwwQQQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;zzzGGG;;;VVVhhh;;;>>>oooKKKXXXwwwwwwUUUmmmkkk;;;;;;;;;;;;EEEooo{{{hhh;;;;;;;;;IIIIII;;;;;;hhh;;;BBBhhh~~~hhh>>>;;;XXXwwwwwwUUUmmmkkk;;;;;;XXXwwwiiiwwwwwwSSSssshhh;;;;;;BBBhhh~~~hhh>>>;;;;;;wwwhhh;;;;;;;;;rrrkkknnntttnnnz{{;;;XXXhhh;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;>>><<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXXXXwwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@qqq<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;>>><<<;;;;;;;;;wwwhhh;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXĴ;;;;;;;;;QQQ@@@qqq<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;hhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;ooommmooonnnzzz;;;wwwƴhhh;;;;;;;;;;;;;;;;;;XXXhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;}}}xxx;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwƴXXXhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwddd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;}}}xxx;;;;;;;;;XXXhhhXXXhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;www̵ZZZ;;;;;;;;;϶hhhwwwddd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXhhh;;;;;;;;;;;;@@@hhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwQQQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXhhh;;;;;;;;;vvvnnnttttttqqqyyy;;;XXXwwwwwwwwwwwwwwwwwwwwwQQQ;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEEwwwEEE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwwwwwwwsssVVV;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEEwwwEEE;;;;;;;;;wwwhhhwwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwsss;;;;;;;;;;;;XXXwwwwwwwwwQQQwwwhhh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;;;;;;;;;;XXX{{{{{{kkkwwwQQQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wwwhhh;;;;;;;;;~~~|}}nnn;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwIII;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwIII;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@qqq<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwIIIXXXwwwwwwIII;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@@qqq<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwIII;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;XXXwwwwwwIII;;;;;;;;;̽lll;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;̽kkkqqq;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;̽|||ooowww;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;̽dzqqqqqq̽nnnxxx㺺oooppp̽nnnxyy㺺oooppp̽nnnxxx㺺oooppp̽ųrrrmmmзnnnwww̽ųrrrmmnжnnnwww̽ųrrrmmmзnnnwww̽ǜoppvvv˧wwwsss̽ǜpppxxxʧwwwsss̽ǜoppvvv˧wwwsss̹̽xxxvvvݻwww}}}̺̽xxxvwwݻwww}}}̹̽xxxvvvݻwww}}}̽嵵Ϲppp̦̽嵵Ϲqqq˦̽嵵Ϲppp̦̽۷ϔnnnÖ̽۷ϔnoo–̽۷ϔnnnÖ̽rrrwwxؽ̽rrrxxxؽ̽rrrwwxؽ̽տnnnť̽oooŤ̽տnnnť̽הrrr㸸̽הsss㸸̽הrrr㸸̽ooo{{{Ч̽opp|||Ц̽ooo{{{Чִحnnnʛִ̽حnnnʛִ̽حnnnʛallegro-5.0.10/examples/data/mysha.tga0000644000175000001440000036440711057522251016771 0ustar tjadenusers @   0 (A008080 (0( A08I8AIAI808 ( 0((I8AQIQQAII8I0((   800A080(((((IAAYIQQAI808 (((((0((0 (0( I8AQAII8A8((((808YIQaQYQAIA8A0 ((0 (8008080((  0((IAIYIQI8A0(( IAIYIQ I8I8(8    8(0A08A8A8080 (0((YIQaQYYIQA08((800QIQYIYYIQA0A ( 808I8IA0A8080 (   8((YIQaQYiYaaIYI8A0 ( (A8AYIQ I8I0 (   A88I8AA8A0(( (0((QAIaQYaYaYIQI8I0 (( A08IIQYIYI8IA0A0 (  ( (A08I8II0A0(8 ( QAIaIYaQYYIQQAI808A88QAIYIQQIQI8IA0A8(80(( A0AI8IA0A8(8 ( (IAAYIYaQYYIYYIQQAIQIIQIQYIQYIYQIQIIQA8AI8IA0A8(80 ( ((  IAAaIYaQYYIYQIYYIYQIQQAII8IA0A0(8 0  (0((8(00( (0( QAIYIQaQYYQYYIYQIQQAIIIQAAI8(8 ( (   808I8AI088(((  (800QIQYQYYQQYIQQIYQIQQAIIIQIAIQAII8IA0A80A0 ( ( 0((8(88088(00 ( ( (   (A0AI8IQAIIAAA00( 0 ((8((IAAYQQYQYYIQQIQQAIIIQQAIIAII8IAAI80A0(88(08(88088(8 ( (   (A08I8AYIQYIIA00 (((0000 ((0( 8((IAAYIIaQYYQYYIQQAIIIQI8IIAII8IAAIA0A80A8(80(8 ( 0 ((  0((I8AYIQYQYI8A0 ( (808A8AA000( (0( A88QAIYQQaQYYIYQIQQAIIAIIIQI8IAAI 80A8(80(80088088(80(( ( (     (80AQAIYIQYQYI8I8(0( (80AI8II8A8(0(( (0((8((8(08((800IAAYIQaYYaQYYQYYIQQIQIIQAAIA8AI8AA0A80A0(80 ( 0 ( 8(08088((   (I8IYIQYIYI8I8(0( (A0AI8IA080(   (( 800A00I88IAAQAAQAIQIIYIIYIQYQQaYYaYaaQYYQYYIYQAIIAIAAI80A8(80(8 ( ( (808I8AA088(((  80AIIQQIQIAI8(8(  0(8A0AI8IA8A808(((8(08((800A00A88IAAYIIYQQaQQaYQYQYaYYYQYaYaaYYYQYYIYQIYQAII8I80A0(8 ( (   (800I8AQAII088(( 0 (AAIQAII8I8080 ( (0 (A0AI8A80A0((   ( 0((( 8((A88IIAYIIYQQaQQaYYaQYaYYYQQaQYaYYaQYYQYYIQQIQI8IAAIA8A80A0(8((8 ( (   (8(8I8AIAIYIQQAII8A0 ( (A8AQAII8IA0A0 (0(880A0(8 (((0( A00IAAQA8QAAYQQaQQaYYiYYiaaiYYiYaiYYaYYaQYYQYaQYYYYYQYQIQQAII8IA8A80A0(8 ( ( (8(8A0AQ8IQAI A0A0 ( (80AIIQQ8IA8A8088(880A8080 (   ( 800QA8YQQaYYiYYqaaiaaqaaiaaiYaiaaiYYaYYYQY YQQYQYQIQIIIQAIIAIAAI88A80A0(8((8 ( (  (0 (80AI8IQAII8I8(8( (808I8IA0A80A8(8 (0( A00I88YIAaQQqaYqaayiiqiayiiiiiqiiqaiiaaiYaaYYaQYaYYaQYYQQYQYYQQYIYQIQIAII8IAAI80A8080(8 ( ( (A0AI8IIAII8A0 (  0 (80AI8IA0A80A8(80(8((8((QA8YQQiYYqiiyiiyqqqiiyiiqiiyiiqiiiaaqaaiYaaYYaQQYQQYQYYQQQIQQAIIAIAAI80A0(8 (   0(8A0AI8II8AA0A0(880AI8IAAIA0A8088(80(8(0( A00QAAaQQiaaqaaqiiyqqyqiyqqyiiqiiyiiqiiqaiqaaqaiiaaiYYaYYaQYYQYYQQ QQQIAII8I88A8(80(8 ( ( (0(8A0AI8IIIQ I8IAAIA0A80A8088(8   (  ( 0( A88YIAaYQqaaqiiyqqqqyqqqqyiiqiiqaiqaaiaaiYaiaaaYYaQYYQQQAII8IA08 ( (   (80AI8IIIQQAIIAIAAIA8AA0A 8(0    (8080((   0( I88YQQiYYqiiyqqqqyqyyqqyyqqyqqqiiqiaqaiiaaaYYaQYYQQYIQYQQYIQYQQQAIA8A0((   (0(880AAAIIAIQAIQIYYIYQIQIIQI8IAAIA0A8(0( (0((8080((  ((800IIAqaYqiayqqqqyyyyyyyqqqyqqyiiqiiqaiiaaiYaaYaaYYYYYYQYYQQIAIA8A0((((888AIAIIIQQIYYIYYIQQIQQAIIIQI8IAAIA8AA0A0(80 (0((808A0A0(( ( ((( 0((0( A88aYQqaaqqyqyyyyyyyyyyyyqqyqqyiiqaiiaaaYaaYYYQYYQQYQYQIQIAIA080(( 0(8I8IQIQQIYYQYQIQQIYQIQQAII8IAAIA0A8(80(800880A8(8 ( (  (8((0 (( ( 800QA8YIIqaYyiiqqyyyyyyyyyyyyyyyyyyyqqyqqyqiyiiqiiiaaiYaaYYaQYYQYaQYYQYYIQQIII8A8000( (  (80AI8IQIQYIYQIYYIYQIQQAII8IAAIA8A88A80A8(80(80080(8 ( 0( 8000(((A08808  (0( 0((0( A00QA8YQQiYYqaaqqyyyyyyyyyyyqqyqqyiiqiiiaaqaaiaaaYaaYYaQYYQYYIQQIIQIQQIIIAAA880(( (  0 (I8IIIQYIYQIQQAII8II8AA8A80A8080(8 (  800IAAA08(A88A0A ((800A88IIAaQQqaYyiiqqyqyyyyyyyyqqqyqqqiiiaaqaiiaiiYaaYaaYYYYYaYY YQYYQQQIIA888(((  (808I8IIIQQIQYIYQIQQIYIIQQAIIAI IIQI8IA8A80A0(8 ((I88QAII8A( A88I8I8(00( QA8aQQiaaqaayiiqqyyyyyyyqqyqqyiiqiiqaiiaaqiiqaiiaaiYaaYaiYaaYYaYaYYYaYYYQYYQQQIIIAAA88A088(0 ( (0(880AAAIIIQQIQYIQYIYQIYQIQ QAIIIQQAIIIQIAII8AA8A0(8 (  0( IAAYIQIAIA008((IAAQIIQAIA00YIAqiayqiqqyyyyyyyyyyyyyyqqyiiqiiqaiiaaqiiqaiaYaiYaaYaaYYYYYaYYYQYaQYYQQQIIIAAA88A000(( ( (((880AAAIIIQQIQYIQYIYQIYYIQYQYQIQQAIIIQAAIA8A8080(( ( 0 (A08YIQaQYYQQQAIYIQaQYiYaiYYyqiyyyyyyyyyyyyyyyqqqqyiiqiiqaiiaiqaiiaaaYaiaaiYaaYaaYYaYaaYYaQYYQYQQQQIQQIIIAAA08A888000(( (0( ((  (8(8I8IIAIYIYYQYYIYYQYQIYQIQIAIA8AA0A80A((8 ((  0((A08QAIaQYaYaiYaaYYaYaiaaqaayiiyqqyyyyyyyyqqqiiqaiqiiqaiiYaaYaaYYaYaaYYaYaaYYaYaaYYaYaaYYaQYaYYYQQQIQIIIIIAIAAI88 A880(( (0((0 (0( ( ( (808I8IIAIQIYYQYYIYYQYQIQQAIIAAA8A8080(( ( ( 0( 0 (8((0 (0((8((8(0A(0 ( ( ((0((8((A00I88QIIaQYaYaiaiqiqyiiyqqqqyyyyyyqqyyqqyqqqiiyqqqaiiaaaaaaYaaYYaYaiYaaYaaaaiaaaYYaYaiYaaYYaYaaYYaYaaYYYYYYQQYIQQIQIIAQAAIAIIAAA88IAAA088(0(((    (0(8AAIIIQYQaYQYYQaYQY YIYQIQIAII8AA88888((8  (( 0( 0((0 (0((0 (8((8(08((0((8(0A(08(0A(08(0A00800A00A08A00A(0A(8A00A(0I00A08I08808I00I08A08808A08A00A08A00A08(( ( 0( 0((8((8(00((0( (0( 0((8((A00QAAYIIYQQiYYqaayqqqiiyqqyyyyyyyyqqyyyqqyiiqiiyiiqaiiaaaYaaYYiYaaYaaYYiYaaYaaYYaYaaYYaYaaYYaYaaYYaQYYYYaQYYQQQQQYQQYQYYQQYIQQIQQIIIAIA88800 ( (((888AIIQYQaaQYaYaaQYYQYQIQIAIAAI888800 (    ( 0( 0((0( 0 (0((8((8(00((8((8(08((8(0A(0800A00A(0A00A08A00A08I08A08A00A08I08A08A00I00I08A00I00I08A08I00A00A08I08A08A00I00A00A08I00A08A00I08(((  ( 800A88 A000 (0( 0((A00QA8YQQaQQaYQqaYqiayqiyqyyyyyyqqqiiqaiiaaiYaaYYaYaiYaaYaaYYaYaiYaaYaiYaaYaiaaaYaiYaiaaaYaiYaaYaaYYYQYYQQYQYYQQYQYaQYYQQQIQQIIIAIA8A808(((0(   ((8A8AIIQYQYaYa aQYYQYYQQQIQIAIA880((   (   (0((800A00A08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A00I08A08I08A08I00I08I00I08A08I00A00A08I08A08A(8I00( 0( A88IIAYIIIIAYIIYIAIIAYQQaYQqaYyqiqqyqyyyyyqqqiqqiiqiqqaiiaiiYaaYaiaaiYaaYaaYYaYaaaaaYaiaaaYaaaaiaaaYYaYaaaaiYaaYaaYYqaYaYaaYYYQYYQQYQYYQQYIQYQQQQQYQQYIQYQQQQQQIQQIIIAAA880(((  ((8A8AIIQYQYaQYiYaaYa aYYYQYQIQIII88A800 (   ( (((88(8A08I08A08I08A08I08A08I08I88I08A08I08A08I08A08I08A08I08A08I08A08 I08A(8A08I08A08I08I00A00A(8A(0I08A00I00A00I08A00A08I08A08A00A08A00A(0A00A08A00 (0( 800A00QA8IIAaYQqaaqiiyiayqiyqqyqyyyyyyqqyqqqiiqaiiaiiaaaYaiaaaYaaaaiaaaaaaYYiYaiaaiYaaYaaaaiYaiaaaYaiaaiYaaYaaYYYQQQIQQQQYQQYQYYQQQIQYIQQQQYQQYIQYQQYIIYQQQIQQIIQIQYQQYIQ YQQQIQQIIA8A8080((8(0808A8AQIQYQYaQYaYaaQYYQQQQQIAAA080 (   ( 0 ( ( 0((880AA0AI08A08I08I88A08I08A08I08A08I88A08I08A08I08A08I08A08I08A08I00A00I08I00A00A08I08A08I08A08I08A08A00A08I08A08A00I08A08I00A00A08I08A08(8((A00YIAaYQqaaqiaqqy yyyyyyqqyqqqiiiiiyiiqiiqaiqiiiiiiaiiaaaYaaaiiaaaaaiaaiYaaYYaaaaYaiYaaYaaYYiaaaYaiaaaYaaYYYQQQIQQIIYQQYQYYQQQIQYIQQQQYQQYIQYQQQQQQIQQIIIAIIAAIIQQIQQQQYQYaYaaYYaYaYQYaQYYQQQIIQAIA08 ( ( ( ( ( (0(8A0AA8AA08I08A08I08A08I08A08I08A08I08I08A08A00A08I08A08A00A08A00A08I08A08A00I08A08I08A00I08A08A00I00A00A08A00800A00( ( 0( (( 8((0((8((A88QA8aQQqaYqqyyyyyyqqiaiqiiqaiqiiiaiiaaiYYaYaiaaaaaiaaiYaaYaiYaaaaaYaiYaaYaiaaaaaaYaaYYiYaaYaaYYYYYYQYYQQQQQQIQQIIYIQQIQYQQYIQQIQYIQQIQYQQQIQYIQYQQYIQYQQYQY YQQaQYYQYaYYYYYYQYYQQYIII880((  (  ( ( ( ( 0((8008A8AI08A08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A00A08I08A08I08I00A08A(0A08I08A08888AAIIIAQIIaYQaYYYYYQIIAAI0(( (0 (8((8(0A08A008008((8(0800 A00I88IIAYQQaYYqaYyiiyy yyyyqqqiqqiiiaaiYaaYaiYaiaaiaiqaiiaiiaaaYaYQYYYYaYYaYaaaaiaaaYaaYYaaaiaaaYaiaaaYaiaaaYaaYYaYaaYYaQYYQYYQQQQQQIIQIQIIIQIIYIQQIQQQQQIIQIQQIIYQQYIQQQQYQQYQYYQQYQYYQQIAI8880((    ( ( (  ( (((80(888AA8AI88A08I08A08I08A08I08A08I08A08I08A08A08I08A00A08A00A08I08A08A00A08I00A00I00A08A(8I08A00A08A00A08A00A08A00qqyyyyyyyqyiaiYYYAAI((80((8((A08I8AIAAQAAQ8AI8A Q8AYIIYQQaYYiaaqiiqqyòúòyyyqyyqqqaiiaiaYaiYaiaiiYaaYaYQYQIYQIQYQYaYaiaaaYaaYYiYaiaaaYaiaaaYaaYYaQYYQQQQQQIQYIQQIIIIIQIIQIQYIQQIQYQQaQYaQQYQQYQYaQQYQQYQYYQQYIQQIIIAAA08    ( (  (((880AA8AA0AI08A88A08I08A08I08A08I08A08I08A08I08A08I08I08I00A08I08A00A08I08A08I08A00I08I00I08A00A08I08A08I08A08I00A00A08A00I00I08A00I00A08A00A08yqiqaYaIII8080((800I88I8AQAAQ8AQAIQIIYQQqaYqiaqqyyòú˺úòyyyqyyqqqiqiaiiYaiaiqaqqaiaaiaQYaYaaQYYQYYQQQIQIIQIAIQIQaQYaYYiYaaYaaYYiYaiaaaaaaYaaaaaYYYYYaYYaQYYQYYQQQIQIIQIIIQIQQIIQIQQIIQIQYIQQIQYIQYQYYQQQQQQIQYQQYQYYQQaQYYQYaQYYQQYQYYQQYIQQIQYIQQIIIAA8000(( (      (((8008808A88A08I08A08I08A08I08A08I08A08I08A08A(8A08I08A00A08A00I08A08A00I00A00A08A00A(0A(8I00A00A08A00A08A00A08A00 yqyiaiYQYIAI800A00I8AQ8AI8AQAAQ8IQAAQAIQIIYQQaYYqaayiiyqòú˺úò yyyyqyyyyqyyqqqaqyqqqaqqiqiYaaaiiYaaYaaQYYQYYIYQIQQIYYIYQIQaQYaYYiYaaYYaYaiYaiaaiYaaYaaYYaYaYYYYQQQIQQIIQIQYIQQIIYQQYYYYQQQIQYQQYQYYQQaQYYQYaQYYQYYQQaQYYQYaQYYQYYQQYQYYQQQQQQIIIAAA88(((      (((8000008808A08I08A08I08A08I08A08I08A08I08I08A08I08A08A00A08A00A08I00I08A00A08A00A(0A00A08A00A08I08A08A00I08yyyyyqiqYYaQIQI88I08I8AQAI YIIYIQaQYiaaqiayqiòòúú˺úòyyyyyyqyyiyqaqiaqiYaaaiaYaYIYYQaaYaaaiaQYYQaYIYaQYYQaaQYYQYYIYYIQYQYaYaiaaaYaaYYYQYYQQQQQQIQIIIQIIIIQQIQYIQYQQQIQYQQYYYYQQQIQQQQYQQQQQYQQaQYaYYYQYYYYaYYYQQaQYaYYaQYYYYYQYaQYYQQaQQYQQYQYYQQQAAI8A0(( (     ((((0((000808A08A00I08A08I08A08A88A08I08A08A00A08I00A00A08A00A08A00A08I08A08A00A08A00I08A00A08A00I08A08A00A08I00A00A(0A08A00I00qqyyyyyyyyyyyqiqaYaQIQQ8AI8AQ8AQAI YIIYIQaQQaYYqaayqiyqòúòòúú˺úòòyyiyqqyqaqiYqaaiaYaYQaQIYQAaQIYYQaaYaYIYaQYYQYYIQQIQaQYiYYiaaiYaaYYaYaaYYaYaiYaaYaYQYYQQYQYYIQQIQIIQYQQQQQQIQYIQQIQQIYaQYaYYYQYQQQQIIIAIQAIQIQYQQYIQYQQQQQYQQYQYYQQaYYYQYYYYaYYYQYYYYaYYYQYYQQaQYaQQYQQaYYYQQYQYaQYYQQYIQQIIQAA8000 (      (((80((808A08I08A08I08A08A08I08A08I08A08I08A08A00A08A(8A08A00A08I08A00A(0A00A08iaiiiiqiiqqiyqqyqyyyyyyqyqiqiYaYQYQAAI8AQ8AQAAIAAQAI YIIaQYiYYqiiyqòú˺˺úòòyqqaqiYqYQaaAqQAaQ8YA8iQAaYIYYQaaQYYQaYQYQQQYQYaYYaaaaYYYQYaYYiYYaYYYYYYQYYQQYQYYQQQIQYQQQQQQIQYQQaQYaYaaYYYQYQQQQIQYIQQIQaYYYQYaYQYQYYQQaYYaQYYQYYQQYIQQIQQIIA8A800 (     (((8000808A08I08A08I88I08A08I08A08I08I08A08A00A08I08A00A08I08A08A00I08A08A00A08A00A08A00808A08A00A(0A08A00I00A00A08A00aYYaaaiaaqiiqqiyqqqqyyyyqyqiiaYaYIQI8AQ8AQAIQ8AI8AIAA QAIYIIYIQaYYiaaqqòú˺úúòúòqqaqiYqYQaQAaA8i0 AA8iQAaYIYaYaaaiaYaaQYaYaiYaaYaiYaaYaaYYYYYYQQYIQaYYYQYaQYYQYQIQYIQYQQYIQQIQYIQaQQaYYYYYYQYaYYYYYYQYYIQQIQYQQQIQYQYYYYaYYYQQYQYaYYiaaaYYYQQQQQQIQQAII8A800((( (  (((0((808A08I08A08I08A08I08A08I08A08I08A08A08A00A08I08A08I08A08I08A08A00A08I08A(8A08A00A08A(8A(0A08A00A08A(0A08A(0A(8YQQYYYiaaiiiqiiyqqyqyyyyyyqqqiiaQYIAII8AQ8AQAAQ8AQAAI8A IAAQAIQIIYIIYQQqaYqiayqú˺úú˺òú˺òòyiqYiYqYQaA8i0 AA8iQ8YQAaaYaaaiiYqiaiaaiiaiiYaaYaiYaiaiaYaaQYYQYYYYaYYYYYYQQQQQQIYYQYYQQYQYYQQYIQYQQYQYaQYYQYYYYYQYYYYYQYYIYYQQYQYYQQQIQaYYaQYYQYYQQaYYaYaaYYYQQYQYYQQQQQQIQQIIQIQQQQQIQIAIA880(( (     (((80((808A08I08A08I08A08I08A08I08A08I08A08A08I08A08I08I00A08A00I08A00A08A00A08A00A08I08A00A08A(0800A00I00A00A08A00I00QQQaYYaaaiaaqiiqqqyqqyyyyyyyyyiiiaiYQQQAIQ8AI8AQ8AQAAQAIYIIYQQaYYqaaqqòú˺ú˺ú˺òò˺òyyiqaiYqaAqQAaA8iYQaiYqqaqqiqiaqiYqaaiaQYaYaiaiqaiaYaaYYaYaYQQYIQYQQYQYQIQYIQYQYaQYaYYYQYQIQYQYYQQYIQYQYYQQYIYQIQYQQYIQQIQYQQYQYaYYaaaiYYYQYYQQQQQYQQYIQQIQQQQQIQQIIQIQQIIQAAA888000(( (   (((8000808A08I08A08I08A08I08A08I08A08I08I00A08I08A08I08A08I08A08A(8A08I00A(0A00A08A00I08A08A00A(8YQYaaaiiiqiqqqqyqyyqqyyyyyyyyyqqqaiaYaQAII8AQ8AQAAQAIQIQYQQaYYiaayqqyyò˺úúú˺úòúòòqyiqaiYqqYqaqYQAaA8iQAaiYqqaqyiyqiqqaqaYaaQYaaiiaiaYaaYYaYaaYYYQYaYYYYYYQYYQQYQYaQYaYaYYYYQYYIQYQYaQYaYYYYYYQYYQQYQYYQQQQQYIQaYYaaaYYYYQYYQQQIQQIIYIQYQYYIIQIIIAIQAIQIIQIQQIIIAIA8A8000(( (  (((80((A00A08808A08I08A08I08A08I08A08I88I8AI08A08A00A08I08A08A00A08A00A08A(8A(0A08A00A(8A(0A00A08A00A08A00A08I00YYYYYaaaaiiiqiiqiqqqqyqyyyyyyqiqiYaYQYQAII8AQ8AI8AIAI QAIYIQYQQaYYiYYyiiyyò˺ú˺úòúòúòòòqyiqayiqaYQaA8iQAaiYqqaqiaiaYaaaiqaiaaaaYaaYYaQYYQYaYYYQYYQQQIQYQYYYYaYYYQYQQQYIQQIQYQYYQQYIQQIQYQYYYYaYYYQQQIQYQQaYYYQQQIIQAIQIIIIIIAAIAIQIIQIQQIIIAAA880((((8 ((((((80((800808A08I08A08I08I88A88A08I08I00I08A00A08I00A08I08A08I08A08I08A08I08A08I00A08A00A08A00A08A(0A00A08YYaaaaiiiqiiqqqyqqyyyyyyyqyqiqqiiaYaYIQQAAQ8AQ8IQ8AI8AQ8AQAIYIQYQQiYYyiiyqò˺ú˺úòúòòúòyqyiqaiYqA8iYQaiaqqqyyiyqaqiYaaaiiaiqiqyqqqaiiaiaYaYYYYQYYQQQIQYIQYQQYQYaQYaYYYQYYQQQQQQIQQQQYQYQQQYQYYIYaYYYQYYQQQQQ aQYYQYYQQQQQQIQIIQIIIIAIA8AAAIIAAQAIQIIIIIQIIIAAA880000((((( ((((((8808A88A08I08A08I08A08I88I8AQ88I88A08A08A00I00I08A08A00I08A00A08800I00A00A08A00A08I00A00A(0I08A00A08aaaaaiiaiqiiiiiqiiiiiqiqyqqyqyyyqqyqqqaiaQYQIQQAIQIIYIQQIQQAIQAA QAIQAAQAIYIQaQQqaaqqò˺úú˺ú˺úòúò òyqyiqaiYqaAqiYqyiqyqqqyyiyqiqqaqiaiiYaaYaYYaaQYaYaaQYaYYaYaaYYYQYYQQQIQYIQQIQYQYaQYaYYaYaaYYYQQYQYaQYaYYYQQYIQQIQQIIIAIIAAA8AAAIIAAIAIQIIQAII8A8080000((((( (((8000808A08A88I08A08I8AI08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08I00A00A08I08A00A08A00A08800I00I08A(8A00A08aYaaaaaaiiaaiaiqaiqiiyqqqiiqaiiYaYQYQIQI8AQAAYIIaQQYQQYIQaQQaYYyiiyòú˺ú˺úòòúòyqyiqyiqaiYqiaqyiyyqyqyqyqyyiyqiqiaiqaiqaqqaiyqqiiiiaaYYYYQYYQQQIQQIIYIQQQQQIQYQQYQYaYYaYaaaaaYaaQYaYYaYYaQYYQYYQQYIQQIQQIIIAAIAIIAAAAIA88A8AIAAIAIQIIIAAA88A088080(((((((8000A08808A08A88I8AA88I08A08I08A08A00A08A00A08A00A08A00A08I00A08A00I08A08A00808A00A08A00A08aQYaYYaYaaYYaYaaYYiYaiaaiYaqaaiYYaQYYIQIAII8AIAAQ8A QAAYIIaQQaYYaQYaYYqaYyqòú˺úú˺˺˺ú˺ú˺úòúò yqyqyiqayiyiyqyyqqqyiaqqaqyiyyqqqaqiaiqiiiaiaYaYIYYIQQIQYIIYIQYQYaYYiYaiaaqaiiaiiiiiaaaYaaaaYYYaYYYQYQQQQIQaYaYYYYQYYQQYYYYQYYQQQIQQQQQIIIAIIAAA8AI8AIAAIIIQIQYIIQAIIAIA8AA88800000(((((80((000A8AI8AI88I08A08A88I08A08I08A08I08A08A08I08A08I08A08I08A08A00A08A00I08A08I08A08A00800A00A08808A00A08A00A08A(0A08A00aQYYQQaQQYQQaQQYIQaQQaYYaQYaQQYQQYIIQAIQ8AI8AQ8AQAA QAIQIIYIQYQQaQYqaYqiayòú˺ú˺ú˺úòyqyiqyiyqyiiYqqaqyiyqaqqiqiaiiYaaYaiYaaYaiYaaYaYQYaYYaaaiaaaaaaYYYYYYQQYQYQQQYQQQQQYQQQQQYQQYIQQIQYQYYQYaQYYQQQIIIIIIAIIIIIAIIIIQIQQIIIAIIAAA88808000888A8AA08I08A08I08A08A08A00A08I08A08I08I00A00A08A00A08A00800A00A08A00A08A00A(0YIIYIQQIQQIIYIIQIIYIIQAAYIIQAIYIIQAAI8AQ8AIAAI8AQ8AQAIQAAYIIYQQaYYqaayqi˺ú˺ú˺úyqyiyiqqaqyqyqyiyyqqqiqyiyqiqiaiqiqqiiiaaaYaYQYYIYQIQYIYQIQYIQQIQQIIQAIQIQYIQYQYYQQaQYYQYYYYYQYYYYaYYaQYYQQQIQQIIQQQYQYQIQQIIQAAIAIAAIIAIIIIQAIQIIQAIIAAA88888808008000808A08A8AI08A08I08I88I08A08I08A08I08A08I88I08A08I08A08I08A00A08808A00A08I08I00A00A(0I08A08A00I08A08A00A08I08I00A(0A08A00Q8AQAAI8AQAAQ8AI8AQ8AI8AQ8AI8AQ8AI8AQ8AI8AQ8AQAAQAIQIIYIIaYQqiiyú˺ú˺ò˺úòyqyqyiqyyyqyiyyqyyqqqaqqiqqqqqiqiiiiaiiaaqaaiaaiYaaYaiYaaYYiYYqaYaYYiYYaYYaYaaaaYQYaYYaYaaYYYYYYQYaYYaQYYQYQQQQIQIAIA8AA8888AA8AIAIQIIQIQQQQQIII8A808000008808A8AA08I08A08I08A08I08A08I08A08I08A08I00A08A00A08A00A08A00A08A00A08A00A08A00I8AI88I8AIAAI8AI88I8AIAAQAAQ8AQAIYIIaQQ˺ú˺òòòòòyqqqqyaYaqqyyqqyiyqqyyqyyyqiqiaiaYaYYaQIQQAIQIQYQYYYYYQYaYYYYYYQQQQQQIQYIQYQQYQYaYaaYYaQYaYYaYaYYYaYYYQYYQQQIQQAIIAIA8AA08A8AI8IIAIQIIQAIIAIQAIIIIQIQIAAA8880800088888AA8AA88I8AA08I88I08A08I08A08I08A08A08I08A08I08A08I08A08I08A08I08A00A08A(0A08A(0A08I08A08A00800A08A(0A00A08A00A08A00A(0A08I08A08I8AIAAI8AQ8AI8AQ8AI8AQ8AQAIYIIaYYúú˺˺òòòyyqyyqqqaqyqyyqyqyqiqiaiaYaYQYQIQQAIQIQQQQYQYYQQYIQQIQYIQQIQYIQYQQQIQQIIIIIQIIQIQQIIYQQQQQYQYaYYaYaaYYYQYYIQQIQYQQYQYYQQQQQQIQQIIQAIIIIQIQQIIIAAA8AA88888A88A8AA88A08I08A08I08A08I88A08I08A08I08A08I08A08I08A08A00A08A00A08A00A08A00A08A00I00A00A08A00800A00808A08A00A08A(0A00I8AQ8AI8AQ8AI8AQ8AI8AQ8AQAAQ8AI8AQ8AQAIYQQ˺˺ú˺úúúòòòòòyqyyyyyyyqqqaiiaiqiqyqqqiiqaiiYaaYaaQYYQYYIQQIQYIQQQQYQQQIQQIIIAIIIQQIQYQQaYaiYaaYaiYaaYaiaaaaaaYYaQQQQQ QIIIAIAAIIAIIIIIAAA8AIAAIAIAAIIIIIAIAAIA8A88A888A8AI88A08A88I08I88A08I08A08A08A00A08I00A00A08A(0A08A00A08A00A08A(8A08I08A088(0A(0A08A00A08A(8QAAI8AI88Q8AIAAI8AQ8AI8AIAAI8AQ8AI8AQ8AIAAQAAQAIYII˺òòòòòò yyyiyiYq qqyyqyyqyyyyyqqqiqiaiiaaiiiqqiyqqyqyqqqaiiYaaQYYQYYIQQAIIAIQIQqiiqiaiaaaYYYYYQQQIIQIIIIIAIAAAAIIAAA88A8AA88888AAIIAIAAIA8A80888AA8AI8AI88A08A88A08I08A08I08A08I08A00A08A88A08A00A08I08I00A08A00I08A00A08A00A(0A00A08I8AQ8AI8AQ8AI8AQ8AI8AQAAQAIYII ˺úòò˺úòòòòqyqaqiaqyyyyqaiYQYYIYYQYaYaiiiyqqyqyyyyyyqqyiiqiiqaiqaaiaaiaiqaaiaaaYYYYYaYYYQYQQQIAAA8AA88A8AI8AA8AA88A8AAAIA8AA88888A8AI8AAAIIAAI8AA8AI8AI88I8AI08I88A08I88A08A00A08I08A08I08I08A08I08A08I08A08A00I08A08I08A00A08A00A08A00I00A08A00A08A00A08A00A08808A00A08I8AI88I8AA8AI8AQ8AI8AQ8AQAAYIIQAIYIIúòò˺úòòò úòòúòqqqqyyyqqiaiiaaaYaaYYYQYYYYYYaaYYaYaYYYYYaaaaiaiiiiqiiyqiqiiaYaiaaaYYYQYQQQQIIIAAAAIA8AA88A8A808A8A888A8AIAAI8AA8AA88A8AAAIIAIIAAI8AA8AA88I88I8AA88A08A88I88A08I08A08I88A08A08A00I08A08A00I00A00I08A00A08A00A08A00A08A00A08A00A08A00A08A00A(0A08I8AI88Q8AI8AIAAI88I8AIAAI8AQ8AI8AQAAQAIYIIú˺òòúò˺úò˺òyyqyyiyyyyyyyyiaiaYaiaaaYaiaaaaaaYaYYYYQYQQQYIQQIQQQQQIQYQYYQQYYYYQQQQQYQQYQYYQQQQQQIIQAIIAIAAI88AA8AAAIIAIAAIA8AIAAA8AAAIIAIIAAIAII8AI0AI08I0AA08I08A08I08I08A08I08A08A(8I08A00I08A08I08A08A00A08808A08A00A08I08I00A00A08808A00I00A00A08I8AI88I8AI88Q8AI8AQAAQ8AIAAI8AQ8AQAAQAIYIIúú˺òòú˺òòò˺˺˺òqyyyyyiyyqyyyyqyyyyqyqiqqiiiiiqiiqaiiaaaYaYYYaYYaYaaYYYQYYQQQIQIIIQIQ aaaaYaYYYYQYYQQQIQIIIIAIAAI88A888A88A8A888AAI88AIAAIAIAAIIAIIAAAAIIAIAAIIAIIIIIAIIIIIAII8AI08A08A88I88I08A08I08A08I08A08I08A08A00A08I08A08A00A08A00A(0A(88(8A08A00A08A00A08A00A08A(8A08A00A08A00I00I8AI88I8AI88I8AQ8AI8AQ8AI8AIAAI8AQAAQAIQAAQAIQIIYIIYQQ˺òò˺ò˺˺òy yqyyyyyqyqiqyqqqiqqaiiaiiaaaaaaYaYYYYQYYQQQIQQQQQIQQQQQIQaYaaYYYQYQIIIIIAAIA8AI8AAAIA8AIAAIAIAAIIAIAAIIAIIAAIAIQIQIAIIAAI8AA88I0AI08A08A88A08I08A08I08A08I08A08I08A08I08A08A00A08A(8A(0A08I08A08A(8A08A00A08A00808A08I8AA8AI8AQ8AI8AQAAI8AQ8AI8AQ8AQAAQAIQIQYIQaQQaYY˺òò˺˺úòyyyyyyqyqiqyqqqqqqiiqiqiiiaaaaYaYYYYQYYYYYQYQQQYQQYQYQIQaYaaYYYYaYYYYQQIIQIAIAAIIAIIIIQIIIIQIIIIAIQAIIIIIIQQIQQIIIAIQAAI8AI08A08I88A08I08A08I08A08A08I08A00A08808A08A00808A00A08A00808A08I00A00A08I08A08A00A08A00A08A00I8AQ8AI8AQ8AI88I8AQAAIAAQAAQAIYIQaQQaYYiaa˺úòò˺ú˺òyqyyyyyyyyqqqiiiaiiaaaYaYQYQIYYQYaYYYQYYQQQIQYQQYYYYQYYYYYQYQQQQIQIAIAAIIAAIAIAAIIAIIIIQIIIIIQIQYQQQIQIIIQIQIIQQIQQIIQ8AI8AA88I0AI08I88A08I08A08I08A08I08I08A08I08A08I08A08A00A08A(0A08A00A08I08A00A08A00A(0A08A00A08A00I8AI88I8AA8AI8AQAAYIIYQQiaa˺ò˺ú˺˺òyyqqyyyqyyyyyyyyqyqiqyqqqiqqaiiaiaYaYQYaYYYQYYQQQIQQQQYIQiaiiaaaaaaYaYYYQQQIIIIAAIAIA8AAAIIAAAAIIAIIIIQIQQIIIIIIAIIIIQIQQIIIAAI8AA08I88I08A08I08A08I08A08A00A08I08A08A00A08I08A00A08A00A08A008008(0A(0I08A08A00A08A00800A00A08A00A08I88I8AI88I8AA8AI8AQ8AQAAIAAQAAQAIQAAQIIYIQYQQqia˺òò˺ò˺˺˺˺òò yyyyqiqyqqyyyqyyyyyyyqqqiqiaiiaaiYaaYaaYYaYaYYaYQYQQQYQQQQQaaaaYaaYYQQQQIQIIIIAIAAIA8AAAIA8AIAAIAIIIIQIQIIQIIIIAIQIIIIQQIQYQQYIQQIIQAIIAAI8AI08I88I08A08I08A08A08I08A08I08A00A08I08A08808I08A08A00I00A08A00A08I08A00A08I08A08A00A08I08A08A00I08A00A08A00A08A00I8AI88I8AI88I8AIAAQAIQAAQAIQIIYIQaIQaQQqia˺òòòú˺˺˺òúyyqiqyqqyyyyyyyyyyyqyyyyqqqiqyqqqiqiaiaaaiaaqiiiaaYQYaYYYQYQIQQQQYQQaYYaQYYQYYQQQIQIIIIAAA8AAAIIAIIIIIIQIAIIIIIIQQIQQIIQAIIAII8AA8AA88I88I08A08I08A08A08I08A08A00A08I08A08A00A08A00A(0A00A08A00800A00A08A00I08A00800A00I00I8AI88Q8AI8AI88I8AQAAIAAQAAQAIYIIYQQaQQaYYqaaúòúò˺˺úòyyyqyyyyyyyyyqiqyyyyyqiqiaiqiiYQYaYYYQQQIQIIIIIQQIQaYaaaaYYaYQYQIQQIIIIIIAAIAIAAIA8AAAIIAIIIQQIQIIIIAIIIQYQQQIQQAII8AI88A08A88I08A08I08A08I08A08I08A08A00A08A00A08A(0A08A00A08A00A08I08A08A(8A00A08A00A08A00I00A00A08A00A08I8AI88I8AA88I88I8AA8AI8AQ8AQAAIAIQAIQIIYIQYQYaYYqqiúòòúò˺˺òqyqyyyyqyyyyyyyyyqyyqq yyyqyyyyyyyyyyqyqqyqqqiqiaiiYaaYYYIQQIQYQYQIQQIIQIQQQQIIQiiiiaiaaaYYYQQQQIQIAIAAIA8AAAIIAIIIIIIQQQQYQQQIQIAIQAII8AA8AI88A88I88I08A08I08A08I08A08A00A08I08A00A08A00A08A00A08A00A08A00A08A00A08A00800A00A08A00I00A08A(0I8AI88I8AI88I8AA8AI8AQAIQAAQAIYIQaYYiYayqqúò˺˺˺ò yyyyyyiyqaiiaiiaa iiiqiqyqqyyyyqqyyiaaaYaiYaaQYQIQYQQQIQqiqqiiiaiiaaaYaYQYYQQQIQIAIAAIIAIAAIIAIQIQIIQIIIIAIIIQYQYYQQQIQQIIIAAI8AA88A08I08I0AA08I08A08A(8I08A08I08A08I08A00A08A00A08A00I08800A08A00A08A(8A(0A00A08A(8A00A08A00I8AI88Q8AI8AA88I8AQ8AIAAQAIYIIYIQaIQYQQaYYiaaqaayqiòúú˺˺˺úòyyyyqqiaiiaaaYaYQYaYYiaiiaaiaiiiiiaiiaaaYaaQYYQYQIQQQQQIQiaiiaaaYaaYYQQQIIQIAIIIIIAIIIQQIQIIQQIQIIQQQQQIQIIQIIIQIIQIQYQYYIQQIIIAAI8AI0AA08I08A08I08A08A08A00A08A00I08A08I00A00A08A(0A08A00A08A00A08A00A(0A00A08A00A08A00I8AQ8AI8AI88I8AQ8AI8AI0AI8AQAIYIQQIQQIIYIIQIIYIQYIIYIQYQYaYYqia˺ò˺˺˺ ˺˺úòyyyyqqqiqyqqqiqiaiaYaiaiiaaaYaaYYaaaiaaaYaiaiaYaaQYYQYYQQYYYYQYQQQQIQIIQQIQQQQYQYQIQQQQYQYYYYYQYYQQQIIIAAI8AI88I0AA08A08A00A08A00I00A00A08I08A08I08A08A(8I08A08I08A08A00A08A00A08A00I00A(0A08A00A(0A00A08A(0I00I8AI88A88I8AI88I8AI88I8AQ88I88I8AQAAQ8AI8AQ8AQAAQAIYIIYQQiaa˺˺ú˺Ӻò˺úyyqyyyyyyqiqiaiqiqqqqqiqqiiiaiiaaiaiaYaYYYYQQQIQQQQYQYaaaiaiqqqiiiiaiaYaYQYQQQQIQIIQIIIIAIQIQQQQYQYQQQYQYQQQQIQYQYA08A00A08A00800A00800A00A08A00A08A00A08A00A08A00800A00A(0800A00A08A00I8AQAAI8AQ8AI8AA8AAAII8AI88I8AI88Q88Q8AI8AQAAQ8AYIIaQQqiaúò˺òúòyiyiaiiiqqqyyyyyyyyqiqYIYYQaiiiqiqqqyqyqyyyyqyqiqiaiiaaiiiiaiaaiaaaiaiiaaaYYYQQQIQYQYQIQQQQYQYiaiiaaaYaYYYQQQIIQIIIIIQA08I08A08A00A08A00A08A00A08A00I08I00A08A00A(8A00I08A08I08A00A08A00A(0A00A(0I8AI88I8AI88I8AI88I8AI88I8AI88I8AIAAQAAIAII8AQAAYQQqia˺ò˺˺òò yyqyiaiYIYYQaaYaYYaIIY0(8IAIQAI80A0(8Q8YYQaqqyqyyyyyyqyyqqiaiaQYYQYaQYaYaaaaiaaaaaiaaaYYYQYYYYYQYYQQaaiiaiiaaaaaaYaaYYYYYYQYA08A00A08A00A08A88A08A00A08A00A08A(8800A00A08A00I00A00A08A00I00A08A00A08A(0A00A(0A00A(0A00I08A00A(0I8AI88I8AI88I8AIAAI8AQ8AI8AQ8AI8AQ8AQAIYIIqaYúòú˺qY˺˺òòyyyqYYaIIQ88A80A 0008I8I0 A 080AYYaiiqyqyyyqyqiqyyyyqyqaiiYaaYaYQYYYYYQYYYYaaaaYYYYYYQYaQYYQYaaiiaiiaaaaaaYYaaaA08A00A08I08A08A00A08A00I00A08A00A(0A00A08A00A08A00A(0A08A(0A08A00I8AI88I8AI88I8AI88I8AIAAQAAI8AIAAQAIQAAQAIQIIYQQqaY˺úò˺Q8Y˺ú yyiai0 A 0 ( (88A80AQ8YIIYaaiqaqyqyyyyqqiaiqiiyqqqiiqiqqaiiaaaYaiaiiYaaQYYQYaYYYQYYIQQIQYQYYYYA08I08A08A00A08A00A08A00800I00A00A08800A00A08800A00800A08A00800A00800A08A00I88I8AI88I8AQ8AI88I8AA8AI8AA8AI8AIAAQ8AQAIQIIQIQYIQYQQaQYiYaiaaqii˺˺ ú˺A8i˺˺yyqyiYa80A 0 (008QIYQAaYQaiaiyqqiaiqiqyyqiqqiiqiqqqqqiiiaiYYYYQYYQQYQYYQQYIQA08I08A08I00A08A00A08I08A08I08A00A08A00A08I08A00A08I08800A00A08A00A08A00A08I8AA8AI8AI88I8AI88I08I88I8AQ8AI8AIAAQAAQAIQAAQAIYIIYIQaQYiYaqii˺ú˺A8i˺òiaqaQYQ8YIIQ 088AaaiiaqqiqyyyyyyqqyyyqqyiiiaiiaaaYaaYYYQYYYYYQYA08808800A00A08A00A08I08A00A08A00A(0A08A00A08A00A08A00800A(0A00A08A(0A00I8AQ8AI8AI0AI8AQ8AI8AA8AI8AIAAI8AIAAI8AQAAQAIQAAQAIQIIYQQaQQqaa˺ú˺qY˺úqaaiQIYQ8YI8I 0I8I ( 0YQaqaqyyyyyyqyyqqyyyqqqiiqiqyqqqiiaYaYYYYQYQIQYIQYQYQQQYQYA08I08A08I08A08A00A08A00A08A(0A00A08A00A08A00A08A00A08A00A08A(8I08A08A00A08A00A08A00A08A(8A08I88I8AI88I8AQ8AI8AQ8AQAAQAIYIIQAIQIIYIIYQQaQQqia úòúӺ˺òòyqaqYIYAAI0(8YQaqai (((8QIYiaiyqqyyyyyyqqqiqyqyyyyqqqiqqqqqiqiaiiaaaYaYQYQIQYQYA08I08A08A00A08808A08I08A08A00A08A00A(0A00A08800A08A00A08A00A(0I8AI88Q8AI8AI88I8AQAAQ8AI8AI88Q8AI8AQ8AQAAQAIYIIYIQaQQiaaú˺úúòyyqyiYa80A0 AYQaI8I0(8YQaiaiyqqyyyyyyyqqqqyyqqqiq yqqqqqqiiaYaaYYaQYYYYYQYYYYYQYYYaYQYA08I08A08A00A08I00A00A08A00A08A00A08A00A08A00A08A00A08A(0A00A088(8A00A(0I88A88I8AI88I8AI88I8AI88I8AQ8AI88QAAQAIYIIQIQYIQaQQ˺òòqiqQ8Y((8A0AI8I0 AI8IQIYaYaaaiqiqyqyyyqyyqqyyyqqqaiiiiqiiqiqiaiYYYYIYYQYYYYaYaYYYYYaaYaA08I08A08A00A(0A00A08A00I00A00808A00A08808A00A08A00A08A(0A08A(0800A00A(0A08Q8AI88I8AI88I8AI88I8AI88I8AI88I8AQ8AI8AQ8AI8AIAAQAIYIIò˺˺òyiyaQY0 AIIQQ8I80A0 A0(8 00 AI8IYQaiaqqiqqaqqiqyqyyyyyqyyqqiaaaYaiaiaQYYQYaYaA08A00A08A00A(8A08A00A08I08A08A(0I00A00A08808A00A08A(0I08A08A00A08A00A08A00I08A08A00A08A00808A08I8AI08A08A88I8AI88I8AI88A88I8AI88I8AI88I8AQ8AI8AQAAQIIòúòyiyiYaQ8Y0 AA0AQAII8IA0A0 AI8IYIYiYayqyyyyyqyyyyyyyyqyyqqqiqiaiaYaaaaaYaYYaaYaaaiA08I08A00A08A00A08A00800808A08808800A00A08800A(0A00A(0A00800A00A08A00A08A00A(0A08800A00I00A00I88I8AA8AI8AI88I8AA8AI8AI88I8AI88I8AI88I8AI88I8AQ8AI8AIAAQAIYQQ˺˺ ˺òqqaqaYaI8I0 A A0AQ8YaaiqiqyqqqqyyqyyyyyqyqiiqaiiaiaYaYYaaYaI08A08I08A08I08A08I08A08A00A08A00A08808A(0A08808A08A00A08A00A08A00A(0A00A(8I08I8AI88I8AI88I8AI88I8AI88A88I8AA8AI8AI88I8AIAAQAAQAIYIQaQYú˺˺˺yqqaqiYqYQaQAaYIYiaiiaqqqyyqyyyyqyyyyyyyyyqiqiaiYYaaaaaYaiaiaaiiaiiaqA00I08A08A00A08A00A08A00A08A00A08A00A08A00A08A00A(0A00A(0A00A(0A008(0A(0A00I8AI88A8AA08I08I8AA8AI8AQ8AQ88I88I8AQAAI8AIAAQAIYIIYIQYQQaQY˺ ˺úòyqyqyiyyyyyyyyyyyyyqiiiYaaYaiaiaYaiiiiaiiaaiaiaaiiaiqiqiaiiaqA08A00A08A00A08A00A08808A00A08A00A(0A08A00I00A00A08A00I00A08A00A08I08A00A08A(0A08A(0A00A88I88I8AA88I8AA8AI88I8AIAAI8AIAAIAII8IQAIYIIYIQYQQaQYò˺ úyyyyyyqyyyyyyyyqqqaiaYaYYaYQYaaaaYaYYaiaiqaqqiqA00A08A00A08I00A00A08A(88(0808A08A00808A(0A00A(0A00A08A00A(08(0A00Q8AI8AI88I8AA8AI88I8AI88I8AQ8AI88I8AQAAQAIQAAYIIQAIQIIYIIYIQò˺ òyyyyyyyyyqqqaiaaiaYaYYaaaiiiqqiqqqyyqyyqA08I08A08I08A08A00I08A00A08A00A08A00A08A(8A(0A00A08A00800A(0A00A08A00A08I08A00A(0A00A(0A00I00A(0A00A08A00A08800A00I88I8AI88I8AI88I8AI88I8AI88I8AI88I8AIAAQAAQAIYII˺ ˺úyyyqyyyyyqyyqqyyyqyyyyqqqiqiaqiaiaaiiiqqiqqqyyqyyA08A00A08808A08A00A08A00A08A(0A08A00A08808800A00A08A00A08A(0A00A08A(0A00A08A00A(08(0A00I88Q88I88I8AI88I8AQ8AI8AQ8AQAIò˺ yyyyyqyyyyqyqiqyqqyqyyqqqiqqaiiaiaaiiaiiaqqiqqqyyqyyI8AI88A88A08I08A08A00A08I08A08I08A08I08A(0A08A00A08A00A08A00A08A00A08A(8A(0A08A00A08A00I00A(0A08A(0A00A08I8AI88I8AI88I8AA88I88I8AI88I8AI88I8AI88I8AQ8AQAA˺˺úyyyqyyyqiqyqqyqyqiqiiqqiqiaqaaiiaqiiqqqyyqyqqyyqyiiqiiiqiiqiqiiiaYYYIIQAIQAAI8AI88I8AI88A88A08I08A00A08I08A00A08A00I08I00A00A08A00A08A00I08A00A(0A00A(0A00A08A00A08A00A08A00A(0A00A(8800A00A(0A00A(0800A(0I8AI88I8AI88I8AQ88I88I8AI08I8AQ8AI8AIAIQAI˺úò yyyqyqiqqqqyqyyyqqiqiaiaaiiaiiYaaaiiiqqqyiiqqiqqiqqqqqiqiaiaYYaQYQAIQ8AI8AI08A08A08A00A08I00I08A08I08A08A00A(0A08A(0A08A(0I00A08A00A08A00A08A00A(8A08A(0A(8A(0A00A(0A(8A00A(0I08A(0A00I8AI88I8AI88I8AA8AI88I08I8AI88I8AI88I8AA88I8AQAAòúyyyqaqiaiqiqyqyyqqyqyqaiiaiiaqaaiYQaYYaaaiiaqaaiiiqqqyiiqiiqqiqqqyqiqqiiiaiaYYYIQQAIQAAI8AI88I08A08A00A08A00A08808A00A08A00A08A00A08I00A00A08A00A(0A00800A00808800A00A08A00800A00A(0I8AI88I8AI08I88I8AI88I8AQ88A88I8AI88I8AI88I8AQ8AQAIò˺ yyqaqiaiyqqqiqqaqaaiiaiaYaQIYYQaiiqiaqiiqqqyyqyyyyyyqyqqyqqqqiqiiiiaaaQYYIQQAAI8AA8AA08I08A08A08I08A08800A08A00A08A00A08A(0A08A00A08A00A08A00A08A00A08A00A(0I00I8AI88I8AI88I8AI88I8AA88I88I8AI88I8AI88I8AQ8AQAIò˺úòúyyyyiaiaaiqiqiiqqiqyqyqqyaaiiaqaaiiaqqqyiiqqqyyyyyqyqqyqqqqqyqqqqiqiaiiYaaQYYIQQAII8AI88A08I08A08A08A00A08A00A08A00A08A00A08A00A08A00A(08(0800A00A(0A00800A00800A(0A00A(08(0A00I8AI88I8AI88I8AI0AI88I8AI0AI8AI88I8AQ8AQAA˺˺úú yyqqqyqyyiyiaqaaiQIYaaiiaqiiqqqyyqyyyyyyyyyyyyyyyqyyqyqyyyyyqyqqyqiqiaiaYaYIQQAIIAAI8AI88A08I88I08A88A08A00A08A00A08I08A08I00A00I00A08A00A08A00808A08A00I08A(0A00A(08(0A00A08800A08A(8800A00I88A88I8AI88I8AI88A8AA88I88I8AA8AQ8AI88A8AA88A0AA8AI8AI88I8AI88Q8AI8AQAAúúqqiqyqqqqyiaqqiqiaqaaiYQaiYqaaiiiqqqyyqyyyyyyyyyyyyyqyqiqiaiaYYYIIQAAQ8AI88I08A08A88I88A08A08I08A08A00I00A08A00I00A00A08A(0A00A08A(0A08A00A08A00800A00A08A008(0A(0A00800A00I8AI08I0AI8AI88I8AI08A88I8AI88I8AQAAIAAQAA˺ú yyqyqiqiaq aaiiYqiaqiiqiaqaYaYQaiYqiaqiiqqqyyyyyyyyyyyyyyyqyqiqiaaaYYYIQQAII8AI08A08I08A08I08A08A08I08A08A00A08A00A08A00A08A(8I08A08A00I08A(0A00A08A(0A08A00A08A(0A00I00A(0A00A(8A(0A(8A(0A00I00A00A(0I88I8AI88I8AA08A88I8AA88I88I8AI08I8AI88I8AA8AI88I8AI88I8A˺ò yyyyqyiaqqiqiaqYQaQAaYQaYYaaaiiaqqqyyqyyyyyyqqqaiiYaYQQQAIQ8II8AI88I08A08808A08A00A08A00A08A00800A00A08A00A(0A00808A00800A08A008(0A(0A00A(0A00A(08008(0A00I08I8AI88I8AI88A88I88I8AQ8AI08I88I8AI88I8AQ8AI8AӺ˺ú˺ yyqqyyyqqaqiaqqaqYQaQAaYQaiYqqaqqqyyiyqyyyy qqqqiiaYYYQQYIIQAIQAAI8AI88A8AI8AA08I08A08A08A00A08I08A08A00A08A00A(0A08I08A08I08A08800A00A08A(0A08A008(0A(0A00I00A(0A00A(0A00A(0A00I88I08A08A88I88 I8AA0AI88I8AI88A88I88A88I88I8AI88I8AI88I8AI88Q8AI8AQ8A˺˺úúyyqyyiyyqyqyiYqiaqYQaQAaYQaiYqiaqqqyqyyyyyqqqiiaYYYQQQIIQ8AI8AA88A08A08I00A00A08A(0A00A08A00800A08A00A08A00A08A(0A00A08A00A(0A00A(0A00A(0A00A(08(0A00A(0800A08A00I8AI88I8AI88I8AA8AI88I8AI88I8AA8AI88I8AA8AQ8AI8AQ8A˺úúòyyqyqqyyqqqyyqyiyqqyiaqiYqiaqqqyyqyyy yyyyyqiiqaiaQYYIQQIIQAIQ8AI8AA08I08A08I08A08A08I08A08A00A08A00A08A00A08A00A08A00A08A00A(0A00A08A00A08A(0I08A00A08A(0A(8A(0A00A08A(0I88I08A08I8AQ8AI88I8AI88I8AI88I8AA88I0AI88I8AA88I88I8AúyyiiaqqyqqaqiaqqqyyqyyyyyyyyqqqiqqaiiaaaQYYIQIAAI8AI08A08I08A08800A00800A00800A08A00A08A00A08808A00A08A(8800I00A00A08A(8A(0A00A(0A00A(0A00A(0A00800A008(0A00A(08(0A00A(08(8I8AI88I8AI88I08I8AI88I8AI88I0AI08I88A8AI8AA8AI8AI88I8Aú˺yyqaqqqyyqyyyqqqyyiyqy yyyqqqiiiiYaiYYYQQQIIQAIIAAI8AI88A08I08A08A00A08A(8I00I08A08A00A08A00A(0A08A00I08A08A(8A(0A00A08A(0A08A00A(8A08A(0A00A(8A(0A00A(8A(0A(8808A00A(08(0A00A08A(0I8AI88I08I88I08I88I0AA88I88I8AI88I8AI88I8AA88I8AI88˺òúúqyyqaqiYqiaqqqyyyqqqyyqyq yyqyqiiiaaaQQYQQYIQQAIQAAI8AI88A08I88A08A08A00A08A00A08808A08A00800A(0800A08808A00A08A00A(0A008(0A00800808A(0A00A(0A00A(0A00A(0A00A(0A00A(0808A(08(0A00I88I8AI88I8AI08I8AQ8AI88I8AI08I88I8AI0AI88A88I8AI88ú úò˺yyyqyiiaqiYqiaqqaqyiyyqqqyyqyyyyqqqiiiYaYQQYIIQAAQ8AI8AI0AI88I08A08A08A00A08I08A00A08808A00A(0A00A08A00A(0A00A(0A00A(0A00A(08(0A(0A(8A(0A(8A00A(88(0A(0A00A(0I08I8AA88A8AI88I8AI08A88I88I8AA88I8AI88I8AI88Q88ò˺yyyiyqaqiaqqqyyiyyqyqyqyyyyyqiiiaaaYYYIQQAII8AI08I88I08A08A08A00I08A08A00A08A00A08A00I00A00A08A00A(0A00A(0A08A00I08A08A00800A(0800A08A(0A00A(08(0A008(0A(08(0800A(0A(8A00800A(08(8I08I88I08I88I8AA88I8AA88A8AI8AI08I88A8AI88I8AI08I8AI88Q8AI8A˺˺ yyqyiyqqyiyqqyy yyyqqqaaiYYYIQQIIQAIQ8AI88A08I08A08I08A08A08I08A08A00A08I08A00A08A00A08A00A(0A08A00A08A00A08A(0A00A(0A00A(0A08A008(0A(0A00A(0A00I88I8AA8AI88A8AA88I8AI08I88A88A08I88A08I08I8AI88I8AI88yiiyòúòyqqqyyyyyqyqqyyyyiiqaaaYQYQQQAIQAAI8AA8AA08I08A08I08A08I08A08I08A08A00A08808800A00A08A(0A(8A008(0A00A08A00A08A(0A08A00A08A(88(0A(08(0A(08(0800A00A08A00A(0A00800A00A(0A00A(08(0I8AI08I8AI88I8AI88I8AI88Q88I88A88I0AA08A8AI88I8AI88I8AI88I8AaQQqaYyqiyú˺òyqyiyyyyyyqyqyqyyqqiaaaYYYIIQAIQAAI8AI88I08A08I08A08A08I08A00A08A00A08A00A08A00I08A08A00A(0A00800A00A08808A00A08808A00A(0A08A00A08A00A(0800A00808A08A00I88A88I88A88A08I08I8AI08I88I08I88A88A08A88I08I8AI88I8AI0AI8AA08A88I8AI88QAIYIIiYYyiay˺òyiiaq qayiyyyqyyqyyyyyyyyyqqqiiiYYYQQQAIQAAQ8AI8AI88A88A08I08A08A08A00A08A00A08A00A08800A00A08A(0A00A(0A00A(0A00A(0A00A(0A08800A(0A008(0A(0A00A(0A00I8AI08I88A88I88I0AA0AI88I8AI88A8AI88A8AI88A08I88I8AA0AA08I08I8AI88I0AIAIQIIYQQqaYyqi˺òyiqayqyyqyyyqyqyyqaiiYaYQQYIQQAAI8AI88I08A08I08A08I08A08A00A08A00A08A00A08A00A088(0A00A08A00I00A00800A08A00800A00A(0A00A(8A(08008(0A(88(0A00A(0A00A(0A00I88I8AI08I88A88I8AI08I88I8AI88A8AA08I88I08I88A88I88I8AI88QAIQIIYIQaQYiaa ˺˺yyqyiiaqqayyqyiyqyyaQQYIIQAIIAAI8AA88A08808A08I08A08I08A08808A08800A08A00800A08A00A08A00A08A00A08800A00800A00800808A08A(0A00A(0A008(0800A(08008(0A(08(0A(0A00800A00I08I88I8AI88I8AI88I08A88I88I08I88I8AI88I8AI0AI88I8AI88QAIYIIaQQaYYòyyyiyqyyiiYqqyiyiyiyqyYIIQAAI8AA8AA88I08A08I08I88A08A00A08A(0A08A00A08A00A(08(8A00A08A00A(0A08808A08A00800A(8A00A(8A(0A00A08A00800A00808A(0A00I00A00A(0I00A(08(0A00I88I08A88 I08A08A8AA88I88I08I88A88A08A88A08A88I88I08A08I8AI0AI08I88A8AI8AI88QAAYIIYIQ˺òyyqqayqqayiyyyyQ8AI8AA08I88A08I08A08I08A08A00A08A00A08A00A08A00I08A00A08A00A(0A00A08A00A(08(0800A08A00A(0A00A(0A008(0A(0A00A(08(0A(0A00A(08(0A(0A00A(0I08I8AI08I8AI88I08I88I08I0AI88I8AI88A08I88I8AA88I08I88I08I88A0AI08I0AQAIYIIӺ˺úyyqyyqyiiYqyiyqyiqayiyqqyI8AI88I8AA08I08A08808A08I08A(8A08I08A08A00A(8A08A00A08A(8A08A(8A08A00A(0A00A(0A08A00A08A00A(08(0A08A00A(0A08A(0A00A(08088(0A(8I88A88I88A08I88I08I88A08I08A08A0AI8AI08I88I08I88I08I8AI88I0AI08I88QAAQAI˺yyqyiyiyiqayiqyqyqyyA08A88I08A08I08A88A08A(8A08A00A08A(0A08A00A08808A(0A08A00A08A00A08A00A08A(0A00A(0A00A(08(0800A(0A00A(0A008(0800A00A(0I88A88I88I08A88I08I88I0AI08A08I88I8AI08I88I08I88I8AI0AI08I8AI88I8AIAA˺òyyyiqayqyiqayqyyiyyqA88A08A0AA08I08A08A08I08A08A00808A08A00A08808A(8A08808A08A00808A08800A00A08A(08(0A00A08800A00A(8A(0A00A(0A08A00A08A00A08A(0A00A(08(0A00A(08(0A(0A008(0A00A(0A08I08A88A08I08I8AI08I88I08A8AI08A88I88I08A08I88I08A08A88I88A08A88A8AI88I08I8A òòyyyiqYyiyyyyqyiyqyyA08A08A00A08808A00I08A00A08A00800A08A00A08808A08A00A(08(0A00800A(0A00A(0A00A(8A(0A00A(0A00A088(08088(0A(08(0A00I88I08A08I88I08I88A88I88I08I88I08A08I88A88I88I8AI08I88A88A8AA08I08I88I08I88˺ò˺yyqyiyqyyyqyyA08A08I08A08I08A08A00A08800A00I00A08A00A08A(0A00A(0A08A00A08A00A08A00A088(0A(0A(8A(0A088(0A08A(0A(8A(08(0A008(0A00A(0A008(0A008(0A(08(0A(0I8AA88I88I08A08I88A08I08I8AI88I08I88I08A88I8AA08I88I08I88˺òyqyqyqyyqA08A(8A00808A08A00808A00A08A00A08800A08A00A08A00A08A00A(0A00A(0A00A08808A(0A00A(0A088(0A008(0A(08(0A00A(08(08(8800A00A(08(0A00A(0800A(08(0A(0I88A88A08I88I0AI8AI08I0AI8AI88I08I0AI08I8AI88I8AI88A0AA08Ӻ˺yqyyyqyiqyA08A88A08I08A08A00800A08A00A(0A08A00A08A00I08A00A(0A08A00A08A00A(0A088(88(0A(0A(8A(0A00A(0A(8A008(0A(0A08A(0A00800A(0A08A(0I8AA88A08A88I88I08A88I88A08I88A88A08A88A08A88I08A08I08I88I08I88I8AI08˺˺yyiyyqy808A08808A08808A08A(8A00800A00A08A(8800808A08A(8A(0A00A(0A08A00A08A(0I00A(0A00800A00A(08(0A(08(0A(08(08008(0A(0A00A(08(0A(0I08I88A08I88I08A08I08I88I08A88I8AI88I8AI88I08I88I08ú˺˺òyiqYyiyyqyyyyA08808800A08A00A08A00808A08A(0A00A08A(0A00A(8A08A00A(0A08A00A(0A(8I00A08A(8A(08(0A(08(0A(0A(8A00A(0I08I88A08I08I8AI08A88I88A08I08I88I0AA08I08I88I08I88I8AA88A08˺˺˺òòyyqyiyqyyA00A08A00A08A(8A08A00A08A00A08A00A(0A00A08800A08A00A08A00A08A(0A008(0A00A(0800A008(0A(08(0A(0A00800A(08(0A00A(0A00I08I88I08A08I08I8AI08I88I08A88I08I88A08I88I0AA0AA08I0AI08˺òúò˺òòyyyyiqayiyqyyA08A00A(0A08I08A08I08A08A00A08A(8A08A008(8A(8A(0A00A08A(8A08A00A(8A(0A00A(0A08A(88(0A00A(0A00A08A(0A08A008008(08008(0A(08(0A008(0I08I88A08I08I88I08A08I08A88I08A88I88A08I88A88A08I08I88˺ò˺ò˺ò yyqqyyiqayiyqyA08808A08A00800A00A08A00A08800A08A00A08A008(0A(0A08A00800A(0A00A(0A00800A00A(0A(8A(0A008(0A(0A00A08A00A(0A00A(08(0A(08(0A(0I08A08I08A08I08I88I08I0AI88I08I88A08I88I0AI88I08I8AI0AI08I88A8AA08˺úúòúúòòyqyyyqyiyyyyA08808A00A08800808A08A(8A00A(8A08A(0A(8A(0A00A(0A088(0A(0A00A08A008(0A(0A08A00A(0A(8A00A(0A00A(0A00A(0A08I08A08I08A08I08A08I08A08A88I88I08A08A88A08I08I88A08I08A08úúúòúúòòyyyqyiyqyyyqyyqYIAA08I08A08I00A(0A08A00A(0A08808A00A08808800A(0A08A(0A08800A00A(0A(8A00A(0A00A(0A00A08800A00A(08(0800A00800A008008(0A(0A00A(08(0A(0A008(0I08A88A08I08I88A08I08I88I08A08I08I8AI0AI08A08I08A88A08I0AI88˺òúòyyqqaqyiyqyqyyyyqiQ8AA08A(0A08A00A(8A(0A00A(0A08A(8A08A(0A(8A00A(0A08A(08(0A(0A00A08A(0A00A(0A(8A00A(0A(8A00A(0A08A(0A(8A(0A08A(0A08A(0A00I08A08I08A08I08A08I08A08I08A88I88A08I08I88I08˺ò˺yyyyqyqqqyyiiaqyiyqyyyyqaaI88A08I88A08A(0I08A08A00A08A00A08A00A08808A08A00A08A(0A00A08800A00A08A00A(0A00A08A00A08A00A(08(0A(0A008088(0A(0A08A00A(08(0A(08(0A(08(0A(08(0A(0I8AI08A08I08A08A88I88I08A08I08I88I08I8AI08A08I0AI08Q88I08A08I08úòòyyyyyqyiqaqqqyyyyyyaIQI08I00A08A00I08A08A00A08808A08A(8A08A00A(0A08A00A08A00A(8A(0A(8A00A(0A(8A(0A(8A(08(0A(0A00A(0A00A(0A(8A(0A00A(08(0A(0A00A(0I88A08A88I88I08A08I08A08A88I88A08I08I88A8AI08A08I08I88I08A08A88I8AQA8yúòqaaqyqyqyqyqyiyyyyqqQ8AA(8I08I0AA08A08808A00A08A00A08A00A08A00I00A08A00A08A(0A00A(0A08A(8A(0A00A08A00A(0A00A(8A00A(8A(08(0A(0A00A08A(08(0A00A(08(0A(0A00A(08(0A(08(0A(0I08I88I08A08I08A08I88I08A08I88I08A08I08I88I08I88I08I0AI8AI08 I00qaIúYIII08 úúúyyyyqqqyyiyqyyqaYQ88I08I0AI08A08A08A00A(8A00A08808A008008(0A(0A(8A(0A00A(8808A00A(08(0A(08(0A00A(0A00A(0A00A(8A(08(88(0A(08(0A088(0A(08(0A(8A(08(0A(08008(0I08A08I88I08I88A08I08A08I08I88A08I08A08I08I88A08I88A08I08A08I08A08I8AA08QA8úúyyYIAA(0I00Q8Aúyyyyyyqqqyyqy yqQA8A00A08I08A08A08A00A08A00A08A00A08A00A08A(88(8800A00A08A008(0A008(0A08A(0A00A(0A00A(0A008(0A(08(0A00A(0A00A(08(0A(0A08A(0800A(08(0I08A08I08A08I08I0AI88I08I88A08I88A88I08I8AI08I00yiaú˺úyiaI008(0I88I8AQ8AI8A˺úyyqyyyyqaII08A08A0AA08I08A(8A08I08A08I08A08I08A08A00A(8A08A00A08808A08A00A08A(8A(0A(8808A00A(8A(0 A088(0A08A(0A088008(0A(0A00A08A(08(0A(08(0A(08(0A(0A00A(0I08A08I08A08I08I88A08I08A08I08A08I08A88I08A88I08A08I8AA8AA08I88yqaQQA(0I8AI8IQAI˺ú yyyqy qiaQ88A00A08I08A08I08A08A08A00A08A00A08A00A08800A08A(0A00A(8A(0A00A(08(8A00A(08(0A00A(08(08(8A(0A00A(08(0800A00800A(08(0A00A(08(0A(0A008(0A(08(0A008(0A(0800A008(0A(0A00A(08(0A(0A88A08I88I08A08I08A08I88I08A08I08A08I08I0AI88YIAaQQYIAI00A(0I08I8AQ8AQAIò˺˺úyqqyiiqaYqaayyqyqqyyyyqYIAI08A08I08A08I08A08A08A(0A088(8A08A00I08A08A00A08A00A08A00A08A00A(0A08I00A(0A08A00I00A088(8A(0A08A(0I00A00A(0A00A(08(88(0A(08(0A(08(0A(0A(88(88(0A(0I08I88A88I08A08I08I88I08A08I08I88I8AA08A88A08I08I88I08A08I88I08A08I0AI8AI08I8AI88I08I00I08A08I0AI08I88I8AI8IIAIQAIQ8AI8AiYYyiayò˺˺úòyyyyqqqyiiqaaaQYaIQYIAqaYyqyyaQQI00A08A0AA08I08A08A00A08A00A08A00A08A00I08A00A(0A00A08A(0A00A08A008(0A00A08A(0A08A008(0800A(0A00A(8A(0A088008(0A(08008(08008(0A(08(0A(0A08A008(0A008(0A(0A00800A00A(08(0A(0A08I08A08I08A08I08A08I88A08I88A08I08A08I08A08I08I88I08A08I08A8AA08I08I8AI88I8AA8AI8AI0AI8AI88I8AYIIaYYyiiyqqyqyòú˺˺˺ú˺òòyqyyqqyiiqaYiYYqaaiYYaQQaIQQAII8AA88yiayyyiaQ8AA00A08I08I08A08A00A08A00A08800A08A00A08800A08A00A08A(8A08A(0A08A(8A(0808800A08A(8A(0A08A(0A(8A(0A00A(0A00A(0A(8A(0A08A00A(0A(88(0A(0A00I00A(0A00A(0A08A(0I08A08I08A88I88I08A08I08A08I08A08I08A08I08A88A08A88A08I8AA88A08I08I8AI88A0AA8AA88I08I8AI88I08I8AA8AI8AA8AI8AI88Q8AI8AI88I8AQ8IIAAQAAQ8AI8AQAIaQQiYa iYYqaYyiayqiqqyyyqqyqiyiiqaaqaYqaaiYaiYYYIIYIAQAAYIIYIQYQYYIQQAII8AI08A08aYQyyqiYIIA08808A08I08A08I08A08I08A08A00A08I08I00A08A00I08A08808A00808A(0A(8A00A08A00A08800A00A08A(88(8A00A(0A08A00808800A(0A08A00A(0A00800A008(0800A(08(0A(08(0A(0A008(0A00A(08(0A(0I88A88A08I08I8AA08I08A08I08A08I08I88A88I08A08A88I08I0AI08I88A08A88I08I08I0AI08A08A88I88I8AI88I8AI08A8AI08I88I8AI0AI8AQ8AQ8IQ8AI8AQ8AQAIYIQaQYaIQYIQaQQaQYiYYqaayiiyqqyqyyyqqqyyyyyqyyyyyyqyyyqiyiiqaaiYYaQQYIIYQQYIQQAAI8AQAAYIIQAII8AI0A808qaYyyyyYIIA00A08I08A08I08A08I08A08I08A08I08A08808A00A08I08A00I08A(8A(0A00A08I08A08808A08I00A08A00A08A00A(8A08A(0A08A(0808A(0A00I00A(0A00A(0A00A(08(0A(08(0A(8A(0A(88(0I08I88A08A88A08I08A08I88A08I08A08A8AI88I08A88I08I88A08I88A88A08A88A08I08I88I8AI88I08A0AI08I8AI08A0AI08I88A88I88I8AI88I08I0AA08I88I8AI88A8AI8AA8AI8AI0AI08A8AI8AI0AI8AQAIYIQ QAIQAAQ8AQAIYIQYIIaQQiYYiYaqaaqaYiYYaQQiYYqaYqaayiiyqiyiaqaYiYYaYQqaYqaaqaYqaaqaYiYYaQQYIIQAAYIIYIQYIIQAIYIIQAAA8AI08I8AQ8AI8AI0AI8AA088(0qaIyyqaQQI00A00A08I08A08I88A08I08A08I08A08I08A08A00A08I08A00A08I08A08I08A00A08800A00A08800A00A08A(8A08A(0A08A00800A00A08A00A088008(0A(8A008008(0A(0A00A(0I00A(0A00800A(0A00A08A(0A00A(08008(0A(08(0A(0I08A08I08I8AA08I08A08I08A08I08A08I08A08I08I88A08I88I08Q88I8AI08I8AI0AA0AA08I8AA8AA88I88I08I88I08I8AI0AI08A88I8AI0AI88I8AI88I8AI0AA0AI0AI08I0AI88A0AI88I8AQ8AI8AQ8AQAIYIIQAAI8AQ8IQAIYIQYQQaQQYIIYIQYIIaIIaQQiYYaQQYIIYIQYIIQAIYIIYIQaIQYIQaIQYIQYIIQAIQ8AQAIQ8AI8AQ8AQAIQ8AI88Q8AI8AI08I8AI88I8AA08I0AI08A(8Q88yqiYIAI00A(0A08I08A08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A(8A08A00A08A(8A08A(0A08808A08A(0A08A00A(0A08A(0A00A(8A008(8A(8A00A(0A08A(0I00A00A(8A(0A00A(0800A(0A00A(08(0A(0A88A08I08A08I88A08I08A08I08A08I08A08I08A08I08A08I08I88I08A08I08I88I08A08A88A08I08I0AI88A08I08A08I8AA88I08A88I88A8AA88I8AA0AI0AA88I88I8AI08I88I8AA88I8AQ8AI8AI0AI08I88A88I8AI88A88A8AI8AQAIQ8AI88I8AIAIYIIQAAQ8AI8AIAAQAIQ8AYIAYIIaQQYIQQAIQAAQ8AQAIQ8AI8AQAAYIIQAIYIIQ8AQAAI8AQ8AI8AI88A0AI88Q8AI8AQ8AI8AI88 I0AA08I08A(0I08yiaYIAA08808A08I08A88A08I00A08I08A08I08A08A(8A08I08A08I08A08800A00A08A(0A088(0A(0A08I08A08A(0A088(0A(8A00A08A00A08800A00A08A00A(8A(0A00A(0A00A(0A00A(0A00A08A(0A08A(0A00A(08(0A(0A00A(08(0A(0I88A08A88I08I88A88I08A88I08A08I08A08I08A08I0AI08A08I08A08I08I88I08I88I08I88A08I8AI0AI08I88I08A08I8AI0AI08I88I0AI08I88I8AI0AI08I0AI8AI88I08I8AI0AI8AI08A0AI0AI88I08A8AI08I8AA8AI88I0AA0AI8AI08Q88I0AI8AQ8AI8AI0AI8AQ8AQAIQAAI8AQ8AI8AQ8AQAIYIIQ8AQ8II8AQ8AQ8IQAIQ8II8AQ8AI8AA8AI88I8AI0AA08I08I8AI08I88I8AI08A(0I08yiayqiaQQI00A(0I08A08I08A08I08A08I08A08I08A08I08A08I08A08A(8A08A00A08I08A08I08A(88(8I08A08A(0A(8I08I00A(8A00A08A(8808A(8A00A(8A08A00A08A(8A00A08A(08(0A00A08A(08(0A(08(08(8A(08(0A08A(08(88(0A(0A08I08A08I08A08I08A08I88I08I88A08I08A88A08I08A08I08A08A88I88I08I0AI08A88I88I08A08I08I8AA08I08A88I88I08A08I8AI88I08I88A08I88I8AA88A08I88I8AA8AI8AI88A88I88A08I8AI0AA0AA8AI8AI88I8AA8AI8AQ8AI8AQ8AQAIIAII8AI88I8AA88I8AQ8AI08I8AI88I8A I88I08I0AI88I0AA08A88A8AI08I0AA0AI08A0AA08 I08A08I08A08800YIAyqiyyqaQQQ88A(0A08I08A08I08A08I08A08I00A08A88A00A08I08A08808A08A00A08A00A08I08A00A08A00A08I08A00800A08A00I00A00A(0A(88(0A00A(08(0A08A00I00A(0A00A(0A008(0A(08(8800A00800A(08(0A(0I08Q88I88I08I88I08A08A88A08I08A88I08A08I08I8AI08A08I08A08I08A08I08I88A08I88I08A08I08A88I08A08I08I88I0AI08I8AI08I0AI08A8AA08I8AI08I0AI88I0AI08A08I88A88I8AA88I8AA8AA08I08I8AA88I08I8AA88I8AI08A08I08A8AI8AI0AI8AI0AI08I88I8AA8AI8AI0AI8AI0AI8AQ8AI8II8AI0AI8AI0AI8AQ8AI8AI0AI8AI0AI8AI0AI88I8AA08I08I8AA0AA08I0AI8AA08I8AI08A08I08A08A(8A(0I00Q88YIAQ88A(0A(8I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08I08A08A00A08808A08800A00A(0A00A08A00A(0A08A00A(8A(08(8808A(0A00A08A(8A08A(8A(0808A(0A088088008(0A(0A00A(0A088(0A(08(0A00A(0A00A08A88I08A08A88A08I88I08A00A08I08A08I08A08A88I08A08A88I88A08I08A08A88A08I0AA08I0AI08I88A88A08A88I08I88I08I88A88888A88I08I88A08I08I88A88I08I0AI08A08I88I08A08I88I08I0AI88A88I0AA0AA88I8AI0AI08A08A0AI88I8AI0AI08I88I8AI0AI8AI08I8AI88I8AA08A0AI8AQ8AI8AI88A8AI8AI88I8AI0AI8AI0AA8AI88I8AI88A08A88I8AI88I8AI0AI08I8AA08I08A08A88I08A08I08A88I08A08A88I08A08A0AA08A(8A(0A08I08A08I08A08A00A08A00A08I08A08A(0A08A00I00A08A(8A088(0A08A(0A08A00A08A00A08A(8A08A00A08A(0A008008(0A(08(0800A00A(8A(0A008(0A(08(0A(08(0A(08(0I08A08I88A08I08A08I88A88I08I0AI08A08I88I08I8AA08I88I08A08I08I8AA08I08A08I8AI08I8AA8AA88I0AI08A08I0AA08I08I88I08I88I8AI08I0AA0AI08I0AI08I88A88I8AI08A08A0AI88I08A08I8AI08I8AQ8AI88I0AI08I88I0AI08I88A88I0AI8AI0AI8AA08I8AI08I0AI08I0AA88I88I8AI0AI08I88A08I8AI0AI08I0AI08I8AI88I08A08I08I0AA08A8AI8AI88I08A08I8AA08I08A08A8AA08I08I0AA08I08A0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A(8A08808A08A00I08A08A00A(0A08A(8A(0A00808A(0A00A08A00A(8A08A(0A00A(0A(8A00A(0A08A(0A008(0A(0A08A(0A(88(0A(0A(8A08A00A(08(0A(0A00I08A08I08A08I08A08I08A08I08A08I08A08A88I08A08I08A08I88A88A08I08A08I08I88I08A08I08I88I08A88I0AI8AA88I08A08I08A08I88A08I88I08A08I08I8AI88I08I8AI0AI08I8AI88I08A08I88I08A08I08I8AA88I08I8AA08I0AI08I88I08I0AI88I08A0AA8AI8AA08I8AA8AI88I8AI88I08A0AI0AI08A08A88A08I08A08I88A0AI8AA8AA08I08A88A08I08A08A8AI08A08I08A88I08A08I88I08A0AA08I08A08I08A08I08A08I08A08A00A08I08A08A00A08A00A08808A08A00A08A(0A(8A00A08A00A(0A(8A(0A08A(0A(8A(0A08A(8A(0A00800A(0A08A(0A00800A(0A08A(08(0A(0800A(0A00800A008(0A(08008(0A(0I08A08I08A88I08A08I88I08A08I08A08I08A08I0AI08A08I88I08I8AA08I08A08A0AA08I08A08I08I8AI88I8AA08A0AA08I88A88A8AI0AA08I08I8AA88I0AI08I8AI08I0AI08I88A08A0AA08I88A08I8AI0AI08A08I8AI08I8AI08I8AA88I0AA08I88I08I88I08A08I8AI0AA0AI8AI88I08I88I0AI08I0AA08A8AI08I0AA08I08I0AA0AA08A0AA08I08A08I0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08808A08I00A08A(8I08A08A00I00A08I00A00A08A(8A08A(0A(8A08A(0A00A(0A(8A(0A00A08A(0A(8A(0A00A(8A00A08A00I00A00A(08008(0A08A00A(0800A(08(0A(0I08A08A88A08I08A08I08A08I08A08I88A08I88A08I08A08I08A08I08I88A08I88A08A88A08I88A08I08I88I0AI08I0AA0AI0AA0AI0AA08A88A8AA08I08I88I08I88I08A88A08I0AA08I88I8AI88I8AI88A08I88A88A08I08I88I08I88A08I8AA0AI08I0AA08I08I8AI08A08A88I8AI08A08I08I88I0AI08I88A08A88A08A88I08I88I08A0AA08A0AI08A08I08A08I08I0AI08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A00808A08A00A08808A00A08A(8A00A08A00A(0A08A(0808A00A08A00A08A(8800A00A08A00A08A(0A088088(0A(08(0A(0A00A(0A(88(0A(08(08008(0A(0A00A(08(0A(08(0A(0I88I08A08A88I08A08I08A08I08I88A08I08A08I08A08I88I08A08I08A08A88I88I08A08I08I88I08A08I88A0AA8AI08A08I08A08A88I8AA08I08I88I08A08I8AI08A08A0AI08A08I88I0AA08I08I0AI08A08I0AI88A88I88I0AI8AA08I08I8AI08I0AI08I8AA08I08I88I0AI8AI08I0AA0AA08I08I0AA08I08A08I08A08I08A08I08I8AI08A08I08I0AI08A08I08A08I08A08I08A08A0AA08I08A08A88A08I08A08A0AA08I08A08A(8A08I08A08A00A08A(8A08I08A08A00A08A00A08A00A08A00A(8A(0A(88(0A(0A(8A(0A08A(8A00A(08(88(0A(0A00A(0A00A(08(0A(0A(8A(08(0A00A(0A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A88I88A08A00I00I08A88I08A0AA08I08A08I88I08A08I08A08I08A08I08A88A08A0AI08I88I08A08I0AA08I08A08A88I88A8AI8AA0AI0AA08I08A88A8AI08I88I08I88A88I0AI88I08I88A08A0AI0AI8AA08I88I08A08A88I88I0AA08I08I0AI8AI0AI08A0AA08A8AA88A08I88I08I8AI08A08I8AA08A0AA8AA08I08A08I08I0AA88I08A08I08A08I08A08I88I08A08I08A08I08A08I08A08I08A08I08A08A00A08808A08I08A08808A08I08A08I08A08808A08I08A(8A08A00A08A(0A08800A00A08808A08A00A08A(0800A00A(0A(8A08A(0A00A(0A008(0A(08(0A00A088(0A008(0A(0A(8A(08088008(0A(08(0A(08(0A00A(08(0A(0A08I08A08A88I08A08I08A08I08A08I08A08I08A08I88I08A08I08I88I08A08I08A08A88I88I08A08I0AA08I08A08I08I0AI08A08I08I88I08I88I08A08I0AI08I88A08I88A08I08I0AA08I08A08I08A08A8AI08A0AA08I08I0AI08I88A0AI08I0AI08I0AI08A08I0AI08A08I0AI08A08I88A08I08A88A08I0AI08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08808A08I08A(8A08A00A08808A08A00A08A00A(8A(0A(8A08A(88(8808A00800A00800A08A00A(0A(8A(0808800A00800A(0A088(08(8A(88(0A(0A(88(0800A(0I008(0A(0A08A88I08A08I08A08I08A08I08A08I08A08I08A08I08I88A08I08A08I08A08I08A08I08A08I08I88A08I88I08A08I08A08A8AI08I88A88A08I08A88A08I88A88A08I88I08A88A08A8AI08A08I08A08I08I88A08I08A08A88A08A0AI08A08I0AA08A88A08I08A08I08A08I08A08I08A08I08A08I08A08808A08I08A08I08A08I08A08I08A08808A08A00A08A(8A08A00A08808A08A00A08A(8A08I00A08A(0A00A08808A08A(08(0A(0A00A(8A00808A008(0A(0A008008(0A(08(0A00808A088088008(0A008(0A(08(0A(08(0A(0A00A(0A008(0A(08(0A(08(0I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08I88I08A08I08I0AI08A08A88I08I0AA08I08A08I08A08A88I08A08A88A08I0AI08A08A88I08I0AI08A08I08A0AI08A08I08I88I08A0AI8AI0AA08I08A08I08I0AI08I8AA08I08I0AI08A08I08A08I08A08I0AI08A08I08A08I08A08I08A08I08A08A0AA08I08A08I08A08I08A08I08A08I08A08I08A00A(8A08I08A08A(8A00A(0A08I00A(0A00808A00A08800A00A(88(0A00A(0A08808A088(0A(0A(88(0A(0A008(0A(0A(8A(0A(8A00A(08(0A(0A008(0A(08(0A(08(0A(08(0I08A08I08A08I08A88A08I08A08I08A08I08A08A88I88A08I08A08I88A08I08A08I08A08I08A08I08I88I08A08I08I88A08I08A08I08A08A88I8AA88A08I08I88A88A08I08A08A0AA08A88I88A08I08A08I88I08A08I08A08I88A0AA08I08I0AA08I08A08I0AA08I08A08I88I08A08I08A08I08A88I08A88A08I08A08I08A08I88A08I08A08I08A08808A08A00A08A(0A08808A00I08A08A00A(8A008(8A(08008(0A(0A08A00A08A00A08A00A08A00A(0A00A(0A08A008(0A00A(0A00808A08A008(0I00A(08008(0A(0A008(08008(0A(08(0A(08(0A(08(0A(0I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I88I08A08I08A08I08I88I08A08I08A0AA08I08A08I08A08I08A08I88I08A08I08A88A08I0AI08A08I0AI08A08I88I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I0AA08I08A08I08A08I08A08I08A08A00I08A08I08A(8A08I00I08A08A(0I08A(0A08A00A08A00A08A00A08A(8A00A08A008(0A08A00A(0A08A00A08A(0A(8A(0A00A(0A08A(08(0A(0A008(0A(0800A(08(0A(08(0A(0I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A88A08I08A88A08I08A08I08A08I08A08I0AI88A08I88A88I08A08A88I88A88A08I08A08A88A08I88A08A88I08A08A88I08I0AI08I0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08I08A08I08A08I08A08A00A08808A08A00A(8A08A00A08A00A08800A08A(0A08I08A(8808A08A00800A08A00A(8A08A(0A00A(08(0800A08A(0A(88(0A(0A08A(0A088(88(0A008(0A(0A08A008(0A(08(0A(8A(0A00A(08(0A(08(00((8(0A(08(0A(08(0A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I0AI08A08I08I88I08I0AI08A08I08A08I08A08I8AA08I08A08I08A08A88A8AA08I08A88A0AA8AI08A08A88A08I0AI08A08I08A08I08I88A08I08A08I08A08I08A08I08A08I08I8AI08A08I08A08I08A08I08A08I08A08808A08I08A08I08A08I08A08I00A08I08A(8A08A00A(08(8808A08A00808A08A(8A00A(0A00A08A(8A00A(8A(0A00I08A08A(0A08800A(0A00A(0A08I00A(0A00A(0A(8A(08(0A(08(0A(08(0A(08(0A(0A08I08A08A00A08I08A08I08A08I08A08I08A08I08A08I08I88A08A88I08A08I08A08A88A08I08I88A08I08A08I08A08I08A08I08A08I08A08A88A08I08A08I08A08I08A08I08A08I08A08I08A88A08I08A08I88A08I08A08I88A08I08A08I08A08I08A08I08A08I08A08I08I0AA08I08A08I08A08I08A08A00A08808A08A(0A08I08A08808A08A00I08A00A08I08A08I00I08A08A00A08A00I08A08I08A08A(8A(0A00A08A00A(0A08808A(8A(0A00A08A(08(8A08A(0A08A(8A(0A00A(0A00A(0A00A(08008(0A(08(0A(0A00800A(08(0A(08(0A(08(0A(08(0A(0A08I08A08A88A08I08A08A88I08A08I08A08I08A08I08A08I08A08I08A88A08I08A08I08A08I08A08I08A08I08I8AA08A88I88I08A08I88A08I8AA08I08A08I08A08I08A08I88A08I88I08I0AI08A08I08A08I08A08I08I0AI08A08A0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08808A08I08A08808A08A(0A08A(0A08A(0I00A(0A(8A08A(8A08A00A08I08A(0I08A08I00A(0A(8A08A00A08A(8A(0I08A08A00A08A(0A088(0A08A00A(08(0A(0A(8A08A00A(08(0A(08(0A(0A(8A(08(0A(08(0A(0I08A08I08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I88A08I08A88A08I08A08I08A08I08A08I08A08I08A08I08A08A88I08A08A88A08I08A08I08A08I08I88A08A88A08I08A08A0AA08I08A08I08A08I08A08I08I0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08I08A08A00808A08A00800A08A(0A00I08A08808A08A(8A08A(8A08A(0A08A008(0A(88(8808A08I08A00A08800A08A00A08A00A(0A08A(0800A00A(0A008(0800A00800A(0A(8A(08(0800A(08(0A(08(0A(08(08((8(0I08A(8I08A08A00I08A08I00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I88A08I08A08I08A08I08A08I08A08I08A08A0AI08A08I88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A0AA08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A088(8A(8A08I08A08A(8I08A08A00I00A08I08A(88(8A08I08A(0A088(8808A08A(88(0A00A(0I00A(88(0A08800A(0A008008(0A(08(8A(0A08A(0A00A(08(0800A08A(0A008008(0A(08(0A(08(88(0A(0I00A(08(0A(08(0A(08(0A(08(0A08I08A08A00I08A08A00I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A88A08I08A08I08A08A88A08A88I08A08I08A08I08A88A08I08A08I08A08I08A08I08A08I08A08I08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08808A08I08A08I08A08I08A08I08A08A00A08A00A08A00A08A00A08A00A08A00A(0A00800A00A088(0A00800A(08(0A(0A00A08A00A(8A(08(0A(0A(8A(0A00A(0A00A(08(0A(08(0A008(0A(08(0A(08(0A(08(08((A08I08A08A00I08A08I08A08I08A08I08A08I08A08I08A88A08A0AA08I08A08I08A08I08A08I08A08A88A08I08A88A08I08A08I08A08I08A08I08A08A00I08A08I08A08I08A08I08A08I08A08I08A08808A08I08A08I08A08I08A08I08A08I08A08A(8A08I08A08808A08I08A08I08A08808A08I08A(0A08I08A08A(8A08A(8I00A08A00A08A(8A(0A08I08A(0A08A(8A08A00A08A(0A08A(0A08A(8A(0A08A00A08A(0A00A(0A00A08A00A(0A088(0A(0A088(0800A(08(0A(08(0A(08(0A(08(0A(08(0A(08(0A(08(0A08A00A08I08A08I08A08I08I00A00A08A00I08A08I08A08I00I08A08A00I08A08I08A08I08A88A08I08A08I08A08I08A08I08A08I08A08I88I08A08A88A08I08A08A88A08I08A08I08I88A08I08A08I08A08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08A00A08808A08A00800A08800A08A(0A00I08A088(0A08800A00A08A00A088008(0A08A00808A00A08A008(0A(08(0800A088(0A(0808A00A(0A00A088(0A(0A00A(08(0800A(08(0A(08(0800A(08(0A(08(0A(08(0A(08(0A(08(0A08A00A08I08A00A08A00I08A08I08A00I08A08A00A08I08A08I08A08I08A08A00A08I08I00I08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08I88A08I08A08I08A08I08A08808A08A00A08I08A08I08A08I08A08I08A(8A08I08A08I08A08A00A08I08A08A00A08808A00A08808A08A(0A08800A08A(0I00A08I00A(0A00A08A(8A08A(8A08A(0A00A(08(0A(0A08A(0A(88(0A00A(08(0A(08(0A(0A00A(08(0A(08(0A(08(0A(08(0A088(0A(08(0A(08(0A00A(08(08((A08A00A08A00I00A08A88A08I08A08I08A08A00A08I08A08I08A08A88I08A08I08A08A88I08A08I08A08A88A08A00A08I08I88A08I08A08I88A08I08A08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A00A08A(8I08A08A00808A08A00A08A00A08I08A08A(0A08A00A08A(8A00A08A00A08A00A08A(8A08 A00A08I08A08808800A(8A00A(0A00800A08A00A08A(8A(0A(8A(08(0A00800A008(0A(0A00A(8A(0A008(0808A(08(0A08A00A(08(0A008008(0A(08(0A00A(08(0A(08(0A(08(08((8(00((8(0A00A08I08A08I08A08I00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A00A08I08I88I08A00I08A08I08A08I08I88A08I08A08I08A08I08A00I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08A00A08I08A08A(8A00I08A08A00A08A00A08A00A08I08A(0A(8A08I00A08A00A08800A(08(0A08A(0A00A08A(88(0A(0A08A(0A00A(08(0A(08(0A(0A(8A088(0A(08(0A(08(0A(08(0A(08(08((A08A00A08A00A08A00I08I00I08A08A00I00I08A08I08A00A08A88A08I08A08I08A08I08A08I08A08I08A00A08I08A08I08A08I08A08I08A08I08A08I88I08A08I08A08I08A08I08A08I88A08I08A08I08I88I08A08I08A08I08A00A08I08A08I08A08I08A08A00A08A00A08I08A08A00A08800A08A00A08A00A(0A08A00A(0A00A(0A00800A08A00A(8A(0A08A00A(0A(88(0A00800A008(0A(0A00A(08(0A00A(08(0A(08(08008(0A(08(0A008008(0A(08(0A08I08A08I08A(0A08A(0I08A08I08A08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I88A08I08A08808A08I08A88A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08I08A08I08A08A00A(0A(8A08I08A(0A08A00I08A08A00A(0A08A(8I08A(08(0808A00A08808A(0A08A00A08A00A08A00808A00A08800A00A(0A00A(0A00A(0A00A(08(0A00A(0A008(0A(0A00A(0A008(0A00A(08008(0A(08(0A(08(0A(08(08((A(08((8(0A08A00A08808A08I08A08I08A00A08A00I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A(8A08I08A00A08800A00I08A08I08A08I08A08A00I08A08I08A08808A08A00808A088(0A08A00A08I00A(0A00800A00A08A(8A(0A08A00800A00A(0A08800A00A(0A00A08A00A08A(0A00A(08(0A(08(0A008008(0A(08(0A00A(08(0A(08(0A008(0A(08(0A(08(0A(08(0A(08(00((8((0 (8((A08A00A08I08A08A00A08I08A08I08A08A00I08A08I08A08A00I08A08I08A08I08A08I08A08I08A08I08A08I08A08A00A08I08A08I08A08I08A08A88A08I08A08I08A08I08A08I08A08I00A08A00A08I08A08I08A08I08A08I08A08A00A08I08A08A00I08A08808A08A00A08A00A08I08A08A(0A08808A08A(8A08A00A(0800A(0A08A00A08A(0A00A(0A00A08A00A(0A00A08A(0A00800A(0A00A(0A00808A(08(0A00A(08(0A(0A008(0A(08(0A(08(0A(08(0A(0A00A(08(0A(08(08((A08A00I08A08A00A08A(8A00A08A00I00I08A08I08A08A00A08A00A08A00A08A00A08I08A08I08A08808A08I08A08I08A08A88A08I08A08A00I08A08I08A88A08I08A08I08A08I08A08A00A08I08A08I08A08I08A08I08A08A00A08I08A08A00A08A00A08A(0A08A00A08I08A(8A(0A00I08A00A(0A00800A08A00A08A(0A00A(0800A008(0A(08(0800A(0A00A(0A00A(08(0A008(0A00A(0A00A(0A(8800A00A(08(0A(08(0A008(0A(08(0A(08(08((8(08((0((8(00((8(08((A00A08A00I08A08808800A08I08A00A08I08A08A00A08A00A08I08A08I08A08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A00I08A08I88I08A08I08A08I08A08A00A08I08A08I08A08I08A00I08A08I08A08I08A08I08A08I08A08A00A08I08A08A00A08A(8A00A08A00A08A00A08A(0A08A00A(8A(0A(8A(0A00A(0A08A(8A00A088(0A(88(0A(0A00A(0A(8A(08(0A(0A(8A(0A(8A(0A008(0A(08(0A(08(0A(08(0A(08(08((800A08A00A08A00A08A00A088(88(0A00A08808A08A00A08A00A08A(0I00I08A08A00A08I08A08A00A08I00A00A08I08A08A00A08I88A08I08A08I08A08I08A08A00A08I08A08A00A08I08A08A00I00A08A00A08A00I08A08A00A08808800808A08A00A(8A08A00A08A00A08A00I08A08A00A(8A08A00A08A(0A00A08I08A(0A00A(0A08A(8A(0A00A(0A00A08A(0A(8A(08(0A(0A00A(08(0A(0800A00A(0A008008(0A00800A(08(08((A00A(08(0A(08(08((8(08((8(08((0((A08A00A08I08A00A08I08A08I08A08A00A08A00A08I08A08808I08A00A08A00I08A08I08A08A00I00A08A(0A08I08A(8A08I08A08I08A00A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A08I08A00A08A(8A08I08A08A(8I08A08A00A08A00A08A00A08A(0A08800A08A(0A00A08A00A(0A08A00A(0A08A(8A08808A08A008(0A(0A00A(0A00A(0A00A(08(0A(08(0A(08(0A(08(0A(08(0A(08(0A(08(08((A(08(00((8(0A00A08A00A08A00800A08A00A08A00I08A08A00800A08A00A08A00I08A08A00A08A00I08A08A(8A00A08A00A08808A08A00A08I08A08A00A08A00A08I08A08I08A08A00A08A00I08A08A00A08A00A08I08A08I08A08A00A08800808A08I00I08A08I08A08A00A08800A08800A08A(0A088(8A08A00A08A00A08A00808A00A08800A08808A08I00A00A08A(08(08(88(0A00A08A00A(08(0800A00A(0A008(0800A00A(0A008(0A008008(0A(0A00A(08(0A(08(0A(08(0A(08(0A(08(08((8(08((8(08((8(00((TRUEVISION-XFILE.allegro-5.0.10/examples/data/a4_font.tga0000644000175000001440000014767511172105527017211 0ustar tjadenusers A EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEETRUEVISION-XFILE.allegro-5.0.10/examples/data/texture.tga0000644000175000001440000001435711206075014017340 0ustar tjadenusers @@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~,,~~,,~~,,~~,,pp>>pp>>ӄpp>>pp>>ӈaa aa %aa aa ,,9>>@;FFAA   hh,,~~>>hh,,~~>>>>t9,,>>>>~~~~pp~~~~pp~~gtSS>>~~ ~~SS>>~~~~ tmmQQӂppӂ~~ppӂ~~tӃ~~Ӄ~~t~~~~xt~~~~t~~,,~~,,t(,,pp>>ӄpp>>g9QQӈ aa ,,aa Y  ,,NN>>YYAAFFAA   hh,,~~>>NNNNhh,,~~>>hh,,~~>>>>~~~~pp~~~~pp~~~~pp~~SS>>~~~~ SS>>~~ ~~SS>>~~~~ӂppӂ~~ppӂ~~ppӂ~~Ӄ~~Ӄ~~Ӄ~~~~~~~~~~~~~~~~,,##66~~,,~~,,ӄpp>>݄NN##pp>>pp>>ӈ ,, aa 1{{## aa aa ,,>>9>>FFAA@RRFFAA  >>~~>>>>t>>HH,,YY++hh,,~~>>>>~~pp~~gtYY]]OOYY~~pp~~~~ t99++YYgg YYSS>>~~~~ӂ~~tggOOggĂYYppӂ~~~~tăYYӃ~~~~xt]]YY~~~~AAtggYY~~AA~~t,,ggYY,,~~ӆ~~FF>>,,g2=OO++~~FF33EE ,,~~ ""Y CC ~~ ,,>>~~GG~~pp>>FFAA\\}}\\FFAA   >>~~>>hh,,~~>>hh,,~~>>hh,,~~>>>>~~pp~~~~pp~~~~pp~~~~pp~~ ~~SS>>~~ ~~SS>>~~ ~~SS>>~~~~ӂ~~ppӂ~~ppӂ~~ppӂ~~~~Ӄ~~Ӄ~~Ӄ~~~~~~~~~~~~AA~~AA~~AA~~~~~~~~~~,,~~FF>>,,~~FF>>,,~~FF>>,,pp>>~~ ~~ ~~ SS ~~~~~~Ӂ>>Ӈ>>Ӈ>>ӆhhTRUEVISION-XFILE.allegro-5.0.10/examples/data/mysha.pcx0000644000175000001440000017021511057522251017000 0ustar tjadenusers ?,,UUUUUUUUUUUUU@77p77pp771p7pp7epp7711pp7pp7epp77p77epp77pp7ppp7ppepp7pp77ppeppeepp77pp77epp77pp7ppeppepp77pp1pp88eppep77pp1pp1pffppp7pp7p777p11ppp87pfmm77p7ffm117ff7m17ff77m771mff77fmmffmffmmfmmfmm33m3m3mm22p77ppe7pepepp77p77ppeepee77pp77eppep78pfppeppeppe7ppeeppeeppeeppeeppeppeppeppepeeppeeppeppeppeppeppeeppe77ppppeppeep77pp7pp77ppfpp11ppff77p7fp7ffppppp7mff7ff7ff7ffmmffmmffmffmmfmmfmfmm3fmm2mm11p77pp7pp7ppm7ppp77pp77pf8epp77peepp7pp87ppepp7p6ppepeeppepp77ppeepp7ppeepp78pp7pp7ep7pp1pp7pp7pp77pp7ep77p77ppff7pef7ffpf77f77ppfffmff7ffmff117f71mm71ffmm337ffmmfmm3mm33m33227pp77ep1ppe77ppepp77p77ppeeppepp77ppeeppeppeppeeppeppeeppeeppe77epp6eeppeeppepp77ppeppeppee7eeppeeppepeppepp77ppeepp77pp77p77p7pffpp7…fff7ffp7pmmmf7fffmmffffff7mmffmmfmffmmffmm33pp77ep7pp77pp78eppepp7pp77pp7p77ppeppeepppeppepp4ppepp7eeppe4ppeppeppepp77ppeppeppeppeepp77ppep7pp7ppfpp77peff7e77ff711pp77ppf7ff117mffmm11ff7ff7fm7mm77f7f17fmffmm7mmfmffmm33mm32m2m33p77ppepp77ppeppepp7eeppepp7eppeppeeppeppeppeeppeep7peeppeeppeepp4ppeppeppeppepp8pp7ppeepeepeppepp77ppeepp7eppp77pp77ppeppffppp7ff1ffp77ppff77ff7p77f7ppf71ff7ff77ffm7ffmf7mffmmffmmffmff7fmmffmm3pp7pppeppee77pp7eppepeppeppeppeeppepepp7eeppeppeppeppeppeppeepepp77ppeppe7pp17eppeppepp77epeppp7pmpp77pp8ff7717ppfp7177fp17f77p7pff77ffmmfmm7711mffm7ffmffm7mmffmmfmmffmmffmm233nn3ppeppefppfeepeepp7ppeppepeeppeppeepeppepp6ppepppe44ppeepepeppeppeepeeppeeppeppeppeeppeeppeppeppeepp77ppeeppeeppepp7fppeffpp7epp7fpefm7pffp77pp7p77pp17ff7ff7ff7fm7f7mmf7ff7mm7ff1mffmmfmmfmm3f3mmp77pp7p77ee8epp78eppe77pp4ppeppeppeppeppee7peppeppeppeppepp6eppeeppeepepp6ppeppe6eppeppee7ppeppeppepp7pp77ppepp77pp1pp77pp7fp7f7ff7711p77fp77fmm77177mmf7fm7fmffmm1mffmm711mmffmm77ppeeppeepp8peeppeppeppeppeeppeeppeppeeppeeppee77ppee66ee77eppeeppe6peppepe7eepeppeppeppeepeppeeppeepeeppeeppeppeppeeppepp77pp77ppepp77ep77pp77pp77ppefp8pp7pp1fmpff7pmmffpf77ffmffmmfpmmffmmffmmfmmffmm33pp77pp78pp4ppeeppeep77ppeppepp4eeppepp4eeppeepp4p77ppee6ppepp6pep4ppeppepeppeeppepeeppeepp7pp77ppepp77p7pp7ppeppfpp7p7pp77p77ppp7pep17f71pp7pffffm7717mf7ff7mfmmp7ffmm711mffm7ffmmfmmfmm3mm22mpp77pe77pp77eppe7ep77ppeppeepep7ppe88ee77peeppeppeppeppeeppeppeppepepeeppee6peppepeepppp7ppeppeppeeppepeppeep77ppeepp77pp77pppffp1ppff8pp8f7pppff77fmfppffm77fmmfmmf7fmffmffmfmmpmmffmmffm7ffm33pp77ppeppeppe8877pp7eeppepp8ep7eeppeppe4peppeppepeeppepp6eepp4ppeepp4peppe6ppeeppepp44ppeppeeppeeppeppeeppeppeeppeppeppeppepp7ppeepp7ppp771pp11ppff77epmp1177p77pp1mp777p7mffm11ppmf7ff7pmmf7ffm1fmffmm11fmmfmmffmmfmmfmmpep77eepeeppeppeeppeeppe4pppeppeeppeeppeepp4pee4ppeeppeeppeeppep7eeppeeppeppeeppeppeepppeppeppeeppeepepppeeppppeeppeeppeffpepp8pp77ppfppefppp77ppfpfpfp77pf7ff7pp77fpmfpmm1fmmffmmffmmfmmffmmfmffmmppepp77eepp77eppeppeppeppeppepeppepp4peppepp44pp4eppeppee4ppeeppeppeppeepeeppe4ppepeppeppeeppeppeppeepeeppepeppeppeppeppeppepp7pp77pp7pp77pp77pp77ff7117ppm771fmff7p77ffmffff77f77ffmmffmm7mmfmmfmffmm33eeepp7epp88ppeppepeppeppeppeppeppeppeepp6ppeeppeppeeppeeppeppeep6ppeeppeppeeppepeepeeppeeppppeeppeeppeppeppeeppepeeppeepeppeeppeeppeepppeppep78ppeppefppppm77ff8mpp1ff71mfffpf7ffm1pf71mmfmmffmff8ffmffmmffmmffmmeeppe7pepeeppeeppeppeppeppepp66ppe4peepeeppeppeppeeppepp44epp4peeppeppe6p44ppeepppeeppepeppeeppeppeppeeppepepeppeppepp7ppeppepp7pp71ppf7epppppppffpp7mmppe77p11pp7pp7fpf117ff7m1771fffmm11fmmffmffmm3mmppepp4ppepp4eeppeeppeeppeppeppe4ppeeppeppeppeppeop46eep66ppopepeeppeepp6p6eeepeeppeppeeeeppppeppeppeppeeppeeppeppeeppeppeppepeppepeeppeepp77pppepppffppfpf8fp…pp77peffepp8ffp7pfep77pffpmp77fmfp7ffmmffmfffmmffmmfpepp7ppeeppeppeeppeppeeppe6pp4eeppep4ppe6peeppeppeeppeppepp4ppeppeppeppeppeppe4pepp6ppep6ppeppeppepeeppeppepeeppeepepp77ppppffppeepppp77e77ppepp8epp7pp7eppepf7pp7ffpf77pfpfpf7ff7ff7ff11mmfmmf771ffmmfmmfmmfmmfppeppeppeppeeppeeppeeppeeppeppeppeepeeppe6eeeeppeppeeppoppeppepp4ppee4ep4ppeeppeeppee6peppeeppeppeeppeeoeeppeppeeppepeeppppeppeppepp88ppep7fpp77pp7ff7pp77f7eppfp1ff7ffp8ff7ffffmffmmffmffmmfepeppeepeeppeepeepeeppeepeppeppepep4ppee4peeppeppepp6pp64eep464peepp4pp6pp4eep4eeeppeepeepeeppeeppeppeeppeppeeppeppeppeeppepp7ppepeeppeeppeep7pppp7pp77pp7pp1ppffppep711p77ppff77fm1pffmffpfpm77mffp7mmfmmff7ffmmfmm2mmffmmfmeeppeppeepeeppeppeppeppeppeppeepp6eepeppee66eepeppeeppeeppep6eeppe4peppep6eppeppeeppeppeppeppeepeppppeeppeeppepepp7eppeepp8eppfefpp7pp77pp77pp7p77mpp7ffp77ppffff7ffpffmf7mmf11ffmfmmfeppeppe4ppepeeppepp46ppeepp6ppeeppeppeppe6eeppe6ppeppeep4o44ppee64ppeeppp46ppeepp6eeppep6peeppeppppepp66eeppeppe4ee4ppeppep6ppeeppeepppp77ppfp7ep7777f1mfp77p77p77p77ff7fpp7mm7ff7p7mm8ff1mff7m1mfmmffmffmmffeeppeeppeeppeeppeppeeppeepeeppeeppee6eeppeeepp4eppepeep4eep4ppepp4eeeeppeeepe6eeooppeppeeeoppeeeppeppeeppeeppeppeeppeeppeeppppeppeppeeppeeppeppe77ppeppÅ7ffp8f777p17…m7ffppmf…mf7mffff7fmmf7mffmmffmmffmpp44eppeppeppeppeepeppee6peeppeeppeppeppee6p6eppeepee664ppee44pp664pp6ee4peeppeeppee66pepp4pepppp4ppeeppeepeeppeeppeepeeppppeppeppeppepppp77ppp7pppp77pp8ppff7ppffmf7777mff771mmfm7pp1mm7mffmffmf7ff7mmfmmffmmppeepp4eepeeppeepeepeep66eeppee6eppepp46eeppeeppeeeppee6e6eepe6pp6ppeeppeppepeepeeee66eeeeeppeepeep6ppee4ppeeppepeeppeeppeeppeppeeppepeppeeppppepp7ppp77pp77fpp71771p7fff1771ffpmmmfmm1ff8mffpeepeepeeppeppeeppeeppepp46p78e44epeepp6eppeppepe4pee6eppppepp466ope44ee66e6446e66popp6ep46ppeoeep4pp66eeoeepopppeeppe4eeppeeppeepp6eeppeppepeeppeppepp7pppeppppeeppepppepp77ppfpp17pp7pff177fppff77ff77mffm77pmm7mmfff1mffmmffm7ffmmf6epp4eeppeppee6ppeeppeepp6eppeepp446eppee6eep66eppepp4oppe6eppoepep6peeeep6466oppeoeeeoppee6oeĄpepeeppeeppeppeoeepeeeepeppeeppeepppepp4ppeeppppeeppepp7ppppeepp77p77p77pp7fmmffffpp77fmf7ff7fmmfffmm7ffeep44ppeeppeppepp6pp6ppeppeeppee66p66p4pp66ppee6ep4pe6e6ee4ppp6oo6o6p64pee66e6ppoepeooep4oeepe66ee66pp4p4e6eeppeeppeppeeeppeppepeppeeppeppeeppepp7p7pp77p7pp7p7fpf77p77p17pp7pfppmmfmmf77fmmfm1mff7fmffmmffeeppee4eepp6eppeepeppepp66eeopepppeepeo66opp644peoo4eoeee66pp66poeeppoeeooeo44pp6ee6epooo66ee6eppeepeepppepppeeppeeppeppeppeeppeepeppeeppeepeppeeppeepp8ppep788p87pppfppf7fff77pff777pp787f1mp7ff1ffmmf77eeppeeppeppeeppeeppepp4eppepp64peeppee6eppe6e4o44eeppep6pp66eeppeoo6eeooeoo6ep6eeppeo4eopee6e6eopo66o6eep4peepp66oppe4ppeppeppe4eepp6eepeepeeppeeppeepp7ppepp77pp7pppp77ppf77p7ffppffpf771ffppff771ffpffmmff1f7117mff1mmffeep6ppepp64eeeepp6eeop6epeeoppeeppoeeo4epppe66e66oeeeee644oeep66epooeeog6ee6e64ooppoeee466oee6ppooeeeeo6epeppo6epoppeepppeeppepeeppeppeppeeppeeppeeppeepeppeppepp77ppppp77epp7fppff77f7pp7pf7ffÅ7fpff7mfpffmmffp7ffmmfpp4ep4p6e7ppeeppep4epp446pep4ppppe64pp4ee6e6444e6ppe64eeeepp66epp6e6444oep6oe6oooeo6oppoogoo66oo66oo66o66p4o6oeoppeepp4eepe4eep4eepppffppeeppeepp7pp7ppeppffp78ppppmmppfp77pp7ppp7pff771mffmm177ff7mffmffmffmmee=6ee6eep4ppee4epeeoepeepeppe6p6eepe44epe6eeoeeepoee6ep644oo44opeeo4eo4oepeeooooe6ooooooogooooogoooooĄ6oppeoppopoepeeppff8=!!=ffeppeppeepeeppeppepeppep7ppeppepp77pppp17ff7pp7fp77ff7pppffffp1mff7ffpmfm7ff77ppeppeepeepp6ee6ppee44pepeepp46ee46eeppeeooppe446eeppo66ee6p66o4p66oooo646pooo6oooogooggqoo6oo4oogeeo6oo6e6p4eeeppepep1!&LO'OO%A=ffpeppepeepp8p47ppepppp7pp77ppe77pp77ppe71p77877fm7fmp78ff7ff7mmff1711ffmmf6p4ee644ee4eeppeeppeppepeeppee6e6ee6ppoee6epoe6e6oÄeo66eeoooee66eeeo6ooee=oggooogqFD&%RSTVVZXX\YY\\}XXXZZW{TQPRRMMNIJF$@@E@Ahqqo4#Q|yÚKKK#g77ppeeppepepepp7pp7pp1pp7pp1pp77pppffpf1ppfppfff7ff7ffp7ffmff778f7ffpffee644eppee6eppe6opp4pee6eepp6eep44eepe66ee46466eeooooooeoo6e8eppe6ooqggooqq;;9rBA@#&MP'VZZX\\[[]]^^]][[\Y\Y\XZWVTPPOSMN&IJFEthh!$T|ǠÚKž%A8pppeepppp6ppeepp77p7pp7pp77e7f7ppf77p77mm7pfpp7m11ff77ffp1mf11m1mmffmffp7mm7mf717ffmmf4pp6eepeepp6eepeepp6eeeoee6pee6o664646p4oo44ooee66!A!8feoogqqggqqq;ts?E#J&PTZX\]]^^a^^aa^^^[[\YY}WWVT''QPPSRw&JFF$EP{ĜšxxL!eeppeeppeepppeppeppppfppp7epp7pp7p77pp7ffpp8fp78pffpff87ff7ffmmffmmffmfmffeeppeppe6peepeppee4ee4eepp466oeepp6o44oo46eep4466op6RAffooqq:;;qqA?C&%RTVX]aaaaa__a__aaa^^^^[[YYWWUQRMKN&TV|ȚƚxL=7peppeppee4pep77ppeppppp77pp77pp77p11pf77f77f77fm7fmf7ffm171ffmm7ffmf7mffmm7mmf17mf7fmmfeeppeeppee66ee6pp664eeo6oe6o46eoopp6eeop6opoppo44oe8#}|#8m6ogoqq:AtArrAA@EIRPVZX]]aa__b____b__a^^^[[\YYYXXVU||zy{|ǠÛÝxxKww%eppppepeppeppppeeppppeepeeppep77p77ppp77pp…f77ffpmpfp1mf7pffmffmffmff77ffeepp6ee6ppepe6ppeppe66pp6pepeeppee6pe44eep6o64poo66oop"R{{WUI!f8gg<?F&RPTZY[^_bb```bb``bb____^a^^^^[[[[YYW||U{ȳĚxxĞLJgeppeepp1ppepppp7pppp77pp7pp77pp77p78pp7pff77fpff7p77ff777ffmmff77pffm7ffmff7ffmffmmfoeppep46eppee6eeoeeppe=eepeeep46e6oop6oo„e66oee'~{{Qyv;gh@EJI%OTZX\)+a__b```c````b_____^_[[[^[[Y~{{yǶĴ ÝȝȚKKŸMheepeeppeppeppepeppepp78pp8pp7eepp7ppp…p7ffpp77pp77ff7ffffffmf77ff7ffff77ffmf7feeppeppeeppeeppee4466pe6ee6eeo4eoep4o66oo6666oo66=X~~{{xAEIMOTVX\]abbc``c``c``c``__`_b____^^[[[^}W{{| ´ÝžwwLE6p64pp4ppeppeppeeppeppfepp7p77pp7ppp77pff7p117p77ff7pp77p77fmmff7mmffp7ffmmffmmfmffmmfe4pee66ppee6eeppeooepe4p66peep6oee66o6ooeo66ooo6!R}}~~{{äLJRT\^__``c`ccdc`cc`cc``c``b__``__^__^[[į~W|{{|ęÚƞwgo6eep4ppeppeppeeppppffpp7f77ffpppff77ffpfmf7pf77f77ff7ffpffffpffpf7peepeppeppep4466ep4ppe66peepp6ppe4466oepo6666p66ogoo46Y}~QzPVXaa__bcc cd ddccdd``ddc``__``__^^[[[~||~{ǠĴܚȠwÞwL!ee6pppp7ppeppeppeppepp8fpp7fpp77p11ffpffpp17f77ff77f7p17fmm1711771mmff7ffmf7mmeeppeppe66e6e6pp66eeoee66pepp46ee66oo66oeoogo"%\}}~~{|O~_bcc d dd dd dcc``dcc``__`__``___[[~~~{ÝȠ žwwI;66pp46peeppppeepp7pp1pp77ppffff77fppmff77p7mmffp7f7f77ff7ffee6pe6eeppe44ee446pp644ppee66oo6p466ppo66oopoo6VY}}}~{Ť_c`cc ccdd ccd ,,dd ccd```____``____`^^[Y}~~}{{~{˳Ŵ wȠȚwI;eooeppe88pp7pppp77pp7pp77177pp7p11pp77p7mfpp711ff77f717ffff7mmf7p77ff7ffmffmmfe6eppeeoe6ee4ee6p6ppe6ee66ooppoo6ooo6oogoo6#X}}~~zz^cd dd cdd `d,,dd` dc``bb__`_^__^^__`^^[[~~X~{ii~{|̴öȠÞ wwvAggopeepepppepp77pp7pp7fpeppepp77ppp77f7pp77f7ffpmm7f77pffp771m1mffmm7mme66ppeoe446ppee6ppe6ee66oo44pe64466466446o6oooooo==AS\\}}{{yW^`cc`ddccd`cdd,ddcddc``__``__^^^__[ï}}XXY~{{~{Ƕ˴àw xwwx@!r;;q564eppepp77pp77ppË77e77p71p77ppp7fm711ff77ff7ff77ff77pmmfmm76646e44e6eep6ooee6e6ooeoo6oo66oooe6ooooogo55o;?FIOY}}}}]^[Y[^^^___``_`__```b````d`dc_ba\]]X~~y̶özzOKGJE@;q@EMPUYŀ}§~è}}^^[®__`````dcc``ccbba]]\~~|¥̶ƴȵáyyzOߟLLDu@A;<;qEF&R'Z(a_`_Y~}}€}}}}§}~~}Y}\aa__b,`cc`d``b````_``cd`bb__ `__b^__a]]~U|| ȞȝijàǡßĞKKGHFE9qqrqoee66eepppp11pp7ppepp77epp77pp77p7787p77f7fpp77ep711f11pff77ffmm7mmffm1f71ff66o66oeoog66ooee6oo64oo64ogoooCIRV^cc _Y}}ɬɦ}\]]]_bb_`dd,,d,``,d`ccc_bb``b__bb__[]YYY~X{|zȝĴ±™ ڟzğKKKGHDCs9;9:goo4ppepppp87ppf7pp711pp77p77ppf7pp7ff77ff7f77fm77f1p77eeoo6oo664466oogee66oo6ogooqqr9t>sF&RVX]a`cc cc cc_~ÀY}}~~~}j}}j\]]b__``bbcc,d c dc`dccc``‚bc____^^]][[}}{UU|UU||UQzPPLxH ę™ ȞǟȞşžžGGGGGC>9;qIRTXaa``c cc , Y~YY€~~X}\j}}\]+abb`cbcc`,,dcc``cc`bcbb__`b_a^^[[Y~W{U|U||QQ|UxKxH— ÞȟKGGÛDus9qoo6eppeppeppepppp7pp77p7117pp77f77771p7mf77f77ff1m7ooeo66ooee44oo66oo<55<<55&'Zcc cc ,,_XYY}}Ħ~~}}\\+abcc,c,,dcc`c``c`cbb__a^[€}{UUU|V|yyQQLOzwMxv • ÝȞȞğßLKÚÛH?>rqoeepeppeppeepeeppeppppeepp7pp77p77pep7eff77pfpp7pf778f77ff7877ff6644o6oo646og644o6o66ggo<;@E&P(bb _}€}}~~~~X}\)aaccc cbcc ,cc`b``bbb__^^][[Y{UUQ|UyQQyQzOzwxۖ  ›ÚÞǞޟޟܖĖܖ rq5oo66pp6ee4ppeppepp7pp77ppepp8778p77pp77pp7ef7fm77pp11p177o6o66o66oo466o66oo6oogqq:9A>uJNPV()cc c ,~}€}­~~§X~}\]abb c`cc,`cc`c,c`cc,``bbc`c``cbb__^^[\~QQyQ|yOOyQQzzywLvHH   ŚȞÞÛ– ۗstrqo66ppeeppeppppp77pp7pp7p77pp7p77fm177f711771ff7fmm7o66ooe66o66o=4oo66oo6ooggqq;A@&P(]abc cc , }€}¬~~}\]b,,bbc c``c,c``c`cb``c`c`_`___^^YWW{QU{yyQQyzOzLOyGD  – Ú˚ܖ ۗ?tr<L'W\]abbc ccccc d`[}}}ì~~\]**bccbb ccbc, `c``c`b__aY{U|Uy|yQzzwOzGxvGxHDu  šƚݚG— C>rqtqggooeeppepepp7epp77pp8eppep7ffpffpf8p7pp77pp77pfff7f7feff77oo66oo6oo46oo66o6o6oog<<:A$OVaaa*b ccbb`ccaX~Y}Y~~ɦ~X]ababccbb_`cb_bcbbcc` ``cb`_ba[Y}UQyyyUQzLLxxxvKLwvHHD×   GGC>>;q9;qoop6778ppe7pp77pp7ppp77p77ppffpp77p177p77pff77pff7pp77ffm7goo66o66oo66oog66oOX]*c``cb_bbbccb§§{~\]kbbaabbab_aabcc`ccbbaa^]Y}}~{QyLQUQwKKwšxxGGvHHHHDu •   ܖ — ڗÔ9;q5ooppeppeppeppepp4eeppepepp7e77pp77p7pf7pp7711f7p7pe7ff7f78ff7p77p117746o44oo6oo5oo5qq;rr99tt>?R]abccca_bccbbba\{{©~\Y\]+*bb*aabbaab` c` cc`c__aa[}}W{|yQyxOwwxxvvxKKHHHvHHDu ٕ Ĕė  ڔ >9:$F&'(]+**bcc ccbbaabcc`b__bbaY~§X\]ka**bbaa]]aab , ``c`bbca^^a^][}~|Qww˜›vxGvHHKvvHHCsڔ? ė Ĕ >9:5go6eeppeppeppeepeeppeepp7p7pp77pp77p7ffp7877p7788p77pe77pffpf7oo6o6o66oo664oooo6oo5trqgoo66eepp7ppepp4ppe77pp77pp71pp177p1ff77f7717p77p77fp177877g6oo6o66oo6o66oogogoo5q;;#%'Z\]+aaccccc^^abcba]]^^[Y~XX\)+aa]]}{Ŵ{\+*abb_aa^^ab^[]]\}~WQOOxKxt ʾ—HGDD?•tǕ?  ڔ > ٕ>r:tؑؑ Ƒ • Ĕ Õ ‘ ؑqooppeppeeppepp7eppeppeppep7pp87p77p7pp7p7pp77ppf7p7ff66oo6oogoog >gooeppeepeppeeppeppeppeppepp77pp77pff7p77p77p7p7pp…epp7p77p7pppoooo66o6e6oggoo55đ‘ב •‘đ Õđ >rqoopee66oo64o644644o64ppe4peepp177p77ppe7p7fp77p77pp771f77pff76oo66oog6ooooo5gqq:r99ts?CHLTZ(a**bcc ccbbbb_^]\\[\}XX\](\][]+};ͰͱZ\[]]aabaa]][]Y}}X{{W{|ysDDHHCCC”Ñ999r‘ ٕؑ Õ>99r:55<5r‘ؕƑٔڔ • Õ?>rr;ؑt‘ؑב ”? ?>>>99‘>Õ> Õגq‘99Ñב ڗۗ ?>‘ בגؑ9ב>Ɣss Ĕ? ґr:qooppeppeppe7epee7ppe77ppepeepp7pp7p7p77ee8pp777epe77pp77f7ffo6644o66oo6oo=66oo>ڗDDڔ ’ב’9:qooeeppepeppeppeppeppepp7pp77177117pp77pp77p77p77177ff17pp77ogoo6oogooooqr:;::r;rr>>L'X\)aa***cbb**bb_a]][YXZZX\\XX\]]X|Y\\]]]aa]\\][YY}X~{{|ywxKwxxxKKxKwxHDDD?>>??Òב ٔCt99’ ’’ؑ9:5o66ppe6ppeeppeppeepeppeeppeep77pp787peepeppeppepp7pp77p78ffp77f77pf8oo66go4oog5qq;rh9>?E%PV\\))]]+aab*ccbbbb__bbb__baa]\ZZ(\XX\\}}Y\\[[\\[]]aa^aa]]\\[Y}}WW~UVUyzzzxxvxwKxxKKwxGGHHD?‘>???t בבÔC??Ô?> ֍ ג :r:5oppeeppeeppepp17pp77p7ep877pfp77p7pp7f7p77p77oo6oo6ooooqqsD%P\]]aa**bbbb**b*bbba^[ZZ\\XX}}Y\]]\\)]]a]+]]\\}~~{{W{{|yOKGxvĚxvvxxNuÔ??ڗDDH?st9ǒג ٔC×C?9č ֍ 9:5o44ppepeepp6eppeepeeppeepeppepeppepee77pp77pp77ee1pp7ppf7pp7p77oo66o466ooog<>&RTX([))]aa**bbaa^]]^]]^a*b**baab_a+[\\ZVZ(()a\~~XYY]]\(\\][]]^^]]YY\}~W{{UQPwxxKwGHHvGGvvHDDHHܖJDss>r: Ò ?CDD—ÔגŽƍ 9qo6446eppeepp4ppeeppeepepp7ppe77p7p7p77pp7p7p771177p778ppfoo66go66oo<5ELTVX(\\)]]aa**a*aa+]]a]aa^]]YZZ((\+]\~~X\\]]\\]\\]]a]]}}ZWW{{||yOxxvHGvHHvvHHHHHH—”CC‘>9 99ב>??×u??s :5 Í 9qoo6pp4epeppepeppeppee7ppepp7p7pfpp7pp7pepp7pp77pp7787p7poo66oo6oo55q<99ؑÒ>?C????>t955Î Ē:qoo446epeeppe8eepp88ffeeppfp7ppep77ppepp77p77f77p7717p77e717866oo6ooogg<5 999ؕ•s?????ٕ>>ג֍Ž5֒ ֍: 9r:qq5ooee6eppeppeeppeeppeeppeppeppe77pepeepp78pp7pe7pep77peep77e7p77pp7o6oooo<;9?LTVX(\\)]]++a++aab*aa^]])\\XX~{VVXX(\\)\XX\\}Y\\]]][}}~WW{i||yzKKLOKJHHHHGIHD—uՑ>>99’r Ñؕ??s>>???”?555֒::֍::55oopp6eppeppeeppeepeepp77ppeepp77pee77pp77p7711mfepp7p7177p7pogoogg6oo<5<?D&PTZX\\]]++**bb*aaa[]\\YXZVVZZX\\X\\}}XX}\][]]\j~~{{{{|yy|zzzyyIHHGvHDCC??•>>ő9Œ9>>>?ڔC???ؑג55:֒9֒ ’:goo44e6ppeppeppeepp77pep7eeppeppeepp77pffp77ppee77pp7ffp77pp77oooogooC&R'ZXX(\\]]++**bb_aaaaa]]YYXZWVVZZXX~ZZX\Àj}{Z{{|yywȞywwwvHHGH—DDCÕؑؑ9Ò99‘>?s>>??•> 9 : ֍q :??????•>:oÎ55’5oo44eepp4ppeeppeeppepeeppepp7ppeppeeppeepp77ppfppeppp7p7ppoo6oo6ggoo<%PVZX(\\))]]+aa++aaa+]]\\Y(XZV||VZZXX~~Z{|{~~}}X~||yyyHHHHCCCu?•>>99Ē9tÑ>>>>•ٕٕؑ9֍4555֍֍ooep46epeepeppeppepp77pp77pp77ppeepp7pp7fpp77p7pp77ppp7pp78oo66go56oo5oogoo<>9999:qƎ55ooeppeppeeppeeppe78eppeppee77eppep7pp7pe8877pp7877poo66oooogoogg<;q;A&OTZX\)]]++aa++][[]]\\YZVTTVZXZWWZZ~~|i~{~~{ģx šxxGD?ĕ> > ٔCCCCDCCCC??>>Õ?>>:5544Ԏ5o4Ž55o46o44pp46pep6ppeppeppeepp77ep787e77p77p77pp77p77p77p77ffpoogoogooggoo>>>Ñ5Ž4Žo44o5ooo6oee6pp6p7ppeppeeppeppeppe77peppepeppeepp7eppe77pp7p78pp7pp7pp77pp77p> >>?ssCC?> 5544oo66p4peppeppeeppepp87ppeppepe77pp4pp77ppe8pp77e77pp77ff77pogoogoogoog>>>tt>>•sss??>A:55Ž66pp4ee6ppeepp4peppeppepp7pp7pp87ppffpp77p7ppppeppmfpp77po5oogoogooggqq;;>C&PTXX(\]])\((\\))]][))\\(\\}XXZZVPPQTVVZZ{{Zi||ģijxwxqqב99rrr9:::::99>>ؑ>>>•>r999::qÒ:544Ž4peppep6ppepeppeppeeppeepeeppepp77pp77p77pp77pp7877pp7717pp7pff77oo66oo55oo6oo5<>9גr99Ñtđt>>>>>t>>>9qpp:qq’5444opp66eppeppeeppeeppee7epeppeppepepe7pffpfppeep771pff7pp77pp7fppeppgg>@$>>@>>>>‘9‘99‘>>‘>tג44:::oŽpeeppeepeppeeppeepeepp7pepeepp8pp7pp77pp77pp77pp77pp77;rr:;::;<;q;;ENOTVVZX((\\])]][\\YXXXX\\XVVTzRRPTV{{||·µö™ÜDC?’Ēr:qqÒr9t>•ss??>>99Ñ>>t9:ב:<qq::q54ԋՋpeppee6eeppeppepp6ee46eepeeppeppeppeppee7pp77ppe87fep77epp77pe8fpp7tt99AA9ArrAA>tA9;qggoog<??>999999rё>>>>>>ȑt9:֍ō֒::54Žppeeppeeppeppepp77pp77ppeppee877p77pp7177p77p7fft>•>>>s?ssEE@@troo5gg<;A>t>$%OTVZZXX(\)])])[\\YX}XXXXXZZZZViTPzOyTTU|UV{| DCrĒ;r>>s?u?•>99>‘t>>ٕؑ9ؑ9::55o5’;q412Վoo6epp4epeppeepp7eepeppeeppeppeppeeppeppeepp7pp7eppep7717pp7pp7pfp77 ??uuCDDCusoo<;A9rrA>F&L'TZX\\)])\Y\\XX~ZZZZVi|TTQPPzzPT||i{|yµƳű´—uuDD?ؑ9’::r’9>>Õt>>>>99>>>>tt9r::5554455::54p22pp44oo44eeppeep4pp6epeepp6eppee77pp77p77pp7p7pp8p7epp777p77p CCCڗDDHHJDutq:rrq<>>99rƒÑt>>Ñ>>ٕ>99>>99tt>>9r:5555::qo2Ջp4eeppooeeppeppeepeeppeppeppeppeppeppeppeppepp7pe87pee7p77p18e77p CDDHGGvvCr>9’בƑ9>9t>>ؑ>>>9t9ג ֍55q:::5424ppeppep66o=6ppeeppeppeppeppep7pp778eepp7e77pp1877pp7pp877fee77p CĖHHGNNvHsqoogoqr9>@FI%R'TZZX((\\Y\YXZZWVTTVVWZZZWVWZZVZZVTOOPPT||yř uuٕ>t>>9>rđ99r’r99>>99>>>t>>99>9:q:5:::54221ppeppee664peeppeepeppeeppe88epp88ee77pp88ppeeppepeppepp88p77pp77pf7ppۖDDHGGKKxvHDuqoogg?DIMPTVVZZXX(\((\\XXZV|UVZZWVVUVVZVVTyPPRzQTTyźtt ”>>>>ؑ99tؑrrt>ؑ99‘9rr::’9t>ؑ99>‘99:rr;::q::1227ppppeppeeppeepp66o6ee7ppep7eepp7ppepp77pp77ppfp7f7pp77pp77p88>?CDDHHGN%KKxvHF9qggogg<EJNRPTVVZXXXXXXZVTUZXZZVVVVUUVVWWVV|TTQzRzPPyyűŲ± ttu>>9r9đrt>>Ñ9r999rĒ99rt99‘>@999rrג:::<412Ċppeepeppeepeeppee66oeep77peepe78ee8ppeeppeppeppp88ff77pp77ep779?CDDHHGGK%MKKGHDCtog<9׿99r99ttÑؑ9999::999>>t99>>>999::ג42ӊ2ppeeppepeepeppeppeepeepp877eppeppe88p77ee77p7pp7ppe77ppff1787p78>?CDJHH&GGKKMLLGCroogqggoo55q;r>?JNMP'VZZXX\\UVZZZZWVVVVUUTTPPTVVTTPPRMMRPzzwx; ttsÕs>9r>>‘tr99rrA>>ؑr99Œ99A>>99>?>>99Òqo1Ɗ2ppeppeeppepeeppeppeepeepeeppeepep7ppeppeeppepp77ppeepp77ppfp77pfpfCDHH&HGKKMMLLMwKs>‘>@>ؑ999Ò9’9t>‘rÒ999A>>99>>t99r:1ŠÊՋppepp6eeppeepeppeppeepeepp7peepp7ppe7peep77epp7p77pp77pp7fp7877p77 HHI&G%KKLLHggooggqq;rA>E%R'TZZ{VZ(XZWWZZVVTTyOPQTTQPTTPQTTzMMLNNxx tƑrt@?s>>>s9r’ 9גrt>:q9rr9999>>>99tA9>9t99r:<1nÊЊЊ2peppeeppeeppeppeepeeppeppeppeepp7pppp77pe7ff7pÛGGKKMLLxH 6eooqq;rt?NMPTUZZVVZXZZVV|TQTTPPTQOOPP'PP'TTzLP'wxxvvIHHs tttrrÑ??•>>99ג: r99999Ò999t>>9t>>tؑt99A9999EFNRPTTVVZXXZZVVTV|TP''QPPQQTQPROPQPPTTRR'TPMLMNGvHHHDDDss s•ttt>s>>s??s>>99::Òrr:99Ò9999tttt99tttt999:54Њpeppeepeepeeppeeppeppepp8ppepeep77pp77pp88e77p7ff7pp77peep77ešLLK֋216oo<>s>>s??ٕ>>>t9 ֒:::rr999999tÑt99rrr:5124ppeeppeepepeepeepp8eppee88eppepppe77pp77ep787pp7f8877pp77p7p77 GGNNH23poo5?CJ&MOPP'VVZZZZVVU|TQQPP'PPRRPOzRPPTPPTQPzPOzRRMNNHDuus”s•‘’?>>s?•??>>t9גr:::rÒ99tA99A999r:5pӊÊÊe4ppeeppepeepeepepeepeepeeppeppeepee88ppe7ppeeppee77e8e77peppepp887p78e78p77p::>>:2n3mpp77133m11769>$FINMROPTTVVV|QQyOOPPOORRLRROOPPOP'T'PyPRRLMNNvIDC?ss?u??‘>>?>?•???>>>t9:::r:::99r9999992»6ppeppeepeepeppeppeppepp77eppeeppe77pp7ppepp7pp8778pe77p77p77pp77////..00Ј..000.003234"A$J&&%ROOPP'TTVV|TQPOOPOORMMwRRPPQPPQyPzzRMKxGIIHDDÔCCuC??@@????sssٕs??ٕ>s>ؑ99ג::r9rrÒ99rr9rr99Ñ9t>ؑ9;620ˆeepp4ppeepeepeppeeppe88ppeppeppeeppeepeep77p77ppeppe88ppfpeepp---/////.//.0037!EJ&NN%MMROPPQTQQTTQOOzRROOLMLRRMMRPTSSQPSRSRRMKNvIvHJDCFCCuCCڔ??ŕ ???ss>>ٕss>??•>>99::99Ēr9r99ג:55 ב>>t9:qpȈppeepeppeppeeppeeppeeppepp7peepp7pp7ppep77epee77eep7787pp77117-//.017"ECC#D&N%LLROPPORRPOzRwwRRLLRRMMRPPRRPRRMMxNvINHJDCCu??ƕ???>>s??ss??s>>9999rr9r9;;9:9rr9:2mtÕtt995pnȈeeppee6peepepp6ppeppeeppeeppeppeeppepp87e87ppeppeppep77pep77epp87ppeepp..É.щΉ//////.004;;!9$JIGG%MRMKKMRLRMMLLMMNNLLRMMRRMMNGGNHDD—Cuus?s>>ٕ???>>s>$>>9999rr999r99ג:5420 tsÕ>1»ppeppeeppeepee6epeeppeppeeppeppeppepepe87fe77887ee7pep77p77f7pp77.....0..00.......00001447n27"9A$NNIIvxMMKKMKMLLMMNMLLwMMRLLMKMMRMNNxNNHDDCCu?s>s>>sssÕ?s?ƕs>>9‘99t99:. Õt942ӈ2177p7ppeppepeeppeppeepeeppeeppeepeppeeppeppeppe77eeppep88e88epp877pep88///////../...00.00023m2002237<;9@EDDCDHIIG%MKKMMKNNMMKNRMMKKLLKKMxNNvHDHHDDFCCFu??>>sĕ>s>>Õ>>>>>ttt99999rr:4100l//ш t•t1--ъ002nn233m223m33mff117ff77pp7ppep7ppepp78e78epp877ppep77877p8pp77e/////....000..0023376:ttFDDJHGNMNxxN&NxKMNMRMMLMMRMMxNNHDHJJDDCCDu??ٕ>>s??>>•s>>•>>>>99r<5445pmҊ./ ‘o4/-Ή///..0002nn2n33m332mfmffmm7177p7f7f8ppe8epp77p7p/////..//.//00Њ2pqts>?EFDHINNGGNNKNNMRMMNMLMMNGGvHHDDCuCCuss>>>•>>>>>>tt>995566422n0../‰ΈÑq52/Ή/-------//.....00n3nn233mmf/////.//...nprt9qqrts@@IvIHIINNvNMRMMNNIHHDDJFCuu??ssĕ>>>>ttג:55pp412000000..ш--////----////...//////Ή////..5r735:q77!JJHINNINNMMxKNMMNNvHIHHDDFCu?Cus>>>>‘t99:54720/.///... rrqq 2--/./‰////-----//////////06qo04m."A?EFJII&&NMMKK%MxN%NNIIHHJDDFCu?Cu?s•s>>>>9:54pm00...///‰/// rq q o/---////////щ///////----////////.15p.04014A$FJIINNGGNvIIHHJDDCC?uss>>>>9:430./..Ή////// q -////////////ll///////////--/////////////.12.0p//027"9@EJHIINNGIINvIIHHJDDFC?EE?>>ttÑr::::5420.//.///l////n Óqqo/--//////////Ή.//./////////.0.03n.00001";$FJIHII&IIHIIHIIHHJJDDFC??s>>t‘tr:o10ӈ//////////.//Ή“q/////////////////////....0/.00..024EJJHHIHHIIHIJJDFFu??>>99p2ӈÉ///////мq///////////Ή///.щ...0.01$DDJJHIIHHJJDFFCuu??s>>‘992///////Έ rq nn22.////////////.щ/....69@CDDJJHHJJHJJDDCCu??>>tt9r9r9q2/q m0022/////////////////./.04!ECDDJJDJJFFCCuE?ss?>>t99qp--// qqm.ъ2///////-////////////////./..‰l..7>tt‘99׍Ј/////ď //////////////////l//ʼn..003"9@CCFFDCCFCCFCC??Es>>A9999q///-o0./////-////////////Ή//ʼn//////..76!A$EFFCuu??s>>t>tt9999//Ήonn0/.///////////////////////////..01"9>@@E??EE?s?@@>>đ9qÈnq0/////////////////////////Ή///ll.0..075"<9A>>@??@ss@>>ttÑqшqqnl/ n//////////////////////////////...02034;;99A>>tt>>9t>trrΉorqon.qnn./////////////////////.//.0..0m331745;;9A>>>‘q/Ή1oqqe3./Έnqnno2//////////////////////////.//.//.0..0017765ttq½-//Ήoop30./ 00l////////////////////////////////Ј..0023m3115r>ttr oünʻ//m3.//Έrm0pl/////////////////////////////////////////////.É/.00..4q9ttq 2../Έqrm0.om0///////////////////////////////////..ĉl..ˆ.//.35;trqq ýÈ//..0.///2oronll7.//////////////////////////////////////..////.359rqq qmŒ»l////Ήporr;7//n0////////////////////////////////Ή///l//щ//l019rq qn2mn////Ήq570.//n0./////////////////////////////////////////.qrtŒqq ˆӊЈ.///Ӌoe30./Ή/////////////////////////////////////////5ttēqqʊl////Ή02m0./Ήl./////////////////////////////////////05trq:r n-//0.///////////////////////////////////////////////////////qtrq4qr22-/////.щ//////////////////////////////////////////////////////.2qtrn0p n0p/////////////////////////////////////////////////////////3rtson..rrn4o2/////////////////////////////////////////////////////2rttrp0//01rlӋn////////////////////////////////////////////////////2rro2.//.Ӎrrъmpn////////////////////////////////////////////////////.oqo30/0rtqnl/0n12////////////////////////////////////////////////1p2./5rrq/.02n/////////////////////////////////////////////////////////ш/.2oq2.Јl///////////////////////////////////////Ή////////////////////..////.po//////////////////////////////////////////////////////////.n7n///////////////////////////////////////////////////////////////////l.ӈ//////////////////////////////////////////////////////////..l/////////////////////////////////////////////////////////////////////.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Ή////////////////////////////////////////////////////////////////..////////////////////////////////////////////////////////////////..//////////////////////////////////////////////////// ( 8008((IAAA88QIIYIIaYYiaayqqqiiyyAIIiqqIaq (0QYaaiqiqyqyúAIY8AQaiyYaqy(008((0((888AAAI88I00A00IQQYIIQIIYAAQ88QYYaaaiYYiQQaIIaiiqqqyaaqiiyyyyyqq˲80I0(AA8QQIaú0(8( 0A8I80AIAQQIYaYiYQaiaqyú˺A0I8(AI8QYIa  8088(8IAIA8AI8IA0AYQYQIQYIYiaiaYayqyqiqyiyqaqyqy˺òúY8QqYiqAaqiyyYq( 8(0A08A 0YIQaQYaAQqaiyqyaqiy0 qyyi8A((( 888000IIIQQQYYYaaaiiiqqqyyy<<<}}]]]allegro-5.0.10/examples/data/ex_ttf.ini0000644000175000001440000000167511476661306017152 0ustar tjadenusers# There are problems with UTF-8 string literals under MSVC. # There appear to be two cases: # 1. It thinks our source file use the local file encoding. This mostly # works okay: the UTF-8 strings look like strings in an 8-bit charset and # will be passed through directly. But in other locales (e.g. East Asian) # it won't work. # 2. If we add a UTF-8 byte order mark (signature) then MSVC will recognise # the source file as UTF-8, but will then try to re-encode the strings # into the local charset. # So, unfortunately, for portability to MSVC, we have to externalise UTF-8 # strings or write them out using escape codes. symbols1=■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱ symbols2=▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊ symbols3=○◌◍◎●◐◑◒◓◔◕◖◗◘◙ substr1=«Thís»|you substr2=should|‘ìş’ substr3=not|“cøünt”|see substr4=réstrïçteđ…|this. allegro-5.0.10/examples/data/bkg.png0000644000175000001440000002222711134212121016377 0ustar tjadenusersPNG  IHDR X'sRGBbKGDC pHYs  tIME Ԭ/tEXtCommentCreated with GIMPW IDATx;LvP cf  !ԨJd2~~WS<P`($:9x C^;$,y";o\ ˮ`HvMэWC`(X ,{e`H kat ,2V3"Ww̗npZco)WMy JrP`(U9_eLU`岔 ♉'.NYwats yh#2'XX ,7ƿƊnͮ62b zS\^sߵnsBiֵ, @u5%neŖH?óˎ<0}%+3$|]Պm&C7KoOX ,}~҂~ە;dS7-w˻:yge I6rT.` @( "?d`rnE)W+C凜bxH:ȮYߓ̛m,` , Q^盘㖇9F^I3 g^l/;YW8ۻVۏՊyIEO)X ,G hr.kݽAu,OFYl9o4\ߣ_)+P, @uWʚF מ^6_?႖fe[>F#v}Ӣk\'oOX ,]irú13g^ԓ/u<|䐣];]=P`(X\:D!ay'Rm^!_&(;<]93u-ne_jTHS|!C`(X , hrJ>9:!C7f>~sFeG555r]13-wwk<P`(X\V63[3 94ZSF2on5#J͞|Yf9'X , ^fHZ$2de3j03~S%~4W®dU9`(X ,>$tmLk7=(4f^ߵ޿ I^>!OX ,}>3Y,|fiH)kcA|^!`o?.+k4G @0 @(?7w})'#y}+f&9沱r;)3/w+e/MY @P`p]@cJ]1VCNN썖|8nw]>;X߂xP`(&^]Ɂdvew%P4Mffɍ4ymek{vE 3ߥX\{P`(&Җ ;/yЭ8Y]y3(=3}ݿ'ѐ~R @P`ptd?i QW&oD l2`gU>{37fޡ]my(w)<P`(uoT:.=3*%w}!˺9CwݽbG3g6s<P`(uMgy1_퐎˲L޼(#|a%Ayϻ*k] l ]wJQyLP`<+{33ywmjHbk43 >|Wu'1䍇,!ӻ<P`(X\wɽ,y]YC,6p$ˮ(/q{8q+ys!   @ຏܻ{ZFiV]q)yWafsACF7.ՌZ^A ٯ'XX ,|>3~[<.ಌ~eWIvXuQ{Wv @0 @(w%6 IԐT6Օ1]67lk _ YgwW]Wpź1d9`(X ,{]!٩]=]ǜwk"댆$_y_ YҺFYyQ]!kl @0 @(M|633=IRpa[98C`yG5$}Ō4 ?6sY} @0 @(Ej_BɦQ~{7:ɧ|[CZgye=8o0y/,` , Q_N;$9+6/8on _?i뾁;lu͍!7ɮVʊ%7W  @xܿnm]֠W^68yW0o37ƾϼF]13|掺V߅{cr}hL=P`(&'=It}x Rˈ/AYb nQ^n򍧿 缣ʛuy[.{! v-nCf~;$[]e,` , Q:duMʵoa&nܯQޖk WC~5wMɛ]$w , Qқ7怗e5L ޸eMo*7C+q}c]67%  @P`pݕ&0ɹyBX r`&&M޲q$g~[b}we)`(X ,ɽ3ݸ+wf3WjHkv`vyﺏ֫!IyjEr}ٌ]W`S`(Xsly';36oF]CR`׫*߇򅀮̫ ~ @0 @(?7>IRV!,s+;. |$o$#9Q>Wy+z, @u Su}trF;򙊍3?4ҵƆe`S`(X^փ6$UI̱#p4r+{,q;p |dffz^qwPv~V\k<P`(X\w}fܮygHy,y+O?𥍙WrZs'XX ,|\1|,%_ۮT\q[e[\͍߮e 9ߍ k @0 @(?7wu Y#x edƹôkw(ݘ?dZf/| 3o9dNzLP`9~!elH(-y1~ʟ̻{ՊM @P`p|)sϻ2dw4~ugރ+xZ6~[bNs=OX ,}<$+yƁ͛eٸy]]euƙww/fv\vf]~gs}rFCWW]iyo( N$`S`(X8ՎN::w>n9e]y+RwYN  @x$!IG~SCZʢҺzH|ՠkz\7iwHț9+_h5  @x$t211tHpΜfewhz5s>`2x"w,` , Q^{~y]cՎfnkNۙ]yS+ͼ*o4VvTKW|l, @uwkjyuMne.wwC~Vq^w!  @x&63Zq 셏^>3g4䍥ߔ\ygΜxP`(J{WrY^3 j_wʶ׷>$#><P`(&!ɹ'[^}ry[jAHnSweC^S(;kUYѧe_5  @ຟ7Ww9oްQ`銤w=,Ak#׷zLP`P8!wP 'XX ,·"yfZ{y]z홧0.9+>SOLꦯH`(X ,}H㼔Dz-]!9+nF>T0dSO wU_D @P`pMCRwg&5Y֏Y#|噓}!7٘x[΍}zS*,` , Q^D׼)kj˷j#877\UNyHv`wߊt-Z ? @0 @(5 gA"s5*3*KF6&Ð +SvN֍|cloo @P`pݕ$۲毎*?|vun=_1f~an3o DY%OX ,׽wP>AL_\vF_,A7"BY+_^y\  @&!CO"d'(o7 rw i݂NvHOX ,7>:WFy;Jo{'egb[F|mힹks,` , Q6%}kTޝ7Vy3gc}u]wG֍g13$s,` , Qܻ{z92g^Vck(.,3 \UFk9sbe(,cm  @x+M]i]}<3+co+5{ߖ3)we"uGy;s}Y=P`(&^S(߮TMv]!9_ eNޮMLc-y7N/ݵu,` , Q~nr/o.Ԑ.¯v+݂!p1 h~?s/JWx}4$178yǜ77 [?`S`(XsF/"/90el37~]$~y]ɼʻqrҊxFyo;ݡeS%, @uOS^x`c`^W񇼼 l'/oIs.3,[;iZ7l CCxP`(uND&ʮ-wb-N!8]<knuyw OX ,]ir_G#IDAT!yTܵFp28]_({l$7N3-W]_<P`(X\Q2Rv]CQYpYW=9i]]G^M!p1!7 @0 @(5mlE8>3:on4i~@ތ;WGunz_2ɼ!K*xLP`<ߔ%n7$yHbL!eY]gTޕ5CFW#s=deظ̼FzP`(& []r?̦/ nB߽?sey'\{OX ,"8Gxf̋2䘇ՐT޷+ ֫oZt}`W+fs׽?m{LP`<}زe਺}f}8V]~G]wWWa1̫tvO)X ,Gy]V⮜2+Rʊ GHg?FːKP}  @&!qN}&  =$ 0dS'y1dCv  @x7 <P`(X\2sϊx߲Mg5   `xt5.qIENDB`allegro-5.0.10/examples/data/icon.png0000644000175000001440000000100012054130035016553 0ustar tjadenusersPNG  IHDR00+"PLTEcolH`(Xx4|S5tRNS@fIDAT8mRQ  kff%}OH L6!E.]mAw tUu%@ylM< ["/f5~t/'1nB@TŰ5sv#cNìs`tRY 諳Y(-šiꚽMh}=1wˎ8h̒8cR*T:[9&&tPbr\Ys2Ցٖy\Վײ4~跎=nLö:5 ziOu, 9yQ2> QHs hδ@( f,ě%Ja^t^[`@A yӷゞ{j5ȼNX"n\K)1zhCxBIENDB`allegro-5.0.10/examples/data/testing.ogg0000644000175000001440000006415611346327546017337 0ustar tjadenusersOggS TvorbisDqOggS T }-vorbisXiph.Org libVorbis I 20040629vorbis)BCV1L ŀАU`$)fI)(yHI)0c1c1c 4d( Ij9g'r9iN8 Q9 &cnkn)% Y@H!RH!b!b!r!r * 2 L2餓N:騣:(B -JL1Vc]|s9s9s BCV BdB!R)r 2ȀАU GI˱$O,Q53ESTMUUUUu]Wvevuv}Y[}Y[؅]aaaa}}} 4d #9)"9d ")Ifjihm˲,˲ iiiiiiifYeYeYeYeYeYeYeYeYeYeYeYeY@h*@@qq$ER$r, Y@R,r4Gs4s@BDFHJLNP@OggS: TaB'KI"   <qXd}7!DY2%'V-"FݟϊX(rjDZ!NxNkKg;eMDz,\|򑑓cPI',R hS.UAUEPwjݱI7% ׃=Az02J"&JALLĈY @Ŵjت `<q$%8 # ɊHJA 4FRBPS,D-1DXڈhc۸땞5t*Mn3S0:EQI$;q ?I rȌ.zn/0\q7n_cTA(e<-~OteX:hіE`OΤK2$_B5 ׺hBL}BA?< ;V9} pG'u")eJ:SS%%FPŮoQi$Yų|hk>>`DL7"]8 ) `(UPQ(X.X錯2) ~G,2Q1ş]"w !H–~]0qY+ߋ ѫ=:(~X%2:(X*AƢ޴l.J!q*bf#fPð vVa8"FK)+l "UFT4֢j@ p"y.v/qabbZ7QBdǷ֪ Dt(U[X cQUlU{A[4bE:c`(nz?ᴜxrc6\i^[EG~>G~8QoAhmp 3ނ(8JQ-OB RR9"#RRd bcg5 @fQZ'!̗$ĩNhlժFZituA`4mdr/)ms` ̶s0F FA" T-Sܾ~-̭Ȃ kܧQAB ώ@ULk"&Plnm;g:hU4 oB$^[rG֋rnp6&\m8uҢǔ!}O؀b 2S!86_2S!86_w!&6ON!vppHEĜ"b@ڪ Ar(r@Ŋ`Xh)XEU5XAPKD0jD0`lAPdssZŶ =]ZqWaU3"8H\m tfT4D58_;NI﯇PRlFO*wEuCQ9#*iʺ9FM`m+~&(AÏ;Ad^Tpɩ 63LQNsp:3331 bբk 0 0X"ONG`0XF΂j EFhQDT@TUDĀ* ֬̓  ns!kX,EmaehM! I%99rp`1Na&ffb&f@Li +V-Xբibg iB͖6Ҫ*֨F#V- vO젇3;k|fkPjf[X(6`)W6bUc:-2"`tR}a!a@jphUCMO RL1cMyt߼wtuɭH^ S@%H}/p ֪?pMzM>(y|2:#:l<>HQ6AY È$CTb؁YLHE F1v66jkW`U XhT-~=+\`Qu( KD`VRw9u]@2HA@lD4lѡWfdS,zjE0W1Gg~\NiqP h6·d{B÷Pr^xNd酊 {y[{淵Bvo(*&:PBVR' "t1;888"&vbb11ffbbb@LS,6jk۫j1 W[1MCM+Vl4,0,("(F4bAM! b5tdE-Xg>$E@RjX QA_9/wsVTzRc8HF,Ul:[~5tfe{`,d'ncQ[Ejԣ} ׿D,ISH,gDBXOggSk T`7W,'$9;:8OSL8&AA>;:HHNNO:PMKHIMHGJNN.1E^f@`Q=eWH (ļėiK2zI $,*L*T,FLL,FLjc5LN,P VE,M fV4LE- ".ӉT@U%D[0؂1-iAA,`Z+N NE]2ZwvJ5υ Ţ+: # `&B1]W>}c\g8PTN}Fnv޷5X-P#%ͪ?u@۩{`vp_YP'gT2X,EgD}F%#bPtF @+IOHEĈY@ّ́33@d!Xl-,6V[ `0"X!H DEE5`Z"dv/ObJqFU`bȾjuvum%Ul}dQR}}e|zDcD (m v 9wڂHOGo x.~UÏ[@fC?HRzكn,=c'e!{6j}Pmd%4X;5hD.1<q\ƬD)jQȢN!eD!zrpp:#bG 331390bkUETQk``Vj+Xl۪`E`v')n$+IqpĦ@ݪX6aXBA'ij'CTDOi@3E*(Dk#`Q@@49EVZA\w]l%AK!ԛv\ZJGv.y` n=>Һhn?g`¿?3u1)I*7;#KMHbp#0yH3LG;rSY؁Y4Q;{FaaUŴ`Y Qm(*X "DAv wDrE2C@ thj6+ `EAU9<1A 9fֵֶkji~cqF|3,IXۙh>.5OX/|ɰkVȮVcsǞ^gA~=t5n }bA<P#)6w8`ϊCq p=+?Edn(BtG89"vp f&cbfb&@ U+EP‚|)A1W#.hM1,1lju7ah@[%]Y@qNְB4@ tVT$"}RbED5F÷ HɜIH O(qD"Cɮ^Q ƂA$Ojh68]}r-P05aaMrX/#*#G10ߕml4:wK?-d``5b6X|# (Z,(!rzѩ"5FKEpj@:UENDdl)= AlHAMpgr`7&d0`F1"+Z/"ZJ`ݤo*:l:w,5"5t;Bw?}RfݢZ 5YeM%6S J%bbbLjb0bE+ւXcP#bP;Ӵ쭶jkQ(FU /g85pQUV!Jvʊ$#'ښ6ثVf*4"hPjUx܊qndj]ndj]ܨL` `U1Y4HުFVkD<25eĎluct_B`0' " $:1:th5"bEDQa[{Uj*d7Λ zވԈ(bPb "[fP9g*kJ%1A)jبb 6 Vt*F0Z ֈN֩Rj+QI,ul:iBWM?x0Ouf6M3rX P1X+ja)j5[ЁUT#`:*"6rVRs vD6uVLjnZ?Ft^ #`og* XZSh&e R4l6)呌 ,mR#xkYD0 ԨU#֪6Fժj5|LuBժF!Oo~=ٮ:ד`Z|6AA2B$$%5ZjPTP(ZA+ ۊ!؊"}vuͣJv_Q%wpgF K#`bX0-Ţ ZՇފZVZ x 4U#tғVjdcJrkV%S[~VKXL```5ĂQv[@+hߣZؑt{+PU`/bʼJFDa5"XWw-XZVdUu֊V[];ٝ܂uwŻ9-X7{WKC`(QA! j 낕E4EcAU4 \i;^` Sm+ a*MJ$ɵXQj()h4@ue'"ή QV4B /AH~td]L0A@X5FcT*֊XS¢ЂF1q:F+Z:.L-N_Umvgjq7 5uP5XUDEPUk,AVjJ׫HJ-7+f+f+~iɇ@%@%x `UkqYjh(Fi(Yjj`+~ѦЍ%~m (^ByG'bthPEk5`Quh5F"*-|w|OggS@ TctI&.(??-4#-4 zJf\Ldɪq2C,T #TS8x:JL,F %bEՈEDE5\B8|aAA Qaq1VRk*ccigӲK7"Q`EUV[$hXc,"VTA4QPѠ٩P] 9c˽eZ,XQgi^8FF#l1Z+bE躔 ۊ`V5ZbU|`Ÿg C5i͚l~vb۴^JE)|K^%r>Bwg:_%r>Bwg:! 989؁SJbIv"V;bko*bg5[jBܵ V,hTTeK[`Ld@Y5]!;C Z ؒDZZPů;{22\|wnͪSUL KDv}i!qV_KqZDD/w 0 TVlFú",]Es[KF`Lhw{WE~U- ([$SGJ*kxaDSLFZO4y#`s/r$6bb1&f&c&ff&jakk+X-{Tb"ؚiڊUDkĊAhQ5:)#9jĈXe064AAkĂU Um|ne=8tj[ULkhZ ͪVUjZժE޿mt$PZs;_ߩ_+"EJܿG@Tcp% ߤ5L -'Z̭H g'/[ח߿臤 `E>Us3jnxcr>Í\d} R9LI ؑ1Xƪ*aY԰b vVSlMU؊-+UATAp\CZyT{5E5 Ok DlQQVDk\nAL$OnnmhbC,#Le+ :-ED; [oUUPDtXU Z"hTD筕!}جʿϰ[ +p: F6ri _o"%@gҋڴIj& ~%=*980JÑ{!Urp@5RO5ef"H*<dfv$F0Řc5 FcԨ#֨(VU4 V(*VT F 8͠~]I8J&( t\EbDbh(VEETAS~D<>cFD`E#V-" ô-Q0UŊ5F+ 8r^ePhWAEt` ؂@Vpa"C҂ed e~5_$1`m|JU-A1,FZ ~ A6^rN7A^HTA8yCoԈ14~N5b Dm22+L'u2@d$Kqp ,@L9f1+jZUc"kEDXAUb*bcAAE: FQT۷lJ ;QT-Q^-%!Z'|PV*VU4*"XZPP쮪*܉l3*,о[ e \rgԒsTճ̱ ",Npl<1w `֭) Z`]ʱp ` \Y6P6 n5-DM}8~xz yxz !YRr 6!;rH*!E؁ÝXUQjUZU5F1F0*-ҢbIkI ~V#v\Yc+(V,FQ@~5OV ԪIuQH!k~ ֹW6Вzg%ryk` LfpG _:~I㝹읙3ģ~kQ:^xT`#C]ŭ$GIAT+P &L6SR TbbLL̤33`ԪV`UQ1bi5,L UKE hQ5Fb*"V#豭Z0"" E;Fi6mتV5!FkAa@EXjmTTEQth4 h4ED{5?$2ݳFgΣ1HZ]?ND±tT5S "E6)nnnRn atnLh-a<R|ͺ'oV1Zg>y<',OO<rȧn}^6Gf*vH b,F;r13ښUbհa5Q[ԊVLK +Vm0 KPшQUeN(Vш ʢ&,VZ,aXr=4 "NTAQ#XTE]/j^ٔm7;`` IU_TdߚVze|w۟| M\/oE*UVkD|P຋&_*rM.ȋEKbxѢonO^ZE%1?VsIbL{bksp(C*vb)bb,JIZAmbcS[MKªͦMDɊ *VVUň`u z{!E#- Zj49z᦯  h- t(eEQz-P@c1yqOŪE' Ӧ[ [)h-F[|jwOCFX~?XP@]0.PI F#N$8k i(FR)rR)rH5%,G枊89J!`fN$"#XECj;EPT`UT8= &ݼ TVhP0"-k*谨iDA@@1aV5"Z nx2 7kwD[VZ ( `:K-. h1"Jk9aE-"hTDՈT{$(jo" pPh4T"^Oὸ `bBwd>ym}+R;ym}+RjQyIp$@,.Gx2TbĎRb$P+Ī*jP [1D@`:5RtQEEVPAONQT om֏O@#%ݖĊklEt*"Zu%븐Qgr ?PU+Ƣ*X hIFh OT[N#)F1V4 2jN+8$u"TNET%Uա"bQT"- X"C&坺-uř`9hYCtoVsan4,!790߄HO&;8Jc&NE3 UUQj'1Pa5 {XXbC hh,j ,S5VĪ5ʃ=f*ôb09R:v/[Հ*DkUDc *dx&aZEQXXI&FQrQj谀-lϥAA;ΌkCIMJ b1UpҺ(R%e?=QZBaGbsf4D }s7}KM1)&FŘd`A-ژV;ڙj`iaMbŪ),ME11**8dVTł":\Z^oۋ@$PAVk*DD{9z& jAdv FE4yl"lM"FTJՌ*;F >FwLU%ĊGjqcŎOggS@ T.'!/ F*|i%dٳÒC{#>]kl#=)<l#=)<y2c!cKqXJ*1GbL$V{l1j`+vVlPSmTٚ`MU4((XTbZPĿb PPxwSEi1`*VE#b}{Y<ҩQ֩j"Mtlr3A5.*)*fX5d=~Ň"x\ $.<=yXf"3Ok8rgR_E޷@5I\=22$TJa8)j<˖"ȴ$YC q#`Sd5oD&)jRSrH h9c1cfff1 "VTŨiբմj *XZAhƶֶ`(pm*h6n8 JbDkQ Ql8-?Ë%2EDDh4(Fhbkňp9VhhT1$9̀LW> {`kU@_h"pVm^w_#/: ٿgf>H9br75D$?r *f$>9D:,\&BB',!#Rx11 baQ;[a6VZ-6X؛mR K-P X1^޽vUAAUòtEUA@bUU1 XvYRU S Qp{y?1@D-#bhUI&nz@c.x4=fO!q3U<\[%xkFWӂzei _"N,3Ih 'H}.yA R pȤ,JP!^RS9,ؑ1)b,, bPjQ`c[Z4-Ī!jK T T"(VIQ50jrDDFĨ*^UNf.7+njQ,AAЀQUۨ% oReYj_FE{ϭr EZ, ^?x (_}oBɴW^IÕϴ]{%eT{l`2ѕmf#`,A]=0>TU&hD*|4RR9p@0133 kXVĪaZX&P*& "%(؀ hm~WCU&MWrOb10l9#*A IX3dkMyV޽m^ b@چZ&b] KC̚bR}S^]?MF#HId p0ĺt'3A%%ex[B~XU*hwkaW݁7#ҤIR9ˁ1apcfbAHDP[S-ZbLC!"jͪbQlѠ QE&-DWږQ'~l?=2a`a 5AkSjB bZkXWMBw[>!"kkOա(Q,2goH%MR: tT_M"V]>O7oDžߗyaTva8̣Ճrӷ%w[@>hU,h|8yhX@q@ 3-iG +vX @E ikkkڂaZE1-*a15 ,YPEРjUQ,ժZkE5 2uAB˲:- `u*[}غ޲׳E¿s0  VjT$.{CҲj,"D@_O޺ 0:My=I.T>R5yiwb ^mep1$knA5QǢ'ye^(9*(ɗ {@W(9*(ɗ {@weTĜNHYňŘYLL[7ְj5ؘENҪaEM1M,lQ ϪրbQ,"mᣢ6Z0@Ei|-$"7#gή\2\v}g{9tr$TG YDv);4u6).yTEK6"%xc*QgW6O82  8[nb5OdEdC8Tbw= 0_.Eex8u M8 dK4C;RHqXij$'ɧ O<=ZE^hT v9+4~P;8pC*qrW ;13131;0ڛvV[acoU 1.C(Ժ͢bb-Ժ0EՊb, VZen kE bDi h5PjJ#8ԻomX oEǽ:!!(`i!ŢA58CĭNtmY蘱0L1 P;px` 2x i3Ї{,|#|O̫d% sw:CN!@#c9&m_0,@̨q ̨q &"Ն(ʺL%TJEȁx0135VUkXԪ[մ+bVhAZ XUQ>HCEQPӺتEXŞj{+kUY5b!q*06(V5i*"9Ac5XU'Eb,` }\T|Qdi#) Cv]iixwĘ!"<,loe<++xXP8#)TyH;3BQS"-U*TXXĘ APNL ;ð3X1j Q떨UӚSLS(UEUMJW(6ֈMЯ={@ȪTTkQD* i[fhD GmWݧG^luwtA<_Tyd#҄OTzٵx}ѿzSS|x-7_[y OggS@ T.=\ %&" (&1,B*(I4ZBH.N5(y3iS-U*Gb"c1sp `#cP ްM[ 1P&,FAC*ZUT XP,hՒ>աb b_>c6K!XE1ZESc/"EQPn)TpF ]2L,MKĪB Ŏ`n=MLt5zDf&O!y5g0Nօh0b_Mr!G4H*G.cݬ8$ܺP$֘[jNHtTbĘŘRްWްڪ` Q,iZŠ JQR Ql0 \ -) (ZJ߇*"Y.W  UZ-2"Q69Z ;cE:A^%V=*L>ʫ;D(hEUuh` op͵q|t-{cFuQ-|mH=tк%;-Tjw.⪉Z5,V0Y~($8y)w($8y)w1p!#fcG$31b7;[F6jc/XL)= !jUhUU+j!tyڒKe/b#J[)}bF"QTWCQv hB…l9r}!h4XX|e )a ph֎@fP]VJ eρXОZ;%fJvA#t8A-D09"zRj9r1Em3d5VDȴ9=;1 Fff11ZUUF1ƪŪ ba],"*Vհ6Y "}YlEX1%%ȵY%IQS,&(|jQFaXVEb '\l;Yur%Gw4X Wt " iy;; v۝m74bԂ\3~ΝkLDbF{6]:?Hӫ 8AtjQ]"Grl)pp"F, $31ioSl" j؋Q lf  bKҴAŴİF`bUF1 FHT*JsC*ڢAsǥ}%8b Sϝ[>A d_:QX`"`!Zh#E+6 U .qS؀u"Her-xٸ:QAOCʮ[°Gi3?_mw>8Df1H7)UȢ,i&0M TNHEL,11;03;8UVډjU[UIĴfŰ Aj@Īb[PE*ZU#~)bk, ]TUPk,dIJu 0tB.XT4ֈZ3 Q0MFDa,Dpɋû#m]!{1@9]d!Qرe$zX_jABCHÎh[xDVonLK3ҿg),jKLK:;6ܓXlt ԗCinNvw^Zcc xN2) DM" X 6&6`F,0~8PN<$ӡ^PB9XLvPfPd%BANO!#bG33ĨQ#FcXf[X(vɧ"F[AZQ1"(U9?y$=ˇЈQ;7C ;IߴbDdk`WoE6>(LXǰIҊ ZS*c@ '?drsd*((֬?M@}/9Cش/-6Q^/HGPj1j$B#o}({huAEM2i TR%3Ł03 "+cXTC 5-bU *(:+FEȐnhM2MdVi^x@.P!)Tc$;nG!m `KJĕ,@LLak`g*\>#!J@XBf S- kXѪ:` EQ iMx*((0A)G{/e}b@Bcɹ K~';X ĐzZ -!`c%DF4Mn)a!j)vǡ 0 1Q杜$%? +Qu23OggS" T:+%&t/*hp'*  YkQl3+eH{Cl|hO{GbFQ@|U( k"m–aGNM#ĈY`64mMSƢ64-ةiŴǴSUM0,Ԋai "1تV "*b^Ȋ<%˻LtҬ~HpSTPn):E˂1(j`X19iEEB Kա (hT#Ak":@UnO!%_ّ)iF Ҿ=r HvzqXrVf߼gDYCN8Һ?#:/ZvZƑڦ[*1oy;b& $3 `k Xvbai6Y.uLXUE"Z1(U#*VXh6>BShJLLkZXZP,bZZ* )jf#&}J#naMX T| %72%9#łF FO|7b&<$m>.u b2b L8 d >f\3/4ًw _IĆ hyWa^۰rs:1I$IL `+bj6bo#&lkֱb+jXjZZQ֬SZ ZUAUPTUAVDMzvR%I>ja)6Z3P5zR~ɵXw]~IwWS/Cs}w>(QDՊu L S&=inh.$g|φ6r wlCɆ׾Ballegro-5.0.10/examples/data/DejaVuSans.ttf0000644000175000001440000227670411243261160017675 0ustar tjadenusers0FFTMR<GDEF]XXGPOS/GSUBN֘LOS/2! Vcmap .cvt i9<fpgmq4vj<gasp glyfyO|headwmp6hhea $hmtxv~Uhkernk/6i4<~locaJTUlmaxpqi namepMi@=postL3Hprep; x\hermrm$W           "##$HIIJLMQRpq|}     "#     ; < < = I J P Q Q R U V W X o p q r   ~!"qr|}2334Y \DFLTzarabarmnbraicanschercyrlgeorgrekhanihebrkana*lao 6latnFmathnko ogamrunrtfngthaiKUR SND URD MKD SRB 4ISM 4KSM 4LSM 4MOL 4NSM 4ROM 4SKS 4SSM 4 kern8kern>markFmarkTmark\markdmkmkjmkmkrmkmkx    "*2:BLT\dlt|x8  8 >/024<7j7:I`j0&:  sv{sv{ &,28>DJPV\bhntz::::r 4 4 `Iqrtuwxyz|Iqrtuwxyz|JPV\bhntz$ l N>X  &,lwlwlwfn " &,28l`l~l~l`l~l`Z& #HNTZ`flrx~tt;888  !"    ! "(.4:@FB :v| $*06<BHNTZ`flrx~hhh=DhhhDhh=DDnnnnhh   !# J P)rr0tt1v|2339  J P%r|,3378 $*06<BHNTZ`flrx~ &,{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ $6HZl~ cj cj cj cj c c cj cj#sv{>DJPV\bhntz*  &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv|     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v |     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z  "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~{U:t!N8'Qn ppjjj,v,,vjj  XXXXD[j[j, 8 8>>j pjjj^jj,,,,,,,     8 8 8 j j>>, ppjI^`k/#eYYYcP`{U:tii!NQnU!Q{++++++jj++jj++jj++ 8 8jj 8 8jj,,X X ,,XX,,X X ,,X X      j j,j,j j j,j,j>  ++pp++,,,, ,,,,,,,,,,2  pp++pp++jjjj++jj++,,XX,,XX,,XXjjjj    XXjjXXjjXX&j&jXX&j&j[j[jSjSj[j[jSjSjXX 8 8jjjj 8 8,j,j>>SS&j&j>++jjj  pp++j++ 8jjjj++^++j++,XX,XX,XX,X X   >SSp++ jIII^^^```kkk///###eeeYYYYYYYYY$AMpBDcs~2#sv{BHNTZ`flrx~F 'PV\bhntz "(.4U0+0008q00800i00E0 0100000P=i0v00v00d000UU8000U $*,022 45 78:> "0 $6HZl~ cr cr cr cr cr cr cr crIqrtuwxyz|RX^djpv|``& b lrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv|     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v |     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z R``S`4rrLRLX X X X [r[r~x,LLRLLRLxLLLxx4RI^`n#YYY`R``S`++++++LL++LL++++LL@LL@XXXXXXXXxxxxxx++XV++,,,:,,,,:,:,,,,,:,:LrrX+F+Frr++L&LRR++LL++XXXXX~X~X X X X RRX X & & X X &&[r[rSrSr[r[rSrSr~~x~x~LLFLRFSrSrR&R&R++R&RL XVX++++LLRL++R++++XXXxXxXxXxX~X~4S4S4++&RIII^^^```nnn###YYYYYYYYY%%//88Mp')Hfghij4?QZ2[Iqrtuwxyz|rx~`{{{{{{{{` <BHNTZ`flrx~]xx@[")@>E"~~x2x::-."> @FLRX^djpv|]kxyyyxyz[f"w)h>yEy`P["~[~t`zxy2{`uxJJ::++-.   !" 28>DJPV\bhnttbbbbt`~~`~` Z R   !"# $*06<BHNTZ Y &,28>DJPV\bhntz "(.4:@FLRX^djpv| $=D]468QT9Zd=grHw{T D6L  $Js}- {{8> 7pv| $*06<BHNTZ`flrx~L/'s.}////////s}/////s{y5D;/}R7$&(,268DFHLRVX-* [\]^klz?   $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv|     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v | L\/.Rs''}srJf;RRsRR%}^Gb`R////}}J////Rs}f7R/'z`RR///.RR'}r`RTTRTcRRJ@@RjRjRbRb}RRRRRRRR}R555RRaRt;Q'RRRRRRR}}^G^dRRR::R'aHRR_R:RGR R~RJ}'/'}'}^TTT@X}Tg^GX^//LBRRf,4$R'_zRf4L}`ReT'sR^G^5s/RRwRRJV1vvvR;nR RRL5s/<\R&Rx9\wR}RO$= D]$>BCHIJKRT  UV--WEEXNNYTTZYY[aa\ll]vv^{{_`bf iJqLmFFIILL""3366|}346;>FJNRW S S [ ^ ` b e e h m t t x x | }      ~ ~ "36QT7VW;Yd=grIw{UZ&&m((n]foy{|}??~   !"# $*06<BHNTZn 6ntz "(.4:@FNT\bjpv| $*06<BHNTZ`flrx~ &,28>DJPV\bhntz &,28>DJPV\bhntz     " ( . 4 : @ F L R X ^ d j p v |      & , 2 8 > D J P V \ b h n t z     " ( . 4 : @ F L R X ^ d j p v |     $ * 0 6 < B H N T Z ` f l r x ~      & , 2 8 > D J P V \ b h n t z  "*06<BHNTZ`fntz "(.4:@FLRX^djpv|  &,28>DJPV\bhntz &,28>DJPV\bhntzL\/.*s''}srJ{#{{;j{//{{s{ {o{{'{}{^{G{b{`{{'{{}}{Q{{{{}{\LX;\//''{ssr`{{{'{{{./'}{r`{{T{{{{c{R{R{J|@{@{{{jj{{b{b{}{/{{{{{{{{}{{{3{33{^{a{p{{;{Q{'{{{}{}{^{G{^d{{{{{::'a{H{{/{{j:{G{ J{~^{}J|E{}{{{{E}{p{{t{}{j{{{b{{^{~~{}{t{^{{{{/'{{{H/rtOs}s'LsoqGGYNsT{a{E{{{{@{{t{{{{}{{{{T{`{kb{{K{{{{{{{{t{{'{///{{4{^{c{s{"{O{,s{O{%'}{{{O{t{t{e{sK{{{{'}{E{b{{{{^{{{T{{TT{{@{{{{{}{{{{{{{{{T{g{b{^{G{{{{^{{LBRf,4${' _zf4DL}1{`{e**}T{{'s^{G{^{{{3s{{/ {0{{{{'l{n{T{T{wJ{{{1{{v{vqv{*\;{n{{{L5s/<\&Rx9{\{w{{{{{}{m$= D]$>?ABCDFG  HI55JBBKEELHIMNNOPPPRVQXYV[]X__[aa\ff]ij^lp`txe{{jkl pJxLmE]deiikkmmooww.DL ["#a*+c.6e@@nMMoXXp^^qbbr|}suvxyz3;{>GJNQW[[ S S [ ^ ` b e e h m t t x x | }      ~ ~$'*02588::QTVWYdgrw{ && ((!]f",/0124??5  "#( J P.r|533@A$*06>FLRX`flrx~ &,28>FNTZ`flrx~{{{{{{{{{{{{{{{{{{orr{r{{{{{{{{{{{{{{A{{{{{{{{{{{{{{ {{{{{{{{{{{{{{&!0#5PKr9KD &&K9a}au9aauaau/&DaDDkkDDDDkDD)ak}/DDa9}D}&&9}k}k}&D aDY}aaauNaaau}}k}ka aakkAk&k}}DHVaD)kkDN9a}au9aau/9a}au9aau/9a}au9aau/&kD&9a}au9aau/9a}a9aa/D?}DVD aDKr9KD &&Kk}k&/<&O$$%%&&''))**++-- .. // 22 33 445566778899::;;<<==HHIINNQQRRUUYYZZ[[ \\!mm"}}#$%&%'( )*+!!,,-((. /  0  ""&&100::?? 2 3 4$$%%&&''))** ++-- ./22 3344 5566 778899::;;<<==DDFFGGHHIIJKLLOOPPQQRRTTUUVV WW!XX"YY#ZZ$[[%\\&mm'}}()* ++,,-../"/&&010101234352678888393:;;  3<3<=<;    !! "" ## $$>%%5&&''!((?++@--@//@0011"33@55@66A77B88C99D::??4EFEF G43H4IJ H HA I IK J JL K KB L LA M MB C D M N O^$%&')*+-./23456789:;<=HINQRUYZ[\m}  "&0:? `$XAYAEGKMQ SW .DFLTzarabarmnbraicanschercyrlgeorgrek"hani2hebr>kanaPlao \latnhmathnko ogamrunrtfng thaiKUR SND (URD (  MKD SRB  4ISM FKSM FLSM FMOL ZNSM FROM ZSKS FSSM F    aaltaaltaaltccmpccmpccmpccmpdligdligdligfinafinahlighliginitinit ligaligalocl locl&locl,medi2medi8rlig>rligHsaltPsaltVsalt\     'PX`h "*2:BJRZbjrzJ\ nvX               p   *  H   R !$% B6##66>9LM *_ J K L M i$=EEGGIIKKLMNOWW      ""$$&&((**,,..0022446688:;==??AAHHRRTTVV  **__  J M &   &$$4F!!$$4F""$$4F##$$4F$$$$4F%%(0AD&.6EEGI&.6JKMN&.6OQSS&(0TW&v6Pblv",6PZd        $%&'()*,-./024578:;<=>A B  !$'*-0D$&(*,0268<@DHLNPRTX\`dhlptx|Megp#%B  "%(+.1l3.4:>BFJVZ^bfjnrvz~ QQSSUY^egmop)1B  #&),/2l3-39=AEIUY]aeimquy} QQSSUY^egmop)12  ww vssvw~&8Jlww zw zw utrq utqrtuwz 00> $*&$*&$J 8 "(IOILOLI OLIRl$*06< xwvutsrqP{NzMy &,!xwvutqOzQzRfnp0$B 8  WVWA(:FPZfr "   " $; <V p0 q(/ QF WX VR")567DF o ogfhdeji#9?FLTZgfhdeji#9?FLTZ,-DO *"&?,-DO\  X6 usvtyzr3{w|x  ! LM *_ YYYYY33f . `)PfEd@ m,$, x~OSXZbw~%V_  :UZot?5JR>PjGv#.[jx{EMWY[]} ' d q ! !I!K!N!###!#(#,#u#z#}######$#$i&&'' '''K'M'R'V'^''''''()) )A))))***/***++$+T,o,w,}-e-o..%..MGMQWn+?KO6<>ADO#t QWZ\pz 1Ya  !@Z`ty? 7LT@RtFn&0]w{ HPY[]_ * j t !! !K!N!S!###$#+#s#z#}######$"$`%&''' ')'M'O'V'X'a'''''')) )@))))** */*}**+++S,`,q,y-0-o.."..MDLPTb&0FN8>@CFR pv^\TO>=<4/,+&" mljiga`_^][ZYWVUSQ~}|zyqpofbY+)320/." zvsoQPOMI>8642\ ?><;:96530/) A,gb^0%$#qhkkkkkkkk5k1k+k'k!kjjj|"|snmlkjig_W ~bOQSWXZZ\bpwz~"#7 %1VY_a "$?D  F  HIJK!:L@UfZZ|`o}tty??#-/U 57JLRT:e>@PRjt  FG nv 3#H&.V0[_]jwx{{ d   E HM PW YY [[ ]] _}  2 g v    ' * d j q t  / 4 J L N P!! Q! !I [!K!K !N!N !S! !# ## P##! R#$#( X#+#, ]#s#u _#z#z b#}#} c## d## e## f## z## |## }$"$# ~$`$i %& &&'''@'' D' ''H')'Kd'M'M'O'R'V'V'X'^'a''''''''''''())) )  )@)A )) ))))))*** **/*/.*}*/**S**`++b++$}+S+T,`,o,q,w,y,}-0-e-o-o...".%....MMDGLM"PQ$TW&bn*7;=L&+Q0?WFKgNOmosw|~68<>>@ACDFOR #ptvV89;>@DFFJPRkՠ)]   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a rdei xpk rvj \s gw @ O MT il|=cn XT Dm} b T: @  y qz5fqu-J3T99NR7s`s3VV9s3D{o{RoHT3fs +b-{T#\q#H99`#fy```{w``b{{Rffw;{J/}oo5jo{-{T7fD)fs, %Id@QX Y!-,%Id@QX Y!-,  P y PXY%%# P y PXY%-,KPX EDY!-,%E`D-,KSX%%EDY!!-,ED-,%%I%%I` ch #:e:-ff@ /10!%!!fsr)5 5@ K TX8Y<2991/0 P ]%3#3#5qeB@KTKT[X8Y1<20@0 @ P ` p ]#!#o$++`@1      91/<<<<<<<2220@   ]!! !3!!!!#!#!5!!5!T%Dh$ig8R>hggh`TifaabbNm!(/@U" '&( /)/))/B" ) *!#*- ) " & 0K TX8YK TKT[KT[X@8Y<<<1/299990KSX99Y"#.'5.546753.'>54&dijfod]SS\dtzq{---@A$*.U# jXV`OnZXhq) #'3@6$%&%&'$'B .$ &($4'!%   ! + 1 4K TK T[K T[KT[KT[K T[X18Y9912<0KSXY""32654&'2#"&546"32654&%3#2#"&546WccWUccUVcbWWcd1Zܻۻa ۻۼ 0@      !         B  (('+'$ .  .'.'!!199999991/9990KSX99999999Y"2]@ " ) **&:4D ^YZ UZZY0g{ "-  ' (   2'') #**(/2; 49?2J LKFO2VZ Y UY\_2j i`2uy z 2229]]3267 >73#'#"5467.54632.#"[UԠ_I{;B h]hΆ02޸SUWDi;#QX?@Yr~YW׀c?}<$$/1oX3go7@ KTKT[X8Y10@ @P`p]#o+{ 7@  KTX 8YKTX @8Y29910#&547{>;o @ <99103#654<:=JN@,       <2<2991<22990 %#'-73%g:r:g:PrPbybcy #@   <<1/<<0!!#!5!-Ө-Ӫ--@ 1073#ӤR@d10!!d1/073#B-@B/9910KSXY"3#m #@  10"32'2#"  P3343ssyzZ @@B  KTX@8Y1/20KSXY"]7!5%3!!JeJsHHժJ@'B   KTKT[KT[X8Y91/20KSX9Y"@2UVVzzvtvust]]%!!567>54&#"5>32Ls3aM_xzXE[w:mIwBC12\ps(p@.    #)&  )KTKT[X 8Y99190@ daa d!]!"&'532654&+532654&#"5>32?^jTmǹSrsY %Đ%%12wps{$& Ѳ|d @   B    K TK T[X 8Y<291/<290KSXY"@* *HYiw+&+6NO O Vfuz ]] !33##!55^%3`d^@#    KTKT[X8YKTX@8Y190!!>32!"&'532654&#",X,$^hZkʭQTժ 10$& $X@$  "% " !%190@]]"32654&.#">32# !2 LL;kPL;y$&W]ybhc@B991/0KSXY"KTX@878Y@X9Hg]]!#!3V+ #/C@% '-'0 $*$ !0991990"32654&%.54$32#"$54632654&#"HŚV г "Əُattt$X@# %!"" %190@]]7532#"543 !"&2654&#"LK:lL>$& V\s[#@<21/073#3### %@  <2103#3#ӤR#٬@^M@*B$#29190KSXY" 5Ѧ`@ #<210!!!!^O@+B$#<9190KSXY"55//m$e@+$     &%K TX8Y99991/9990y z z ]%3##546?>54&#"5>32ſ8ZZ93lOa^gHZX/'eVY5^1YnFC98ŸLVV/5<4q L@2  L4307$7CM34( (+(I+*(I,=M<9912990K TK T[KT[KT[KT[XMMM@878Y@ NN/N?N]32654&#"#"&5463253>54&'&$#"3267#"$'&5476$32|{zy!orqp ˘s'6@   0210].# !267# !2'ffjzSb_^^_HHghG.@   2 99991/0`]3 !%! )5BhPa/w.,~ .@   21/0 ]!!!!!!9>ժF# )@ 21/0 ]!!!!#ZpPժH7s9@ 43 1990%!5!# !2.# !26uu^opkSUmnHF_`%; ,@ 8  221/<20P ]3!3#!#"d+9.KTX@8Y1/0@ 0@P`]3#+f B@  9 KTX@8Y991990@ 0 @ P ` ]3+53265M?nj @(B  291/<290KSXY"]@ ((764GFCUgvw    (+*66650 A@E@@@ b`hgwp  ,]q]q3! !#3wH1j%@ :1/0@ 0P]3!!_ժ @4  B    >  91/<290KSXY"p]@V   && & 45 i|{y   #,'( 4<VY ej vy ]]! !###-}-+3 y@B6 991/<2990KSXY" ]@068HGif FIWXeiy ]]!3!#j+s #@  310"32' ! ':xyLHH[[bb:@   ? 291/0@ ?_]32654&#%!2+#8/ϒs R@*  B     39991990KSX9Y""32#'# ! '? !#y;:xLHHab[T@5  B    ?  299991/<9990KSX9Y"@]@Bz%%%&'&&& 66FFhuuw]]#.+#! 32654&#A{>ٿJx~hb؍O'~@<    B %( "-"(9999190KSX99Y")])/)O)].#"!"&'532654&/.54$32Hs_wzj{r{i76vce+ٶ0/EF~n|-&J@@@1/20K TX@878Y@  @ p ]!!#!ժ+)@@   8AKTX8Y1299990]332653! ˮ®u\*$h@'B91/290KSXY"P]@b*GGZ} *&&))% 833<<7HEEIIGYVfiizvvyyu)]]!3 3J+D {@I      B     91/<2290KSXY"]@  ($ >>4 0 LMB @ Yjkg ` {|      !   # $ %  <:5306 9 ? 0FFJ@E@BBB@@ D M @@XVY Pfgab```d d d wv{xwtyywpx   []]3 3 3# #D:9:9+=; f@  1 ]@ /<20KBPX@   @    Y3 3 # #su \Y+3{@(B@@ 91/290KSXY" ]@<5000F@@@QQQe &)78@ ghxp ]]3 3#f9\ @BB K TK T[X8Y991/0KSXY"@@ )&8HGH    / 59? GJO UYfio wx ]]!!!5!sP=g՚oX;@CK TX@8YKTKT[X8Y210!#3!XB-@B/9910KSXY"#mo0@CKTKT[X@8Y<10!53#5oXޏ@ 91290 # #HHu-10!5f1@ D10K TKT[X@878Y #ofv{-{ %@'   #   E&22991/9990@n0000 0!0"?'@@@@ @!@"PPPP P!P"P'p' !"'''000 0!@@@ @!PPP P!``` `!ppp p! !]]"326=7#5#"&5463!54&#"5>32߬o?`TeZ3f{bsٴ)Lfa..'' 8@  G F221/0`]4&#"326>32#"&'#3姒:{{:/Rdaadq{?@  HE210@ ].#"3267#"!2NPƳPNM]-U5++++$$>:#qZ8@G E221/0`]3#5#"3232654&#":||ǧ^daDDaq{p@$   KE9190@)?p?????,// , ooooo ]q]!3267# 32.#" ͷjbck)^Z44*,8 Cė/Y@     LK TX @8YKTX 8Y<<991/22990@P]#"!!##535463cM/ѹPhc/яNqVZ{ (J@#  &#' & G E)221/990`***]4&#"326!"&'5326=#"3253aQQR9||9=,*[cb::bcd4@  N  F21/<90`]#4&#"#3>32d||Bu\edy+@F<21/0@  @ P ` p ]3#3#`Vy D@   O  F<2991990@ @P`p]3+532653#F1iL`a( @)B F 291/<90KSXY" ]@_ ')+Vfgsw    ('(++@ h` ]q]33 ##%kǹi#y"F1/0@ @P`p]3#{"Z@&   PPF#291/<<<290@0$P$p$$$$$$$ ]>32#4&#"#4&#"#3>32)Erurw?yz|v\`gb|d{6@  N  F21/<90`]#4&#"#3>32d||Bu\`edqu{ J@  QE10@#?{{   {  {]"32654&'2#"s98V{>@ GF2210@ `]%#3>32#"&4&#"326s:{{8 daaqVZ{ >@   GE2210@ `]32654&#"#"3253#/s:||:/daDDadJ{0@    F21/90P].#"#3>32JI,:.˾`fco{'@<  S  SB %( R"E(9999190KSX99Y"']@m   . , , , ; ; ; ; $( ( *//*(() )!$'      '/)?)_))))))]]q.#"#"&'532654&/.54632NZb?ĥZlfae@f?((TT@I!*##55YQKP%$78@  F<<2991/<2990]!!;#"&5#53w{KsբN`>X{;@    NF921/290o]332653#5#"&||Cua{fc=`@'BK TX@8YKTKT[X8Y91/290KSXY"@Hj{  &&)) 55::0FFIIFH@VVYYPffiigh`ut{{uz>]]3 3#=^^\`TV5` @IU U U U   B     K TKT[KT[KT[K T[X@8YK TK T[KT[X8Y91/<2290KSXY"@" 5 IIF @ [[U P nnf yy          %%#'!%""%' $ ! # 9669 0FHF@B@@@D D D @@VVVPQRRPS T U cdejejjjn a g ouuy}x}zzxy  { v } @/   y]]333# #V`jjj;y` C@F      B   K TKT[KT[KT[X@8YKTX8Y91/<290KSXY"@   & =1 UWX f vzvt        )&% * :9746 9 0 IFE J @ YVYYWVYVV Y P o x  /]] # # 3 dkr))`HJq=V`@C        B     K TKT[X @8YKTX 8Y9129990KSX2Y"@     # 5 I O N Z Z j        '$$  )( % $ $ ' ** 755008 6 6 8 990A@@@@@@@@B E G II@TQQUPPVUVW W U U YYPffh ii`{xx   e]]+5326?3 3N|lLT3!;^^hzHTNlX` @B K TK T[X8YKTX@8Y2991/0KSXY"@B&GI  + 690 @@E@@CWY_ ``f``b ]]!!!5!qjL}e`ۓ%$w@4 %   !  % $  C %K TX@8Y<<29999999199999990&]#"&=4&+5326=46;#"3>l==k>DV[noZVtsݓXX10#$@6%   #%#C %K TX8YKTX@8Y<2<9999999199999990&]326=467.=4&+532;#"+FUZooZUF?l>>l?VWstݔ1#@  1990#"'&'&'&#"5>32326ian ^Xbian ^V1OD;>MSOE<>L5 b@ <2991/0K TX @ 878YKTKT[KT[X  @878Y P ]#53#3+e#!Q@+     "  "<<<221<9990%.'>7#&73JDFHAMf fIX⸹)**'# 32!b`@!    <<1/2<2990K TX@878Y66].#"!!!!53#535632NL=ty-=))׏/я^R#/@I -'! - -'!0 *$0* $ $(st*(s099999999919999999907'#"&''7.5467'7>324&#"326{r%$&(r;t=:x=q%%&&s7t@?s9q(&%%s>v:@t8s'%$|pprR@F  B     fe f e<2299991/2<2<290KSXY"K TX@878Y@(' ' ')((79  ]]!#!5!5'!5!3 3!!!c`Tþ{yT9{3{JD{3@ <210##  \= >@54&.#"#"&'532654/.5467.54632{?>?>S8alӃ\]>9̭IXW:fqր][;;ȦI.Z.L-[.K''PGZsweZ54m@''TLf{xf[1,pEF)@dd1<20K TK T[X@878YK TK T[KT[KT[X@878YKTKT[X@878Y@````pppp]3#%3#^y/IC@&=>:A$104G$ 7aD=0^* D^ J21/02#"$'&5476$"3267>54&'..#"3267#"&54632mmllmmmmllmm^^``^^⃄^]]^\^BB@zBCFInmmmmnnmmmmng^^^傁^^__^]⃅]^^! "s;)_@3(%%  * "(kl"k *22999199990!!#5#"&546;54&#"5>32"326=P,]uu>DIE~bRhP{@p?Dq[[""CO@Mr%# @I    B   o o n<2991<2990KSXY" 5 5%-+#-+#RR^@ 10!#!^d10!!d/8L`@6EBC?2H09JC 9 $HE301B54&'.'2#"$'&5476$#32654&'2#'.+#^^``^^⃄^]]^\^ㄘmmllmmmmllmm}{{nWXfi`C.;I6Bf^^^傁^^__^]⃅]^^gnmmmmnnmmmmnb>KL?gwyVpMI`3Db+/10K TKT[X@878Y!!Vu=  @  Z[Z10"32654&'2#"&546PnnPPnoO@v+..ooPOmmOOp1.-rB .@     <2<21/<<0!!#!5!!!-Ө-}}^J@$}}B ~9190KSX2Y"!!56754&#"5>32 "?XhU4zHM98rn81^BQ##{l0b(H@'    #)~&~ )999190#"&'532654&+532654&#"5>32 \e9}F4wCmxolV^^ad_(fQI7Z`mR|yOFJLl?<:=svcE`sRf1@ D10K TKT[X@878Y3#fV` M@%  !   NF!2912<990"`""]3326533267#"&'#"&'#% )I#ER2bf*V H<9 NPOONN;9 %@]] 91290!###.54$yfNݸHF103#F#u@  ' 1/90!#"&'532654&'T76xv.W+"J/;<+->i0Y[ 0.W= ,@   |]|| 12035733! c)t'+n`d.@  klk 9910!!2#"&546"32654&PXγгi~hi}|P{ݿܾsH# @I  B   o op<<991<2990KSXY"5 %5 +-+-#^R^  ^R^  &{' d 5?&{'td 5b&u' d 5 $@/  !# #%" " "!& %999919990KTKT[KT[X%%%@878Y@ ttttv]33267#"&546?>7>5#537ZZ:3mN`^gIYX0&DeWX5^1YnFC98ŸLVV/5<6hk&$uuhk&$suhm&$vu  +@ ]1h^&$tu #+@ @O# /#]1hN&$ru  +@ 0?  ]1hm !@T   !!  ! !!!B     !  VV!"2299999991/<9990KSXY" #]@  s P#f iu {yyv v!# ]]4&#"326!.54632#!#TY?@WX??Y!X=>sr?<҈_Z?YWA?XXN)sIsrFv)H@9  B     <291/<0KSXY"]@gww  ]!!!!!!#!59=qժF՞su'&&z-k&(uuk&(sum&(vu@@ ]1N&(ru @@ @]1;k&,u/uk&,s/u`m&,v/u +1XN&,r/u +1  g@    2  y<291/220@(   ]]! )#53!!3 !iP`P5~.,3^&1tu"+@ 0?""]1sk&2u'usk&2s'usm&2v'u+@]1s^&2t'u!0 +@ 0!?0 !/0!0]1sN&2r'u +@ @O]1? @M    B   <291<290KSXY"  ' 7 7w55v8vL57y5yy5f +@< +,  )&  *&& &,+,* # )#3,99999999199999990@*WZWU!je!{vu! FYVjddj(|svz( ]] 324&'.#"&5!27!"&''3>_'y=_''NOy;WfNPƀ[gX@CHp@CpDfbMKYg[KKX)k&8uu)k&8su)m&8vu +@ / ]1)N&8ru +@P_@O /]1k&<ssu =@   ? 2291/0@ ?_]332+#32654&#'ђ/@0-'!  **.  !' $'$-F099991/990@@'(     ! "&  : :!MM I!I"jj  ]]4632#"&'532654&/.5467.#"#:A9`@IPAtx;e\`Wqqs`/Q*%jd_[?T>7;[gp{-f&DCR @?&/&&]1{-f&DvR @?&/&&]1{-f&DR (,+1{-7&DR.< +@ ./<.<]1{-&DjR -( +@(o(P-_(@-O(0-?(-( ]1{-&DR%@&,,& 2882 ++1@ ?5?/5/]0{o{3>@C'-%= 4%:.-*1 %?47&%7& =&-7"E?<9999912<<29990@0+0,0-0.0/00@+@,@-@.@/@0P+P,P-P.P/P0+0@@@@@@@@@??? ??0,0-0.0/@,@-@.@/P,P-P.P/ooo oo`,`-`.`/p,p-p.p/,-./]q].#">32!3267#"&'#"&5463!54&#"5>32"326=DJԄ ̷hddjMI؏`TeZ߬o0Z^Z55*,ywxx..''`f{bsٴ)qu{&Fzqf&HCqf&Hvqf&H"+1q&Hj@@ ]1f'Cof'v\f& +1F&j +1qu('@^%{&%#${##{#({'(#&'('%$%(('"#" ! B('&%"! ## #)&' ! (%#" QE)999999919990KSXY"?*]@v%+("/#/$)%-&-'*(6%F%X X!` `!f"u u!u"%#%$&&&''(6$6%F$E%Z Z!b b!z{     {zzv v!x"**']].#"32654&#"432''%'3%F2X)6 ~r4*!M!ü޼z&77kc\̑oabd7&Qquf&RCsquf&Rvsquf&Rs+1qu7&Rs .+@ /. .]1qu&Rjs +@ @O0?]1o )@ r <<103#3#!!oAH +@<+,&  )&  *&& &,+,* # #Q)E,22999999199999990@p(?-YVUV jf!{    { z{ {!"#$%{&%--&YVUZ(ifej(ztvz($$]] 32654&'.#".5327#"&'')gA\*g>}66]C_56`?`!*(Ou))Hn.Mw834OMx43NXf&XC{Xf&Xv{Xf&X{ +1X&Xj{ +@ @O0?]1=Vf&\v^V>@ GF2210@ `]%#3>32#"&4&#"326s:{{8daa=V&\j^+@ 0? /]1h1'q;$ +@@O]1{-&qJD+@o]1h'J$+1@oo]0{-&OD"+1u&${u{&Ds'k&&s-uqf&Fvs'm'vLu& <=/1qf&Fs'P&&zLuq&Fs'm&&w-u@]1qf&F&'wq&Gq @_?]1 q$J@$ "    GE%<<1/<20`&&&]!5!533##5#"3232654&#"F:||ǧN}}daDDa3&(q=q'qH@p]1m'yu(@@]1qH'H@p]1P&(zuq&Hu&(qu{&Hxg&(wo@@ ]1qa&H!+@!]1sm'v\u* <=/1qVZf&hJ  <=/1sm&*yuqVZH&JsP'z\u*@?]0qVZ&hJs'^*qVZ4' J;m'vu+ +@ / ]1dm'vuK*+1KQX88Y@ @@]:@    8 22221/<2222203!533##!##53!5qʨ"ʨ9Qx>@!   N  2221/<2290#4&#"##5353!!>32||}}`Bu\zzedx^'t.u, +1g7'+1Y1'q.;,+1H'q+1gm'y.u,+1VH'+1u%'d,u 'JLP&,z/u<<1??]0y{,@ F91/0@4D@P`p]3#\`{f'-\,@1V'M8L@F1f_m'v.u-+1V\f'+1j' .' N` @(B F 291/<290KSXY" ]@_ ')+Vfgsw    ('(++@ h` ]q]33 ##%kǹ`!jl'snv/Jl'sZvO<1KQX@8Y@O]0j' /' O@@]1j'q/'q9O @]1j'y1w/'ysOK QKSKQZ[X@8Y1u ?@   : y<<991/900P]3%!!'79Pw^Mo;jnH ^@  z z <<991/90KTX @ 878Y@ @ P ` sz p ]37#'7Ǹ}Lɸ{JZjXj3l'sv1@O]1dm&vBQ @?O]13' 1d{' Q3_&1wg +@ /  ]1df&Q +@]1'QU~V;@  AKTX8Y21@ /0!"#367632+53265PͳNijQRW1fOCCoa`ZVd{;@  NF 21/90`!!]+5327654&#"#367632dRQi&&||BYZuccH``01`e22wxs1'q';2 +@]1qu&qsR+1sm'y'u2+@]1quH&sR#+1sk'{'u2quf'Rs ;@   299991/220!!!!! !# !39OAg@AժF|pm|q{'3@1 . ("%4"1 K1 Q+E499912<2290@%?5_5p55555????? ooooo ]q].#"!3267#"&'#"32>32%"32654& H ̷jbdjQGьBN5Z44*,nmnm98olkp݇Tl'sv5m&vBUT' 5J{' UT_&5w}g@_]0Zf&U +@]1l'sv6om&vBVm'vu6  ))Ic:1of&%V  ))Ic:1u&6zou{&Vzm&6wu + ""Ic:1of&V + ""Ic:1u&zP77u&zW_&7wsg +1@_]07&Wq7p@]1F@   @ @ <<1/2<20@@p ]!!!!#!5!!  ժA@7C@  F<<2<<2991/<<<20]!!3#;#"'&=#535#53w{%&sQQ''PO>)^'tu8 '+@ ]1X7'X&+1)1'q;8 +@ / ]1X'qX+1)m'yu8+@]1XH'X+1)o&8iX&X| @@@!]1)k'{u8^f'Xe)&8u{&X'Dt'v|:+1V5m'EZ+1t'vr|< +1=Vm&^\+1N&<rsu +1\l'sv=Xm&vB]\N'zs=X&]\m&=wuXf&] +@ ]1/#@  L<1/0!##53546;#"c'&яN()g ,D@% ")%,$'".EG* ,(%#'F-<2221/<204'&#"327667632#"'&'##5353!!STTSSTTS:YX{{XY:E/tssttsstRd0110d}}P)C@#   . *29991/90"]!2654&#!2654&#%!2#!"#546D+ |v݇f>orqp ˘0_i1F&8@# (EGF'221/067632#"'&'#!%4'&#"3276s:YX{{XY:NkrSTTSSTTSd0110dtssttsst 3@  . /21@  / 9/04'&#!!276!2#!#ONDNO|N8DCDCD>@  G /221@  /ij9/0>32#"&'##34&#"326s:{{:"QrdaadDs'0@  0 <10>3 !"&'53 !"shSzjffbGGaaHH_^9'(9^_sZd$D@"! %  %  0%210&&].# !267# !2676;#"'ffjzS` SfM?nb_^^_HHgh$bzq"N@$ ## HE#210@ $$$$$].#"3267#"!2546;#"NPƳPNM]-GFE0iL~++++$$>: a .@   2 99991/0`]3 !%! )"#5465BhPav/w.,~0_i1F.@  .21@   /0)!"!!"$54$3!!@DNN|#+qZ?@G E221/0` ]5!#5#"3232654&#" M:||:ndaDDadqVtc'T@ )E Q E(]99@   (99@%S 910%!"'53254%&'&326&#">kGxfu'~@3cnBOFFu\0%p9 *E +@    21@ /0!5!!5!!5E>9+uD@& 39190!!"56$3 ! 7327upo^   2`_FHg[{(@@$ )) #)* &)190.54$32.#";#"3267# $546؃ YsrSǾmTj^У%!| &${spw21%%ݐf#A@  2991990 ]!!!!+53265ZpPM?nժHVe@#   LK TX@8YKTX8Y<<9912299990@P]#"!!+53265#535463cM/ѮcMPhc뻫Ph*Nsd&I@43! F'1@'$$'990%!5!# !246;#".# !26uu^[DM?npkSUmnꪖ_`%Rv%@ 'P $&]ĵ 91@ %$&222990@ #%$$<<$#$%#@$"! #9927654'&'3#"'&5476736,3,,3,6hC.KddK.Ch B9Iy\\yI9B z^ȮwBAWWABw1G*O@, *&NF+291@ '&&  #/<<9990%27654'&'5+"&54&#"#3>323LTWJ>ymoF||BuLibep_!edg .@  KTX@8Y991/9903;#"&n?M-– R E@   >f3@)B 6  999991/299990KSXY" ]@068HGif FIWXeiy]]!3!+53265jG?n+Vd{Ks 1@ 3221@   0! ! "!&32sy:;x Vb[[z=g&24v'X Rs3@ !  <1/0!4&#! !2!2"327&nzy;pa'Xܯ–bb-LgFqVY{!:@ """# E"9104'&##"3232"327&&&idRصRQ@TVt1098``:6:@   ? 291/0@ ?_]32654&#%!2+#"#5468ʄv/ϒ0_i1FV$O@$#% %G  F%22991990@ `&&&&]%#46;#">32#"&4&#"326siL:{{8(adaaTV@  ?  2299991@  /9990@ @u|]#.+#33 326&#A{>ٿJx~hb؍Oђ r!d@ -" "99991@B!  "90KSX@ Y6 327# '&546?6764'& {璑z<;YZL-|숋_ppٶ+23@@md{'@  !! RE(99991@ '$$(90@S !S BKSX99Y"]@/)?)_))))))]@% '$&((*//*( ( ))$]@.,,,;;;; q>323267#"&546?>54&#"Lf@eaflZ?bZN?$%PKQY55##*!I@TT((7V6@   O 221@   <20;#"&5# 54!23%&'&#"3wMc/R5!n|wj=hP`@o,0A37V?@ F<<291@/<2990!!;+53276="&5#53w{KsF0j&&էN01`>X@ @  991/2990K TX@878Y@@p ]!!##"#546;^vժ+Zi1F7I@  F<<2291@  /<299990]!!;#"&5#53546;#"w{KsբcMcN`NQfT@ @@ 120K TX@878Y@@p ]!!;#"&!n?Nժ=–_&84i' XN:@!3   1@   <2220!! 47!5!3254'5!X ƱXw>*a"Lav-@   /<91@ 0%254'&'5!'&'&33cAnMagn"ʦmWDtz–d@  @ @99/1@  /9990@        BKSXY""#3 632#54&9%NZUUIG9\[ny6P=V{j@  K TKT[X @8YKTX 8Y9991@:        B    9990KSX2Y"@      '$$  )( % $ $ ' 755008 6 6 8 A@@@@@@@@B E G TQQUPPVUVW W U U ffh { F]@%     # 5 I O N Z Z j ]+5326?3 67632#54&#"N|lLT3!;^0XQ99) hzHTN43`rr:T*\@5    B  B K TK T[X 8Y9991/<20KSX<<<323#L:s_%'ST_ijxzX"Jh0@umHLIwKK!!C12\RI`1]5@ F1@  0 4&#!!!%$ $5& )sQ;-%,%hV)$yhL?`3@  F1@ 203 4&#!!!32!"'hi;-ԧc%,&cV)$yJX$!"'&'5327674'&+#5333!plnUQQLITNPc9:V>}ws}#(rAbLrV{@@  F221@ B 0KSXY#36763254'&#"s4QҸMNr98xܭz BR1pqWBAV&@ F10@ @P`p]3#V''V:@    <<2<<219/<2<203!!!!#!5!5!5!s____,Ԫ m'?' f'@'qf'@Gf$'-/V'Me/V'MvOf'-_1V'M>1V'MeQhm&$wu<1{-f&DZ +'+1`m&,w/u  Ic:1^f&  Ic:1sm&2w'uquf&Rv <1)m&8wu<1Xf&Xv  Ic:1)3&08X1'q{;)Z&86X"&X)Z&80X"&X)`&80X"&Xq{h3&${-1&qR;h3&${-&DH4'q>{o'qs%T@!$"43 &<1@"#%&99ܰ KTX"@8Y<203## !2.# !2675#535!5yyuu^opkC XSUmnHF_`%'XqV{ 4X@"2% G,E5221@ #% ) 2/3 &)/99<20`666]4&#"3263#!"&'532767!5!6=#"3253:aQQRZ9||9=nXF]@,*_EG^[cb::bcsm&*wJu!<@!T!$!]1qVZc&JJjm'wu.m&Nwu* +1KQX88Y@ @@]se'42qeu{'Rse1'q';qeu&qsm'wuyXL/f&TVdf'%  Ic:1 '=' ']'q']Gsl'sv*qVZc&Jv-5@8221@ /203!327653! '&5!#>=B>d`gd"dPNOKZ߀xxv 9V@@  221@ B 0KSXY%#3676324'&#"8WST=<HW5xz7 GF3k'uu1dd&QChs&s\}{s&s}Hl's\v{oc&vefl'svHc&vhp&$|z{-d'Dh6&$x>{-H'eDp&(|zqc'H6&(x>qH'Hsp&,|Yzc'fw6&,x>>UH'$sp&2|Azqud'Rs6&2x>quH'RTp&5|yzJc'%UT6&5x>^H'-U)p&8|zXd'X)6&8x>XH'X'v6o{',V'S77'WRs. 56$>54&#"57>54.#"5632?4o1\}p_s54&#"57>54.#"5$32Fp>!BlJc(v];?"AW?-1CA#E ptgDZX%KlaF='.`[b[3XpVU 2#PQ̝qpD(4%3254'"632!"'#67&5#"'&76323 76'& %44nI5"C0:XY|ˀ|YX:ST$TTTTT- H:E<$d0110d^jtssttssq% ;W@$3=E (B!8;7B/E<̲ ;]91@$3< ;<,<990" 7654&327654'&'52 '&54767&'&5476!˸jkkjpkk_;̨_`Lm䖋_``aCUtMMMMMN'|OEH-AA+Mdha "ccttttُcc"FYXSJqq 4C@6E B42()+&BE5221@4)".559920" 7654'& '&5467&'&5473327654'qSRRS SSSR:4HRQ;4?+IHIJ,MMMMMNMMJ@b@Y "ccttttُ"#VKYIAAAAAtw>\V@ B  K TK T[X 8Y991@ B  /0KSX@ Y@@ )&8HGH  /59?GJOUYfiowx]]+53276=!5!5!!Hri&&gPP%01oXV`@   K TK T[X 8YKTX @8YĴ@`]99Դ@`]1@ B  /0KSX@ Y@2&GI + 690EIWY_fh]]+53276=!5!5!!۞Hri&&5ejLP%01%hP&$@{-&D_u&(zqu{&Hz{s3&2bqu1&qs;s3&2iqu&RsO'z't2qu&sRs3&2jqu1&qs;1'qr;<=V&q^\p\%3254'"632!"'#67&73%44nI5"C1- H:EVy` 8@   OF 991990@  @ P ` p ]3+53265F1iL`aq #/A@1E%G +G!E0<<<<1@( . /22220 6& 23632#"'#5#"'&76'&  7/ST$Trrrrˀ]STTSST$Tjtss ^ŨŢtsstjtssqV{ %/D@1E$G+G'E0<<<<1@ *.! 02<220'&  7"'##"'&763253632 6& STTSST$TrrˀrrST$TdtsstjtssRŢŪjtss|3 #!#'#7'7 3!Jafp|҈2F;R/o]jY'FF8O ",'&76!27&'!2767# '#&# rfuSv=:efc.1 tsfjwv9tFXh$xYv+!f //_H$$\/ح ]"+'7&576!27&'32767#"'&#"i`UUQ.-Y_vcPNONMRS]7GGcc^N lOU ^q+$Vqrg j ;@   : <<1/<20@ 0P]33#!!#53ʿ_w1##'!5!7 !4" gZ8f,i> XRBY bo{=4'&/&'&54632.#"3#"'&/&'&'&'53276 23@LLfLNZDE11?PS{W*L'TrGY$alfccaFF'K((%$JK((**T@%$!,KL[@~$=&[#5-,X3`!;#"'&/&+=!qjN\1*LlTrGY=Z^e`1~$=&[? %P6@ 9991@  /0##32654&+"56;2'񍚚EOZ*,FP{7@   991@  /032654'&#"5632##/dLUIVVN}AH+Fnt  (\@ #  . &%)<229991@(% #/99/<20*]!!!2654&#!2654&#%!2#!#53[D+ |迿ɐʇf>orqp ˘p _@ 8AKTX8Y<2<21@   29/<<2299990]3!33#! 5#53!3265˥ߦ®j*$}h0B33#!!!!#7#!#!AX .AA<VF㪾FqB&-1&'&'!3267#"'#&'&3273&#"#So+Jajbck{cPm!)81G\9/Zo Z 6Z44*,!  C "2JcfRY@    9 KTX@8Y<2991<2990@ 0@P`]#+53265#5333RM?nʿwHVS@$   OF<<22991<2990@ @P`p]33#+53265#533#F1iL`(aؤsf$C@$  %" %  %2299199053;#"&5# !232#"nEMMT–\\xEEqV@{$H@"%"%G E%229910`&&&]#"&=#"3253;32654&#"@F:||:Li1戮VּdaDDada= T @  ?  !<299991@!  B  /<229990KSX9Y"@"]@Bz%%%&'&&& "66FFhuuw]]#.+##53! 32654&#A{>ٿJxʿ~hbw؍OJ{=@ F<<<1@  /<20P]###533>32.#":.I,h<ĤfcΡ3!733!#!53!ٗ ٗwјv9 V`+5326?!533!33!+N|lLT3!øLùmhzHT33`{ ,@ .% F-22991@-&%"*-%  9990@1?$?%?&?'O$O%O&O'_$_%_&_'o$o%o&o'$%&'$%&']@+?#?$?%?&?'?(?)O#O$O%O&O'O(O)_#_$_%_&_'_(_)]2654'&#"367632#!3267#"&߬A@o\]?^^fe~ST`Te__Z+f{b:9ml)Lf01a```FE..'qZ{8@G E221/0`]53#5#"3232654&#":||ǧdaDDa{ 8@  G F221/0`]4&#"326>32#"&'#3姒:||:/Rdaad` $C@  !G! F%22991/0`&&&]4&#"326>32#"&'#46;#"姒:{{:Z[/Rdaad~Ӝ}}{ 0@ ! !"EH!<106763 #"'&'5327654'&#"LQQU]SRMNONPccccPNON5#$+qrrq+qs{'/O@( ,,H"E02991@.*%00@ 11111].#"67632#"'#47&'&!23254#"NPc'>IjJ?_SPI 9/-U:Me5++rQ,3H=Y}/)9DhQ#3 :#:9KqV@$K@$%"%OG E%221990`]#"&=#"323;32654&#"@F:||:Li1戮VּdaDDad^ؙa=q$=@" %%  GE%2210`]546;#"#5#"3232654&#"iL:||ǧadaDDaq{"r@ KE#91@  #90@)?$p$$$$?????,//,ooooo ]q]47632!"&'532767!7&'&#"qkcbdcjfg ]\RS^,*4cdWWZZq{A@$  KE91905!.#"5>3 #"73267qN ͷjbck 9Z44*,#ė|{ 4w@6.('4 KE5<Ķ&  91@/.'""5 5@  &"90@ 4 &'<<<<<%6'6'32#"'&'&'&5>3 73;#"'&5Nf  R`\Lladbck $˸&&i+@WR֊>8E#Z`vg'#d4*,#)u10`Z|I|*|>i@@603273;#"'&5|PUTZGUU]UTNHtCDFEwGQPabLq_&&i+@WR@\l%88ZX83,-F@.. NBj10`ZȦFq|/;@ 1 &,E01@00)0#90"327654'&+5327654'&'2# 76`cchҗUTNHtCDFEhqr<V`K@   OF<<22991<2990@ @P`p]33#+53265#53F1iL`(aؤqV 0U@)  &#-* *-+& G E122991/990`222]4&#"326!"&'5326=#"32546;#"aQQR9||9iL=,*[cb::bcaqVZ` #C@ # GE$21/990`%%%]!"326!"&'5326=#"43!aQQR9|=ͻ,*[cb:*qO{8@4 E1990%#5!#"!2.#"326Ae{-h]_cƳO|$$>:77>>`Rd`#y@ %  $ĵ 91@  $222  990<<<<< 3#"&54767327654'&'bB_j&;;&j_BC(::(xܱSccS$-EIdccdIE-`d`#y@ %  $ĵ 91@  $222  990<<<<< 3#"&54767327654'&'b)rG,EE,Gr)C'88'bLx>>xLb-!@2FF2@!-VX`9@     NF21290`]332653##"&||Cua{VfcdC@!   N  F2991/<9990`]#4&#"#46;#">32d||iMBu\~aedVd!J@%  " NF"2991/9990`#]+53265#"#46;#"632diLiMHa=~a >@    F<<<2221/<20@ @P`p]33###533#¸`<Ĥn`Mt` '@   221@   /2205!#3!53t褤K#<@ % V V$<<1@#! !//2<903327673#"'#&'&#"#67632= &}33[ &}33[ %$RIJ %$RIJMT5@  <2<1@ /9/<2033##4'# 7632&#"3=5*7M\TK9V_ (@  F 1@   990;#"&5y=x1F|t(L6$@#&#" F%<̲#91@B""  " /9/ 990@$#@  **8;ILT[q ]@$$%$$5$7E$FT$\ ]@    ]2!"'&'5327654'&+5!#3!CicUQ^cdjTmcd\[je8+lh%12KKKJ3Lb&^@PP F'<91@  #''<<<290@0(P(p((((((( ]%#"&5332765332653#5#"'&Cb`ruSSrw=ZXyzVUy=<b`^zbze32>>Vb&a@PP F'<91@  #''<<<290@0(P(p((((((( ]%#"&5332765332653##"'&Cb`ruSSrw=ZXyzVUy=<b`^zbzZe32>>V{0c@PP)%'F1291@ %*!*-(&/<<290@02P2p2222222 ]>32+5327654&#"#4'&#"#3>32)E__RQi&&ru99wSS?yzUV|v{zH``01NM_``gb>>Vk{Q@N O F2991@ /9@   990`]#4&#"+532653>32k||F1iLBu\satedVJ{;@ N  F21@   /  90&54&#"#3>32;#"R||Bu&&i1F``edH10d` y@BNF 991/<2990KSXY" ]@068HGif FIWXeiy ]]!3!##`ylqu{ ,@  Q E2210"!.265!2#"qt蔔98q$`I@  E2ij 991@   /<<@ 9/0!!!!! '&76!#";:E*%xxxx%`ݛlklm>|$2@ &E E%1@ #%<202765 26= "&'"&H`k&InI&k`B"F:.aע ģ0[1[0T\l6puypVi`/@   /2991@  /90%!"/32653#r%832JI,:.˾ fcVJ{:@  F2190P].#";#"&53>32JI,Li:.˾atfc~{%@ 21@  /29903!5346;#"iLAat~{%@ 1@  /29903!534&+532ʴLiAa`@4  B      F299991/<9990KSX9Y"@]@Bz%%%&'&&& 66FFhuuw]]#.+#!232654&#0s2âJ{Qpwu t]:'`iVNM``E@  F299991@  /29990332673#!32654&#Q{Jî2s0jp|Ɓuw`':]t i`MNVoV{0@C  S('  S'('B1 '(!.1' ($R$+E19999190KSX99Y"0].#"#"/;#"&=32654&/.54632NZb?ĥdXLie@f?((TT@I!* ajYQKP%$V4@ O F<22991@  99046;#"+5326cMF1iK»Ph)aV O@ !O F!<<229921@! ! !99<20546;#"3#+53265#53#5cMF1iK`NPh(aؤi7V5e"O 1@ 04&+532;#"&McKi1F(hPaV2@   O 221@  /<20!3## 54!346;#"#"3276w5RcMów|n!o@`Ph3A07^3@   /<<2991@  /<2990]!5!4&+5323#{Ksբ>`N7V=@   F<<2991<2990]!!;#"&5#53w{Liൣa>`C@     NF2221/222220` ]3!33##5#"&=#5!326:CuȮ||h=$#^lfk`8@   91/20@ 3 3#f%.]`8XV`@"B  OK TK T[X8YKTX@8Y2991/0KSXY"@B&GI + 690@@E@@CWY_``f``b]]!!;#"&=!5!qjLLi/F7e`ۧa%X`!@  "KTK T[X8YKTX@8Y299<21@  /<0@ BKSXY"@:&GI #+ #690#@@ECWY_#``fb###]]!367632+#47!5!3254qjL"TA`:&>R~ie8FX`ۢG7W9W`/=3<;4%6]XL/` @ "!̲91@B!  !9/ 990@ @  **8;ILT[q ]@  %$ 5 7E FT \ ]@    ]2!"'&'5327654'&+5!5!`q|/=@1 %,%E01@0 0"0( 90";#"327654'&% !"$5467&'&5476EwEFDCtHNTUhcc`a|p<:!a>>`V.9@ F<<991@   /<203#33## 54!3#"32767Ku_+xG`͋BA0 L` ## 33R9L T#`@ F1/03!!`3qV $C@  #%% "GE%2210@ `&&&&]32654&#"#"32546;#"#/s:||:iM/daDDadaX$L@ & %<<ij#1@  $! /<2KPXY032765&'&#"56763 3###53T?V:9cPONNLQQUmlprLbAr+#}swԤX$M@ &"#E%<<ij "#1@ $!# ##/<2KPXY0535&'&5476!2&'&#";3##plnUQQLNONPc9:V>ws}#+rAbLrq &) 76'& %3!!!+5#"'&7632/ST$TTTTT iL:XY|ˀ|YXjtssttssH^Lۓd0110MqL4@#5#"'&76323!2!"'&'5327654'&+5 76'& Z:XY|ˀ|YX:jejbVQ^cdjTmcd\]:ST$TTTTT3d0110d^L$8*mh%12KKKJjtssttssq 3: 76'& %%!332!##47!#5#"'&763233254#/ST$TTTTTghL<):XY|ˀ|YX:FXjtssttss_ 3<;4d0110d^6[7@F.#"#"'&'#"'&5#533!!;5327654'&/&'&54632NZED11?QR|{Za]gQQ{%&sfccaFF3,@LLf?((**T@%$!,KL[[!&PO`>''M5-,QK($)$JK7V&/!05476;#"+53276=#"'&5#53!3wxWQîc&'QRF1i&&QQ3%&sN[V((h)``01PO`>''7p-9D!6!2&'&#"63 #"'47!"'&5#533276'&#"&57!3w{UQQLNONPcccO+eKTIQQ;BS_r(ր%&sz#+qrfr v)2LOAPO`> 'KV ''/Vo5+5327654&#"#!##535476;#"!;67632oRQi&&||ӹWWc'&-BYZuccH``01/яNUV((hce22wx#5.#"#"'&'#34632327654'&/&'&NZDE11?PS{|Zb]hf8b_caFF2-@LL?((**T@%$!,KL[[!&2-,QK($)$JK @   F<2991@ B /0KSX@  Y@B &GI   + 09 @@@@@C EWY `````b f]]3!!!+iLLۓ6 333# #333# #6ttttU=63@    <2<21@  220!#!#!#!#6kkUXrXJ3@ NF 21@ 0%#"&54&+53232653#׃Li1FęaBþyVv!:@ #NF "21@" ""0%#"&54&+53232653;#"&'׃Li1FPh2FęaBþyfu0@ 32tNN^luu)qJy}wYYk\g88u:KSX@ 32tNN^lugrB0)qJy}wYYk\xkW6Vr88 #@<<1@03+5327653#zt43r,Bttx66XVru@ 1@ /0.#"#3>32.biuu$uT  qksa97H <1 /032653#5#"&'H.bitt$uT  qkJa97Hu' <1@  /<032653;#"&=#"&'H.bit0B,rg$uT  qkJ V6Xlx a97 !+33276?3327654'&+CFCDtk=%%(f{n!!"}K'))'K}N;[--s?5/.6 333# #6tt&+53276?331/.N]D0 {{bp"#WK/itftf&t  @ 10#5Rڬ@u1 ܴ? O ]ܶ ]<1ܲ]90526544u@XX@sPOOP{X@?X{POPPu1 @    ]<1 Բ]90"'&4763"3sPOOPs@XX@PPOP{X?@Xu+@ 91@   032765&'&#"567632#'y7$#?q22110335WDDFk[@*7K$@ ` XFh_@Cu-@ 91@   0#&'&547632&'&#"3kGDEW53301212q>$%6y[AmC@_hFX ` @$K7*@ 2% % g 25-5g'|?f=u912]90K TKT[X@878Y3# #fg|?fLu91<Բ]90K TKT[X@878Y@ 5:5:3]]33|g?f7@ u91290K TKT[X@878Y3#'#f?f7@ u91<90K TKT[X@878Y373x^@1@/0#^+b+qsRf3#ff #ofv^@1@/0%#^++Tq^#onvsR3#lo#E@ j,5!##–,dU 533##5#5Dud&u!5!&>ߖ)9H W@ VV1<0K TX@878YKTKT[KT[X@878Y332673#"&v aWV` v HKKJLDfN@ d10K TK T[X@878Y KTKT[X@878Y3#  @ V xV104&#"3267#"&54632X@AWWA@Xzssss?XW@AWX@sssLu @   '1/90!33267#"&546w-+76 >&Dzs5=X.. W]0iJ7c@$   VwVv99991<<99990K TK T[X@878Y'.#"#>3232673#"&9! &$}f[&@%9! &$}f[&@Z7IR!7IRfB@991<20K TKT[X@878Y3#3#߉fx%3;#"'&5&&i+@WRd10`ZȢf '#7'373\\]]\aa``u # 5473733254/MMz /1/03#zttu/2&'&#"#"'&'532654'&/&'&547632j1549W++](}24NM9>=D@?>=RX o(l00GF@99 a /$*+MW33 k2-*)*IX01 u! #'#37 ͉H+uX@ 1/0!!5!AGЈX'@??//21/]0!!5!3A4X@ 21/0!!5!3AhhX'@pp0021/]0!!5!3A4X@ 1/0%3!5?p+v'qqm 93vJ!_@ Vw V v"99991@   "<<99990K TX@878Y'&'&#"#67632327673#"&9 &}33[&@%9 &}33[&@7 %$RIJ!7 %$RIJ{f6@ D910K TKT[X@878Y # mXfvq{Pf6@ D910K TKT[X@878Y3#fs{?f<@u991290K TKT[X@878Y3#'#?fsH7b/q|  )1H{d%@ 910@4D]3#h{)I@ dd 91<20@#4D`````````ppppp]3#%3#^y)7{"@ V@ V /1@@ /0632#546?654&#"7pihX,#w3-.>GZdH3UC=A   (6%""($4f{Cf<@u991<90K TKT[X@878Y373NxsD/1/0#DD'4]fB@991<20K TKT[X@878Y#!#͇fxx)1')1H VV/1 /<0#.#"#> v aWV` v ")KKJLD( @0#3Ӥ?#55#53pp{53#7"op{y3#@uUCqPUv$<#5353#ĠxxxF33##xx2xU?p!5!#Ik{1@V/K TK T[KT[X@8Y21@ /0532654&'3#"&=X.. W]0iw-+76 >&Dzs5V @  V21@ /0"&5463"3VZ||Z(55(}ZY|x5'(5 M3!5353D M#5!##걈ň$ #53533##Ġxxxx 5! zV '+53276=0RQi&&``01wV %3;#"'&5w&&iQR10``fSC'SjC( @V xV1@ /04&#"3267#"&54632[6'(55('6y|ZZ||ZZ|&65'(56&Z}}ZY||jT @03#Ӥ#uzLuD/1/0#D`tP#5!#fJc9X#"4533273273" v aWV` v "6KKJL9HS/TB  #"'&'.#"5>32326SKOZq Mg3OINS5dJ t]F ;73 !;?<6 7=xh!5xhh5!Ĥh'`_^NO'ygfFXY @  V21@ /02#52654&#Z||Z(55(B}ZY|x5'(5[3!53[J!!5#>J*>c9X632#&#"#&'"#72;tv gfv ifvtR+ '7'77}`}}`}}`}}`p}`}}`}}`}}` .54675>54'&'C!RI 7!RI 0PQn +0PQn : '  fCqPfvH7FbV+I#5!#!Ֆ֖V,2!5!5!5!>>2xx3#3#@`tt!#!–*>,Jf'73327673#"'&'#7&'&#"#67632Bmk  &}33[& !Bnk  &}33[& g  $%RJI g $%RJI J!%'.#"#4632326=3#"&3#3#9 $(}gV$=09" (}gT";薖Җh! 2-ev 3)dw.CJ"ttc( 7!#'73!'3p~(͛3#557'2d͛~~x&'&4767@*,,*@rNPPNr*,@A++{OPPN`1'+!x050567654'&xrNPPNr@*,,*{NPPO{++A@,*.Do2>&"762"'"&46264&" 5O57O5>||=>||66O5555M75m?|}A@}|6M65O5p pk Ppk!!p kpT!!p ଔ* '#'&'&#"#67632327673#"'&O,$e5Fqp[?9ZO,$a9Gqp[?9J7  $0GJI "7  $,KJI pn w(5!'3#7ws~~d͛q` !#!#!#Sb+e !#####b+tf@103AntVH@10%#AnH3y`V #"'&=3; #V!. {q{'yOF{'y#sRf1@ D10K TKT[X@878Y3#fFR&jl@_]@_q0hf'&HFyuf't*f',}f'z.f'4(f'n9f'h=6'.Mh$%j@ 1/03!!)ժh=@ B1/0KSX@Y !3f5:9+(\=;+s!2@"" "#3"10!!"3276'&' ! '&76>b܁܁:xżp[bb,j.h<@ B1/<0KSX@Y3#3#:9&+031b *@    <<1/0!!!!!!29iggqs2;3 F@B   <<1/220KSX@   Y%!!5 5!!>!8ߪp7<s'<@) !%(<<<<1@' %'/<<<<0367654'&'&'&76753#–bbʖbbWssWWssW=;;s.@ <<1/22<20!6'"'&336763#ּՂnʊnhg椌gHN&3@ &("3'1/<2220%!567654'&#"!5!&'&576! cccd?IH1/GGaʦa>”XN'r/u. +1N'rqu9 +1qf&Enf&PIVdf'Kf&MF*&Yqy *@ ,%E+99@ ?/]q@ ) !/99@<<10@  ]@IIIJN LNIK ]@:9:88? <>]@ + +*))]@  ]@++]'&#"3273;#"'&'#"'&763 N,-=MKLyHc( #) Xn^T).^,ru7 nik%1)0T*XoW)&V!7@E F21@  90%#! !"3 5 4# yYo 0kEdZ&J:@ V`@@ 1@ /<20@ 993#&+532i^;,_1FLdVD~qu-T@(/E( Q!E. ]99@%%.99@S910&#"#"'&4767&5!232654'&'&fu5KxD7VUV[a~@Fu\0%p̥@$OF(Iqrs`g |2=@" 33'(#,34 '0E310&'&547632&'&#";#"32767#"'&546p<@ KQX@8Y1@ 20%#457654'&# !5!ʄOTJPE* :;f,KOxsPWKL,#%5,*3Y'iVd{1@  FN  F21/0@]#4&#"#367632d||BYZuccH`e22wxqu$!O@ """#E QE"2]21@?]0@ w##]!3276'&#"2#"'&76EVSI 6VQ@=񈉉d~uvn` @ F1@ /0;#"'&5c"$lYoRR`+.0`b` I@   F 21@ /<20@    <<33 ##Gb`/ZFB?= F@ 1@ /<0@  # #'&+5z~J/k`ue<2~V`wJ`B@1@ /20@ 99!367676'&'31!xdLjE.*{`T|p5dwY|rNįtkR&@@ (" %'1@ '#"'<90%#457654'&# %$47#5! $ڄOTJPE* :MKOxsPWKL,#%5,*,X$Rݿ qu{RJ`/@  1@ /220!#3267#"&5!##J117,#J%x\c`PH? XV{1@ EQ F]1067632#"&'#44&#"326=;{:+fZ#adqR{$6@ !& HE%1@% %0 !2.#"32#457654'&-ULNPƯPTJPE* >:##++LOxsPWKL,#%5,*q` 1@  QE]1@ 0"32654'&'!##"'&76sRVVOcm񈉉qnsȷzn휝dm`#@  1@ /20%;#"'&5!5!!$lYoRR\ W0`b*`+@ E F@?? ?]1@ /<0327676'&'31'"'&5R27ki;jF-*eb`+@EvfwZ{sxvpVh )=@+E(#E*<<1@ *'*<2<20"27654'&'2##"'&7673=A__UVF6˷džfB:VVMpˑRh]p[nmNssg.;Uda@    <<91@  <<90%KSX@   99  9 9Y#&+53;'$ܕ11FA3N11F~0)~pV`6@   <<1@  <2<<0&'&53367653#EkUJ|CUvܷ%aw~LB,BTxnc#n'`8@E  E1@  /<2<0 433233243! &aƏ˪ޏƛa!)R@O@+}&Mj.*&jYquf&}S*f&"Y'f&]YVj 3! # # wHV1M$ 'G@)E& F(2Բ?]1@ ("((Զ?]990267656#" '&76#327>&iPDyz]6;~oxҤ]Y:PWp=l޺lǧ_ը,嶖ꀰ-ўqu$ 7@ !EE <1@  04'&#" '&4632  1BSxyJ̃Я#/p~ZZ7Ai6deBWQ I@ "!9Ĵ?@]1@ /<99@ o]0#4''&"562%62#"FR**RMw(oUCHk&_*SKHv H# 0r{C @[)/Bf'nfPWQN'rufpV'A@)   $E(<<<<1@ (  (<<<<02##"'&76327676'&#"DžǷdžǷqMTVMqqLWULc휙owgsugHgusgAm`E@ EE91@ <22205!#%$! 47)323764A,Ma")aM:GϤ*RѧOp[g9&'&47#"54654'&#"563277632327"'532! `7"7$>9[@[`7"7>9[&F]_I I5l|"O z:6hl0'[Ml |"Oz:6hlf$11sXD@!  ܶ0]9ܶ0]1@   <0#&'&76!   76';:{HpҳI椤qVu{ <@!E E ܲ0]9991@   <0"32654'&#&'&7632sVVUVVV9kjstntstu n}{R$.@ & #%1@ %"%0 32#457654'&# '&76)F`{[mzYTJPE* :xe+wTOxsPWKL,#%5,*eNqRQ` 4@ " E!IJ]1@ ! !0")!"32#457654'&g-[oPTJPE* >LOxsPWKL,#%5,*#)@VF'6  (<1@ ( $(0347632&'&#"!!#"'&'53276`1213$)),x:KAb933.1220W@Rd >Qoɏ?s K_7"'&76'&526n 'BQ_'BQ_[~,`*l#FR`*l#FRB@ 91B/0KSX@Y #!3&pM]rV`!#56! #'#64?!"QhRR_@0:IKiXL}/M4!wx#&'#&' #'nd2Fb.-t`4#M!P^sK=W@< 9:?5 +,">99KSX +9> &1>29<90'6767&'&'#"'&46733276=332764''3=D۴vayͤgDd''dey{d;]TCHI}rHGFFtAGCT_8d榈d*0QA^^^Fkmihhimw'AFU'`%S@!'E  E&99KSX"Pe^Ґ8*7D ! ! 12԰.#AL.#^Yq4+& "H4B;;=/?"+VhPOV !! 7654'&#"#676! 3 7llc^#,V)ۄe]6?fضdVj{ # 7654'&#"#67632327\B\\TP%I/yYk}oSKu,2R¤ຐs5%! &'&#"567632 67632'&#" ;!53276n"?E! rK,/ 4'Kr !D<&tEGGH h=" C(FK#C "&E !!6{5%! &'&#"56763267632'&#";!53276[96:@%((%@:6-:IkI:8=3553gs%+$67632! '&76!2767&#"327*W8QU{2Τ|sK^lȺhiieb-sJV"1Pһ '$Astxssq[/&67632#"'&76!27674'&#"3276I,)e[xtgO_\SG]EZSTVXXTRS7xJF61𢢜Pһ ''rsstxsst,V4@  <<1@   <220#5!#!#!3`d`du7U3@  <<1@   <220#5####!3_pzpppg3#"54654'&#"563277632327#"'$47(`7"7$>9[@[`7"7>9[@[|"O z:6hl0%[Ml |"Oz:6hl0%?[MV{$:@&E QF% ]1@%" %04767632#"'&')! $'&  7Z6;x[Y: +STTSST$T%Уb^#10dX4tsstjtssq{FVyMsaq{!&'&#"!!32?# '&76!2%%cjf_[_fMJOhk en(' c\\c( +{!56763 !"/532767!5!&'&#"'(ne khOJMf_[_fjc% ؜c\\c Vs'& @  >  91@ B  /<290KSX@  Yp]@ 6II YY @  &)5:EJ ]]! !###-}-!+V` O@ F  1@ B   /290KSX@   Y!!###`{`UV{'4767632#"'&'!!#5#5'&  7Z=;{XY:eSTTSST$TfZ#10dȪpptsstjtsss'Hs'&y3s''yk&uuN&ruBBBB|#I#IabhFaF`C`#BC`CUXC`C85YBB#Ih;5#I@PX@855Yf4@  <1@/20%+532654&#!#!5!!!2L>o||Rh"9+Fjk&sus'N@  2<1@  IIPX@8Y0! ! &! !!! 'zOFӐhgս6,XNf-T/3@   <1@  /<20!565!32#!% 4&+pٕxL@+8/Xڦ5@ 2<21@   /<2<20!!#3!332#4&+326 z6࡟9d݇,@   <1@    /<202#4&#!#!5!!||Rqf9+Fk&su3k&uu#m'yru; )@   1  /<20)3!3!#++h$.@  . 21@  /04&#!!26!!2)DlN݇@%j@ 1/03!!)ժe4@ <1@  /2220%!!67!3#!#p&axު D+?x4&A((v@   <2991@B   /<<2290KSX@    <<Y@ I:I:I:I:I:I:@  <<<<33 # # # 3DDxM(?@ * %)21@  %&" )02#"$'532654&+532654&#"5>I8z,|йԳƆ\qѲ|!ĐBY+wps{M("3 y@ B  6 991/<2990KSXY" ]@068HGif  FI WX ei y   ]]#!33j+3m&yu# + KT KT[KT[X@ 88Y1 Y@   2991@ B  /<290KSX@    <<Y3! # #_yT:%@   1@  /<035675!#!T>Wxfb/X++0;+s2;@ 1/<0#!#;"++3s'&7#> 1B /20KSX@   Y%+53276?3 3 OM?w.-!suٵ2&]*jklyj =@!   <<<<1@ /<2<203>54&'$%53# W==U+  -=;; )@  <1@ /2<0)3!33#;ʪ+$@  21 /20!!"&533!3_||xdv+ *@    1@ /2<<0%!3!3!3OOʪ+++o2@  <1@   /22<<0)3!3!33#OOʪ++< *@  21/0!!5!!2#4'&#!!276GN6ONDPO+DCDCF&, $@   21/04'&#!!2763!2#!ONDNONDCDCo#N@ <21@   IIPX@8Y0! 7!5!&! 56! ! 'oOzFՎaa0&8@''!&$#(  !%$'2<1/0"3276'&76! ! '&!#3~܂܀s;:ŴL椤kj@@  21@ B  /<0KSX  Y3!!" &$54$)#!:ƒdv'V+w{-{Dp7):@+E'Q! E*21@*$ *9902#"'&5476$%676"32654&}:[;z631-~LӔ{0w)v ,u8w>` /@ " F!21@  /0!2654&#32654&#%!2#!r~~hhVlj9_ZZ^SJJOgyr`F1/03!!`3k`4@  <1@  /2220%!!6765!3#!#}v[(bt:d6(U3Rq{HF`@   <2991@B   /<<2290KSX@    <<Y@ I:I:I:I:I:I:@  <<<<33 ##'# 3?nn`QO6m|(N@ &* )1@ #)) ) KQXY KQXY0#"&'532654&+532654&#"5>32|PZG]twGabLx\l%%pZXkYF@\]y` ?@B  F F 991/<2990KSX@  Y##3y`}`y&# +KTKT[KT[X@ 88Y1` Y@  F 2991@ B  /<290KSX@    <<Y33 ##Tsŷ`OQ5Ls`$@ F  1  /<0356765!#!L8D{X^~ŷoPO` M@B   F F 1/<290KSX@   Y! !### >? ˸ʹ`'P` '@  F F 221/<203!3#!#U`7qu{R`@ FF1/<0#!#`3`V{Sq{F<m` 1/20!!#!<1BB`3=V`\pVg (3B@5E)! '.E4<<<<1@,41$ 4<2<20327&#"#"323>32#"&'4&#"326/{brrb{9SS99SS9{brrb{/Ǩ<9^N5=L^^LN^Ǩ;y`[` (@ F <1 /2<0)3!33#9U`33R`;@ F21/2#I #IRX 8Y0!!"'&533!3Hf\45h)_Vu;;` )@ F  F 1 /2<<0%!3!3!3ڹ"ٹ`3+`2@  F<1@   /22<<0)3!3!33#"ٹڹ`333R>.` ,@ E  21@   /02#!!5!!!2654&q8$~͓7_ZZ^{'">`%@ E  F21 /04&#!!263!2#!z~~@9LZ^_n7q{M@ H<21@   IIPX@8Y073267!5!.#"563 !"'q2 ǚ-VړiVFHL{ :@ E  F2<1@/0"32654&632#"'##3Jq и¾.`At"`<@  21@ B  /<0KSX  Y;#" .5463!##zwwVtS^a\'qk&CZq&jBBBB|#I##Iabh#FaF`C`#BC`CUXC`C85YBB##Ih;#5##I@PX#@8#55Y/V?@N F <221@ /<20#533!!>325654&#"#߰Bvz||яLmedY).ПĞm&vq{N@ HE221@  I IPX @8Y02&#"!!327# ǟ 2ғ-{FViګVH>=o{VyLFVyML`6@!E  <1@ /<0356765!32#!!%2654&+L8DثX^x~~~ŷ7oPv_ZZ^`8@E   F2<21@    /<2<2032#!!#3!2654&+N޹"\~~`7`73_ZZ^/:@N F<221@ /<<20#533!!>32#4&#"#߰Buʸ||яLmed*m&voyk&C]=V&^` )@ F F 1  /<20)3!3!#TfUf`3s48@$%6 )  51@ $-/<2<0"'&46733276=332764''3#"'&':y{d;]TCHI}rHGFFtAGCT_8d{{ђed''deFkmihhimw'AFf^^^^'`]:@  <<<1@    /<20!2#!!5!53!4'&#!!276XNpqONDNOQQfDCDC:@E  <<<1@    /<20$4&#!!2!5!3!!!2##~~EW^͓Lʣ+#3376!2&'&# !!!2767# '&SvwhfstgFtsfjwvú 9$#G_//wƪ//_H$$O{#2&#"!!327# '&'##33676>\" , Ux{ z{FVAW^3VH`3ʀ !#!#!#3 73` !#####3 Ñkk`_ !#!#!#!#3!3  o_<9d7`!#####!#3!3 kÑkk`_s@   9ܴO]9ܶ@@]9991@B  /<<9<20KSX@  Y@]##767!#'&'!ʓdսxQPtՀ`>YY~b҆12z(k{`~@   9ܲ]9ܲ0]9991@B  /<<9<20KSX@Yp]! #4'&'##767E]kKV:VS8V‰Jl&VtO\KtU'4! !#'&'##767!#3!PtՀ`ʓdսUn>qd2z Y~b_49n(.`! !#4'&'##767!#3!7kKV:VS8V‰]w&VtO\Kt`?sVszS#"&#"3276&#"#"'&54763!27654'4327654!"567376767632'&#"ssD#`At bTDt;<}J5?u_hFAXVRuťޠsj#B#' "2ZbrRUgr %',azQ^XRj7&6J- @' WoWdE\`[tO#"&#"32632&#"#"'&53!2654'&'"#5223 54'&#"5673767632&#"vmDPb!',-cX;b12i?,ZnN .rr. >._- > ^ >‘  tӪ ҫ q{&P%327654'&+"&'&'#";67>2# '&5476!36767623 !#"'&'&r-HVV?- ,4, -GVUH- ,4 .xt. 4 .wt. 4 `ta  _tp_   颈   袉   vt&"'0'&#'s3'<cS'&<sV'9@  0Դ/?]1@   /0]!# '&76!2&'&# 3!#SvwhfstkSh$#G_//ӂqV{9@  HE1@ /0@ ]! '&576!2&'&#";#UQQLNONPccccɖ#+qr͹rq;'''7'77'77did}}didii}}}d}}}}dBz/!"'&'&'&547676763!476767623 8  8 g    ) M #&#"56763 v][Jw}$)/K'*Ca"53#7 a#55#53g M 365%$# ʭf'rQ q\t{F` &3@MZg#.#"#> #.#"#> #.#"#> #.#"#> #.#"#> #.#"#> #.#"#> #.#"#> v aWV` v "8v aWV` v "v aWV` v "fv aWV` v "v aWV` v "v aWV` v " v aWV` v "v aWV` v "AKKJLQKKJLKKJLKKJLKKJL)KKJLKKJLKKJLX- #)/'7'7'7%'%53-#%5#53 3#kyo\wyo\zV\Ly[`@¬@_ӤRӤRZy\yW\zn[wyo\ԤRԤR߬@¬@Vm&=yuV8&>!:@  <<<1@    /<20!2#!#535334'&#!!276N訨ʨONDNOQQfDCDC&E 9@ E <<<1@  /<204'&#!!276!2#!#5333>CB>ytts9L^*..+URRRя>'+#!2'674&+327'7Uj~ rGj#u~{Sqrے-,9/~V{)%'7654'& 32'#"'&'#367632*nOSTTSSTFoWl{XY::YX{ ]ststsjts].01d d01j@ 1/03!3!)2$ F1/03!3!`:33G )@  <<1/<20!!5!!!!!N)#l8U` +@  <<1@  /<20!!5!!!!!?`۪ f3@  <1@/0#!!!2+5327654&#)qmL>87||9ժFwrKK"V `3@  F<1@/0#!!3 +5327654'&#rFRRQn!&&1`GQ``07 )(33 3## # # 3׈)D"AMF`33 3###'# 3?nfz!n`QL6mu&z9u|&z3! 3## #E#A`33 3###Tw8sŷ`OL5373! ###ʭd_dTy%u`37533 ##5#`eBTse``avFOQ5a!33#! # ##53ʨ_ʨye=3!!3 ###53dTsŷ}}z}5OQ5}2 _@   2991@B   /<290KSX@    <<Y!! # #!2_=y+*` _@   2991@B   /<290KSX@    <<Y!3 ##!*8Tsŷ`OQ56@    8 22<1/<20P]3!33##!#"dA9@`1@  F   F2<21/<203!33##!#W`39L -@   8 221/<203!!!#!#)"d9` +@    F221/<203!!!#!#W`3ͪJft8@<1@ /<0#!#!!2+5327654&#;"rqmL>87||9+wrKK"V!`3@!F <1@  /<0#!#!3 +5327654'&FRRQn!&&1:`GQ``07&.sAY%.54>323267#".'#"$&54>73267>54.#"+9lR2*DaSN}aF-?jQ&h;>e3.x=&QUW+Byc[sp8<{R?S0 $0>&1H3!(BT1kBtW22Tp{:SJ#&4t}f|}ާbm:E/fcYC(+G[`_&bnqxz?P4>73267.54>3232>7#"&'#".>54.#"qKц][-2`X'V$?/(PtMBpP-\_#D-)*%-8%7CFIGԑLV"- !(,!(؜XFrXbr> %gx@]sA9hY^    , Tָ&^dc+KiB&HiCsu''z-qu{'z ,@ @ @ <1@  /20%3##!5!!A+<m` (@   <1@ /20%3##!5!!B1BL<=V`o@  K TKT[X @8YKTX 8YI:9120@BKSXY"%#3 3;^^DNl!#!5!53 3!ssf=V` !!#5!5!53 F;^^`XXNl=;%3## # 3 3p\Y/su A{+3;y`%3## # 3 3q!r))kLHJqG5@ @ @ <1@    /2<20%!33#!!5!!+A+B`3@  <1@    /2<20%!33#!!5!!xZ9B1B9L|.@   <221@  /20%3##!"'&533!3_qm||x˪Awr7ٟd`F@ F  <221@  /2#I#IRX8Y0%3##!"'&=33!3f\45h)L _Vu;;#"'&53;333###;qm||֐wr7ٟ9d+`5333###5#"'&=3f\4+ _Vu;0$@  21 /<0!2#4&#!#z||f9dK"*I@#$ $3 +291@ $ (+<2076! !!267# '&'&=3%!&'& ":Cppoż vzKB@bHam`_F$$UgkL>D9||f{%.i@.&&K /2@ p000]91@& &"*"/o]2</]90"'&=33676!2!32767'$'&&'&#"XY`09Jt⃄ fgjdcbchneNRS]\RZF1!&łZdc4*ZZWWu'Puf{'Q,(vm'y[uFH'f532+5327654&#!#3!qmL>87||qwrKK"9wV`3 +5327654'&#!#33^HRRQn!&&,%wGQ``07$)`6V!#!567!3#:bCux+8.%5ժV.V+`%3##!56765!s{{v^̳;bVdžf;1@ 82<1@  /20%!#3!3+53276q"L>87h_9dKKV`/@ F F2<1@  /<0!#3!3+53276WRQn!&`3``07V!#!#3!33#;"9dժVV@`!#!#3!33#W{`39V/@ 221@  /20%!"'&533!3##_qm||xɪwr7ٟd+`G@ F221@  /2#I #IRX 8Y0%!"'&=33!3##Hf\45h)p_Vu;;V%3####! !+-}-VV`%3####! !H{˸ʲ>?V'P`yOh'J+1@oo]0{-&O"+1hN&ru  +@ 0?  ]1{-&jR -( +@(o(P-_(@-O(0-?(-( ]1H{o{m'yu@@]1qH'@p]1uQq{uN'r ulq&jTm(vN'rQuF'jN'ru&j:yXL/`T31'q;y'q3N'ruy'jsN&r'u +@ @O]1qu&js +@ @O0?]1saqu{7sN&|r'uqu&}jso#N'rguq&j#1'qr;=V&q^#N'rru=V&j^#k'{ru=Vf&^N'ru&j^j #@   <1/03!!3#)ժA` #@  F <1/03!!3#`LFN&ru&jGV9@  <<<1@ /<20!!5!!!!!!+53265N)#iGRiL`na8VU`;@  <<1@ /<<0!!5!!!!!!+53265?`nFRjK۪`na=f*%+532767 # 3 3*SfL>7( ^Y/su bzK5sx+3;Vd` +527>5 # 3 dkkCQO5r))`&9as mHJq=;3 3!!# #!5!suNt\Y+wD{;y` 3 3!!# #!5)) ~q4H &@  21@   /03!!"!"$54$3!fONDNONNCD#CD+fq` %@ F E21  /03!!"!"'&763!5>BC>9sttyLZ+.i.*RRPRUC 09@2&)  1291@"-(1220!"32765#"'&54$3!3327653#"'&NOO_KV! 3j^nN?4pi;?nhf1CDP_m}`61f[JJOZxx9qs` 08@2F&) E1291@" 1-(1220!"32765#"'&54763!3327653#"'&=C>A@j\-1C]^fety>dhd.*^\:9m4l01a`RUaPOORAsxx%7@@9., ,#81@'2-28904'&+5327654'&#"567632327653#"'&'&\]OOQRSrsdeY憆GGRQ?4pi;?nhf0!JK;$& hi|UV!bb[JJOZxx8PaF|5G@7., ,#61@66'2,6 KQXY04'&+5327654'&#"5>32327653#"'&NHtCDFEwGQPabLqr<=ih<>dhpb8f83,-F@.. NO]@AHOHXDEORAsxueV<):@  '+%*1@!'(/90!#4'&+5327654'&#"5676323#s\]OOQRSrsdeY憆GGRQJK;$& hi|UV!baV|)?@ !+) *1@ / KQXY0%3##4'&+5327654'&#"5>32ȻNHtCDFEwGQPabLqr<dhpb{v^̳;b`WORAsxue{-`6@F  F221@  /20327653#"'&=!#3!zgh<>dhpbW`WORAsxue{`3s0@  1@ 0# '&76! &! !2653d-|e'%{9!Ҏ׿qF{0@ E E1@ 076!2&#"3253# '&q кĽbZZb/n||r|r|>禞f/@  @@1@  20327653#"'&5!5!?4oi;?nhin+[JJOZxx}q`2@  1@  2 ]0327653#"'&5!5!x>=ih<>dhpbB1VFEORAsxue{~{R|ITf:/@ 1@ 20356765!+532765!T:WxM?77fb0dKLøLVs`/@ F1@ 20356765!+532765!L3DF1a.&{X^}з0)oPT 35675! 3 # # !T>Wysu \Yfb/X+3{L` # # !56765! k0X^̶8D')`HJoP~ŷt32654&#!##!23 #h /ϒ0*3V{ ##"&'#3>32&  k\{::{T%+ܧ$`tad dakj3&$54$)!!!!!!3!!"d;>v78ȒFwtw{&/!3267# '&'##.5463!632.#"%;#"w ͷjbckVteVgKww^Z44*,'ėS^a\s4qVZ{TD:V5`ZTfs%9@' !&<1@!/<035675!!2+5327654&#!#!T>WxqmL>87||fb/XwrKK"9+LV `'9@)"#(<1@#!/<0356765!3 +5327654'&#!#!L8DFRRQn!&&,{X^~ŷGQa`07$)oPft!?@ #8"2<21@ /<2<203!3!2+5327654&#!#!#qmL>87||"dwrKK"99V`#@@ % !F$2<21@!#/<203!33 +5327654'&#!#!#UFRRQn!&&,`7GQa`07$) !!#!3#q"r+A9` 3##!#`9L3` F@   8A!p] 991@  /2  9033265332#54&+! '&ˮ® ,gQ]*-呐u\GCF1l[R.$)K@  8Ap]2<991@  /Ĵ`]0 ]376! #54&#"!2#54&#!$ˮîXgQ$9 𝶫F1l[%D@   8!&p]<2991@    /<<0O']32#54&+#!"'&54! 4&#"3)GgQG*ɟn(!ˮî5ZrF1l[=ó|#ӢI|H@   8Ap] 91@   /90O ]32#54&+#4&#"#576! YgQGˮîːZ`F1l[O 9$\)$30!2#54'&#!3276=3! '&X_`07QWWWWˑ呐1[[F1l*1jiij 9㒕$2%!67#"'&543 2#54'&#!3 7654'& f<0I|q4_`07Q5˧OPPOOPP'.ƪV][[F1l*1LL]]]^^]])D@8 :  2]99991@  /0%!2#54&#!3!2#54&#!}gQXgQF1l[F1l[)@@  8Ap]<991@  /0]376! #54&#"!2#54&#(ˮìXgQ$9 $F1l[-:#'&'&763!&'&#"#76! 32#54'&!#"327654:gimINK(*WWWː\!%_`05л9:E5:. rs TfLQR2jjiu$[[[F1j,1i--Q@+#! '&4763!332#54'&)"32765pG혐nG_`07TZ5WWWWܕ.|n[[F1l*1}Hijji):@ 8Ap]21@ /09]363 #54&#"#ˠ(ˮ;dK2V 3@ : ]991@ /0@0P]!2#54&#!}gQڶF1l[327653#"'&!#3|%3x*%qXdq`>WWK7}bbpiOA$3! '&7#'&=33!2#54'&#%" 76'&ɼżg``07Q_`07Q|y&bc\[F1l*1[[F1l*1 椤)!## '&33276=3)ˠ혐WWYWd+&jiih) !2#54'&#!5 uw _`07Q1k,[[F1l*1f'1?%#"'&543267#"'&543 327%&#"32 7654'& oUIeβr0I|q9I9~dX/? 9.YOPPOOPP@$2iw'.ƪdkWM( ]]]^^]]?@  8Ap]1@    /90O]%32#54&#!4&#"#576! )GgQìː!F1l[ 9$\,3276=4'&#!#5354763!!"!2#5# '&WWYW07Q `_# Q70X_`ˠ璐ijjgl*1[[1*k[[Fd%!! '&332765!2#54'&#)呐WWWW_`07Q& ܕ$ujiij[[F1l*1S" $53 6&#!5!2654& #4$ 5JRS覥A ++.WHNMItYa[J\n@@  81@   9/0326=3! #"&=33®ìGœgQm 9-!F2lZ) 3276=3! '&576%7%5zZ[WWˑz=s9W/hiik 9ψ&dAU)7@  8Ap]1@   /<90]376! #4&#"!ˮî$\uB)4'&#"#576! %5%$76aZ[îː 1y=\gW/ίgj 92dAU##576! #4'&ˈKuˮ9)uBGlP| 9\̍P0%&'&43 2#54'&#!3!767654'&'& Eq4_`07Q5e, 7OOPܪƪV][[F1l*1L,@B@^^]t~H@   8Ap] 91@   /<90O ]32#54&+#4&#"#76! YgQGˮîːZ`F1l[Ou$\)8!!# '&5332765332#54'&#^혐WWYWG_`07Qd)jiih [[F1l*16).@  8Ap]1@ /0]376! #54&#"(ˮî$9 uS0@ '&53 7654'&#""#6767&'&5476! "327654'&RQJRSSSSRefg#RHJIIPacIJIJcaW"ccttstNMMNMMM *c" Y[`XX^[Y01YtAAAAtY10 =@ 8  Ap]21@  /0 9]54&#"#363 3^ˠu2;dss:\,<47632#"'!2#54'&#!##"'&=337654'&В􄑑I_`07Q _`07Q*]WW]_WW_rsppzzpS[[F1l*1=[[F1l*1A>T]=BD=[V>Cs2167654'&4'"!"'&'5&'&547632qG^CC95+<&0kljxw{vEB[eK[ 4D~n>=>@%c3A +mlpp/E# ,,W`aru~^#33vx%"#476327653[RBhj[RBhjTDDjlTDDjl}fC^7#47! !"33254'&'#" q3U7a\ "9S A5z\&NZ%03!Z}4b`&^@PP F'<91@  #/<<<290@0(P(p((((((( ]%#"&5332765332653#5#"'&E``ruSSrw?XXyzVU|:<b`^zbzh02>>Vd{?@    N  F22<1/90`]54&#"!!#3>32||Buܟ6V edqV{ <@" GE!<221@  !032654&#"##"3253!!/+:||:Z/\RdaDDadOV{=@ N  F2<1@   /<  90!#4&#"#3>32!d||BuZVH`ed X?@ NF2<21/90`]3!!3276=3#5#"'&>>|TVCuddZL PO_bvfcxxqV/{<@ G E221@ 03!#"325332654&#"Zs:||:էRdaDDad,@ F<1@  /0)3!!32#54'&S[zM`01LI[F1i&&Vd{>@   N  F2<1/90`]!4&#"!!3>32||VBu ed\V6{ )u@ +G  F*2ij$!!$ISX $<323#'&5476#"3276#§:{5`4xBdBJ4/' daZ+h|{Nvqq<q/ 4@ ! GE <21@  <<0!"32765#"4763!33ƈbOMSK}<zaksC+D߫LVd5@  N  F21/90`]#4&#"#3>32d||Bu\edV` @F1@0!!3y^ VI@  NF221@  /< 90@]32653#5#"&5!#3||Cu`a{fcLq0\@ 2 $G,E1Ĵ,1@ 011(1<<0!""<<!<<#"327676''&5476;#&!!'&'&4763[AS].SD81N/Vɮ!qZsIR\++(VL-%)$?뮘VX:@     NF2190`]332653##"&||CuZ{VfcdKqZ 4e@ GE5<@ (''*%%*39/ 91@. '/ 90@ `6666]32654&#"#5#"325&+"'&5473;2/nD:|WCv>!%7)/kPըdaDE<6pG5P0,!K7V9{;@ N  F21@   /  90!4&#"#3>329s||BuH`edTX-b@ (N  F.<<2 -9   /1@%/<<! (90#5#"'&=47#5367$732%326=4'&#XCubdzzp>BiO>AycW fcx{Iʪ`&$%8vJMO;) +?@-% $NF,21@ &$&)$/90332654'&/&7676;#"#5#"&|| M.=<(`Cua p0.- */(fcVy`2Z#G@%  N!$21@  !   /<90;32653#5#"&5#"'&5476;#"||Cu;^PZl}YYa{fc^PzKWV{!<@ #E F"<2<1@ ""0!  3!!"'&547654'&#"#4632/Q@'$C#@l;qsDE E+G56dZY0Y^cԫeed{QFV;`%X@##'  &9/1@#&&990%   ! 3!!"'&547676/&5476;#&(3W:'$F[L2se`6g+! E/>A/(32||BuƯ`ed X{XV-=@    NF21@   903326533!#"&||sCua/Vfc{%i@  PPF&<<1@ "  /<<9  90@0'P'p''''''' ]3>32#4&#"#5#"&533276BYƸ||zUVCdȸ||XW{ed\_`fca_\Vd{7@  N  F21/90`]#4&#"#3>32d||Bu\ edqVZ{J`@F1@/0%!!3y&"`V%k@  PPF&<<1@ "  /9  90@0'P'p''''''' ]3>32#4&#"##"&533276BYƸ||vYVCdȸ||XW/ed\_\Vfca_\V{$U@&E  G/<2221@"%%<<IPX32#"&'!!#54&#"326չ:{{:+Īdaad)qu{RzV*"-6u@83 .# *E7<<<<<1@&7/  "7<2#99#93.  90#,<<. #"'&'53&'&547632##4#"27654'&,Dd%Kcfep_{5S#al~EU@<%I]7_E8BQ-a`ta2N-bliZn!vFDs:#+IJ>8@    NF21@   /90332653!!5#"&||^CuZ{OfcR@<21@//073#3#R` 27#"'&'3U oo,rrONcAUUWDC <21I:03#3#D-dC'KRX@8<1YC %  <<1@  <5G.i=dB]Gg`":T)yX`!  1  /204&#!5!23!5!&nZͦy–1CZ`G 1B /<0KSX@      Y4&+532##n̒[^ޕ<S"Xh`$1/20@]1#!5!t/яd`4@ FN F<1 /<0@ @P`p]!#3#4&#!5!2snvy–t`FF1/0]!#3t`X` #  1/20@ ]5!"#7XNrXGяy Kd` (@ F N F1 /<0@]!#4&#!#!2dny–/``*@ E F1@  <0332654&+532! w`ҏ/t`FF10]#3tXV` , FN 1 0@  ]#4&#!5!2nV#–X` @ EN <1 /035!26&#!5! #Xt뒦X&@ F N1 /04=!3!#T[CLzld` )@ F N F1 /0@]3!2%!4&#!6n`–X`^@ F E991@  /<990BKSX@     99Y"#673632!5!4&WWHFdaxѧȠ˨Vt`FF10]#3tV X` %F  1 /0@]4&+532!5!ny–X(` *@ E 1@  20#5! !"264&+" я0D_ЍNO`U@ F 991B/2990KSX@  9999Y%67676535673VGu",:pΈLƒ4U}*p>1=!"$Vd`1@ FN F1@ 0@]#4&#!;#"&5!2dn\pTQV#–U;zdd`,@ E N F<1@  /0! )5!2676&+;#"&5*4{\Lwuq`U;zCVp`D@ F  91@ B 290KSX@  Y#3>=3#q_V`}՛C!`J@ F  991B /<0KSX@      <=3!5!CcMgXC"`ԛ:V`,@F F<1 /0!#76654&#!5!2#3l)WzB'*˺u,/HVv.4X` ) FN 1/0@  ]!#4&#!5!2ny–`/@F F21@   /<<033$763 76763) :0nLaT`Sl+7`+@ F 1@  /<20!#4&#!+53265#5!2ndDrL~y–a; `')) `')- `'--`@ D103#`n`@DD1<203#3#`|"%0#4'&'37676537653#"'% '##5 rb{ .q & q-aT !}Bs12j{@E#$]} q!<"ibP-F`)*5"2767#"'&54767&'&5&76 '##5M@V:118UF%/>7P6.N@?^G?D)7-#F}Bs)^ &# \*$@.") n F>]KH*!#TH#bP-F`z %3#%3#3#%3#ƴ>^< %3#%3#%3#3#%3#>>^!#53ӤR@ 327654'&+5336767N5G4pQf$h?FA@6b ! eI(R[2* #53 3#ӤR%@-$%#5754&'./.54632.#"'/XZH߸g^aOl39ZZ8{4<5/VVL89CFnY1^5YVeU"756767&'&54767632&767/SD435gcbnZdF31`9:H:ZU!LOTAKv?=0ps2#nl '{R'z>oy3#&}9&m~ &~& (f&X} (f$3  !27# '&5767"$JKԖ^`e~h'?6`vc–e4- (&X}?}R%67654'&'3#"'532# b&\}q  ?%#&'$473327676'&/3327653323#"'&'TPxmil_Qb_y^@@$;sR,%@n\Kf% I01_2F,k>GHܳ&%0l}=J"5^.327654'&'&#"&#4763&547632#bzL,5;(.;Dn2KxAZM\MObxX'*9:X DD(NOf7*(?$S-8APH&}? "327654'&'2#"'&5476B!799[]KB{ƶ`Q%T*WE{R,,9.UMAx|KU#JN @ &"34'&!5 767"'&'&547632?,3/V%._]g>v-(tYhYH9!$3/,;̠X*VL_ !"bWg3ZfJ6%#"'$47376767654'&'&'&'4762#&'&'&VfxH?Ba=~T;~BrC:@_` B(EN><}9M I&huqc- !P85J.39sJ%*==!'&"7*S@UYD J&o~ $5%5%HHnnnn$&567&'&54763233"/#"'&5332767654&#" %!lE?I(7 /4KU^r8Z #08 " -d$* 9^W4'6O'&n=NV)qaK" %$5%%5%HHnnnnn$5%Hnn$-&'&5476323"'&'#5276767654&#") lE?I(7$# +EȓV " - 8_W4'6O -n=*{nmp" %$5%Hnn8(#"'&54737676533254'3'&!9EO)"a 2=`YG g -SGL(E?4mmb}8T"RY$6îs9It6Y ! 4&#"32>"&462X@AWWA@Xz柟?XW@AWX栠h732767#"'&'gC*6:)kXZZC5"LMD6{S )L}@FOwO  4373ËF3# !#'3%1yI !nR#'337673#" %1BR{6)coajr!nUPymL%#'37676537653#"' %1/(/H/; 'G 44.5WY9!nr|> @2%,*;l>3  *"2767#"'&54767&'&'&76#zf\MOYp0;JcX~VI|eepdkAXH,7p 4C@#90L@rRiUZhsBBsǮuu5aU#'#"'532N%bU`DK*22<!&'3673b~ĚZ00ZĥxU:Ũ ;6I<3#&'#6̴UxĚZ00Z~bI6; :d#"'&'&547632#54'&#"=:i_{\ %Z[,,G\O98<SGU37e{a}UwnWl42@B^!x$%-`+-!d! M fM&I&9 &9 &'~& && & (&Xz8 (&X? (f&X~ (f&X (&X (f&X (f&X /'I>\ r'|>\ &'|\ &\ :654'&32! '$&73! 76767#"'&54767632)B,4((7(*Hnق@AZAd#?zKbNLZB`.+M;3*)3P&ڴF=)d \^tL"9;l&NKCW4,E$2Hf6&x~&xx)-%2767654'&54767#"'$473$62 #dGf>5?AhXPA7.EB|=Q#!w*6(  %{{qeVUI&b \^~B")+&&j|H#"'$47332767654'3HdnaPm/1]]LGL"fh8D%jdQ45b`ޜ ('&X}? @r'|>nJor&o|>m}~RLR%'&547632&767#"'#'3X\lTX\D8/0E= %1Bx:=$!"4'Qjr!n8j$(327654'&#"327#"'&5732#"-2!WZWXZV%2-Z(.5__52ZJkV0B7,g`p5oU%mao3/AbM3))I<<d (@  1@  0"32$  h P3343ssyzZ (@  1@  /20%!5!3%=Je+HH=  21 /203!#3ulh=   221 /0)5!!5!3=lȪ=   21/0%!!!3!l =21 /0!#3!=l*=1/0!#!3!=lcr8A'91/0#3ASuNA (  < /<10%!3!#N{ 2@ EEܲ@]91@   /<02>4."#&'.4>329[ZZ_PGr䆇䄄rEMp`77`p_88 1ŧbbŧ1 y@ 1/03#+q!/@ E  EԶ 0 ]1@  0 6&    z>z='+@  2291@ /2903#36Q*=q33# =qCq @ 1/<0)3!39Uq"q @ <1/0!5!!59qKqO!>@#E E"ܲ@]ܲ@]1@  /2<0%!!5!&'.4> 2>4.":RJr 惃sKRQ[ZZ{ 1ũbbŨ1 p`88`p`88 %@    21 /03"3#!5!p9 fq2@ E<21@  /<20!#!##"&6 54'&"3qvCf^]8mr^:<UfɃ]8ƃD '@   <<1@  /0#!!!y5!Փ/= '@   <<1@  /03!!!}5!Փ/ %@ <1 /0!!27654'&'2#!3,R4,,=iXXXlι]Oz}I__ҭ$;@   ܲ_]9@   /999@ 10#4'&'5!4B 5McAq_9V= 491@ /̲]촍]0 53#T9+!-@ #"1@  !/203432>324&#"!4&#"!}x5%^ZHZlK--Xh&|ŕnc= &@   <<1  /<<0!5!3!!#KK?=9@  <<<<1@    /<<<<<<0!!5!3!3!!#!KøL=??q!@ 1/0!!9UqqK==1B/0KSX@Y! #tFC00B~+n 4@ <<1@    /<20327654'&+!!2/!!m]%i ;@ED\TqQE=4."XErrJSRJrCEoJ[ZZO{ 2Ʀ1 { 1SV/p_88_p`88} @ 1/0#!#}+B} #@   <1/0#!#3}Om +@   <<1@   /0!%!!5!!z;  TKѓ+qO $=@&E "E%ܲ@]<<ܲ@]1@  "#/<<02>4."%#&'.4767673 [ZZTXErrJSRJrCEoJR"p_88_p`88 2Ʀ1 { 1SV/ qO(#&'.4767675!5!!2>4."XErrJSRJrCEoJRNQ[ZZP 2Ʀ1 { 1SV/ p_88_p`88b/1/0!!VBf#"&/#332?E=9Qct2 %xf" %/x $Dp/1/03#=f7u91290K TKT[X@878Y3#'#f[fE9190@ Ueu@ )9IUe]]!5'3{Bf3326?3#'#"&'Bx% 2tcQ9=Ef$ /% "[fC9190@Ueu&6FZj]]5%3%[{fS/1/03#̭F'/1/<<03#%3#\yu  <1/0#527#53gu  <1/03"3#  gd 1/03#!!Mdd '@  <<1@ /03#3#!!Mޒ1/0'!! '(033!!3'#67654'&67654&udruxtNMddx>DD>xIIv! RTxXY`aw,0dc1-!:;z{t{*L@$% E+<<<<@!#91@$+<@ (+0%"3254"3254#"54!#"543263 #4#"h??AA??A'+,LW@@@@@@@@pطQQ9/@@1(. #E0<<1@!0%* 00"3254"54$3  !2632&#"# 54-654!"`@@@CvBըiUv˫:knL?o@@@@N;Ejfae:.88U8327&'"254"%47&5476! #4'&# 63 #"'632# i60IKhh*)7!o^RX;*:9u`/'"6OfqAtqLI $\9.ȶmQ!6@   E"1@"  "0463 #"&'7325#'&&7'6met "xCBCquЍ h! ACBB )2@  #&E*<1@  *%/0"32654& 4''&5432#5476$ % U%|{e6Lj` %"%:yx~)RhKK>  65@$- 3 (E7<<<1@ 5/7&7"32654&4763  !27632! 54-654!"#"`$ % 琺By#xJi:OknLIo %"%0yKpjNdfDQcwiC|85ss *;@&%   E+<1@")+&+02654&'&47&7'73%$$!% l݁6ZA| $! $Vm-G4 p?{1@ F1@ <@0%"32544!  #"54$32@@@)@@@@Pvv .<@- " 'E/<1@ $/-)/<20%"32654&672#4#"#"'&#" #"53232l$ % L 7*>(z*M#6&8"$ %"%3|0ۯqiPWu{+?@-$'+ ,<1@ )!,&,<0%"3254"3254 #"5#&767663 #4!" @@@@@@!Ӣ7y-^@@@@@@@@edm%W ,9@. $  )E-<1@ '-+"<0"32654&4323254#4#"%$7"@$ % 쐋'(uj %"%@կ̰Xsgh\_"9@ $ E#1@# #<0254#"53265$54767653!"'#W@@>z]U]iTrs@@@@pegu/ssIs|2@  E<1@  0"325447&763! 3%$5@@@ԶMg@@@@R&Ѩ'LBIs2@  E<1@  0"325447&76! 3%$5@@@ԶMg@@@@<%Ҩ'hBY E"32654&!"32654&&''"&5623253765$7465&'7$ % $ % Kfg饤IJ %"% %"%IKbv4ˋ42@7-]fn9h%A@'$ F&1@&<<@" &0!"'# 432!32533253"3254hfg襤>@@@ JJ=|\@@@@@h} -?@, (,$ E.<1@"&. .<<0"32654&2533253!"'# 47&5432d$ % AfgB %"%4˩/JJ=%܉Mh -?@, (,$ E.<1@"&. .<<0"32654&2533253!"'# 47&5432d$ % AfgB %"%4˩JJ=%܋L@`$@1@  <<03!23! '#"543225O)3Ɯ)`,88{s *;@&%   E+<1@")+&+02654&'&47&7'73%$$!% l݁6ZA| $! $Vm-G4 p& ,7@  '#E-<1@+.%.0"32654&4! ! &# ! ! '&54323 c$ $ 6buUKX $ $8${nE{N%O 0@@2, %&E1<1@%/1!*<0%"32654&&'&'&5! 765! '676%&4% $  ,D )@ ' 1#-E5<<1@ )6/%!60"32654& 4%$54!232#"'&#"! '&5432h$ % ${ajjh@MqKy)LJm_ %"%1EYl0xP^b8Rsu_|]F'"2''&'$!32'&547"32?6AS2;9’hhNU~ +;9jq!Bao' u ` +@   /991@ /0! &7623$'4'74"Y#!A[VB8?<kP$U.FM?>={{+@  E1@   <0 ##"2#"53254#"n=;C>@{jVR777r&" @ji  /1  /<20! ! !5 74! %&?%~?>~@i$@  /1 /<220! ! 3!5 76! %&>%~?>wJ~~@ji*@   /1@   /<20! ! !5 74! #5%&?%~?>~N@i.@  /1@  /<220! ! 3!5 76! #5%&>%~?>wJ~~T3"36654'#"5432AA\(DeN[̼o[$N[u%@ /1@ /0"3254"547&54323253r>Juum@s> [yu?{EBXF` '656%"'&76! 4"3YVA!. {x9322674&#"CCjFPH OQ$!%!p'(FnJv-O!3] $ $z{&00, ("32654&&3 #"4/&5432N$ % s $ˌeqɘzm %"%82y,v\#"6@ E#@! 1@ ##04$54%&&5! $#"57"3254ix@@@X4|`Pٳ ?@@@@ ""32654&5&'7!$#"47#$ % dt.; %"%Ȉ_p 8>u%t/;4#"#"'&#"$#&532327632! '&57"32654&"3C2z7J,"/IN\=0BWTO3H$ % Xt\DD\t] 5<\UCfwpv  gH %"%V@/1/03#V '@ /1@  /<0'6"%)56574 65+*+UGm++),}݅.p\(>.4"!27676327673!#5654#"'&'&#";&543.%2~*&IHHܝBOg(LBC]i%>e>.`h>3A?~= h\$kb8:;-F_Zkf2)N !@ /<<1@ /<<053533##5N؎؎؎ P>r@ /1@ /0432#"73254#"ЄLTPPHHH` " 7654&' ! '&476^L:NbX1coqoh`WĒcg&24764'&#"676'&'&5476  pHgc/5pIu upHECle\gUܚsuϨcy\$24"27#&5432# '&5?$5+r%3]f́|pHFPfouTapH/%24'$5432327#"'&#"%$'#"54322533]L/|tkZ1AQf(3Ɯ)DjR:jTh8KOpt$68{cW%24"$'&5?$532&'&32!r|T9lc ~x?LvTamY<KcW-224"7&5&326532&'&32$'&324!B}b$|T9lc ~xr=Ch(筭 ?fXmY<KLvttY4@'&''"&54323253765'$543227#"$#""32654&fg饤u ^|uISL\>$ % ,IKbv4ˋjEaTW8ҋ %"%{ &%"324"324#"54!#"543263 #4#"h??AA??A'+,LWpطQQ%Rpt MU"32654&254"#&76767%4#"#"'&#"$#&3232763276'767$ % nnvp+-"2D2z7J,"0IN\=0J%.3?5xv'Q %"%933hk//3wt\DD\t 5<\UCrTF-2bG;"b,i $5354#" #"524"m~ŶejsX\|9 LX"327$"3273253!"''&76324%$7&76%$5#0#&76262654&'&A?A?fxԅ$8$+Rb,7Hu Ӣ5r$!% @@@@@@@mӔJce$3- /ԋu cd $! $ I"327$"3273653%"'%5254%$7&76%$5#0#&7626A?A? Tcb*@RX6&$Hu Ӣ5r@@@@@@@mo6J,/7'- /ԋu cdPi.".54>7!5!!"32>54&'7i7eȬd7&KlGqǔVXxyӚYlūc66clJ7^sz֟\[{6yEr2b\TZ@#!#".54>7332>53!w!KNM#hN&?Q*nq-Nj=8kT3$ KfWxc*s@nQ/+Lk?Z 5!4.#".54>2!/A%'B/+(=B=if:y'D33D( R0oCEOc88cO'MP.4.#"32>7#".54>7!5!!"@YmEgLLfjJkoX؁q؝XGxdI(YjiMKkii۫uuZ8!4.#".54>32i+Kg<>lP-7:p0M6NifL>@kK*0Rp?>?1ill3eMF}gZ,#!#4.#".54>32!|/@%&@0&%BE;hRPg;(C03F(#P/MCOe96`PFZ(4.#"32>7".5!5!>32&/Oj=kOOδMEHHjMoP.)NpF@pR00RfLLfan0/IP- %#"3!!"$&546$3!!J׉@@ט`a( ]wxԟ\Fww2P:G!!3!n!.x1Z+(4.#"32>#".53>32`+Li=?jM*,Ni=>hL+iJEMfLK{W06\xCKxT.4XwA_bKr62NpZ+4.#"32>#".5##!>32*+Lk?AlM+/Pj<@jM*KihNIHk?pR0,PpEBnO--OnβKKgcBvj12KZ+"32>5!#".54>3!!5!!Q@lO--Ol@>iL+MghONiL.QoA@nQ//Qn@/eMMehJ{PS$!4.#"#4>3!!"632,Mh<>e-PKhr>iM,fL?nR0*'R} gM1Tr@aKfPc K4.#"32>2>73#".5#".54>2*LjOwϙYVz|՚X0/':Yr?DsU0 E nǬc67dȭe7><qU'!RkL)[z{֝[W.>#K]59_|D 6clkǬd77dk{Z'kE"1%P#".5!5!2>53KeiL*-Nj|fH'eMOfXAqT12Vq>P&!#"&'.5467!5!32>534JEp=AB7D4+! )#$+e;:iP/05IGHeLJ )RpEn),/,Nj=Z""!#".54672>53!`NgiMNL6--Nk|jN,+eMKgV[@n6@nQ//Qn@]S#".5332>54&'7SLfiJ,Mi>=iL+>5{-H3eMKg@nQ//Qn@6|>/dfdS 4.#!!2>7##!!!2/Oj;;jO/JGHܓ.gM@qR0,Nl?dEHCMPbF4.#"32>5>54.#"#".4>32YywКYXxԗR6aO"?/$/ .@KZj>mȬd78ekoɭc5[])D0z֞[[z{֞[WwAoV5'//!6cǫc66clv?GOPb 14.+32>#";+##".4>3!2>mTEETmFUl>>lUFk\܀EFޥ^^ހWܢ\YqA@n@oWVn?~ٟ[][ڟ[]F!#!3!3!3FS!4.#"#4>32/Oj;53`EIgJ,Mg<:iO/02Kf>mQ0,Mi=nB-#".'332>=#".533267653BLi`R0Lc8;jO/FIiJ,Ni=:c'YgKSkFzZ40Sm>1/Jg@mQ.+(P|S!4.#"#3632+Kh<7g4QɑeL|?nR0++N|uaKfPk*!5#".54>32.#"32673YUlǬd77dlps[.\YS$wЛYXy^Pr2@6clkƫc6JH,Z՞Z;;xXZ)"32>5!#".54>3!3!Q@mO--Om@>iL+MgiNNi.QoA@nQ//Qn@/eMMehJ35S !4.#!!2>7#!!#!#!2 )4)2VsA4(AsV2*=&$;,S~U+ 9/XZ.?#".'332>54.'.'.54>32#6.#".KfbT1Ng:jN-VU^]4R8eMRlHzY3/Qn@72*63UeMTkH|Z4/Rn@)D BFRZS#"'!!332>53SLf,Ni=53 KihN/Pj732>54.'.54>32#.#"]~|ۤ_-H3K7>kTSj==jS8mV4/Rn@8gQ6';#w٥aL~מY[{:omn:vQNVl=53 ,T,Pf:l #D;%?.a=4.#"32>7+!!#".4>;5!5!54>2-  -)//?%&@.%?/:fPW2WvCDwX22XwDp=  @xY9lY|PW!%! %674#"&5! % %1,lշ._z+,S.+RLo ۤTn8d`'675$!2363 ! ##&!"#"32CxuM6sc*rE) PlaؕyZeY!&732#"&5 ][*8F e]N/I3^@[7rr2eY'!&732=6+537#&5! nN ggGVzkB3L.ķ@JKW~Xq\,d!$75&7! &324'"6Z^,CH!IJ:QU,X\$d56#"! !2363#"32UTcD>0R^<]te'6#"$! +.!TueudY! 473254+5365!5 Wb 퇇2mNEIJ(bC+d`3675$%2363363 565&#'#"#'#&#4%"fDjPQUOR Tg@! 5y<O-6d! !234#"#!#"2mLC{%  }>e~! )!363#"7Y`PlB   ry_d56#"#'#"$!2363 H LDVza!t#rd!! 4732+53274'$53X`4"gzҶ/c7Qib6ȕ!6G))=HdY2! 3325 '%5%Uc| CGko 4Y_nd9$5$#"#'#"$%7367 > B)oQT7-ngDP5kn1w5! 3324&547cTɜW\wؠ?c-'9dY: %3! ! %#d6*Q&q)QGFޕd$! %35#$ 3#3%#" 5;54 X`dHrrr44OfkQؔcdX1&!"'#!525#"3$%2363 #"321ZG\KVOvBppdY_!! %$54#"'! ! 4'7_GD `U6I@bYsrg8A:ԃM){6\lY(3324'7%#"'#723! ߫fB߻cV̿0?7YpeW $!6=3! 47$$5! eڞòkHuLL8TWJ&)*dr54&#"'675&%'%"t_CCt?h]|KytJfqI8=ۣ&*2 5#5#5#d 2"4;%"4#"32;ѹF|pux$LRQ´h=@ B1/0KSX@Y %##.d+hK'Eh)hO'zt@1B/990KSX@Y sNO'z)tN'r)u'ew^?1B/990KSX@Y 5](&xyw^O'z1t'56'&56'O'56O&E'E'EO'EO&O'z0'wE&O'wEO&w^O'z?0 3#!38Ygg`nC^^n7]^7nn7]]0d"&533265453zWA@XzCss!AWX@+!U#454&#"#462zX@AWzB+@XWA!s0U!5!2654&#!5!2@XX@s0{X@?X{0U 4&#"32>"&4623X@AWWA@Xz柟C?XW@AWX栠H> %'111 ]]1<203!3CC~K3#K!5!${1V #5#53533zz{{1##5!z$ %{{:'U'"'=wq'h9hK'Eh0hO'ztw^:<1B/0KSX@Y7 5wM40w^O'z)tw^N'r)uw^'w^:21B/0KSX@Y%5^xyw^O'z1t'56&9'56&O'56O&'wE&O'wEO&O'wE&O'wEO&w^N'r1u<291B0KSX@}}}}Y5`sbbs]103C)8)K'E)*@ 8AKTX8Y1  /<03! #4&#"!!ˮî$*\u)O'ztw^ 2 <1 /07! )5! )w5BhPa.,~w^O'ztw^N'ruw^'y` 2<1 /0%! )! !`aPhB5jiy`O'z"t&''&O'O&'w'(O'wO&('y'(O'yO&(' ~21@  0# $54$!3#"3nn͙ nn{'|'|w}'dy'F> %@ 21@  /90"32654&"$54$32#Bz_̀#R3IK'E %@  21@  /90"32654&#4$32#&f̲_ȭT#R3{O'ztF> (@  21@  90%2654&#"3#"$54$3Bf̲_ȭ벃F>O'ztFN'ru (@  21@  90%2654&#"672#"$53z_̀ʃIO'z5t'F'?'~'|?O&~O&|'F&O'FO&?'~&|?O'~O&|?&~  $~ ]21@ 02654&#"632#"&53XP^J\TaaQ_VFTHUGQK})~J8 2654&#"03#"&54632xOaT\J^P_KQGUHTFV}i~F'x'F'x'F> 1 /0#4$32#4&#"#fK'E 1 /04&#"#4$32f#O'ztF> 1 032653#"$5fF>O'zt FN'ru  1 03#"$53326f餗O'z5t 'F&?'~&|?O'~O&|' F& O' FO& ?' ~& |?O' ~O& |?& ~ ] ]1 03#"&53326yaO\T~JPML 32653#"&5T\OaQLMPJ~w:1/0!#!5!)+jK'E!j@ :1/03!!)ժjO'zt!w:1/0!5!_++wO'zt#wN'ru#j/jO'z5t&5&w'&!'!O'"O&"5'#w&#6O'$wO&$'&&&O''O&'&&]10!!3 nC ~21@  0! $54$)!"3͙ nn{3!5 nw} (@  91@  20"32654&'2#"$547!5__ȘLӦnjFY 'i<FY} )@  91@  20"32654&'!!#"$54$C`^ȋMӑnj 'zi<<w "@  91 /20%2654&#"!5!&54$32__ȋfLnjw'z<>w'r<>FY #@  91 /20%2654&#""$54$32!C^`șMgnjFY'zT<AH}':w}';:3'AFY'yA3'BFY&ByFY'rT<A\ 2654&#""&546 !j>_IEcI_(0MJBSKFXCIn~|Q;n."&5332653ܨabaaJPMMPJ\ 2654&#"0!5!&546 _IcEI_>jm0(MICXFKSBJnn;Q|~w 1 /0%2654&#!5!2#bŘ쥒FY 'OFY 1 /0%"$54$3!!"Cꏙƥ᪑FY'z<Ow  1 /052#!5!2654&᪑w'z<Qw'r<QFY 1 /0"3!!"$54$3CbƙFY'z<TH'Mw&M;3'OF&O13'PF&P1H'Qw&Q;H'Rw&R;3'TF&T13'UF&U1\"3!!"&5463RiPYnvDZHCn~}w^ %5-5 ^j22F  ? 1 /0!3#$53TCc Xon2K' Eh @ ? 1 /053#3  cCT-ncCO'z thF   ? 1 /0%#5%3# c--noXF O'ztjFN'ruj @  ? 1 /0%!#3#c-gCcnO'z3tm'fF'f'h'hO'iO&i'jF&jO'kFO&k'm&mO'nO&n&m  ] ] 1  04&+3#XHǜV+.#"#"&'532654'&/&'&54632Cw7Bh#-8GC>=JGBAm'./G?;=~ÇH)@@V\`RʺªV\`RʺªhZ·%XhZ·Fl632#4&#"#"&3326tҪºR`\VҪºR`\VX%Zh۷ZhFlO'ztF'32654 !"/.#"3"54!2!rz|K٬42 swUҤ'4X˧|`í~pX˧|`J3~F'z<F'763 #52654&#"# '4!"326(24׬'Uvr!24֭٣K|zsp~ȕ`|Xp~8=`|F'z<&F&'F&O'FO&'FU''FU&'FU&'FU&'>72#52654&#"#"&'463"326[*'sobI=J>",BR\*$jt_UV) '2654&"#"'&54632! 33265,B:d:B0<~JIjˮîB,">>",BVU_tjN*$u) '"2654&'632#"&5! #4&#",B:d:B0<~JIj!!ˮîUB,">>",BVU_tj$*\) '"2654&74&#"#! #"&547632(B:d:BB®!!jIJ~<UB,">>",Bu$*Njt_UV)O'zt)O'ztS^$264&"&546; )5! '&Vhf# fw_:@ 91@ B /90KSXY%4$32#4&#"!7g#ʲfhXdfF.=@ 1@ B 90KSXY#"$533265!>ʲf"fw_?@  91@ B 90KSXY '!32653#"$5g"ffd餗 K'  '  O' ;' ;O'  '   O'  ( (2654&""&546323326=3#"&=bFntnPX/Q,CEmaZT:KMMKFHn|ppX;oBGj9$ 3>2654&"!&546323326=3#"&=!"&54632!2654&"bFntnP?+/Q,CEmaʔ/bFntnPZT:KMMKFH;XppX;oBGj9|ppX;T:KMMKFHFY<@   91B /0KSX@ Y!"3"$54$3!7YꏙbXhUFY'z<w8  91B /0KSX@ Y!26544#!wb gXw'z\<FY:@  91B /0KSX@ Y'!"$54$3"3!YhbƙXiU𥒥FY'zi<\'%!"&5463"3!\=.̞RiPYB~}nDZHCw%#535!53!3##q=ԭ-!%#5#53!3!3=~0Ԥ!O'ztw533#!#5!5#5q=-ЭԤwO'zt!3#!#!#5353=ԭ0~!O'zVt 33#!#!5#53m unfy~n ,@  221@  /990%2654&#"672#"'"#3z_̀ٷ{O{ʃIH+'sZ@  21  /0# !3! !5aPh//+jiN !!!5!;VnVN#5!5!5!53!!75$i2$i*mւVxnVnՆu!s #'#37 ͉sH+'Y &s & O& 7&  7O&  &  O& !!!!#!YX  !!###!YX  !!#####!YX    H!!#######! \YX     !!#########! YX     !3!!  !333!!&  !33333!!e    G!3333333!!     !333333333!!      !3!!#!?r !333!!###!?r   !33333!!#####!?r      Y#!3333333!!#######!?r        +!333333333!!#########!?r         SC !3!!#!YX\\SC!333!!###!XX\\\\SC!33333!!#####!\X\\\\\\S FC#!3333333!!#######!ZX\\\\\\\\S C+!333333333!!#########!YX\\\\\\\\\\!33!!# #!՚rՙr %!3!!#!!2^DD^ Wc !!!5!5!!!wsX #5!! !!'!%'! !7%!77'7!  ww u||||||||||||u  G7+/37;?CGKO!5#535#535#53533533533533#3#3#!!#3%#3%#3#3%#3%#3#3%#3%#3??????𨨨!!!!aOq:#[!' 7#}CrarCrrD:[! !rarC}rbar=` !#!#3!ff`G [`3!!!!!!!! j /t`Ӕ&{o{4=J%#"'&=!.#"5>32>32#!3267#"'&32767%2654'&#"JԄ℄N ̷hddddj||MI؏ii~ST`Te__ZjkSR\]i߬A@o\]Z^Z5*,=>` #% 54)3#4+327#!5#53!2x9||ԙf_ڪrĐq{Fg`32654&#%! )s7F0Ǔ$g` ! )#53!#32654&+7F0ɖzٍ`` !!!!!! /`Ӕ|1#"&'5327654'&+5327654'&#"567632p<54& #.54! ì++f++$$>:#tNPƳPNM]*U3MY + 3267>54&#"'>3 '# 5467'7*(Ou))Hn.Mw834OMx43N)gA\*g>}66]C_56`?`q{&/=5!&'&#"5>3267632#"'&'#"'&732767276'&#"qN ffjbdjQGhi񈉉ijBN℄RR\]VVUVVVZdc44*,nmn67윜78lkpĘZYWWsttstuq/u{ 4&#"#32/8qu/ 32653#"4/8`!264&#%!2#!#N[cc[H^^>2`!.54763!##"#676#";jpkla;;?î545w?@@?w iQP%$q2^66**TS++2`!&'&'3;3!"'&546#"37545â?;;a|lkp w?@@?wS66^2q$%PQicQ++ST**<m``$ 653 &53sXٹ};ML+%!5!2654&#!5!#TZ`fcL||BtN5353!5!2654&#!5!#Z`fcxzʤ||Dv/{&#!5!2654&#!5!27654'&#!5!#|vz{\MN`_`gb>> E__ru99wSS?yzVU=`YV5`ZX`]x`73264&+5%5!2 'Ӏ{n Fo}ɽBdd>Jm7{3!!I{/=`N`#!#`I``JZ^`367653#5&'&3U9VˆmmV9S`1Ms,}},uMLs` h !3#'!#ZgVXVq`!!!!!5!#!.AeW"___DXI &327654'&#327654'&#%!2#!g1221g̼^-..-^EOO)(N^h+&&MO%%X@? ]65dL.- rUpz 327654'&#%! )[ZZ[vNONN]eefe !!!!!!R-@___S !5!!5!5!5@-_/__H~$5#5!#"'&547632&'&#"326NJYXe|}}|\SRFFPOWWVVWCj]/rssr'y5UVVUL 3!3#!#΀2Wr3# 3+53265A@1(TFDE`Tli 33 ##-<azBm3!!_ 33###|{9="G 33##|_{EEG ##3G|_{EDEH"327654'&$  '&RQQRQQQQwvvwtww[\\[[\\[\vvvvuvG>@"327654'&327654'&'52#"&54767&'&54763sCDDCstDCCBR65<%j<=0ER^X65`l<=ca==ll*6RI)++LK,++,KL++5##,&)$%LY+8:6iG2278PyAAyP87'21I.* 32764'&#%!2+#Y0110YQQQQ))))]?@@?[ #'&'&+#!232654&#=)&''y.,,LPO)*s\^^\$ )(GTD<32#"&'#3t4554455$pMPPPPMp$uuc@AA@@AA86Z[[Z68^gG3#5#"'&76322764'&"Jtt%78NPQQPN874555555S^8Z[([Z@AA@@AAG#!32767#"'&547632&'&#"@AsC?>>>BADbc^]SSt44Va:: 2j88a WW[ZQRmT3210YGMK SX@ 2KSKQZKT[X888Y1@   /0Y5!.#"5>32#"&73267GsC}>?CŻthVau2koamTebXTb2&'&547632.#";#"32767#"&5476G&%HG{065>=f,K,,+*Ib]W-155_;65-9553+,$$4O,, ^$'U13 `fa<))R`1#"'&'532654'&+5327654'&#"5>32FLHG{065>=23-KX+*Ib]V.156_:65-9j2RQ,+ H4O-+]4$'U 12  `33a<))G 14'&#"327#"'&'53276=#"'&763253J44^]4444]^4PP=7633223r99$88NOPPON88$tm=>>==>>FNO e 45k37XX"XX7_z3#53ztttu 33 ##uuZu2u{"4@ $ #32>32#4&#"tHKYhuu'oMLl+yRowtHJZiw[Wk\sa97EBEB~wZXku4@ zx66X6VYYk\sa8BDG 6@ KSKQZKT[X 88Y1@ /0"32654&'2#"&546]ml^]ll]ǁqqpoWGu 67632#"'&'532764'&#"G0336^_]^:5311213p?>>?p3121 XXYY _ ?@@? G4'&"#46320T6667zWVoBAA@qWWG27653#"'&506667zVWoBAA@qWWu#3>32#"&$4'&"27uu$pMPPPPMpf4554455b_86Z[[Z6@AA@@AA#3#;#"'&5#5350Hww33UUPM,V-,vTPn3327653#5#"&nt''N^67tt+78Jy~{Y,-65\c`9nA!5!27654'&#!5!#Ue22<KLg#"FS10gg%dAl88u{(#"&53327653327653#5#"&Q+<=Rnxu$$IZ54t$$KY45tt(78LMlE!"z[+,64\c[+,66Zcb;F&33#&{{y #! !&'3254554#"t nυ9F}攥^ؙ83a _{3#5&+532{t<,||GXG+&#" '&54767&54!232654'&'&yAJZVWVWW!/bL+"766^]l9=P(r(B4?KWXXWr]$,O'(@?Ajp69G  )"27654'&'2##5"'&5476734 )=;67-!XQVVQs~SVV@h)%661FQ:5}t?3XJOZUUXR=\ ,Ajq@:%'#&+53;'&^sa,(^ra,GX]:DFYzg duudnsd&sdyodsdy67632#"&'#44&#"326&_%sNo%ti\[jj[\i92ض78"{qqrG xd%tdV{(!2.#">32#"&'#32654&#"aQQR9||9F,*[cbbc#Lct`5!#3#3!53#53t𰰰त TV/%+53276'7#3/F0j&*06G#367632#"'&$4'&"27tt%87NPQQPN78f5455554_s^8Z[[ZA@@AA@@Gu&'&#"32767#"&54632u1122q>??>q22110h;533` @??@ _ GKu+325&#"47&'&54632&'&#"632#"Z%0\R@5`$^4412/412q>??5{3 * &;/Z ` ?@@biG.&'&#"32654'&7#"&54632''7'37 i:;n\[nO$$ZY drP =67Tb1#"'&'5327654'&+532654'&#"5>32N+,QR2658-56:_651.V]aIV-+K-32==l/|GHL ))unn77wU:8P#P,i/0\+53276=#533343r,Brrtn x66XU P#PG ,5#"3276#"'&'53276=#"'&54763J]4444]^44tPP=7633223r99$88NOPPO>==>>=۠NO e 45k37XXXXn3327653##"&nt''N^67tt+87Jy~{Y,-65\cO9I 5333##53#Irtggttt\\jz~ ;#"&5C,rfpUWlwI 5!#3!53IMjjo\\E\\I5!#3#3!535#535IMjjjjooo\\\\\\V`3#"54;33#'#"3276ztteztry "3rKNB ,|ssW?#5$ z~3;#"&5ztC,rfSVXlx[`+53276'7#3`34r,Bttax66XS gq3!!q_u{467632+53265&7454&#"#4'&#"#367632+=32#4'&#"43r,B0t*pJz>?t'(N^66x66X6V~a88BDwY,-56\uU 4'&#"#367632;#"'&5P''N^66uu)89Jy?>0B,r34Y,-56\sa8BDzV6X66xq 33##q-{{~G 2#"'&5476"!&'!3276WVVWUWWU6//1w &6^]6&WWWXXWWWW@9\[8E-AA.G&.#5!#3!535&'&5476767654'&OpFVVFp^nCWWCnt6%66%4#76$\\FWWG\\FWWE[*,ApoA-9*A@+Fa:.#"#"/;#"'&=32654'&/.547632;1j8W*,]({44MN9> 0Br34@?>=RX l)k`GF@rb/$+*MW33 V6X66x"j2-*TIX00476;#"+5326z73zno>43r,B0]Me30U:Jx66X6#3#;+5326=#"'&5#5350Hw43r,B033UUPM,ax66X6V -,vTP^!533!33##5#"&=)3276^ntgtuut+87Jy~''N^61\\`9Y,-6/G&5!327654'&'5!# '&54767GE()78Z[78*,?G$"ZYYZ!"J\{':?KY7667YR8>#{\8?>LRRQRR<=:u2653#"'&53QHuDEEDuHPZs{>??>{}ZPz3+"&53?27654'&'&gH#"YZ,rftA Z87)2:08?>LRRlwpU67YQ8C&# #3{{ s7n !!!5!G'L\^=R^7!!#;#"&=!5!G'LC,rf>\^=R VXlx ^7^n#47#5!5!3632#'3254#|`\'Ln& m,7!!^R^=jR37!2#"'&'5327654'&+5!5!hCQ>63``;??C5~Ex>?::hn\& =;M|CD m**PJ*)]R^G !32767&'&"2#"&76So/6^]6/ +66,ǗWVVWVV*MWXMmGYXFovw^wwwv[f!5!73[f3!Px[f#'!5f[f!!#PU騋fBf 3#'#35fxBf 73#'#˴fxh'${-{'TDN'zs%N'>E&%&E&%&Esu'l'sLvquf&vCO'zt'qbN'>G''qZ'zG&'qZ&GOw&'z[quZ&Gz'&'qZ'^&GZ&(q^'HZ&(q^&HK&(7qK{&H7v&(qv{&Hum'yu&(zquH&H'zK#O'zvt)/P&I @s&*2"qVZ&JI;N'zs+dN'>K;'+d'K;P&+j@dN'>Kt;&+ztd&Kz9;&+ 9d&Kv&,Jvg'LYZ&,tF&ajl'sv.l'sZvNj&.&Nj&. &Nvj'/''O jk'*u'/S1'q(;j&/J'Oj'&/\'&Ol'ssv0f&PvO'zwt0'FP't0{'P3N'zs1d'Q3'1d{'Q3&1d{&Q3'&1d{'&QsZ&2fqu &RsV&2lqu&R'jotrsZ&2jqu^&RsZ&2hqu^'Rl'sv3Vf&Sv2O'zt3V'STN'zs5J&UT'}5J{' UT1'q}; "J&q #T&5TJ{&UO'zt6o&%V'6o{'Vm'sv'z6of&V&VvW&6o&#"O'zt *o& +*O'zrt77N&W#>'q77'W&7b7&W'r&77''&W)'8X{'{Xv)&8vX{&XK)&87KX{&Xu7)Z&.8X&+v)4&28X'Xh}&9F=7&Ymh&9=`&Y^Dr'u|:V5k'C ZDr's|:V5m'vZDN'j>:V5'jEZDN'zs:V5&ZGD&:V5`&ZJ=;O'zs;;y&[g=;N&;j>;y&[jfO'zps<=V&\f\m'vu=Xf&]\&=X`&]1\&=X`&]d&KfN&Wj->V5&ZB=V&\{a&D/P&A@7&#"#4>32"#"'532654.546m@f_@&9dc07CjjCӴmob)F[dd[F)Z@hoϋ\(Ž}_-C-->T\_EFvX5P3) $2BgCquHh'${-{'!Dh&$u{-{&DTh:&${'Dh:&${-&Dh[&${'Dhu&${-'Dhm&{-f&"hZ&${-'DhZ&${-'Dh&${-5'DhY&${-&Dh&{-&3&(q{&H&(uq{&H^'tu(q7'H:&(q'H:&(q'H[&(q&Hu&(q'Hm&qf'& Z&,#uD|& &,.&Ls&2'qu{&Rss&2'uqu{&R}s:&2lq'Rs:&2jqu'Rs[&2jq'Rsu&2equ'Rsm&'quf's& sgk's'ubvf&vscgk'u'ubvf&Cscg&b'uv{&c}g^'t'ubv7&scg&b'v&cs)&8X{&X{)&8uX{&X}_k'suqif&v{r_k'uuqif&C{r_&qui{&r}_^'tuqi7'r_&qi&r{r&<ur|=Vk&\C!'v<=V`'t\&<r|=V&\`^'tru<=V7&w\qa&E ppqa&E Hqf&E }qf&E qf&E ~qf&E qm&E vqm&E Dha&& p#ha&& f'& }|f'& f'& ~SXf'& om&&1 Qm&&x Na&I pDa&I 9f&I } f&I %f&I ~Of&I R-a'* p-a'* 7f'* }|If'* f'*" ~Sf'*^ oVda&K pVda&K Vdf&K }Vdf&K pVdf&K ~Vdf&K Vdm&K Vdm&K a', pa', f', }|f', nf',3 ~Sf',d om',t Qm', Nna&M pna&M f&M }'f&M <f&M ~Qf&M =nm&M nm&M Aa'. p5a'. Kf'. }|Kf'. f'.4 ~Sf'.p o"m'. Q)m'. Nqua&S pxqua&S nquf&S }equf&S Tquf&S ~quf&S a&4# pVa&4} Of'4v }|Yf'4 f'46 ~SPf'4w o*a&Y p=*a&Y *f&Y }'*f&Y !*f&Y ~`*f&Y W*m&Y 8*m&Y Ia'9b f'9 f'96 o3m'9L N'a&] p^'a&] T'f&] }Y'f&] ^'f&] ~'f&] 'm&] c'm&] ^a&=N pqa'= if'= }|uf'= Cf'=t ~Syf'= om'=B QPm'= Nqf&E tqf@f&I TfAVdf&K VdfBnf&M fCquf&S {quf`*f&Y 0*fa'f&] M'fbqVa& HqVa& HqVf& HqVf& HqVf& HqVf& HqVm& HqVm& HVha&  oVha&  oVf&  oFVf&  oFVf&  ohVXf&  oVm&  oVm&  o2Vda& 8Vda& 8Vdf& 8Vdf& 8Vdf& 8Vdf& 8Vdm& 8Vdm& 8Va&  oVa&  oVf&  oVf&  oVnf&  o#Vf&  oTVm&  odVm&  oV'a& YV'a& YV'f& YV'f& YV'f& YV'f& YV'm& YV'm& YVa&  o\Vqa&  oVif&  oVuf&  oVCf&  oVyf& ! oVm& " oPVPm& # oqH&Ezq&EqyqVf& $HqVy&EHqVf&@Hq7&E qnqV7& gHhm&&yuh1&&q;f&&B RhfVh&& oxa pVxaH <ܲ?]1 Դ?_]KPXY̲?]90IIPX@@88Y#55#53xgJ7FJm'tjVdf& (8Vd{&K8Vdf&B8Vd7&K qVd7& v8f'*b Ruff',n Rf V;&, of' p  f' p. BJm't pnH&M$n&Mqn&M .%x7&M q.zm&M r0gm&.y.uY1&.q.;f'.q R}f!~f'  f'  _Jm't *H&Y'*&Yq$*&Y *DVa&U pVa&U *7&Y q'*m&Y rm&9yvu1&9q;f'9 Rf#5a'6 F)&j lFRfCV'f& 0YV'`&]YV'f&bY'7&] qOV'7& Yf'4; Rf"f'=D Rf$NV&= osRfvxaH ܲ?]<1 Դ?_]KPXY̲?]90IIPX@@88Y53#7"͔gd10!!dd dy/10!!dOydy/10!!d8ydy/10!!d8yy/10!!y&__J&BBB@ 10#53ӤR?@ 103#ӤR՘?@ 10%3#ӤR@#5R՘?m '@   1<20#53#53ӤRӤR??m '@   1<203#%3#ӤRӤRլ@@m '@    1<20%3#%3#ӤRfӤR@@m #5!#5RmRխ??9; '@  YW Y <<1<203!!#!5!oo\]9;>@   Y W Y <<2<<2122220%!#!5!!5!3!!!oooo\\3!   \ 104632#"&3~|}}||}3q31/073#k1/<20%3#%3#V #@   1/<<220%3#%3#%3#ki3#iq L #'3?K@D$%&%&'$'B@ .(F4 :&$L%IC'1+C =  1 =I 7+ ! L9912<<2220KSXY"KTK T[K T[K T[K T[KT[XL@LL878Y"32654&'2#"&5462#"&546!3#"32654&2#"&546"32654&WddWUccUt%ZVcbWWcdWccWUccܻۻۻۼܻۻ q r "-7;EP\"32654&'2#"&546"32654&'2#"&546  &54%3#"26542#"&546"32654& WddWUccUyWddWUccU<¹ߠZucbcNWccWUccۻۻۻۼ5ۻ(`3(`u(`&  ,(`' ,&  X(`#3W`u(`&  ,(`& ' X , #'#Rs#G@%Bon29190KSXY" 5s-+#R#I@&Bop<9190KSXY"5 +-#^R^  &K'N''=NO'^O$#5>323#7>54'&L Za^gHZX/'-93A% #C98ŸLVV/5<4BR-5^1Y7| B_ % ij991@  <202$7#"$'56:<hh~vvuw~ign % ij991@  <202&$#"56$6;>nvv~hhgi~wuI3 # #bbc$$v=' {' { 3_!!V_+@B10KSXY"3#-\X 3!!#3hX^#"#JX 53#5!!53X^JݏޏJ&""gJ&"JJ'^"d] 7 91@ B  <20KSXY327# 'du](; 2###׎辸( 3+"&5463yv}~}|( ';2+v~}O|}=k {B# #5#5R#۬@n&  =o'  BC''Hd1#"'&'&'&#"5>32326撔 錄ܔ撰 錂1OD;>MSOE<>L~ 8| #'7!5!'737!!qaqqaq)`rrbqr2 535353,(`$' ,& '  XfN 53!535353fXp fN 5353535353,p  3#3#'d 3#%3#3#3#dipD %53535353#!5!3!,|f  feP> 3#3#3#>w 3#3#3#3#W "27654/2#"&5462332233VVVVVVVz@ <<1@03#3#zttttg? @   ] <291<290KTKT[KT[KT[K T[K T[X@878YKTKT[X@878Y@T /9IFYi       "5GK S[ e]] !33##5!55bf]myf !!67632#"&'53264&#"y^^a`<~B9>>Eoo4h6_ MLKJq ff\/"327654'&&'&#"67632#"&547632X3333XW33331221DD &9:DTTXWll122m45[Z4554Z[54bg KL1LMONuv l!#!liH30Y *:"32764'%&'&546 #"'&54767327654'&#"55j]\655T./RQ./SZ85UVUV56-/.UQ100/SS0/*,+KLV,++]12Hdt::dJ01:7PyAAAAyN98?&%%$A?&%%$S.532767#"&547632#"'&2654'&#"1220DC #<9EWXWXkl122Xf33XU5443g KK/MNoouv rh\Z4554Z\44k !!#!5!Q_i_k_8_83!!'3_a!!!!''^_o #&'&4767TRRTe^///._~g3#676'&ge_/../_eT)**)~~~u0@ 32tNN^luu)qJy}wYYk\sa88WT dC{d^TtdbTud?C dfC d\T dlC dYT dST d d8 d  doif dgif dMrdGxdGdu!sdGydV##"32.#"3267!!!!!!Oc%eNLbbL:/667756GFDFG ks9'.473&'3267#"'#7&'#7&'&76%73&'hA>/(%:@w]ayA9&AX}R4>C5Ai<)^_HH?WghйKp(`,%6767# !2.#"3>32.#".aXj]aye6{_]w|^0n&<$'/_HGghGG_^ٜu]\Y!!!!3###5qZpP~WHE9Eb#!!53#535#535632.#"!!!5-쿿=OL=tyB_))HB+#&'&#"#3676323632#4&#"#̪m49wSS>YXyzU6%X\xruxGM_a`f21>&>E3\u"&)''#!333#3#!###535#53355KO8~8~OO4&{{&&{{{ P32654&#+#!233!!;532654&/.54632.#"#"&'5#"&5qzzWQeGl`[z_<`HJU];Ufɘ/ϒjqqR>N#55YQKP%$((TT@I!*##`3E326&##.+#! 32654&/.54632.#"#"'&ٿJx}A{>[b`cae@fLNZb?ĥZa,/b؍$~3YQKP%$((TT@I!*;"&)-1'#53'3!73!733#3#####5!73'!!7]:1000019]zu }Luuguuguuuu_ % #4&#!#)"33!3_SV*$oN&1@: "+ /) 2+"!)#&  , & &*!/<29999999999122<20K TK T[K T[KT[KT[KT[X222@878Y@z  1Ti lnooooiko o!o"o#n$l%i'i-  !"#$%&'()*+,-2   USjg ]].#"!!!!3267#"#734&5465#7332[f A78 ʝf[Y`(77(6bbiZȻ{.# .{ZiHH"{/ #/{"G(33!!###5uX_Tws1s!5!!77#'%5'&PPM4Mo؈onوn9 -bw'67>32#"'&'"326767654'&'&67'>7632#"'.'&/#"'&54632326767654'&'&&#"32">1aJ{%A01Q[W7>/W1   >$<  . #dCw-^URB$`>DL_K>.3b @N\uLMiI(S395l9,8G(/&  -9)ЗiRm:3Xwdg7? 2j7#=5(6$ 629T/ (2M !:5S}$@{mbq~Es/4 -& "TAB`]|@8nRkcd]aC".)5'632327&547632#527654'#"'&#"%654'&#"o|@X"07PYtaTk~j[IwmqJ2530D#24!`NkBX``S㫣†qJ323!!!3267# $547#5\J5 ;_srigCS1r{jJ,{ +kv67&&UB{\* {;^~FE/0K?{w!,&'&#2767#&'&576753w[TUeeUT[Y\Y[dsye]Y\[CvlCi----iH$"u9Bt"#BuflC3!~d=!5!'3 G~d=z!#'73!5~~͛=z5!'3#7=~~d͛{ 3#%3#%3#yfP{ 3#%3#%3#%3#ky)=z #'73!'3#7~~<~~͛͛C $(B"326=7#5#"&54634&#"5>32%3#.#"3267#"&54632pSHfmƩogDc\GD^o8yy8o^IICBRCI M >OW\ 7$44"C +EI.46'&#"#&'53254&'"326=7#5#"&54634&#"5>32%3#VNz$p;i0ʪ%={pSHfmƩogDc\GD}|49d$, !5Lf,1BRCI M >OW\ 7$s'!.#"3267# !2'Y藣yyYjzS #bvAZ4-4ZBuHHghG[!!m&r&F+,/-/ܸܸ,(и(/A&6FVfv ]A] и ии# /!"+!0153&'&'6767!!5&'&76wI3cc3I86QLNN7887NNMR48_ki:rq;zn #++$ * rn<(2.#"3267#"&54632%3#"326&$  &54^o8yy8o^IICDkavva`ww~44"K <M-1332653#5#"&.#"3267#"&54632%3#\QPcu`^o8yy8o^IICDLriuD P44"K{Ro#&&r)Io!6767632#"'&#"32767#"'&'&547!#"'&54632327676"#"'&'&54767632l(9BKc{=&%%03!((!,739%7`lG;7 25]hB4,'5  'B[QF$%]c'G  %! }Kr~,1ьIg)*!&!(D;w},75;!_']7:y}[Ϟ\@4>#,!, 'QFj(JG4$$,*)/9yK#%P73276767654'&'&#"&'&"'632654'&'&54767767#"'&'672#"*i(X%# 1FSE/ O.55FuPU[QF[00rl~"KI}!;IFs;n;_T^͌Q79}w^l.Gyr\[4O9%#i#^MX;yv@c}e.ID\7I;>2V秉uӰ3!3%!!!!!!nnq  dx+%H#>54&#"#3>32u j_ y/wFx \/HT^Ȧ^m$RZ3%632##"#'7-P4-> {|a\=BcL;t9#"'&5476323276765"#"'&54767632thn<7# ;KQ>!|Za,4(XM!},‚<7D9#7.M=.1?@ '(MXI(' jF!2?632327654'&54?#"'&#"632327#"&#"jou9!ydG>PPPP5ʺ68^nm{z}}ȋo֏zZ'PVaK~pmdykb^OP681/::b:DnJ327654'7#"'&'$#5"'47676766767632#"'&'&'&#"32nZS_n0VBRny#HB?X!$9BMw>7l. ;7%,;(ӧuy,D0&3273#"'#67&5477632654#0)W:K32#"&'####53&  O:{{:ܧ$}daad}j %# !3!# dX0dd q+6+/BB/,/<-ݰ.<-ް#? < # 9 FhH)##Ii;BB=#IbiF`FaC`#BC`CUXC`C8Y& <BB00<İ< 6< <9 FhH #Ih; < ְ ݰ,9, FhH &ְ& #Ii;/,#Ih:1#IC`#BC`CPX& ,/C`C8K RX #IC`#BC`C@PXC`C@aC`#B C`C8YYYBB=#IbiF`FaC`#BC`CUXC`C8Y#)<BB1#IRX   <  < Y3525!463"!4632#"&732654&#"5!6jgggg92299229k̀k@4nNggNNggD{{ "-! ! ! ! '32654&#%!2+# JR12)uyӲckkc?L00ey wXQPXdn;C0<67632#"'67327654'&#"#"'&57&547276545[ۄFIyeL )qz]E& JEYq:?.蔁0.A ƂMkeLPק<+(h|H=y|n=B {u.F/4_NT 33!27&#%!2+!67654'&,d.@nX<-]\,q jdZ)VV)s!)%#'# ! % 7& 676'&B 3y;:x+lllli$ #ab[ 2222jT%%5$c$B2 _327654'&'&'#"'&5476323276765""'&5476!6?232767#"'&B=]iS\ZV30Fn7;#FfS9!!< #5,h";<2XngZR{,##9>;K!QIag£S D5@7*'S:y}*7H0 5#!,Il @3Xnh0{(2r:=OSlIX&54'&#"#"'&527654'&#"3"'&547632763227767654'&#"R(O*\xggfg-.@@?@@?\QA@@@S6fggfeӻp/$~AB}:1$ -*MJJ@f[+8vuuv zVWWWXWWVVW\uvuuu# bW1W{|^1$h{vC[SK\GChfy /2 &.2&'&+3!.+!! !27&#676'&%3LDEx-Me5q>HJxnu1EA+ZY*01/O~hbb)j)V>U)-  /!/ и/ ܸи!ܸA]A)9IYiy ] и /9 ///+ +0132654&#+#!273 # #s sNCI/ϒ_6۬kk%T$+.3&##&'&''7#!27%7 67654#?\A>:AٿKE6ToF^~_ ,8~|T3Jۏ/HDh0& ,ok؍]-Dbg('4.#"#"&'532654&/.54632733###UW'AG/E8pi4sG[d/EK7?8pc|3iиY"*/( VAO[`*,2,* M=H\T(l0`!!#!!!!!!!3!!rso+` `ffff'F >@!    b b cbc91<<2<<903#######5Jq7rqr/B^^"h %73# ' 3,o-MoF+,\ %#!!!5!8kO8d qddd XL/ 654&#!5!5!5!!2!"'X $''ߦԧc̆eeaԊfJN=NsDU767654'&#"#"'&5733272632632!"'4'&'&#"'6763232767654'&'&#"_}yj#1Q\$####,TGG\n#?QY>kDM4giMqE#"'&'&5476?&'&547632#"'&547654'&#"3"32767'_ilE_ml=Oc{T3-2") %+fa@aP/Z_|{w:maZu> IhA"%@_l$=PczS2VN-2!$+%$+@e}N069na[u>_T M#"'&'!#!"'&547632327676=!7!&#"#"'&5476!27327#X':'7?<=**M_4. B^l{>!'Ba>nG#&#w4$B00!K=DcK_4B( 03B{>ceDInFT=I,Fw7K. 0# )5!!5!3#Pʪ9Bk32767"'&'&47'&'&'#"'&547632326765&#"6767632377632#"'&'&'&#",5(.'*'E`97y{7a;f7;>F3.^PeMD*#7@,j!HhH<=.%_yipp3 T}B',$ *5܀/,,@!;Da97TVM;nwF^O?/,%!;>jytX<;}f?E'_n H''#  .hJ) 4&#"322#"&54WOmVPm˜ݢt}t{أأg4 4'+5654/&4?'&547 '&5474/c2>Bd=VE/b5c2ltc2c2uc1LS2?Bd,>8?]/c6c1LS2tc1LS2c1LS2903#!".54?>3!4'.#!".54>323!2O,""$%@;5H *Y[#$"x2 1[G(  WA,!2#"&/#!"54?>3!!"&5462TPl 0%= -d,mF"$mG- .7#*(/ $"Sae(!q~B;V&!"&54>323!2#"&'&5 mG * 5G 0%9 . q~( 0 (/ &Js!S'DQIF 4632#"&3!53#5!pQOooOQpoTQooQOonuyy5yZR; ! ! ! ! HH#[[breH !#y;:x L`  !!!!#!3#'!#33 # #DjwZDZ֏R``C5MR.}$z`-1%5"'&'&5#2327#"'&5#!#"#463!#3#, 9Yl(Ht*=Z2dr!Z4@'!8 ֦zEB bLs{dYsZ{3#"#4763 3׮UEEl4FũdGQnCF\xB*WbOZ=0 3%!!,:*nq dd3!3!!!! nn8q  qwS ! ! !!5 5Y*dccS!!6$3 !"$'53 !"kJu^uopkoSUggHF_`2/.2%!#!5!)+!5!_++!# #3bef9WJ " )327&#!3676654'&|tK"P"coAfյ|cv~dAA xPfUmZ #2!7#"547632!3 32767654'&#"* 6B8wx!Nbb|˞"#>|OO'vN 2wx87tKsO=  =d01 PD10d^dTd6Jthi[{ (232767# '&5477632!7!654'&#" N&#G_yZ\klmk}Z5fF 9NJC0<7h:J(u*oDMcFPZd82vRsO 3#3#!!ɸ.Ԇ$N9`V 3##676#732767!ɸ.fʆ#5H2K1i0/N)deеT0Hd01``;&0 #473>32#"&'532654&7>54&#";Ht]h202޸SUWDi;2[UԠ_I@Yr~YW׀c?}<$$/1oX3gQX?@Q` $@   F 21@/0!5!!5!`oX&{' 5ud^X&t' 5ud^&{' 5 d^^&t' 5 db^&u' 5 d?^& ' 5 d~&{' 5 df~& ' 5 dw&{' 5 dbw&u' 5 dfw& ' 5 dlw& ' 5 d&{ 5,'&,,&,',,(Q&,9h9&9,,&9',, &9',',,-&,;=;;=&;,=B&;',,j/s'&'0yL&LLpY&L'LpLA&LY=`Y=&YLD=-&Y'LDL=&Y'LD'LL$J&L[;y`[;&[L[;D&['L[LyOq{FqZG{Py }  ) !3 !## !5hPPh55~ji.,w# + ++ A]A)9IYiy ] A]A)9IYiy ]%"+++ + 013 !#3 #32654&#! )5HHNhPaY.,职~y }(1C3 +3 !32654&+! ) #"35# !35#"&546!`HH5NNPhthNN5H/ó., ji~s'H{d?8   2@ @@ 00 ]1@   990@   <<@ <<KSX << Y5!!dx=xUZxx @   991  2@ OO ?? ]0@   <<@ <<KSX << Y3'#'-Zxxvx<xuP8   2@ OO __ ]1@  990@   <<@ <<KSX << Y'7!5!'7Pwx=xZwxx @  991  2@ @@ PP ]0@   <<@ <<KSX << Y#737Zvxxx76767632&'&'&#"#"'&/#7!#/)85,0F"<;NJX[GR7<"#!2)85,/$#?2WG[XJN;?,!F0O<:" %7xxUZxaxxaxuP8 '7!' 7!'7Pwxx>xaxUwxx>>xxwd?8 !5!3#xwx-xZxY %'3'!!5xZxZxvx檪uP8 22@ O O _ _ ]1@   990@   <<@ <<KSX  <<  Y!#3!'7'8窪xwx-\xwZwx !5!!7#7\xxZxx+xvx7!!5!7'3'xxxxxZxxvxxvxd>%52#!5! 767>54&'&'&>42/+-+-':1 Hxwxܪ-)o=  xwZwx(.46<=69)-d>>3276767654'&'&'&"5476767632+#5!5 6 +/24>A1:'-+/24>xwx  =69)-(.46=<69)-xZxvP>54'&'&'&"3)'7'7!#5#"'&'&'&5476767632# 6 +lxwx>42/+-':1A>42/+ׂ  xwZwx-)96<=64.(-)96=dP8X#532267676767632267676;'7'7#""'&'&'&'&'&""'&'&'& xwx 0$#$   "%'-0$' !  ' '- xwx  ('Z&("  "(&Z'( -xZx$ -#%"&* 'xwZwx ""&*  *&"" dPF%'!5!!'7'7!pxwxpdxwx^:5xZxo:xwZwx* %'7 !^ b9YXxbZ  #!5 xwxoxZx[ !'7'7!#xwxxwZwxZ  !5!3 ixwxDxZx[ 3!'7'7xwxDxwZwx 7#7!5xwZwx=xwxd? !5!3?=xwx-xZx,-eX&7#754767676 #4&'&'&"9xxZvx.-\ZnllnZ\-.BB54'&/#7!!#"'&'&'&54767D !BB54'&x\-..0YXplgtTY0../Z#,@#B"!BB@RNJV]xwx]TQ>]xwx]xLii `iiT4]xZx]4]xwZwx]JiiiiuP8!7'!7!5!7!'7'7!'7!5giiyYuI0]xwx]uIiixK]xwZwx]Kxd?8!!5!!]xwx]7Qix]xZx]xi#'3'#'x\xZx^xhP8^xvx^huP87'!5!'7'7!5$iiQ7]xwx]iix]xwZwx]x737#73jhx^xvZxx\x%hh^xvx^8dP8!7'!!5!'7'iili\]xwx]]xwxiii]xZx]]xwZwx7''3'7#7iii]xZx]]xwZwxliii{]xwx]\]xwx  #7!##PU?,UvU,?UP5#'#5!#5'U,?UvU?ԄU4 753!5373U?ԃUPqPU?U 433!'3ɕPU?UqPU?,Ud?8!!!!5!!c$R&xwxxxxZxxuP8!5!'!5!7'!5!Q$܊xwx&RFxxxwZwxxd?8#''''#53777?(FncxwxFn-FnxZxFnuP8577773'7'7#'''unFxwxcnF-nFxwZwxnF3'!!!!#!5!5!5!'-Zx((ت&&xvxTrx#7!5!5!5!3!!!!7Zxx((&&xxrTxd?8 5!!5!35!dxqxUZxxa 3'#'3#3#-ZxxbvxrxVuP8  '7!5!'7%!#'#5PwxqxUwxxw( 737533-vxxvxrxv4k?9 !#3?xvxתx~\xuI9 !'73#'7!uxvxxvvx7?~ 5!! !!  d }*^V 3! !!d}*p  d HP~ !! !!    ^V #!# !!!d e n ^V !! !3 3!!!E*dr*r$| \d^V )3! !3#!5#3 3 ȃ\Pdx @t %#!5#3'!3!3! !33'ȡdxd:tZdd\nt^V%#!3!3! !3!5#3ĹtIt\Px^V%3 3!!! !!3 37r*kd d| ^V %#!5#3 3!3!! !!33 37ȃ:͊` \h u}~ 7!! !5#35! u\Pdx f:bȃ  zM!#7!!#Mc"?,^xc?x^zM35!3!5!73zpc?Jx^cr+a?^xJ^V 3 3# '! !! !  e   dCuP8)5A '7!"'&'&'&'#5367676762!'7$"!&'&'!27676Pwx 21@=:C.2  21@=:C.2 _x_R#)l$h$#R#$Uwx@21.2@@21.2@xw#w;' , utP'7!5!'7!5!'7!5!'7Pwx===xUZwxתתxwZd?D5!3!!#!dx3xUZxmmxuPD '7!#!5!3!'7Pwxͪ3xUwxmmxwdPD3!'7'7!#!5xwxwwxwxmxwZwxmxZxd?D5!333!!###!dx⪪YxUZxmmmmxuPD '7!###!5!333!'7PwxYxUwxmmmmxwdPD333!'7'7!###!5d xwxdxwxmmxwZwxmmxZx7?@  !JBJAu}@ 7'!5! PJBł}BB7}@7'! ! 6BB A}BBh %!3!3۠ՈR+nm+A&6FVfv ]A]+ +0132#&'&#"327673#" B!OO!BzcI7͙7Ic_L 0"'&547632654'&#"563 3276767&#"\m`cu\6% GGnth r5?,/H@3H5,Y:$UeI+HQ\N,tqzSd69->eSY׮l !5!!5!!5>+5!#7#53!5!!5!733!Kcd04+^^``k](673#"'&'#7&'&$32 '&#" 32$767&'&YjiEd80~i?/c`RQQ$g'-"SRR:;nSz_'BTc_ N@DROg`8@91/90@cmpxyvn]] !3!^DC?`%! !3f<?I!!"$54$3!!!W?JGcGK@ sJxNL``ȟMOx]I&/!!!!3!!"''&'&54$;7#"ؖI$$$GA?d`,,cFU;}YI7ʟ 7c``JxH NGx]g% $54$)!!3!+*(FiNv%FrO:0QI&'&'&'!5!2#!5!676767!5?JGcGK@ 'JxNLȟMOx]I&/'7!5!!5!&#!5!2+4'&'&'3276765 I^Q$$GA?d`,,#FT;}YI7ʟ 7c;JxH HNGx]g )5%2767!5&'&!5(*FiNv%FtFgP:1R, //01!!,wq@gg120!#!# }wq@gg1<03!3wJ}w; ]@    91990@0QVPZ spvupz  Z pp{ t  ]]!! !!5 7AJI3!-10!!ת !#!5!3!!5!--+}ת W+и и и / + +и 01!!#!5!3#-Ө-5B<%?P%73% %#'TUUTUTTUDGrXY %=} *@    91903##'%\sB}}`s-Pb;=v& Xus=e& X s 127#"#"'&'&'#"'&547632676;#"3cd3668+MI6641C;ItY^^SI6?+((C;ItK@tkHMfpEF?$Tx5@ejre!93Ex5@#/;&'#"'&54763267632#"'&%27#""327654'&1C;JsY^^TI6?+((C;JsY^^TI666cd3778s~d3778]$Tx5@ejre!93Ex5@ejreMHMfpEFHMfpEFI%!3!~,I%!3IfIA//+к99к901%&'&'3!!#4'!&'7`'JAW`LqR]+X* Pʋs^(Rs57756u5 +  // 9 9 901 7&'7%%'6 676r{EG%y44RW!L!$Ҿ &!L {JP+3#+fJ+ 7+и//9 90137#'PMVo)gnJ+3#3#@+fJ+{//и/ܸи ܸܸ и и// // 9 9 9 9013737##'[P]ME+qd @oxpAn!3# ih^T3 3##"T^32#4&#"#P(*7332653#"RP7*uM>2&#""&'7327~9GA~9G⧅}}uM& i i%uM& i' i% iJuM-6?67632&#"#"'&'7327&'&5476767654'&'SOJMG79GcBnnVsSOJMG79G]InoSu=,EG%,=,HK%DAF7K|oUDAF71IosV/HgjG$4.JhgH$uMMQZc67632&#"!67632&#"#"'&'7327!#"'&'7327&'&54767!!67654'&SOJMG79G~SOJMG79GcBnnVsSOJMG79GSOJMG79G]InoSu~=,HK% =,EG%DAF77DAF7K|oUDAF7$çDAF70IosV!.JhgH$+/HgjG$uMmqu~67632&#"!67632&#"!67632&#"#"'&'7327!#"'&'7327!#"'&'7327&'&54767!)!67654'&SOJMG79G~SOJMG79G~SOJMG79GcBnnVsSOJMG79GSOJMG79GSOJMG79G]InoSu,~=,HK%2=,EG%DAF77DAF77DAF7K|oUDAF7$çDAF7$çDAF70IosV!.JhgH$+/HgjG$uL.3&#"7#'754'&'#"&'7327#4767>32";EY?w^H6H\O3,,HO;E+@/VfmVmHO?u]HH]sM3 gz.VrmV_zuM<%4'>7'7&#"7"&'7327&'&54767>2=,HK%=Q Hl;EYLmHH7'&#"'"&'7327&'&54767>2=,HK%m#6,=iSH;EcHKs;E]InoSuJ.JghH$6B0+@TH?HK|z1IosV32326ian ^Xbian ^V2NE;=LTNE;=K23276767632.#"#"&'gV^ naibX^ nai2UK=;ENTL=;EN1).#"3".54>323265.#72#"&:QHRdhNi\dnx>@HRdhNi\dnx.ttlH=YOHL\}X[lH=YOHL\}W#"'"#322{dfftX{dfftX#*$0!#.5476767654&'30ND:323267#"''cDXbia]yeEVgia`yS LTNE+~F KUNE,F #"/&'&#"5>32326!!ian^Xbian ^VeoNE;=LTNE;=K`#"/&'&#"5>32326!!ian^Xbian^VeOE;=LSNE; =Kkb%&32767#"'!!'7!5!7&#"5>32%H\ iaBP﹉lZXbian3}o -X"OEd8LSNE;I"#"/&'&#"5>32326!!!!ian^Xbian^VeOE;=LSNE;?Kk˪.#"/&'&#"5>32326#5!7!5!7!!!!'ian^Xbian^VLoKɦoOE;=LSNE;?KL˪s˪sB.32767#"'!!!!'7#5!7!5!7'&#"5>327b K`Jqia'+\+zlh>Tm?u2^Xbianc"%]OE˪Nt˪=LSNE;%N;?@.9*-" *19" <-<<219999990#"'&'&'&#"5>32326#"'&'&'&#"5>32326ian ^Xbian ^Vgian ^Xbian ^VoNE;=LTNE;=KڲOE;=LSNE;=K43267#"'3267#"/'&#"5>327&#"5>29+Vgia@LJZVgia}9+Xbia@MHZXbi a KUOE8KUNE; @^ LTNE8LSNE;f@59#"/&'&#"5>32326#"/&'&#"5>32326!!ian^Xbian^Vgiaq^Xbian3VeLOE;=LSNE;?KҲOE;=LSNE;?Ky5P#"/&'&#"5>32326#"/&'&#"5>32326#"/&'&#"5>32326ian^Xbian^Vgian^Xbian^Vgiaq^Xbian3VײOE;=LSNE;?KҲOE;=LSNE;?KҲOE;=LSNE;?K"32?632.#"#"&'!5!5gV^naibX^naiUK?;ENSL=;EOȪ+  %5 % $%5$[g&Y%ZhӦ69%676767!!"'&'&'!5!!5!676762!!&'&'&[C-87VYYW6 8.CC.8d 6WYYV7 e8-,CE[<0[2332[39\DD+N+DD\93[2332[0<[EC,` !5!676762!!&'&'&!![C.8d 6WYYV7 e8-;++DD\93[2332[0<[EC,`'  ' &  ' &  0' &  .62' '  W63& '  ` 3654'!!5!&547!5!!4434w~0IG00GG2?8>;_8` !!!!"264&'2#"&546HdddeH;k'**z{DbFE``bq+((d:svv`K!!!! &!56뗲`!!!! 3# $c'`!!!!33#$'c`!!!!!!'+]^*^]N䰰` !!!!!3!Np!NNf`07GO!!!!#"3###535463!3267#"&546324&#"'53#5#"&4632264&"?$mmC???DNB&H#$J'`qk[Q_C<17HBB@,I\\I,@p`ctiG6B?9i=$#tu#gSSS`*!!!!>32#4&#"#4&#"#3>32!]?U\Z79EPZ7:DPZZV:;S==:xoHOM]QHPL^P%U20=` ,!!!!3#7#546?>54&#"5>324eeb_--B6'Z0/`4\o$-,N2A+,/-7#!^aO&E++ '>@"     <291<2<<990!!!!!'7!5!7!}/H{};fըfӪL !@  <<<<10!!!!!!ת4!5!7!!!!!!'7!5!7!5!DQ"rn遙RoLT˪˪T˪  )@    <<10!!!!!!!!K T@.B $# <2291/90KSXY" 5 !!@po V@/B$ # <<291/90KSXY"55 !5AǪV 3!! 5 !!@poV !!555 !5BkǪ!5!7!5!7!!!!' 5'`ȉ)P"_=6@ss1stFpo!5!7!5!7!!!!'55'`ȉ)P"_=6ss1stF. 5 5:6:6pr pr . 55556:86:'!67&'&54767&'676'&'{)#Y4JJ4Y#))#Y4JJ4Y#)AAAAGF㞢GGGG➣FG2;;;<<;2;5$?$%5%67$'W eĔd?NĔ])]o& bR)`q% Rd%'%5% >zmzF<˶@6 o@hGp%5'75%7-孈m%˶C@ʴ@hGp/V !5!%5%%%!!'/xvH-rf5LOlUrC@=Vlь=/V%'!5!75%7%5!!' GWb[mmNL>ߪwe=ت=$%#"'&'&'&#"5>32326 5jbn ^Xbh`n ^Vg@ND:3232655jbn ^Xbh`n ^VfNF<>LTNF<>L>)P14%&#"5>32%5%%%3267#"'&'&/' k Xbh`'+kuE%sk ^Vhjbn "Pv1-LTND9ATj͊LTNF<= &TN#wf=J;N} 55 58@'poN} 5 55@'pom`!-%5%%%'5%%5 MM`ZDOA@FZDt@m*_TW&o}䎲w&-r~bUm`!7/%5%%'%5%75%Jvad",,V`bL"_D2,/*/&O{¸[&}P %5$r osaa^~||P 55%$so a||^a)W!%5%5$gV$}]]x|)W3%55%$Vg}$BW|]]RW(%#"'&'&'&#"5>32326%5$ian ^Xbian ^Vg$}NE;=LTNE;=K$]]x|RW(%#"'&'&'&#"5>3232655%$ian ^Xbian ^Ve}$NE;=LTNE;=K$|]]&%5$%67%'Et֋$k}uU)?eKtuu" K 9''567$'567&'%=⃹t֋~}uRU)?Kuu,ަK9'_%!"54763!!"3!슊@^`@ƍ^`_75!27654&#!5!2#@`^@Ȋʣ`^; #";3!!!!#"54763^`0rrndflppꊊ^`&pphƍ3 32654'&+ #!5!!5!32#^`0rrpp9^`phƍ7!!!"'&54763!!"3!Ɋ@_`@,ƍ^`7!!5!27654&#!5!2#@`_@Ȋɖ,`^ȋ '!";!!!!'7!5!7&'&54763!7!!ʉ_`'}E=aLT>scL0R^`5ƍ7 '327654'&/!5!7+!!'7!5!7!5!^`__BV 5cTpX?bLm>U`^`C 7 Xȋ5j )5!7!!'!"'&54763!!"3!.Bqx-qxDɊ@_`@Z54&'&'$  &'&'&547676!!#!5!]\LMLLML\]]\LMLLML\bc1111cbbc1111cbdd''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcbee$7!!"2767>54&'&'$  &'&'&547676r$]\LMLLML\]]\LMLLML\bc1111cbbc1111cbתa''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$3?"2767>54&'&'$  &'&'&547676''7'77]\LMLLML\]]\LMLLML\bc1111cbbc1111cbxyx''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcbxyx$7 "2767>54&'&'$  &'&'&547676pxg]\LMLLML\]]\LMLLML\bc1111cbbc1111cbpx''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$73#"2767>54&'&'$  &'&'&547676]\LMLLML\]]\LMLLML\bc1111cbbc1111cb''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$ 2L"264&'2#"&54>"2767>54&'&'$  &'&'&547676ZPnnnoO@v+..]\LMLLML\]]\LMLLML\bc1111cbbc1111cbAoPOmmp1.-rB''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$+E %#'-73%"2767>54&'&'$  &'&'&547676C4f4C4/f/]\LMLLML\]]\LMLLML\bc1111cbbc1111cb1XSXYS''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$!;!!!!"2767>54&'&'$  &'&'&547676]\LMLLML\]]\LMLLML\bc1111cbbc1111cbj''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$37"2767>54&'&'$  &'&'&547676!!]\LMLLML\]]\LMLLML\bc1111cbbc1111cb8''LMmjML''''LMjmML'dbcwvwvcbddbcvwvwcb$!%!!!!#!5!QX>ddYee$ !!!%!!rPX>ת\$   ' 7 %!%!!=kyykyjjX>xjyjjyk$$ 3#!%!!aX>J@ <1<033!!upJ!#!5!3JI!#!5IssI35!3!|33!!Nup| !#3!!!!.NN$J !#3!!!!.$J !3!!!#3GupJ !#33!!!#3.GVfupJ!#3#3!!!!.cGGf$J33!!!'!'Ssj\s=u5Y6pJ!!!!'!#3!7!sjshxj56$$J!!'!#3!#3s6s=5Y6puJ!#3!!!!!'!#37!s:jsjG$-56$]*5$%67654&#"'632#"'732654'&'$@e=M>P7sZw㔰Zs7P>M=e.(Y7O0<0:>~jy[<<[yj~>:0<0O7Y]*327#"&5476%$'&54632&#"ee=M>P7sZw㔰Zs7P>M=e@.(Y7O0<0:>~jy[<<[yj~>:0<0O7Y( 51  ^ bb:d 5! 5bd 5! ^bbb:yg62"'&'!"&462!6"264S몧Q3Q3TW4drOOsOOSQ3CB3RU4CDPrOOqyg"&462!6762"'&'!$264&"aS몧Q33TW4QrOOsOSQ3CB3RU4CDPrOOqbgR 7!6762"'&'$&"26b1[륢S4OsPOtO.D/YR3BPQqOOy;d 3#!!#3%!5!( 󀨨 ds <!##5!#T~N 35!3 3#K#"T^ !!3# K@ih^T !!3 3#K@#"쪠T^~ )3!!&'.'&ZVF%,E=Ώ?~%FVZDA?=~ !53*,Ԫ֪w # #}}wJw 3 3!#wJww@ 1@ 0"# #4$H̭9B( w@ 1@ 02$53 3H4CC1 (B9#uTHF103#F1  !!'+]^*^]䰰3#3#!5!7 !! 'RLxxLux66x<ux6xx6x'B  ' ''ٛ>PNq^D^'B %  !'''tNP^D'B 5  5!''6bNP'B5 5tN>]P'B 5 'Nt>P`32?632.#"#"&'!5gV^naibX^naiUK= ;ENSL=;EOȪcy 33#cu?Ik8ff%q#cy 33#cffI?#q% )!"3!!"'&5463!! '&76)!"3!k:((P:jZYk񼽽jȊ ()9:PZXD  ȋ )5!2#!5!2654'&#5!27654'&#!5! !YZj:P((:kɊj XZP:9)(ƍN$!4&"#47632! #4'& PtPZXD|p:PP::ȀZX8x8Ȋ:1$2653#"&5! '&3 765PtPZX1::PP:8ZX:8Ȋ|84'&'##47673#Z:KK:ZllY:::ZaȌlala4###!5!5!5!333!!!!'5#Y~~~~,,33ͨ^ 3# 57Ѧ^ 3#55=d//m.   5 5 5 :6:6:6pr pr pr .  5555556:86::6:.  5 !5! 5?@Npo. 5 5!55?ްop9 %5 5!@op9 7 5 !5!?)W5$%5$Ti}$_|x]])W5$%$5iT$}B!]]|!&!%'&'57&%5$%67&%7*?;i@]0qw^%KA6#(AF+3273267#"'' 5cCXbh`^xnieEVhjb_zl]@LTND*F JVND+Fpo"%&#"5>3273267#"''55cCXbh`^xnieEVhjb_zl[LTND*F JVND+FͰW&&#"5>3273267#"''%5$cDXbia]ymieEVgia`yl]$}. LTNE+F KUNE,F]]x|W&&#"5>3273267#"''55%$cDXbia]ymieEVgia`yl[}$3 LTNE+F KUNE,F|]] 7%'%5 '瞃۞L О  @Y8@\9@a ' 7%͞G۞О@?Y@<9@}5!%57%!!'71|Iv\' :qߦ[@Z8@_}7!!'7#5!7%%%9Jpv\]FGjq8@ǹ@ 3!!"'&5]9Deo>ܚVf]>#3]J] 4'&#!5!29Deo$VfX,&'&3!3#76l<(enP==Kne(!< _EA_ <]> 3#!5!2765oeD9>יfVu(3(7@% !!!5 5!!37d  hrv! !! $<Ff +   276764'&'&">  &vvrn66\]]\6666\]]\65kk\SS]\6666\]]\6666\!;>32#"&'#'%53%&  s:{{:!8#!rܧ$daad]chaam@j.!3!3:^ &ۺ+#+#+A&6FVfv ]A]A]A)9IYiy ]+ + $%+$01! 4$32! 4$#"35%33!??qqW|A?rpG~+/ 8?+3&+3+A&6FVfv ]A]A]A)9IYiy ]3и/A&&]A&)&9&I&Y&i&y&&&&&&& ],9+ + +0)+001! 4$32! 4$#"!!56$7>54&#"5>32??qqWO\R!>/_N;sa=0>A?rpGM"?U(?N&:$}:iF D+B5+B+A&6FVfv ]A]A]A)9IYiy ]A55]A5)595I5Y5i5y5555555 ]5B9,5B9,/A,,]A,),9,I,Y,i,y,,,,,,, ]ܺ&9;9+ + )"+)?8+?2/+2/2901! 4$32! 4$#"#"&'532654&+532654&#"5>32??qqW v@X[}DuskcZX\[4yk_=hA?rpG]0OLGN<:,+>2+201! 4$32! 4$#""32654&.#"632#"&5432??qqWN\\NN\\Ta/w N 5jA?rpGb[ZbbZ[b#P =  "#/$/ܸ#и/A&6FVfv ]A]A]A)9IYiy ] 9!9+ + !+01! 4$32! 4$#"!#!??qqWkQ1A?rpGK '?K +=+1F+1+A&6FVfv ]A]A]A)9IYiy ]A&6FVfv ]A]AFF]AF)F9FIFYFiFyFFFFFFF ]%F19%/A%%]A%)%9%I%Y%i%y%%%%%%% ]+=9+/4F19%7ܸ+@+ + ":+".I+.C+C4C901! 4$32! 4$#""32654&%.54632#"&546732654&#"??qqWT__TT__jivvWQMKRRKMQA?rpGPIIPQHIPIvSttSv\\=BB=>BB 4@+>)+>+/8+/A&6FVfv ]A]A]A)9IYiy ]A>&>6>F>V>f>v>>>>>>> ]A>>])>9A88]A8)898I8Y8i8y8888888 ]+ +  2+ ,;+,5&+501! 4$32! 4$#"532676#"&54632#"&2654&#"??qqWUa.w O 5kN[[NN\\A?rpG$O <b[[bb[[b &2>+#+#*<+*60+6+A&6FVfv ]A]A]A)9IYiy ]A00]A0)090I0Y0i0y0000000 ]A<<]A<)<9<I<Y<i<y<<<<<<< ]+ + -9+-$%+$3'+3$01! 4$32! 4$#"35733!"32654&'2#"&546??qqW͞u>@EE@?FF?A?rpG>>'*6ޗ{5!!X3 2!@ 2 5!!5!!5!4)4𬬬 !!!!!4)4XXX 333 Nf  !!!@@@ Nf  53353353353𬬬 3333333XXXX 333322s's' !!!!@@@@22s's'!!!!\!!#!!#\!5!Z!!X!5!$Z!!$X3!-Ԭ3!-.*!!@Ԭ!!@.*5!3,,(!3,X5!!@,(!!@X3!!- 2Ԭ3!!- 2* #!!!P@ZԬ 33!!P-#,Ԭ!!!@# 2Ԭ #!!!P@.* 33!!P-#\*!!!@# 2*!5!3,Z,!!3,X !5!!#@PZ,( !5!33$,PZ,!5!!$@Z, !!!#@PX !!33$,PX*!!!$@X!5!!Z !!!!-XV !5!5!!,ZV!!!X!5!!$#Z !!!!$#XV !5!5!!$#ZV!!!$#X5!3!,-,Ԭ !3!!,-XԬV 5!3!!5,-3,*V!3!,-X*5!!!@,Ԭ !!!!@#XԬV 5!!!!5@,*V!!!@X* #!5!3!,-Z,Ԭ !!3!!,-XԬ !5!3!!,-Z,* !!3!!,-X* !5!!!!@Z,Ԭ !5!3!!$,-#Z,Ԭ !5!!!!$@#Z,Ԭ !!!!!#@#PXԬV #5!5!!!!P$@V,* !!33!!$,P#X*V !5!533!!$P-#ZV* !!!!!@X* !!3!!$,-#X* !!!!!$@#XԬ !5!!!!$@#Z,* !!!!!$@#X*5!35!,-𬬬!!!-,XX33*!!@@*DH5!5!xX333x 2 2H !!!!-Rx !!##xmsZxH !!3!!xm3-sZRH !5!5!5!,NX 5!###lZZXH !5!!!5!4l t,ND 3!!!--Dx 333!x,ԬxD 3!3!,(D 5!5!5!3,,D|X 5!333,,(DX 5!35!3̠| 3!!!!-- 2Rx 333!!xs 2 2Ԭx 3!33!!-s, 2ZR !5!5!5!3,,X !5!333xtZ, 2X 5!3!5!33t, 2H !5!!5!4R 5!!###sZZH 5!!5!3!!t,-sZRD 5!5!3!,-DX 5!333!,,ԬD 5!5!333!DX,!5!5!5!3!!!!,,--R5!333!!###s,,ԬZZ !!!!5!5!333!-s t,ZR, 4763!!"Q[yY[`~| 4'&#!5!2.-Yx[Q`~=?x 5!2653#xY[Q[~|2Ψx !"'&533![Q[Yyx2|~>3m 2>#3> 2> # # 3 3>ݲ}#$cc|5!F3F~|5!|iF3P|!XF!@F~|!|iXF!@P5!5!!5iVV333PP~P!!!iXVV#!#P@P~P;(;!O;!O ;!O;!O;!O;!O;#!O#;(!O(q(!((!((!((!'(I(!]((!((3(:(' q( #'+/3!33!33!33!33!33!3mnmnm 4('/7?GOW_gow#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573#'573(;(!%)-13#3#3!3!##!#3#3#3#3#3#3#^^(ll(lm#;( #q:(!&9 '( 9(& &!"9(&!"9(& &"'9(&!&"'9( '9(& '9(& &!'$! $!!!,7r+uv ))xxp) )$7632#"'327$%&#"%632#"'~~~~eMM>yJJJJJ6````qq|qq#u"@91990  9%-p) 327$%&#"%632#"'MM>y````qq|qqr' '/7?G%&'&'6767&'&'7%'676727"'64'7&"'62&47\+;.81F9K58.42d;E9G,:.80G9J6&8.;+d1O9FLL&_`JnLL'`_n<1& j(0=Ju &,A=N:0('<1& j(0=Ju &1<>EB0(n_II'[[JnII'[[p) %/36%632#"'327&#"6767&'&6py AAAA,+-,,-+A@@Rqq|qq%%mܱ[0$ %@%|"p) )73276'&#"7632#"'327$%&#"%632#"'r99:9rr9:99XWXXXXWXMM>yB!!BB!!oe33eje33````qq|qqp @ 104767632#"'&'&pihѵhiihҵhiѶiiiiѶiiiip $32#"$27$%&#pkk<MAk^a``p $32#"$"3pkk<MAk^``p $32#"$327$pkk\MMAk^>``p $32#"$%&#"pkkAk^>``p $  $"327$!pkk]<MMgAk^```p $  $"!pkk]<Ak^`p})6%63"'pRqq)#2y|q*q( 2654&#"!|~}}|v< ( $%632#"'327$%&#"!IMM>y_O````|qqqqH( ( !#%&#")%632OyyMMqq>~``  3327$3!#"'$@1>qq``) %63"æqv`) 2#%&#u)q>` 527$3Muyv`>q "'$33yuMq`p)%632#%&#"puqq>``p03327$3#"'$puMMuyy``>qq!$ !$ !$! !$!$3! 2654&#"4632"&nȊce;~|ddcc||}$!%!!d r<$!%!!We r<$!%!W7 r<$!%!W7 r<$ !%!!!!+c,b r<<!$ 462"! W|VV} ,|VV|V !$! c  !$! b  p(  7& $  %;<*X֖$ !!!!!!,7,rWb<)) Ie$ !!!!%!!,crWbM)MM^??@7`d?\gOOOOy>*<?v^h"3263#!5276;'4?'4?26u'6"gP39.4! '*C0.xV#m14He '1l1 Z+dd?33 #&'&+"'&#"/573;2?"#'57#&'#"#5676!5:+#9,p!j[%+ > 7VCCc":8}V .e3B=Se` e9*=9 3@=}k %C`:d;emu}'S3273&'3327&'67&'67&'67'32654'&'2327654&#"3672 $54767&'&47'&327632#"/#"57#"54?'&5432'&27632#"/#"57#"54?'&5432'&327632#"/#"57#"54?'&5432'&27632#"/#"57#"54?'&5432'&327632#"/#"57#"54?'&5432'&27632#"/"57#"54?'&5432'4327632#"/#"57#"54?'&5432'&27632#"/#"57#"54?'&5432'&27632#"/#"57#"54?'&5432'&27632#"/#"57#"4?'&54327'4327632#"/#"57#"54?'&54327'&27632#"/"57#"54?'&5432&'67&'67&'67'&327632#"/#"57#"54?'&5432'&27632#"/"57#"54?'&5432'&27632#"/"57#"54?'&5432'&27632#"/"57#"54?'&5432'&327632#"/#"57#"54?'&5432B~ %<z*+')+(@&'$||e<-A}]\B-71SLoWj\vLL)(0/ (( .1(%%,* # $ )*f$% +) $ #*+f%%,* $ $ )*  \o  [ %)#&'%&)#`#$ *) $ #+,U  Q  0 E%% +) $ $*+&EC&V*,)-)-*,%&%&fБfU 3HhfeefhH2pu^QFs棥sKQGh!99!  !77!  4 4 22 K44 22 22  11                   7        %&%&%'%&%'%&22  //  g               44 22  ->O`q +&'&54?632332?654/&#"2#"/54762#"/54762#"/54762#"/54762#"/54762#"/54762#"/547672#"/54762#"/54762#"/5476%2#"/5476%2#"/5476%2#"/5476D.2`{4&/<) e>O ,4H3R 07K $   $   #  #  #  $   #  $   $  U $   # " $   #  7Q=KG<s-8PZy9z _e""#/2dt0&2j ,: . 4 . = ,  ,   -  -  -  -   .  .   ,   -   !! WV9`8 !! 7 ! !WVDu9`8N I 7%7&54769 }V&7A 6$ 8'^4? !2 7%7&547!&'6I@Y%14HFS"="l-2DC[9 &! 4$32 4$ #"&54>2JJhhq0^mNMn2Z^Z2K7iwBNmmN1Z00Z} C"32654%"32654&%#"&54767654$ #"&767&54! ggJIhIhhIJgg[ZQoy y}WZ[zADgJIggIJggJIhhIJgU\\Q srW\\^} A4&#"26%4&#"326! 547&'&632 $54'&'&632hIJgggMgJIhhIJg#@@z[ZW}yOOyoQZ[sIhhIJggJJggJIgg ][[Xrq Q\\} "32654&7#"32ɏǾ/`T_ȐɎ;P12Y}1"264&"3264#"54327&5432#"'&'3xyx& کZTdIU  k#5AMYer3#"'%&547654'!#"'4%$53!76=332654&#"#"&54632'#"&54632#"&54632&'&67632#"&'&676'.547>'.76$6&'&54%6&'&6>#"'.54>32#"'.54 [$gi< D""D =if%LW쥨驧r^]]^ !! !! . . *)X,),*))+. } +G  G+vKK9__9KKݧꧦ]]_""""s!!""W&. - . - a)," "  ))    !) /     p%-5AMYdp|5#!4'&'5#2#"&546"264"264"2647>'.7>'.676&'&>&'&7>'.%7>'.676&'&676&'&53!76=3%#"'676%27+%&547654'7327&'$%'#327%654'&54718楣. . . .  - -Y - -))G))))U*)>- - ~- - VK; yA C0B Ax ;K'6FJ> $06# >JF6&@@1AeA1@@H磤椣筁 . . . .E - -- ,1))),(9)())u- , - - G77W6 W77G D&& ee˥ &&D "(=pp=("u !!'!Pn8hv "!!'!##+572367676MoL)>u eI3?ba8hA:F;/Itxv !!'!  ##' Mo_h[ei[i8hi[ef[l[@36273 ##'5) U.WW1@ US Vdv#,5>~3+&=43+&=4%3+&=43+&=43+&=43+&=43+&=4%33 #&'&+"'&#"/573;2?"#'57#&'#"#5676!5\:V\9\:\:]:&]9[\::+#9,p!j[%+ > 7VCCc":8 #8d#7$6$8;$7i$7 #9pPL  )Z. ;6ZV Z3%Y63 .87p  3DMy!674#!!6?676545&#'323276767654#3#&'&'454632767!672!&=75$/563&43!32+'!67#>54&53# ? I :W0 96;E,Q 2:&l6x0 bm! o۸"\>%Ef~e2U6g!6V#p5C+ C ? P9 @7H4XmM7RV /M(=H: ,qLUD)8Wqke-Pex NW =$ U  /0c)H?2@[nDF8T$.J? !' !T4XKGwL5_K !'7W4Z~wDS&5476322632%632#"'&'#64'#"'&'&54654&'&54767632xJX%&XA,B:\8 [EMH95##Fl% !9@!#jL p_Mi#"?8" %lF##58HN4hok@RRr*%te BB9'7*$%) "fXS5EIf" )%#,7'9CB >E3#"'4332327$'#"$4727%672567654&5&oJ7.b9M D ,B3 qY 5**]d=HN9% sW$,J ]T-MMm@ed: ,'Z M'cM&T)$$ < I2%!"&54676737#&'&54>;7!"&546767!7!"&54>3!6763!26P+=6/2D>R+>2,+v*>>+2  ,2 =,2  =,3>,2463!2!2#!!#!32#3#!>*v+,1>+R=D206=+P#,>3,=  2,= 2,  2+>{"D%4&#!"!0#"3!!"3!#";#"3&'6737#&'6737!"'67!7!&'63!67!2I0!6OS SS: SS>SS]]J]]]]h\\, Bv*>K%39LKIOKHLKIhghghghgE?-L!D72654'6#"'4#"'54#"'54#"'675674767#%$4:JILLHOKHLKIhghgighgD>-sJ1 b6'SS cRR SS?SS\\K\\;\\]]!A*>K{!C%254+'3254+'!254#!'!24+!&#!"463!!2!!#!3#3SS?SS *vA!,]]j\\\\K\\IKLHKOIKL93%N-?EghghghgiL!C32=732=7325732'654&#'%2&'&5&'5&'IKLHKOHLLIJ:4$N->DghgighghSS=SS SSb SS'6a!0J)K>*B \\]]:]]J]]}O &*.26:> 3656;2#'7+"/#"'+"5&54775%"'5476;25'7&56%635&56;374765'75'76=4'&+ +"'4!#"'4543$365&5&#%#754'&5&&547'5367&547+&'&'735&2?"5%75537'7'3533553535'32767&5%2?&#%55'5757757751:e,$?F?Y>F_LA3ELH3,8LYLlEF'!0< k#gF  EeY!! Gp&iq.8ZN$%`BCf F4"4._?ee3&{E(1-+$Kt8 -  $Gs sM rEF"2 >_plTErf^5.>=9|5"-l)d ,&>vv]cccWpC-+ d8 Bpp>W]oaxvuPp82,D ^8, ^B$K+ "1R[+e*; 2 W QP I&? gpo% w ^SA$ 2 9i-5n02 Ai&IY^P]D%\??\OWC ,,1 /211/=;7777=321811{908hN%b\Dh,)h?17I21!122223 21&2%2#"'&=477654'#"'5473Bq4|l anN ilm b 9 b؍MOb>YaYƮ58l7P P@ $0<FX + &=6&# 3 6=%&#"';27!5%67%!&'&'2+"'&=476r cR~UY082.ԍ_W_V"+}IR8D).P9H'S]ٱZYHYoX(I_ ;.2lOP%.G6R%&I8d)Nl>54'67&54&#"&'632.547#"'&'#"'3267654'7327323.#'654'567654&&5476;'&'%&+"#"8DH$$yU ?L[>!WtJ([Fho*m.2\=w\`|UP7:/E" @7?EP]Eix pF@T5ym,"&eB@q(A _% #+B7!N &".OS$XE/K(Aa]dLP*'FCaYr=C44mo C (FKWYFvbph'UD'R< $d#+?Vm#327&"#"'7'632&'$54#&73254'&#"'5&567#&''5$'67'654'6'5$'67'654$'67&'654'''5$56732#"'&#"&'$'63&47"7&'7&'7&'7&'54'6546767675477&545?&''5&#" '6%35&'.54>23#67!&#"W  OB7[l#> F_Vh " "@.,=6tJ4Vp1EQJqMi vhpHI!:JJJ =4m\8B*?o v!"t,`s&*_~P1>5='g=>24<+-s[,*&sd1PT>3J@='h<42J-H#*YT_Y)*)X^TY*$D  ?>}>  *0t"J.  &b54CUE ''!`9 !,(MTE *! }q~=/+)f[4f !B" <@0&9c?"V+GoMK~a? }b9e\ P&0@k"?c*GEJX ?e}9 \4 \6 '''' 6\ N(&'65&'67327&+!65+"3yyys{w ccޱqXeXc6 6 c ,35'533#3!'#'5!5!5#53!5!5#!!-ʷ}} ckvG G @<<3ffX苜qXGccGJ 326&#!2+73 ### 3(ttvgnؐB(33#!!#'!'57!5#'5735׫$"q~q+!#!573#'5!3!'573!#'73!#'5;jjŠJss<wѡIjj8/w{,32#' 3%+ &5%6323'#57'53^VQ6>ѨABؒ6ʞG2k >Y3~||~Obs32732753"'#"'4323$4'5;+"'#"'53275'&'&5?5572%#&'&5%634%476=%@.!%,BE,#!-Q2" $nL/PuHED832#"&546324&"26%! !  Őb{=&*<<*(;E;R::R;KJ67Ϛ{ɬ)::)*<<**<<*):<'L67I&' &' &' &' &' &' &' &'  @FLRX^djp3264'&#"&47367'676756273#'#'5&'&'7&'677&'67'%%&'&'%6767%&'0/CB^0/AC/pkTcR|'N(OfUippqUfO''NQaQh!$ b)dLQk KRt!% c'd&//^000'N'|P_PfppoQ`Qy'N'P\ QgppmQ \Py,  M N>&`7" bK*V&"g{ M M %1=! !  54 #&'&#"#46324632#"&%4632#"&67KJ]_EASvwSAF͒D10EE01DD10EE01D7IL6a]U@SS@U1DD10EE01DD10EE %1=! !  54 3327673#"&4632#"&%4632#"&67KJ]_F@SwvT@E͑D10EE01DD10EE01D7IL6a]U@SS@U1DD10EE01DD10EE %1! !  5# '&'32654&#"32654&#"67KJ;lWPihQV<=UU=-1\ H0e%FKSwZGr=;=NN$E| 1 ?'_>?@7`d@\hPPPPy?+<>w_VG{?,rCA+ +"'5$76%&'547327676=&#~jt1/Q}](+VRxbO P >nS]] =fP+! &56;2'5$%75#"3ui1.P~N](7P,VSZycOpO >S\^ f0:1>7#'#53'&'&54767&'&=33676=3#326'&i($lm$(($[Uu&tU[$&uU[[UV$|ddb e|$% ZSSZ %_TYYT* $4&#"326&5432!!##53&w衤礡PP䤣L~||* $32654&#"%#"54767!5!33#b衤礡7䤣L~|| $&$76+"'&5'476!7!ttsstEus pid5s qttrtt<֤ꧦg\ulS5264&#"#43233#!5 z{ym㗗y{(|j#53533#632#4654&#"#*jjoon}mZyH{zF2 1"32654'#"&4767!!53#5!!3!!#3!!pOO87O:=0LmkL/>Λ2  1O79NN970LؙL1KӘJJ-'<%#5#535&'&'5'73'3#'73'676=35'73'33◰zhNgeMjzzTThOʍ7NjYYӖy?! #!!!'!27674'&#.d ;6zFH%QM_\ǃ$P<]$!#"#&5463 67!2#654&#"V⩁"T]ts]U"X"1((1"u." 6&'67>3"#"54767&'&#52&͕LVa{.+ؔ)0zHUM\&ϖ=Bll)'ҕ*l8lB=j&'5 %$ 56?63#'[Wtutu4ZZ//[[5  @Eo&<"3264,'532'&54632264&" &$#"#"&547>B_^^l;͓hI^9l:͓hI (+|TlgMLx)+{TlϔgMM M>54'.#"32463227#"&5454&#"#"&'&54767632254&K2q'$#K1o'#0ߴGdAoc.% 3t88bWDs-Kx68<32>32#&'567'45'#&+"#4'3>$4&+"?w(K>R0D32>32gYYYD,.:?#)v$E?w(K>Ro}vvxJvaAjtAO]ƀwϧ!5!3##'!5!~2k<@i8080k<j)127632#"'#576&#"4'5267>327&'"SkQmyz,~zi2@:$(.-)zW] ݾgvx-aX[&ŝ9{'Q32263227632&#""'&#"#"'&#"#'3232762327632&#"#"'&#"#"'&"#'Es- p86rV+)|m^?_354.#"!&'.54>325467675#53533#63232>54.#"P#3JTRJWVJQSOMJ4"?*&ElnhPL$ llill %LOhnlD')----+)QPQ((QPQ)+/ 6klj$?6FWWF6?$jlk6 }++--JHNRh|&'4>32"'4>32&'4>32&54>32&54>32#!5!'!567>54.#"32767>4.#"327732>4.#"327>54.#"732>54.#"M_ 6694S55.+C55C&.66 V\+55 c$M##$ 6$#$s`%#$d0"%)h #"#_33@]22-"40446/*33UJ"+33^1/K=0T* ####  #&$$&##&$$&#  B #### *"$$" U!'-2!35!#3!53573#'5#5!35!75!!5'57!s\\ss]]s JRRIJ~֛E77__vtt4!v7CQ^&54767&'&'5676767&'&54>32! 535#5##3654."!2>4.#"  <$))+N-N*)N-M,**%:  @ v<-MTM-?K5:66459<5&?HPPIK* ')+K**K+)' *KIPPH>&5<:6uN|l||l|-I+N))N+@6:55:5Q)5>o654&547!&54='&'654'67.5476;+"'5#"=6&'76767%25#654&'Fz-6 Z8. ,N0H!h6%`+EH )#M ;,Jga#iR k' M +1^hgo8:(@s.Pmz nx?.#1p#41`&>%!ac,,LHJ x}647| + OJJ)!0 P[32>4.#"32>54.#"!5&54767&'&546767&'&4>32'&'.#":e79e89f76e`[S &(*UM,N)(N-KV)&& \@ECApd88dpg669:%N&KRS* 'TM**MT' *SRK&N۠:9}qyyq}c $Tdhy67&'&"!3!67>54.#"!&'.54>325467675#53533#63232>54.#"!57!&'.54>3234'67632!P#3JTRJWVJQSOMJ4"?*&ElnhPL$ llill %LOhnlD')----s=BDw@>=))==AwDB=+)QPQ((QPQ)+/ 6klj$?6FWWF6?$jlk6 }++-- !yCB{C!$$!C{BCy! JHLP&'4>32"'4>32&'4>32&54>32&54>32#!5!5!M_ 6694S55.+C55C&.66 V\+55 c$))_33@]22-"40446/*33UJ"+33^1/NNOOU%)5!5!!35!#3!53573#'5#5!35!s\\ss]]s ^^/oo#E77v4@4767&'&'5676767&'&54>32!&535#5##3  <$))+N-N*)N-M,**%:  @%v<5&?HPPIK* ')+K**K+)' *KIPPH>&5<:6n5|l||l|L3?HN654&5473#!&5454'+#"#7&'654'67654&547;2547#";65'"3%:U"-6 Bu Zg0krX0c-h8E+`%s H>4wM-'9.QY / o8:qhPSmh #%Bz1"0@)5"@YR0.&54767&'&546767&'&4>32; &(*UM,N)(N-KV)&& 9:%N&KRS* 'TM**MT' *SRK&N۠:9C##"'##56'##"/547?^'5@_*SU&/UL ;Yԧ9UP(` XI.s222732#&547636=4'&# #4'&#"*t pz&=<xQ>hG:V Hek%PF5NP B|-&pA&NFX &&5 <F:^;" V gdG7236;2"##'65##"'&5476;235&'&=476e x<JT`(GeRUdfB3 VNTMT,P$ 66$0_ u3dUdt_}s*$"Rt0XX__/ik=ZG8*F 1 . ъf)MC =g9EkO 9!(-);&  ]t!y" & 2| ba$ U+  #8M35733!&54?'7'327!!"'&%#'7367654'77'7'&#"'676ի,&T>=c#]K9.U:1ʈ%`T?7>54&#"5>32&54?'7'327!!"'&%#'7367654'77'7'&#"'676]T@1$J=c#]K9.U:1ʈ%`T?32&54?'7'327!!"'&%#'7367654'77'7'&#"'676Z _3lFHe5^\VOosHGJI)`VKm1Sj,&T>=c#]K9.U:1ʈ%`T?=c#]K9.U:1ʈ%`T?=c#]K9.U:1ʈ%`T?=c#]K9.U:1ʈ%`T?=c#]K9.U:1ʈ%`T?=c#]K9.U:1ʈ%`T?32#"&e|e(<X<ħñ"32#"&$2#".46e|e(<X<ħñ"@<#"4.#"e|e:<#"< !<"#;zch =B4.#"$32>4."e|e:<#"< !<"#;"< !<"#<@;zch =B54.#"##"'5##"$'&'0!5!5&'.4>32!!676767'%''H&(G()G'%H(%'V W3WImuw>DE}AB|GE=md^JW4W Vs'H''H'(H''H`XAK|@X1(ԁ3"|}DD}|" 2/ "1X@|AX1# / 673&/'67 &'"&'6?&'3 ' K[]><+Gg['fBBe&\h?(K?]\K !;32T $ #AC,MMMv A5p_9D-M**  B@0"@R//>wA&oc/D&3.YaQ/5"1'"uE62/u= =!m- .... y 7%  %  32+#".=!"&'&'#&=4;7337_% 8)0/_^^M^1/ 9534<&&<&*(D>?GGzB6C{GG?>D9/C}&632#"&'.#"'#!#!#Ҹ62K#+~KF0R!9'/Nx_TV_T 'NQ9;:#8HL"CD|))Z) 532>4.#";267#&=&$32735&'.4>22[02[24Z1/[)'5*+X A323#67#&"#"/&'&547&#""'6%676V n*[n%'ZxL0<{2;&b;0&8a>!U*~EmLK}`? {a7c[ O&0>j!>a)E~CKW ={d{7 [+M57LL75M-Z '*''*' Y (5[ J5( \d (5J [4 ''/7O_2#".54>&'32367&%2327654'&''67&'&'&'676765467654'&#"7>326323#"'##"'&'#"&'&54767&'&54767232&'&#"6&%6767&'&'&#"676&5467&'&6732767&$$$$OG3%V cc V%4GL944m/122102/.303112.OF}6&V e"w?>v"pt #87! vn":;@A<:"nx !66# sp%./13/.UVT\<>"$!! !"#">kc V &6|FO 93399 <>#"#><  "$ZTU./43..V5$##$59gT;&'9Z^^Z9'':Tg9'(''&()I8:9889: Z_59eU;'( :8.>euvc>-7:bccb;7-?cwud?/8KWZZW **D@@D+8(':Te95^&)(&''(DA:AD.*!Y[[Y!& !-x67&'67&'4&6%67.'%4'6&#"&'6767&54?67&'&#"#&'#&'5&'"'67&'&47632>4.#"%2#".4>'7,3 3%/0),7=*#0*+3.22'8  YfT,1'').UfY >98 "2 B2;F_ XB?2C 3" 894ihgikce"S[XVWXZ#ejpMcNTvJKrZ1VlLWMI p jk%nA V{ww[11[ ww{V @#fd-#JM 7B/""0C7 NK",df#νhhοggQUXXUd %3!'#!52#"62#".54>" h9|M463%&$$5 O Dn; $$$$33'554#$/[QwGSGUW GJGX .5CK&5432632!!#!##53&4&#"326!&&#"327&54654'XP}}P~C;7?_Xej;A>7'sssLFF~||ב-  䤣lrrr)-5DL&'&6767&'"'&'&'&5'476!7!! 76'&'&'6'&utss-5 l&kpid=pDi/tEust,2}ts5sqtt-ԛ1 k&iꧦ g\}ul  An?\27/rtts,͓}qt)8GO'"'!!##53&'&54326!7!&'&36'&&5'47&#"327674'U`P}zpidu>7;C˂;C>xtsK) ||LGD g\uls螝՞䤣hkrr .4&#"326&54762!7!!!##53&w衤礡ᩨhn&䤣羚 o[tꝇ|| +D#"'&'&'&47>76327'7'%'27>764'&'."(F3"D"&%#}bV`ZZ^;D"&&$[X]:3G9:]:F=~=HS]^X&% iiD^29i\=<<92-1X?:<91*=X62'%'!!#5!5!5&'&'.546767''7'''7"2767>54&'&'&4p69].(EGGE@Z-<81VDEGFF'19T]9T:G5>+.11./:95>+.11./:9 \2:a(Eb_E@( %CE_bG(Hij:ο\ij+.wBAw./+.wABw./4+F!!#"'&'.546767675!5!' 2767>54&'&'&"<-Z@EGGEDVRbfNZ@EGGEDV18kbbjC9:/.11.+>59:/.11.+>5疑 (@E_bEC%##(@Eb_EC% kajP/.wBAw.+/.wABw.+ +F####"&'&'&54767>32333'7 '%32676764'&'.#"ܖU (@E_bEC%##(@Eb_EC% Uܭkaj/.wBAw.+/.wABw.+<-Z@EGGEDVRbfNZ@EGGEDV18kjC9:/.11.+>59:/.11.+>55 @  10432#"732654&#"陽…5 @  10432#"K +@kk k kKTX8Y104632#"&732654&#"ϑϑϘuSSuuSSu͒ΐSuuSSvvdPK!)7eK RX@ *.,&"($ k3,k($kk8991@&"6k0k 8<2<299990Y4632632#"'#"&7323&547&#"%6547232654&#"dϑRDDRϑRDDRϘuS?>Su^222Z>?SuuS ͒!!ΐSuXqpWv28ML88LM{WpqXuSSvTZ`z8Rm3#"2767>54&'&/2"'&'.5467676"2767>54&'&/2"'&'.5467676R#)$#R#$ $LK:C.25521@=:C.25521@=R#)$#R#$ $LK:C.25521@=:C.25521@=zZF)(JG()K.2IF21.2FI21F)(JG()K.2IF21.2FI21 J7Qk>767632"'&'.'!"'&'.546767632$"2767>54&'&'$"2767>54&'&'#61@=HK:C.25521@=:C.5%'21@=:C.25521@=HK:C.6#R#$$#R#$$R#)$#R#$ $5[51.2IF21.4`]21.2FI21.5[F)(GG()FF)(JG()KR 5%%%xr6׊eMM^xxV)7654'&'575#!&54767'5!s_vR$N::N$Rv_{aT,X@X,Ta{4b\)1%==%1)\b4ߴ:`\KDDK\`* 4&#"326&'&5432#w衤礡$PP䤣L~{Y,326& '6 !!#!5!(+~uP.Gjt ~||, # !!#!5!L>>0oJ;||,'!5!737!!!!##53z{{{z{|zhz|{||WxT% ! !5! #3 35!'T??LLwLLJ|A|JZt|J|,$264&"&7673% %&uuu>hH]%VgVYFhݦuuv#gGέҔEgEY$&'&5%6;2#"'!!##53uN)$#<^tfFp!E&J <ԩ;  ||lPj'#"'&#"'&'&'&47>7632327>76&'&'&/&'&'&47>762!2!%327>764'&'.#"&#"327>764'&'&s* 0$+$$$ 1#*# ZaZ%% NT12 4 #HH  ")mROeb  , 0  +   ) . $J . %'.D"&B 1 $C mR )Ky    !   V!Edz267>54&'."#"'%"'&'.5467676;27>4.'&+"'&'.54676762%632$"267>54&'&.&&.&m,mQjP(!N!"(! aVf&&bZ55!("!N!(PjoQm,.&&.&q    l?W,>&#< A#"< " (( " <"#A <#&>,W?~    lOOj3!#!"'.'&47676?6767>'.'&#"#"'.'&47>763276;%32676764'.'&#"676764'.'&#"32eOuRd2!  HH# 7   ZTN +Za21#+$0 4$$$+$0 's  *   * OK) Rd#!>& 3"9*$"D. ' - D! 2 . , T% #: & (  IZx-4H67&'&'&+"'&'&'&476767632%632 #"'%#"'&'&'&54767676;276276767654'&'&'&"276767654'&'&'&""'&'&'&547676762"'&'&'&547676762'&'&'&547654'&'&'&";276-&#"+"276767654'&5476%327%&"'&'&476762I  Q\C--%("(/*0.,+"( /X]\9<\X/"$)0*3')"* %1*0CR[        22 2 2 2 %'   &J  &%C\d#_*]OhXC%&  J&   O]*       ")&`&"'$"/' <%ZS  % SZ%< /'* "%5"-($# ;8\= !  !  " /VC "  !  !  [uV/+    V^au 767>54&'&'&#"&54767632 '.5467&54732#"#"676767#"'&#"'67654 ozwbda_f_zx|wbdaM,krnulspsnunNJ*D$ lQ$" 6*D?"5'K(2- # >   :72 331cd툍i`4331cd퍇>mwn<;;8ro졘wp:;;BV0/M8:D@*|sa  -F(7 "*=8&0!2  1-5$& 6:B4V^ (B\w.'%&'&"632%6767>54$2"'&'.546767" 767>54&'&'&'2 '&'&547676?'*&$ 1$-+h+-$F3782**?1 $&>>9|wbdabc`zwbda_f_zxspsnunˎspsnulwI_"2[$  "" gI $[2!v 55 55 31cd퍅caf31cd툍i`43d;8ro졘wp:;;8rown<;x,A-57'36%33#3#!2#!3#3##$'#7$@d5{sVd]F0 0F]dVs{5⒒d@( jPP,PP` 0 ")- !676762!"'&'&'&54!X$#R#+/RFF$#R#$1Sh,  k-"s!|P476?6763&'&'&547632676767654'&547632!54'&'&54'&&#"'&/&'&'&#"#"'&'&/&'&#"&'&'&?6'&'#"'&'&#"!'476='654'&545454'327654'&'&327654'&/%4-)"$0JK&  )7    %0'# #6 +-L __^/s4* 1( .266 |/(1   \   #:7  lS&   x71]/~[#<$  o_%@,: $";vR $X$+|!5DX&PY;9Do6 b'n2  83eF] 4T&  &  /50$?- 1@& 3l K  C"P1 :03<D:5XI.)D&[+-1:   q/A8   g+jl9Lp{7654'"'&#"+"'&54?67676763276323273#5%6767'&#"6"/67#"27632327654'73654'676547&p/l0&J!cS%YE]{@C"$4>-;% ,(6Y>m!N$X6"/,(4sS?X$U>"sJ?K(`./4+2K2.0>S Zp0+1^' ;cs  /^"|Y/ 428ۇϕl%%ot5oA='Y$ aT* ''G+- %_kj~r}jL`І|\gK@/.85c($ (2LS>54/##326?%%3254'654'3>7632#"&547>32'% ;66I   }g ?6qn   -> 9@ H67;  zh| 8 >6!q    B5>%+?F4&'&/76765'7! !'!654'!4'!!$467>2"&'&!654' 33 ^^^RXI#J2VlP# ~!88!~ Kppph,p<(##(#id (2LS.#"227654&'''%'654+.#"65.'&54632#"'.6#"%  I66; o |>?%6!q   9  ;76H   |h> 86qm    BX{[%G'23 %%.'&"27>7%$!"#232%"'&'.4676762%#"#2%k      A>>dIID`nS   SnGYn 5>5 n)(%$#"#64'232%%&'&'&"27676&22k**!n``n!##3W 2327632#"'&'&5476'( > !~GH ".4F+@xH )0$'*' 23277632#"'&'&54763'( e` }{*279HF`0@xJL 1 ,A  ' 7 Ɏ877Ɏ77ɍ8ɍ? tt7tt7t7tt7uB2632#"'&'#"'&54767'&54763267632676 Q   x L$3 z(   6X3  6*=P*> "#  R26#"'#"'&'+"'&'#"'&547&'&54767&&5476326763276T 디% $$YyX$ zc0 + j :  (̢1#: _$ #- Խ =1 '2ĺ pD #!!!!!%!!!!!!!!#!5!36HVBBXBBUHVPBXyBpD !!!!!!""p"p"#pD35#7!!#!5!3rrsrspD!!%!!!!!!r"p"#p"#Rb !!#!5!3ppEU l3!!'#'!!#!!3!5@,r,,_ r,,_>v #!!!!!'!!!!!!!!#!5!3hm_|P_H_pDK#";54&'&'&#'!326767657'&'&'.+3!76767>5{dIB,$2$*DEh{LGC_RQ|66R_CIJ{hED*$2$,BFd{LGC_RQ66R_CIJKIB`OT|87O\FGKzdGB+%2%+BIdzKGF\OT87O`BHL{dGB+%2%+BId  #!! !!! 373#'7#ZAA:Llحmllmzlmllm|}}|d d}cT`C54'&54762327632#"'&+"'&5476=#"#"'&476323(L,68x86,L zFvd0000dvFz L,68x86,L zFvd0000dvFz zFvd0000dvFz L,68x86,L yFvd0110dvFy L,68x86,LV^&'##"&'&'&4767>32367675&'&'.5467676236767>32#"&'&'&'#"'&'.546767675&   R.-R  R-.R "  *!""! ((\(( !""!#%   " R.-R  R-.R    %#!""! ((\(( !""!**!""! ((\(( !""!#%    R.-R  R-.R "   %#!""! ((\(( !""!*  " R.-R  R-.R   Sa4&'&'&'.546767622676767>32#"&'&'&'.#"'&'.54676767>5"#"&'&'&4767>32(,$ ((*& :.r06$&**& )'De!  'd8:b&$$&b:8d'  )a@/!  ')*&$6/r/6$&*)'  ')?c'  &d8:b&!$&b:=_& (bCc"  &d8:b& $&b:=_& (a?/!  ')*&$6/r/6$&*)'  ')De!  'd8:b&$$&b:8d'  )a@)' ((*& :.r06$&**& ((T`0267632#"'&'&'!&'&'&54676763267632#"'&'#"'&'&'&5476767!6767632#"'&'"'&'&'&54767#"'&'&'&5476767632!#"'&'&'&54767#"'&'&'&476767632&'&5476767632!#"'.'&5476767632&'&54767676Z   ( &            <   4          % (      (   2     6           %    <    %  (   W_2767653"4'&'&Wspsnullunsps;8rown<;;j>-'O^__^Oq44H4"hdd0!% %!-@jjjk**37'73 #'xxxx.xx.x..x  pD #'!5!73!GFdFGrEGdGErFGqFGdGFqGEd@L     - FOFc,OO,cFd,PO,dGOP T` '%%%%%% % -wD{wwe#w%f{wwy||y{xxe#w%f{wwxEy||y % %  Zp/AppA/}}ET`     - Zq NqqN  NrqN qrT`% % -ZyllylyyT`%% %% -ZtGcVGttGVcGGstGWcGtsGcpD/3%!!%#'''%!5!%777xo:U.cF.d;UǩoxoU:e.Ec.U9oE.f:UūoxoU9g.Ff.U:oxo9U. 54'&5476276767632+"#"32;2#"'&'&/"'&5476=&'&'#"'&'&547676;232?&547'&#"+"'&'&54767632676'K,68x86,L qA'C<4GW>L d  f L>WG4L d  d L>WG454&'&/54'&5476276767632+"#"32;2#"'&'&/"'&5476=&'&'#"'&'&547676;232?&547'&#"+"'&'&54767632676o**YK,68x86,L qA'C<4GW>L d  f L>WG4L d  d L>WG42#'"372"'&'&/"'&476="'&547>Q!//VZ *nN+G80j@6RR6@j0/P1N TP#00VZ ,lO@W+G80j@6RN6@j03L/N  ]H,`,H Yc!77\4OO4VA7gU3',H^ ]H,`,L&3c!77\4OO7VA7fV4&,H^67654'&"327632#"'&'&/#"'&5476=#"'&'&5476763232?'&#"#"'&'&5476763254'&5476276767632#"'&#"#"'&#"327676%32767654'&'&#"#"Z8%1T1%85e %ZF\ +m8BS/?JV@6RTXN6@VGB1QB8n* \FZ% e53e!&ZFZ *n8BS/?JV@6RR6@VGB1QB8m+ \FZ&!e3DA 5<; > +F$H$F+ > ;<5 AcJ2QD++DQ2J (5H,'9,J&0f) T|\`j4OO7g`\|T 'g/& H,9',I4( (3J,&9-H &0f) T|\`j4OO4j`\|T 'g/&J,9',H5(""'!$(:UJJU:($!'""nFw"2767>54&'&'767632"'"'&'.'"'&'.546767"'&'.546767632.546767632=>343343>==>343343>x>%85670-),(-%8/[0!-(,)-02y/8%0%)-02y/8%-(.'&$W/:#-(,)-02;>/;),)-02;>/8%-( 06{IF{6006{FI{605+'g>:c.&".c;=g'+&1N%&W'+&.c:>k#"$.c:>g'+,B:>g'+&.c;=?nF\v%"'&'.546767"'&'.546767632.5467676267632"'"'&'.27654&'&'&"67&'&'&'276767&5467'&'&#"32767>54&/76767>54&'&'&#"Z0%8/y20-),(-!0[/8%-(,)0-<1:3%>(-%8/|/8%-(>%85670-),(-%8/[0!-(,)-02y/8%0M=  H C# B/g H /*x#$  8## H g/B PP  $#x*/%N1&+'g=;c."&.c:>g'.5 ?=;c.&&.c;=? 5+'g>:c.&".c;=g'+&1N8GG$> >$ c.,bB$#>  Ir0C >'#> LM >#$Bb,.$ >#'> C0rI T`)T:e&'#"&'&'&4767>3267'&#"327%32676764'&'.#"7632#"#.4767676324676762>322##"&'"'&'.5#"'.'&467"&'&'&4767>&'&'.'&'>76?&'326767767>5&'&'.#"767>7.'&/32>7674&'&'67'&'.#"67'&'.'67676767"2767>54&'&'"'&'.54?&'2767>54'7654&'&'&"67'&54676762:    $4 4$ww4 4 xy   %" !()-+U$"! ((\(( !"&S+-)(! '7M"# V2% A()-.R$"! ((\(( !"(O-,*(A"#2P"# "M    ! *4 2 kk  4 2 uKK        i2 4* !== 2 4  `_  wR#$$#R#$$  8 < c !<>     8 < d!!<>   "%UV*) !!$3R  R3&!-(-%Z& "#%(.2$( &&S+,))A!$3R  R3'A))XT$""#%(`$( "      i3+!x== 3 _`        !+3 kk 3 uKJ   F)(GG()F$    %3 3%ww3 3 xy   V^3N^"2767>54&'&/2"'&'.4676762 '&'&547676% %-z35++++++53z35++++++5pWDM69?=;9JHDM69?=;9JHSspsnunˎspsnul}}(.h<;h.((.h; +F$$> +F$H ;<5 A~ ;<5 A+DQ2J (5H,'9,J&0f) T|\`j4OO7g`\|T 'g/& H,9',I4( (3J,&9-H &0f) T|\`j4OO4j`\|T 'g/&J,9',H5(G+DQ2J$(:U$(:U3!'""!'""A''7'753'75377537'7'#5''#5'7#5'7'7<B-DH2#"2767>5!"&54$3!57!#"'&'.5467676#_>I-743TP>CPNDG-2.1/&D9 88 '.* !-8D_2{j@F'%.3r@Md7+4V/2&'&54676762"'&'.546767Zy*,&''&%1]~|45,-++-,54|45,-++-,5(+&a4|d΃fz4a&$(F*.j=3"&'&'&54767>32rJ6464NN4646Jp`684F@NLBD64:866D@NLBD668^~* i654'&#"632327632!"'&5!267&'&#"#"'&54763247632327654'&547632#" 6+Jo.^V|;-˙it36?̺fQMeEJS?(*$ s]vh2K)*NL13^v:Mc*ZeC03N35%&-Kt\K%9S >BWN=!$?$8(F!5{^?Z Q67654 547&'&+327#"'#536767&'&'&5432&5476323254'&5432?-BO>=v06&%K`dC+(k$'eM?$#=Hb B=)+8=.m9eb PB>$3g:84!EB7WPfG+1KHP<Ff#&T'0P+A'<}DC/'"05276767654'&'4rceNS((((`hm@DDF/CD}>C/GFCG !&547>2; 0!!6P<:! !$ ! "#{! !{54&#">32!5!>??qq>0ţ=as;N_/>!RL}A?rFi:}$:&N?(U?"Mt 6+A]A)9IYiy ]1.+. + !'+!+9*'!901! 4$32%4&#">32+32#"&'32654&'26??qq|=_ky4[\XZcksuD}[X@v hA?rs ?<:32#"&'32654&#"75!5!??qqYe2hvvhDw_X@ϰ?A?r%aVUa/  23/4/3и/4ܸA]A)9IYiy ]A&6FVfv ]A] +  + +,&+,/&,901! 4$32#"&54632"32654&#"7>325.??qq\NN\\NN\qºN w/aTJjA?rZbbZ[bb*= P# + + 01! 4$32%!35!??qqlUA?rv]K 1=++ +A]A)9IYiy ]A&6FVfv ]A]A ]A ) 9 I Y i y ]/9;9;/A;;]A;);9;I;Y;i;y;;;;;;; ]5+ )+ +28+201! 4$32#"&5463232654&'>54&#"2#"&546??qq_TT__TT_⾭vijvkKRRKMQQA?rlHQPIIPPI\vSttSvB>=BB=>B &23/4/ܸA]A)9IYiy ]3'и'/-A-&-6-F-V-f-v------- ]A--]+ +  +*0+*# 901! 4$32254&#"326#"&'4632#"&??qq鿹ºO w.aUJk<\NN[[NN\A?rK < O$[bb[[bb $0Ӻ%+%+++A]A)9IYiy ]A++]A+)+9+I+Y+i+y+++++++ ]+ .+ (01! 4$32!5##7##"&5463232654&#"??qq$ŸuF?@EE@?FpA?r*'$ =$>  767654'&'!5%3!!  '&'&54767̆mommom4mommomP\|~{{~||~{{~|96oooo6996oo  oo6}9:݈@>}~Ա~}>@@>}~,,~}> =6P  767654'&'!!567>54&#"5>32  '&'&54767̆mommom4mommom)4 \=)N=kP`aF7I׺\|~{{~||~{{~|96oooo6996oo  oo6_A.Xx;_x55'(IZV@>}~Ա~}>@@>}~,,~}> =B\  767654'&'#"&'532654&+532654&#"5>32  '&'&54767̆mommom4mommomttLUDWx~zB\RGr=\|~{{~||~{{~|96oooo6996oo  oo6yt'(xrjw_Z\bd @>}~Ա~}>@@>}~,,~}> ='A  767654'&'!33##!5  '&'&54767̆mommom4mommomh*˪+\|~{{~||~{{~|96oooo6996oo  oo6 @>}~Ա~}>@@>}~,,~}> =7Q  767654'&'!!>32#"&'532654&#"  '&'&54767̆mommom4mommomz#G#KSLVAC\|~{{~||~{{~|96oooo6996oo  oo6c ۻ)%}|X@>}~Ա~}>@@>}~,,~}> =%>X  767654'&'"32654&.#">32#"32  '&'&54767̆mommom4mommomllm=|< /Vڵ =|^\|~{{~||~{{~|96oooo6996oo  oo6EKۼ>-O@>}~Ա~}>@@>}~,,~}> = :  767654'&'!#!  '&'&54767̆mommom4mommom\N\|~{{~||~{{~|96oooo6996oo  oo6`E#@>}~Ա~}>@@>}~,,~}> =#9E_  767654'&'"2654&%.546  &54632654&#"  '&'&54767̆mommom4mommoms慄htdthutԄ9tihvvhit0\|~{{~||~{{~|96oooo6996oo  oo6,{{|kl{Eggss\hh\]hh@>}~Ա~}>@@>}~,,~}> =2>X  767654'&'53267#"&54632#"&2654&#"  '&'&54767̆mommom4mommom=|< .Vڴ=}mmlJ\|~{{~||~{{~|96oooo6996oo  oo6DJټ@>}~Ա~}>@@>}~,,~}> =+8Ca  76767654'&'&'"32654'.  735733!  '&'&'&5476767̆mo5885om4mo5885omT,+VUVV++2QPPQΠP3p\|~-,g%&݈@>}~~}>@@>}~~}> = $!5!#%  '&'&54767{\|~{{~||~{{~|#:9q @>}~Ա~}>@@>}~,,~}> =6>7>54&#">32!5  '&'&54767I7ݺFa`Lk=N)\\|~{{~||~{{~| ZI('55x_;xX._@>}~Ա~}>@@>}~,,~}> =(B>54&#">32+32#"&'32654&  '&'&54767ir׸G\\Bz~xWDUL2\|~{{~||~{{~|db\Z_wjrx('°t=@>}~Ա~}>@@>}~,,~}> = '! !335#$  '&'&54767hno\|~{{~||~{{~|  @>}~Ա~}>@@>}~,,~}> =7>32#"&'32654&#"!5  '&'&54767CAVHSK#G#\|~{{~||~{{~|=|}'' %@>}~Ա~}>@@>}~,,~}> = $>2#"&546.#"32654&#">32  '&'&54767PmmlC|=ϵѴV/ <|=\|~{{~||~{{~|+޸KE@>}~Ա~}>@@>}~,,~}> = !35$  '&'&54767>h\|~{{~||~{{~|@fE@>}~Ա~}>@@>}~,,~}> = +E2"&46' 654&'>54& 74632#"&  '&'&54767Yt愄/tԃuhtt-tihvvhit0\|~{{~||~{{~|{lk|{{Essgg]hh]\hh@>}~Ա~}>@@>}~,,~}> =$>%32#"3267#"&'"&54632  '&'&54767!C}= дѳV. <|=Allm\|~{{~||~{{~|Q/=޸JDg@>}~Ա~}>@@>}~,,~}> =  :2#"&546$  !5##7  '&'&54767eddedddB¡\|~{{~||~{{~|>-/#&%q @>}~Ա~}>@@>}~,,~}>uPj !!5!!Pp#@pppt 7%FN4NGuP85 zD<22pJJt '-ZKFGNuP!!u\lE>~~>uu+"&'.546?!".4>3!'.5467>2p4,,$$,,42.p ,.".2."., puP8!5! %JZPJJuP8!5! %JHJJuP8 #3#3#3!!5 xx<<oJpppJJuP8 55!#3#3#3oPxx<<΄ΊXXXXuP8!!5 %JJJPD! 6>l>>PD ! DR>l>>P  BlvvuPb3!5 5! '&'.u$##+* ZJMM*+##$0U%!JJ!%UuP84676763!5 5! u$##+* ZJMM*+##$0U%!JJ!%U0!! ^r{VXeoouP855!Dq΄Ξ0uj%5!!53  !<9h9>uj%5!!53  !<9h9>+Z !73#57!!+ Id&+ъ2&+Z 5!'53#'!!!+dI|&22 !'!'!53 !Odcndh 2 3#5!7!!! ndnd;ch dd !53#'5!'! !]n2n22r-hJdc;dJdd 7!573#5!! !2+2n2nr-hLJd;cdJ<6767632"'&'&'! <'CZmo~yti^Z\X^Vqoti^?)X6nGCZ.//+]Y݀z_X0//+]>Iʞ BP "&*.37#37#37#37#5!!!!3'#3'#3'#3'#<<< 7&#"7'7 !%*BF8WU{FC*9oX:WubP 55!5!!'!XXddPRt '327'' !!iFB*8X:*CF9XUpt>*%&#">7'&'&">327&5467>7tBEH#&NKX$W/,0$" D5Hp*G6$"!0,0Y"W!F&'&#GGCuaP'467#"!4676?'&'.5!3!.5P5#$%"//"%X$# 5eeJ(0Y! "X0(Jet*.'.54?'#"&'2767.'32t)H5 X"$ #0,0X"KN&#EHEBCGG&'&KW"Y0,0$"E6GsPX'<6%"'&'.54676$4676762"'&'&&'.54676762$/+z >_ $#R#af#R#)>xbQu 88RK68# 88  vc<*676767632#"'&'&'&%.5467.546A ''+/54<3o8n23'9%%%%bb%%%&:?$ fLLf#&#/:&'X23X'rr'X32XV2c"'&'.54?654&'&'&#!"#!".4?64/&4676763!23!2767>54/&546767622 Z ;:td Z   c   uu  c  2c"'&'.54?654&'&'&+"#!".4?64'&4676763!2;2767>54/&546767622pW\xj IJ \W   8  uP^'#76767&'&/3#>7!5!!5!.'PSJl..&GG&GlHSi7*nK Kn**7OUnm'66'1U=Hd)dH=n&*'$&'&#"'67667 h7Hm^:-3 RE SRQO1̡LHO&57$'&54&#""OER 3-:^mH7hH܏1OQ S #u ! ! j.u-10 3%!#3!Zddd/ #3!53#5ddZd{3 #pph # 3hp&T&T[[ '#'#'##'x\xxjjxx\x,x\ehhP8\xYY73373737+.x\xxjjxx\x.x\8Phhe\x,OlD=072767>54'&'&'&"7#7676767632#"'&ew@RNJV !'7$"!3!&'&'&'!#!2767676wx !1cbbc1! "1cbbc1" `x]\LM&  &ML\;RR &ML\]]\LM&ZwxZQvcbddbcvQZ[RwcbddbcwR[xV''LM\7=e=7\ML'e;6\ML''''LM\6d 8   2@ @@ 00 ]1@   990@   <<@ <<KSX << Y5!!dx yxUZxxu 8   2@ OO __ ]1@  990@   <<@ <<KSX << Y'7!5!'7 wxy xZwxxd 8ڶ 22@ PP_ _O O]1@    9220@   <<@ <<@ <<@ <<KSX <<<< Y5!'7'7!dxxwxxUZxxwZwxxd 8!!5!! s]xwx]ix]xZx]xiu 87'!5!'7'7!5 ii]xwx]iix]xwZwx]xd 8!7'!!5!'7'XiiiI]xwx]h]xwxiii]xZx]]xwZwxd 8 !5!3# Y#xwxݪ-xZxYu 8 #3!'7'7xwx-\xwZwxd 8 !5!53#5! Y]xwx]Q7ii]xZx]Eiiu 8 !'7'7!#3!7'Q]xwx]iic]xwZwx]\iiu 8%77777773'7'7#'''''''uFFxwxcnFFFxwZwxnF,X@,,X ,,X@',,,X,,X@',,,X ',,,X@',',,@,@',,@',,@',',,@',,@',',,@',',,@',',', ,@',, ',,@',',, ',,@',',, ',',,@',',',@',@',',@',',@',',',@',',@',',',@',',',@',',',',@',, ',,@',',,',,@',',, ',',,@',',',@',@',',@',',@',',',@',',@',',',@',',',@',',',' ',@',', ',',@',',', ',',@',',', ',',',@',',','@'',@','',@','',@',','',@','',@',','',@',','',@',',','',pX,p,pX@',,p,pX ',,p,pX@',',,p,pX',,p,pX@',',,p,pX ',',,p,pX@',',',,p,p@',p,p@',',p,p@',',p,p@',',',p,p@',',p,p@',',',p,p@',',',p,p@',',',',p,p ',p,p@',',p,p ',',p,p@',',',p,p ',',p,p@',',',p,p ',',',p,p@',',',',p,p@'',p,p@','',p,p@','',p,p@',','',p,p@','',p,p@',','',p,p@',','',p,p@',',','',p,p',p,p@',',p,p ',',p,p@',',',p,p',',p,p@',',',p,p ',',',p,p@',',',',p,p@'',p,p@','',p,p@','',p,p@',','',p,p@','',p,p@',','',p,p@',','',p,p@',',','',p,p '',p,p@','',p,p ','',p,p@',','',p,p ','',p,p@',','',p,p ',','',p,p@',',','',p,p@''',p,p@',''',p,p@',''',p,p@',',''',p,p@',''',p,p@',',''',p,p@',',''',p,p@',',',''',ppp,p@',p,p ',p,p@',',p,p',p,p@',',p,p ',',p,p@',',',pp@'p,p@','p,p@','p,p@',','p,p@','p,p@',','p,p@',','p,p@',',','pp 'p,p@','p,p ','p,p@',','p,p ','p,p@',','p,p ',','p,p@',',','pp@''p,p@',''p,p@',''p,p@',',''p,p@',''p,p@',',''p,p@',',''p,p@',',',''pp'p,p@','p,p ','p,p@',','p,p','p,p@',','p,p ',','p,p@',',','pp@''p,p@',''p,p@',''p,p@',',''p,p@',''p,p@',',''p,p@',',''p,p@',',',''pp ''p,p@',''p,p ',''p,p@',',''p,p ',''p,p@',',''p,p ',',''p,p@',',',''pp@'''p,p@','''p,p@','''p,p@',','''p,p@','''p,p@',','''p,p@',','''p,p@',',','''p,p',pp,p@',',pp,p ',',pp,p@',',',pp,p',',pp,p@',',',pp,p ',',',pp,p@',',',',pp,p@'',pp,p@','',pp,p@','',pp,p@',','',pp,p@','',pp,p@',','',pp,p@',','',pp,p@',',','',pp,p '',pp,p@','',pp,p ','',pp,p@',','',pp,p ','',pp,p@',','',pp,p ',','',pp,p@',',','',pp,p@''',pp,p@',''',pp,p@',''',pp,p@',',''',pp,p@',''',pp,p@',',''',pp,p@',',''',pp,p@',',',''',pp,p'',pp,p@','',pp,p ','',pp,p@',','',pp,p','',pp,p@',','',pp,p ',','',pp,p@',',','',pp,p@''',pp,p@',''',pp,p@',''',pp,p@',',''',pp,p@',''',pp,p@',',''',pp,p@',',''',pp,p@',',',''',pp,p ''',pp,p@',''',pp,p ',''',pp,p@',',''',pp,p ',''',pp,p@',',''',pp,p ',',''',pp,p@',',',''',pp,p@'''',pp,p@','''',pp,p@','''',pp,p@',','''',pp,p@','''',pp,p@',','''',pp,p@',','''',pp,p@',',','''',ppd?8 !5!53#5!s]xwx]ii]xZx]EiiuP8 !'7'7!#3!7']xwx]siic]xwZwx]\ii 3'#'##-Z-x\xxx\.x\n #\733737#x\xxx\xZ'x\# n\xO'=%"'&'&'&767670327676764'&'&'&pk_V1..1Vbrx`Xk_V1..1V_kpIxXE?#!!';B]YQS@?#!!';BQ9.-\ZnllnZ_.x$-\ZnllnZ\-.)xF!F@RNJV>lmGСBk>DdW0Xdtsݓ.W@#.  -&.%)/K TX)8Y299ܴ]<<999991@ &$-/22907&54&'>5!2;#"#!532654&+CI02Kl>>l5UU5D>kB0GmstݔdXЎW2  5 1Vd22h' %#3 5' :' 73 ٪L^8bb:'B 7''ٛ>PNq'B '''ٛ>PNq^D'B ''>PN'B%  '''tNP'B5  5''bNP#u  u-3!3!!#!#!5 L3ͨ--Ӫ--333333#######5Ϩ---Ӫ---:k7!!  767654'&'$  $'&'&547676h08rtrrtr@rtrrtr VGFFGrGFFG;:rs죟sr:;;:rssr:Ŭɪ:k3?  767654'&'$  $'&'&547676!!#!5!rtrrtr@rtrrtr VGFFGrGFFGssB;:rs죟sr:;;:rssr:ŬɪKss:k3?  767654'&'$  $'&'&547676   ' rtrrtr@rtrrtr VGFFGrGFFG]x3w32x3B;:rs죟sr:;;:rssr:Ŭɪ3x23w3xuM %' io& i' i% iJuM327!5!>2&#"!!"&' ;E 2&#"!!!!"&' ;E $;E Ϊ@z٨zuM&#"%"&'73275%>2";EC;EJ綠mzzuM*3&#"&'67"&'7327&'&54767>2";EIq(P >6D;E]InoSu=,HK%)AH!+p$ z1IosV2";E+@/V]H6H\nUm;D [>wfP3,,I6x/Ur]HH]lVzM>wrN3 F4uM!3#!!>2&#"!!"&'732w~9F 9 }9Gr0}}uM+3#>2&#""&'73273264&c)~9GcBnnVs~9F (6o~ç|K|oU}uMp.3#327264&#">2&#"632#"'"&'z;E-8pƖqS;E;DܛWI3>6я]z!zuM 13#64&"327&'&767>2&#""&'˔֐;E]InoSu;EcBnnVszяϐ-1Io7sV2&#"!!"&'73273!#3;~9G9G ūI}ޭ{ tMm-&#"!2#567&'!"&'7327!5!>2";Ed_``!;D ܻ`;`*I6ƌebIz`:H:`*F4uM#&#"7'"&'7327'7'7>2";Exx;EzxXyxzyxإzuM*327#467>2&#"#4'"&' ;E-A 4yy;E Z>Vy|-2PIϼ+zEa82JzuM'&#"63"&'7327&'&53>2";E*y;E\?Vy~+&8'zLFaI1zuM>32&#"#"&'7327!5KL~9GALK~9G⧅}}gkb>32&#"#"&'73275!KL~9GALK~9G⧅}}Р? 5 5FѶeѦ 55FѶ///m' //& 0'' /'' 0' // ' 0N:A%#"'&'&'&#"5>32326#"'&'&'&#"5>32326 5jbn ^Xbh`n ^Vhjbn ^Xbh`n ^Vg@PNE;=LTNE;=KPD:32326#"'&'&'&#"5>3232655jbn ^Xbh`n ^Vhjbn ^Xbh`n ^VePNE;=LTNE;=KPD:327&#"56767326 5jbDS4WVhjbm\Y@/Xbh`ES3VXbhZmMp[Y@1Vg@PD4KUNE;@LTNE4LRN"*,@J^po_N5<#"'3267#"/'7&#"5>327&#"5>32732655jbDS4WVhjbm\Y@/Xbh`ES3VXbh`n[Y@1VePD4KUNE;@LTNE4LRND:@J^T 5!5!-5 !5!uu/0\^ҲЪ~T -55!55!usҲЪ᪪/0N%#"/&'&#"5>32326!! 5jan^Xbh`n^Vf@PD:32326!!55jan^Xbh`n^VfPD:323265-5ian^Xbian^VgsuOE;=LSNE; =KJ/0:ҲЪ !(#"/&'&#"5>32326-5 5ian^Xbian^VeuOE;=LSNE; =KJҲЪ/0, -55!55!us%ҲЪ᪪(/0٪, 5!5!-5 !5!uu%/0\~ҲЪ^6 5 5 -55uu/0V/ҲЪа/6 -555 5uuҲЪ۰/'/0K/& 55p/ѦѶ& 5 5p/om//&' /G&' H{ 5!5 5!@Ѫop9{ !5! 5 !5!@Ѫ555@pNpop 55 5@p pU(".#"#"&'5327>76325hV^ n`hbX^ nbj@TL>7632 5hV^ n`hbX^ nbj?TL>֪VJ<:DNTL<:DNDop$+5!5!.#"#"&'53276767632 5hV^ n`hbX^ nbj@>֪VJ<:DNTL<:DNDf $!!!5!676762!!&'&'&!!C.8d 6WYYV7 e8-;Z{+DD\93[2332[0<[EC,W7!!%5$$}y]]x|W%!5505%$}$y|]]W !!'7!5!%5$ZZ N$}qPP]]x|W !!'7!5!55%$ZZ N}$qPP|]] K75!5!%5$!:[]3֪k-QtXVv K75!5!55$%$][:!3֪kVXQ-qK!5!7!5!7!!!!'%5$&`ȉ)P"_=6!:[]ss1st-QtXVvqK!5!7!5!7!!!!'55$%$&`ȉ)P"_=6][:!ss1stVXQ-y:E#"'&'&'&#"5>76326#"'&'&'&#"5>32>%5$ian ^Xbib` ^Vgian ^Xbian g!:[](NE;=LTN9 A=KOE;=LSNE;C E-QtXVvy:E#"'&'&'&#"5>76326#"'&'&'&#"5>32>55$%$ian ^Xbib` ^Vgian ^Xbian e][:!(NE;=LTN9 A=KOE;=LSNE;C EVXQ-6A#"'3267#"/'7&#"5>327&#"56767326%5$jbDS4WVhjbm\Y@/Xbh`ES3VXbhZmMp[Y@1Vg!:[]$PD4KUNE;@LTNE4LRN"*,@J-QtXVv6A#"'3267#"/'7&#"5>327&#"5676732655$%$jbDS4WVhjbm\Y@/Xbh`ES3VXbhZmMp[Y@1Ve][:!$PD4KUNE;@LTNE4LRN"*,@JVXQ-7 5@pppo%5555òi ' '!]#\e#N\#]x#L   !77 ! \ݿ##N]##4 !7 7:\#]x#L]ݿ#\eL#1 4  %''' !]ݿ#\eL#1\ݿ#]j#7P~ % ! !!5 5!3!   7?~% !!3 *^V !!^*  ^V!!!^ ' '!##L  !  ##4%7 7#L4L#1 4  ! L#1#7P~ % ! !3!߆^V ! !! !ECuR #7!5!7Zxx/{xx:xu-R '!5!'xx vx:xH% 7!!7vx{/xxxƪxvH-% 3'!!'Zxx vxx$!%!!W7 r$!!!W7 $!!,7r32 &}f[_ &}f[, %$R/ %$R !2+##5332654&+!ʿ[qrqqϐђАfT$@  $ !? %29999991@&  B  $/999990KSX9Y"@&]@Bz%%%&'&&& &66FFhuuw]]#.+;#"&! 32654&#A{>ٿJxn?M~hb–m؍OH#(07#5#"''7&546;7&'&#"5>327354326=-?\g`n;) T`TeZx_958>cc3Vfa<}NV{ E..''rOs+Ax.ٴ) 3{ B333#;#"'&'##53w1ѪKsQ fև3͏oNP r>6!#4&#"#3676323#d||BYZucce22wxLj%3###3!E3A1wH33 3###%̟8ǹiEL#\ !!#!5!sP=g՚oAX` !!#!5!qjLl}e`R%sw-@ 221/053#5# !232#"MT+焀\\xEEf! !+53265##-}-MDnh %!#3!3҈R={0#3 632#54&"$\^TރQr)m`Tῆrr:T*D  # #3 3 67632#54&#"f:9:54'&'&s~&&~~ڢ~.]=@N\N\.]=zz❞zz}qa !SM!R}|pas?#-n@.  '&$ /$ .9999991@ .'& ) )./9999999046$327#"''7&7&#"4'32>s~&Ġn~ڢĠnՑꏧw֜\w֜\zvijޝzwkj!^`|g^` .@   <<<2221/03#3#3#3#):@  1/<0@22 # #3.]F; -@    1@  /<<03!#!#!"9q><@  9/1 ]@ /<220KBPX@     @     @ Y333 # # \Xds3{ 1@   <2<2??]1/<2<20%3#3#3#3#\ 7@  91/0@ BKSXY" !!!!&TdD՚ohh $@    1/<<2203#3#3#hhh7o !@  /221/220!!!!5!!o&.-ժo1/,@! ',01*$ 022122<20!"'53 !"563 676!2&# !27# '&%4rmyymrO4%%4Trmyymr4*B6!*:'(8) 6AB6 )*!6oP@   <<222<<<<21@   /<2<<22<<2203!3!!!!#!#!5!!5!!n""xxyyrr3@21/03!!!ժ,o7@   /<<2<<21@ /<2<203!!!!#!5!!5!CCPPxyr7@ KTX@8Y221/0@ 0 @ P ` ]73#3#>@ 10@ BKSXY"47!5!32654'3! $x˿ßwNetwc #/9@1E- !'E0<2<21@ 0*$002654&#""$54$322654&#""$54$32,,,,PIIPPIIPPIIPPIIPs'(@ ) (1@ #(046$32#"$&732>54.#"s~&&~~ڢ~\ww֜\\ww֜\zz❞zz}``}|``s,P@  ! #.# -9991@ ! ((-99046$32'#"$&73277654.#"s~&&~l~\wj\ww֜\zz➞ikwz|`^jI|``; -@   1@   /2203!3!#,dq9d (@   <<<<1/03#3#3#QIh ?@     <2<2??? ]1/<2<20#53#533#3#3#h+Is'+>@- )(( ,9//)]1@+(#,046$32#"$&732>54.#"3#s~&&~~ڢ~\ww֜\\ww֜\zz❞zz}``}|``s>,P@  %$#& !.! -9991@ #&$%((-99046$327#"$&732>54''&#"s~&Ġn~ڢ~\ww֜\pw֜\zvikzz|``|?l^`sr%1=G@8&,20><2<21@/; 5 )##>9//0! #"&547 !&54632! 32654&#"4&#"326sS_  _mz,,,,,,,,gs'O;H66H;O'sz<11<;22<11<;//d #@   <<1/<203!!#!5!IIjk=;;sr3?Kf@F4%+6:0L2<2<29/<<1@=(I C (7##11L9///<20! #"&547"333###3&54632! 32654&#"4&#"326sS_ ̻A;z,,,,,,,,gs'O;H6ߊ6H;OO4z<11<;22<11<;//;@   2<21/220]!!!33##!!!>ժFh);@ 1/<0)3!3;+y=@ B <1/20KSX@Y!# 5!!!8ks#O@%$!  /<<22<2<21@  /<<<2<<<2032653#2#4&##"#3"3ʊyʊy+VVF%F.@ KTX@8Y1/0!##u-s+f@- ,&'  #+ /<<<222<2<21@+*   #*'"/<<<2<<<29/<205!5"3332653#!!2#4&##"#35ʊAyʊy>FV>=VF=6-@ 1/20!3!3M-$36767#"&546?>7>5#53!Ya^gHZX/'-93B$BS #C98ŸLVV/5<4,5^1Y7:X!##:o#5!#&X3!3hXo!533oXKK'464';6;'769'96:'469&496'96;&9;6'468&456&;46';64&466'466&;:6&7;6'765'86:'56;&8;6'766&:66&:;6'76;'764&:46&:76&586&996&666&5:6&786':64&746';66&;66&866&656&9:6'967&:56&876&546&486&5;6&;86'965&986&566&686&776&::6&8:6&756&766&6:6&886&556&896&956&856&7:6&966'966rid{jXn`+v)4>@01, *$6E591@ $ *052220#"'&'&#"#"'&547673!27676323 4'&'3ft[na`zxz{n[tfCGo~[U]LKfdKJ]U[~oFCD@@DDDk63366336Fk!<@!  # E"91@  ! "2220!"$"# 33276762324rTRrƒ>IxddyI?ВP8[ 77 [8G<r&,>{&s   !3#!! ! H0x:;hLH+fabgp{ "326&33###" rhո  983#!#!#3! !9҈_:o%+kj{"-#5#"&547!#3!63!54&#"5>32"326=?/j`TeZ߬ofasP`A"..''f{bsٴ)e767!!3##!#!!&aO)p(?x4&A D+k`76765!!3##!#!![(bR-f}v(UԓR:d6T356765!!#!T:WO)fb0d+L`356765!!+!L3DS{X^}з3oP! !!+##-}) `! !!### >?h˸ʹ`3'Ps'y2qu{&Ry.se3#%3# '&76   1L  F<HqC{3#%3#"32654&' ! hJ IHn98s j&m'yryq{'yo'y.n:W '/7?GO%3#%3#3#%3#3#%3#"264"264$"264"264$"264"264$"2642+ '&' &547"#"&546;&546 676 3#J"{iihiihiihiihiihiihiihG4UU32UU4IF]97R̬\dfʬ\ʫZee̫ZҜf!!!2+5327654&#!#!qmL>87||ժFwrKK"9+32+532765||BuƣF1n!&edH08L*!!!2!"'&'5327654'&+5!#!^eicUQsj~cd\]ժ˚8+lhzy$1KKIJJ+7L402!"'&'5327654'&+5!;#"&5#533!AicUQ^cdjTmcd\[jKsբe8+lh%12KKKJN`>¨{Rg|1&'&547632&'&#";#"32767#"$546p<HmmFEMUUU8%~` !!!!#+`Ӕo{V 3 3#!+!# ! !J9҈_҈_%s%>+{'{ 5@M"326=%#5#"'#5#"&5463!54&#"5>3205>32"326=63!54&#"߬o?nQ?`TeZxeZ߬o5y`[A3f{bsٴ)Lfa' fa..''~D''f{bsٴ)hn< - 3676! ! '&'!# !  J-p;:xżP.g%H}[[Xr%H{{{"-82 '&'#"&5463!54&#"5>3 6"326="32654&y7!``TeZ*qO߬o{ǝ>REa..''f{bsٴ)nq !3!2653! '!#%{J®sv%_r\4h{{(3%#"&5463!54&#"5>3232653#5# "326=H`TeZ||Cu߬oߍo..''{fcPf{bsٴ) !!#3 3%Lj_:+{N{ ("326=5#"&5463!54&#"5>323߬o?`TeZ^\3f{bsٴ)ͪfa..''5 )!#!#333#%~gY_:gci5R{N{"-0!5#"&5463!54&#"5>32333#"326=!#u?`TeZxgƚÛ߬oGfa..''~mc3f{bsٴ)V !+53276?!#3 3%lKMJ|ثL*+2_:q?=$%2@{VN{'2!5#"&5463!54&#"5>323+5326?"326=u?`TeZ^N|lLT3߬ofa..''wj8zHB3f{bsٴ)s'{f 37!!_(^M*c37#xIS 33#!!#53ʨ_YQx 33###53YR j% 3#! '&#5376 !&'! 76;:~ ż ~HjiF wvҵCҤֆ {'23##"'&'#53676"!&'&!3276o ~~ oV?s?VLVVM{~͐~sUUu%gstgs j$. 676! ! '&'!     ':/##.;:xŽ.$#.yHH5==5[[4=<4HHHq{ 1"32654&!"32654&'267632#"'&'#",nn霜ǝ98 !#!5!)+Vy{3#\{V4&#"#367632#PQfeCBVd{#4&#"#3>32d||Bu\ ed#Ib !5!5!5!b>>I5:@ K TX8Y991@ _]0 P]3#5qeo7@ KTKT[X8Y10@ @P`p]#o+w #!5!!5Pp+ɪF #";##"$54$3@/+X 3333! +m3#mD U%3 3# # #3>:9w+: #'+/37ڷ/$0(7,48<<<<<#+ 3'<<<<< <<<<< <<<<<9̰XKRX8K bf TX30<32#4&#"#9`M1Cuȸ||MM 7BuƸ||e,'"xMfca?'Gzed\V5<!"'&76763!!32653#5#"&5#3!#"&5332765!"3ە^SWsv||CusCuȸ||WVۃ^SBWLa{fcBVfcf__{{V H!&#5#"&5332654/&763!6763232653#5#"'&=4&#"#9`M1Cuȸ||MM 7c%Zk>8nClbd||xe,'"xMfca?'Gz2XO{fcx{䟞[t`&-V 332673 &Vv aWV` v ޞKKJL[`&ASN~`6@  F991B /2<0KSXY%2767653)5!3$Wq2!dj±/8s4tVg` ##4673>=3|u˷d7<T "yX`#!5!e/я`!#3#4&#!5!2snJvy–X`35!26&#!5! #X-뒦yX4=!3!#T\[CLzl` 3!2%!4&#!Wn`–X` !#4&#!5!2nKy–X`!#4&#!+5265#5!2nã rLy–a;- 1 <05!3!----Ӫ&=&= && `&$u`&$`&$\X`&%BCZ`&&Xh`&'d`&(Q`')ZX`&*`&,&Q`&-ZXV`&.X`&/:X&0X`&2%X`&4X(`&5Vd`&7Id`&8{C!`&:nV`&;X`&<I`&=`&><t&)X&%X&/d&8X3>=3##67'#3x]GgG.i=dB`ԛ":T)C '9 '9 X& ~X' ' ' X&c ~X&c ' ' X&c ~X&c'9'9&L~&L'&&cL~&cL'I&I0a&I+p~a&I+p'x~\F&x?&,~ x&>'xx\F&x?&,x x&> (f'X >f'}D>\/&E 8>>/&F 8 (f'~X >f'~&D8\/&E~88>/&F~8 (f'X >f'2D>\/&E8>>/&F8 (f'X >f'2D>\/&E8>>/&F8 ' \ ~&P /&\I> ~/&PI>)7%#"'$47332767654'&54767;#"'&/cͷ?Ahž#62 #dGG&+@XA:g!axLn 6r'|>X %+53276=3+HZ#c,1VV,1jٻ~X%+53276=3;#"+MZ#c,11,c7nVV,1jj1,JoX&~c~X&~cpn"56$3=gi~wun52&$=Ԛuw~ig* '/&'&#"#67632O,$e5Fqp[?8WH7  $0GJI  '327673#"'&'O,$a9Gqp[?8W7  $,KJI Pq,l&fq,Pr,i,k ;#"'&=3!1,cK\WL71,\W+Ps,Pt,l't,fPu,l'u,fPv,l'v,fdw,l'w,f<x,l&fx,UL'yR&0yl9'zRl9&0z @'z>n 6&z>l '{Rl &0{'z>o&zXD&z+p~&z+pyR 3;#"'&1,cKPWskj1,\e'}9&}9X&}~X&}'~m^&~^ '~ &~&~cR~&~cR'&&cR~&cR (f'}X >f&D}\/&E} >/&F} (fX >f0%3#"'&'&'!27# '&5767"#"5$3 "(1{R=IrbJIԖ^` __&m3HZdP^vc–e4)?6 [_w\/&'&'&5672+5327676SSgURHKLXJKݣdht^#4b4bBPH:jV>/);#"'&'+53276767&'&'&5672~AI2hrBV~(;E)Kݣdht^eSgURHK 4b)N"w6a.%PH:jV# ('}?X >&D}?\L&E} >L&F} }RZ}GR &'3;#"'#"'532767654"9aRQS,cKa].-fgsT!"#?zNuIS,!&* 1p*D}'}EZ}G&L}E b&\ ~&3;#"'!5 767654x I*eK2D0# &pgM,>ꅗ:H~ b'}q \ ~&P}q ^ GF%7653323;#"'#"'&''&'#&'$473327676'&/3N0%@nS,cKvDm% I01_@8'TPxmil_Qb_y^@@$:|_2&aS,`[ F{GHܳ&%0l}=J<~ 1%+53276=3327653763#"'&'#"'&+8LcKc,P,+hm,%@n\Kf%#?70`DAbH<;!.,Pd@dczg2&q\ =!1(78#"'&'#"'&'+53276=3327653763;#"'%#?70`DAbH<)+8LcKc,P,+hm,%@nS,cKvD =!1(I;!.,Pd@dczg2&aS,`Z ' ^ G&T  &U 7&V ` <I)"'&5#&'$47332767654'367676;#"/"3276'&'&u&4-JXPxmil_Qf[+!' (s{lHX}a*=RKgL~큻%MGHܳ&%Dl7(2l^F"%GMF ,\v7Ql?[F2 .327654'&#"!"'&'+53276=36767632Ш큺%0LJNA'fKc,P-e_KUskl?[F*#=,PdrNP2T?!'Dmx+8)"'&'+53276=36767632;#"/327654'&#"JNA'fKc,P-e_KUqm*=RKg਑큺%0L*#=,PdrNP2T?!'DKH ,\vl?[F '} ` &\} 2&]} &^} b))5!3%632;#"/%3276'&'&#"@o\Dui*=RKg큻%0Pz\?c!'EMF ,\v?]DQx %3276'&'&#")5!3%6329큻%0Pzu \Duiʸ?]DQx\?c!'Emx))5!3%632;#"/%3276'&'&#"8 \Dui*=RKg큻%0Pz\?c!'EMF ,\v?]DQx'}Rb&d}R&e}R&f}Ru *du %+! '&7.54762;# '!2764"[b=D}a_[9^DU)k_1ocz2t*n@00@p[C+ @Mkl=v8`3$*727&'&5763"327%+5SF7J \X];d}M4F!Ť$/%+532767&'&5476762;#""654'v`kB;(aD hYYh MXD=p`vʨ4/gg/($'UZ'-)74--47)-'bM,(U __ u F'}wdu L&l}F&m}wL&n}'}~\L&}?&}~ ~&}kH'~R~k &~k?&~,~ ~&~8i!D#"'5327654'&'&7676'&'$54733276763;#"'J&P DfXRNB8D-<9_h$$EB|=Q#!v+6(  %{{qe))5!27654'&54767;#"'&/66-62 hGG&+@XA:g!a_h$$EB|=Q#!v+6(  %?+)x.j#$%653;#"'#"'$&733276N1,cKpNyUcE@A(IPmI~jkj1,3.(B"[\ss~B"5 +5327653WPKc,1se\,1j%+5327653;#"SMKc,11,cKVV,1jkj1,^kgt5%327654'&'&#"#"'&#4763&547632;#"bzL,5;(.;D K2KxAZM\HT((&iK*9:X DD(PNNOmf7*(?$GC,,m$%#"'+5326767632%327654'&#"dan@ht4W^Q[a>/4(*X.[4fb0G1P8TYNE5EK&)/4:''5)24fb0$#1P8S1>,E5EX !a%H'}?  +&}?&'}R~'}Rm^ $&'&'&'3;#"'&'#"'&5476 xRot$8pKZI-&8:m*12e CY>)2'+eO,3;I0D-=67654'&#"27&'&5476&'5#"'+5327654'&$"':A4N--0M,Q@(Jxb 41}! @H=.%4-+#%v iEN@TSZ 'D49g=ql)D%'i.C!v-3j  ;AWE L9P)8K6(S/VL_+Y9K1\SJo765&'&'&54767632;#"'&#"#"'$4733276L[/,4PT*uW ##rpl$-AIqYhu?AB[M!3!+ (;=A<^ĸ#0{bV` )gZZrN J'~ o '~ X&~c~X&~c.&y,.&y,&z,&z, &{ &{T#"'53273676537M͞jK`Uq%BUG FA+7T#"'5327367653;#"'&4;IʡjK`Uq%"@Pif<[A FA+7DT)TL* 35'5467676?67654&#">32,X\"$߸g^aOl39ZZ8L{4<+VZ@EL89CFnY1^5YVe !5!5!)5!S2SR7'XF: 'b:= ']C; '<b= ']bH'&'H'''H' ''H'&'H'''H''' H&&'H&&'H' ''H''&H'''H' ''H&''H&''H' ''H&''H&&'H&'' H' '&H&'' H' ' 'H''& H' &'H' ' 'H' '&H' '&H' &' H'''H'&'H''' H'''H'&'H'' 'H''&H''&H'&' H'&'H'&'H''' H'''H'''H''' H'&'H''&H'' 'H'&' H'' 'H'''  H'' &H''& H'''  H'&& H'&& H'' & H'&'H'''H'' 'H'&'H'''H''' H'&&H'&&H'' 'H'''H'''H'' 'H'&'H'&'H'' 'H'&'H'&&H'&' H'' 'H'&' H'' ' H''& H'' &H'' ' H'' &H'' &H'' &  #3 !!#!]W:\w98qq+_N  %*!2#!327&#363&#!3654/654'f;33;$ $#>]a{w DD663! )327&#!36'hPcp~qAA k{qS3%!!!!!!-x9vq dddsd !!!!!#3#oQn.ddqs&&$#"32767!5!# !2deVRuu^oRaG@;@&5dSUmnHFcIf3%!#3!53#.nXddddq dddd fY6765%!#!53265-V?O?nqd J^ dd0 !3 #!3pdw@1q 2 !!!3ddo o !#!! !3!3_Gbn}qR+q  r'( ! '&76 7& 676'&&:żGlllli$ #ab2222jT%%5$c$-6&/.4%&  %5 64&/.$ Pdo&nŢmngzoʷ-[ʚ)'NXd''pui$2Xf| / 3%!!!!rpq ddq $!&%! 65! X!!Y fqba@`|gd5\*$ 3%! 3!dq d+D 3!3%! ! 3! !D5D:9:9d|q  d+l 3%! 3 ! #(\~vbL:H|dq d22{ 3!! #3ndp29V{{",34&'3!5#"&546;54&#"5>3 5#">76/=Kd?Vu`Tw86/^b;:gCzӆ]YfaH..t''UNHGgwt-!>32#"&'!4'&'676763&#"327N:||:^,<<,9RKM_]daadt= z =OsKTdihtJq{#%#"!2&'&#"3276%M]-ULEmGJXHCQRHV,${z$d$$>:##dWS%&-!!5#"323327654'&'&#"N:||v9,<<,^(]_MK^daDDaZKsO=  =Td6Jthio}{!327# 32!.#"}K_mk)#i̩J@b]u-)8 CqzӾ/ 3476%#"!!!#5354763g.9:9|WX -8J_D8d97ddddTVqV{#.=65326=#"325!!"&32767654'&#"jlQR:||:Nry^,<<,9/KM_]=ʌo,*qdaDDad-w=  =OsKihtJH "34'&3'!>32!4&#"! GS5‡OIƁkk h@[:Lded\ПU5 33#!!JKOhV #676#532765!3#%G(=1l$%OQRaеT0Hd01``2 !3 #!3OHіmdi#L&5#"'&5!3J=(G%RQOLiH0T0Z``~J^d{"&1<!>32>32!4&#"!4&#"!3%34'&%34'&OIƁԝTށkkkkd[ GS5 GS5`edJv\П\ПUh h@[: h@[:H{ "34'&%3'!>32!4&#"! GS5‡OIƁkk h@[:hded\ПUqu{ #2#"27&"676'&s3x33x3d4'pp'3(pp({98  kp-$-R-ۀ-qV{-%!!>32#"&4'&'&'676#&#"32N:||9,<<,^؆]_MKdaaKsO= z =oHJthiqV{-%#"325!!3#32767654'&#":||:N<^,<<,9(KM_]daDDad=  =OsK2HHihtJ{3'!>32.#"!N:4I,hdfc˾zo{E67654'&/&'&5432654&/.54632.#"#"&'i'K&'q4=B%%U+.39GSOjqL4vfLJ\_opPx3Zl=vf03"3;@{R?Bsl37'*7CoT78^UNO,, z1$YXDL#/%%7%&7#!!;!"&5#53*\{KsբjU|7N(dUNdudTD` "%&'&5##!5#"&5!3265! GS5CIƁTkkTS hl[:hded0=` 3%! 3!YT^^d\hdTV`3!3%!!3! !bTNdhhdjjjL` 3%! 3 ! #U|p|[hd-s=V`7%! 3+53267>^]_lP|XQ+ۙdi8{dCYXb` 3%!!!5!\vwhddhddh$%s'&'(#)s*;+f-j.j/031s23s4T567)8h9D:=;;<\={-{DEq{FqZGq{H/IqVZ{JdKyLVyMN9{Pd{Qqu{RV{SqVZ{TJ{Uo{V7WX{X=`YV5`Z;y`[=V`\X`]   6/&"27 d3{44{3s s#Տ0,-k37!!5!5%6bJJgq ddd HdH(7!676'&'$32!!7676&#")`"LlDbZE0Q](=ymd͕@9\9pd9hbiddAbs$*0"'5327&+5327&#"56325654&'>54+!ĪeO6?;2:L uWEdJj D d <h@Ѳ|!ŐUl$yXZ#3 !!3#!!5Qpq3d\#66'&#"!! !"'532gd1jKEн܁\`I Kd# F32v cSRav 6978w{z9 j@ VV120K TX@878YKTX@878YKTKT[X@878Y332673#"&v cSRav 6978w{zfGd10KTKT[X@878YKTX@878Y3#@1<203#3#䙋N#!#ęę53#73#'3# 3#3#'3#}}d 3#3#'3#}}d3#3#d 3#3#3#3#dd&;#"'&'#"'$&733$767654'3F??7KX~X\,>%!$'$&73!2%7&'&547676323!!"'654'&'&#"xhn}@AQ+"R:4RQP ioh4"(=)1$+<'g\^sM6,|y$K2S%jAzG' <8BN?0654'&323276767'&54767632#!V)B,4((7(*HTO<?aNbNLZB`.NJ|m+M;3*)3P& ]027EW4,E$2Hf3Џ,' !5;#"'+5327&'&54767632"67654'&'&f$'و'$A??8 D?$ 9P2*I1C299(M.L,0W 5+5DE2.4! k .@%&'&'&547676323!!#'$'&5473!2766'&'&#"B.y9()Wp8c20-=^E>><l/"'"3 9Ld/  #+m=E2X:zFNV}`kL:DbZzWK# :<,; ? &}R~&}R %4'&"2>"'&4762<R8R8z?@?@@?@(8)*8@@@@@?? '~'&'~cRP~&'~cRP' &cL~&cL >&Dz8\K&EzX>K&FzX >&D?\F&E >F&F  >&D\F&E>F&F >&D'}?>\L&E'8} >>L&F'8} 3_+ 5__bV'J@!B  6991/<2990KSXY"]33+532765#ոRQi&&}``01}` 2@  F <<221/<20@  @ P ` p ]33###53ø`<ĤV.` 54!333##"3276!5R w{i&V`p?`3A0c3'q=rUa4'qr[^3'zPq=cZ'sdrUcZ'udrUaZ'sdqaZ'udqvj 3't\q=cZ'wbrUvj V'r}t\cW'wuz|vj0Z's@dt\c:'vus(Dcm:'uDvuvc u'vutvV Y'yPtpVZ'yPsdVZ'yPudV'yPc['vu{Pj&Z,,!!,,O=32653#"&[hq`=QQ, &&| &3;#"'!5 767654x I*e2D0# &pgM,>ꅗ:H~#'|`'|S'|SF'|8@'|+ '~c~@'|+ '~c ~r'|>P9 9F KSKQZX8Y1/0@  @ P ` p ]3;#"&5Li a^q%qqu {&JOw`73#!!dž$Nd`Vw`#676#732767!5ʆ#5H2K1i0/N)deеT0Hd01``vg{'{&3#3## +@     22221/220!#3!53#^ժ ?!5 ?8'qXw8 U'rXw8'wq8'tXw8 U'uXw8 'w,t$'tz$'uzN@ T1/0333N@T 1/20%3!533yոBy@ T1/0)533ysոBq8@ E EԶ0]991@  /0 6& #" 3 *NYh> éA@E E Զ0]91@    /<20 6& "'!53&54 3 *NNJhh> é!8@ E EԶ0]991@  /0 6& &54 #"'!5 hYNJ>z=x 4@   2291@  /290)33!x³j*]Qix 6@   2291@    /2290%!5!33xtj³瓓]Qi' 4@     2291@    /290#5!33j³]Q=q) #33mCq"q )5333!mm"q)533#mOq $@  1/2<0)3!33OkUq""Oq (@   1 /22<0)533!33OιUΓ""q $@  1/2<0)533!3kιU"Oq $@   <1/2035!!5!3ΓK"Oq $@   1/20#5!!5!3ΓK"q @ 1/0!5!!5kqKq:@!E E ܲ@]ܲ@ ]1@  /<0!&'.4> !2>4."RJr 惃sKR9[ZZ 1ũbbŨ1 p`88`p`88!>@#E E"ܲ@]ܲ@]1@  /2<0%!!5!&'.4> 2>4."RJr 惃sKRQ[ZZ{ 1ũbbŨ1 p`88`p`88O:@!EE ܲ@]ܲ@]1@  /<0#5!&'.4> 2>4."RJr 惃sKRQ[ZZ{ 1ũbbŨ1 p`88`p`88O &@    21 /03"3#!5!>k fO "  21 /03"3#!5!>c f $@   21 /03"3#!5!pk fq7@ E<21@  /<20!!##"&6 !354'&"3.Cf^v ]8mr^<Uf"qɃ]8ƃ;@! E <21@ /2<20%!##"&6 !3!554'&"3.Cf^v7]8mr^K<Uf"Ƀ]8ƃ7@ E<21@  /<20%!##"&6 !!554'&"3.Cf^v]8mr^K<UfɃ]8ƃ ,@   <<1@  /03!!!!!55Փ/ 0@   <<1@   /20#53!!!!!55B/D ,@    <<1@  /0)53!!!!ys55B/= ,@  <<1@  /0!!5!!5!355ߒѓ 0@  <<1@  /20#5!!5!!5!355ՓLѓ ,@    <<1@  /0)5!!5!!5!,55Lѓ *@  <1@   20!!27654'&3!23,R4,,=ٹUiXO]Oz}I_"_Ҥ.@  <1@  /220#533!23!!27654'&ιUiXO,R4,,=B_Ҥ]Oz}I_ *@  <1@   /20!!27654'&533!2#,R4,,= ιUiXXXl]Oz}I_"B_ҭ@@  ܲ_]9@  /999@  10!4'&'5!!5Mc4B_9V@9D@   ܲ_]9@  /2999@  10#5!&'&'&'5!! 5Mc4BX]9V@9$@@   ܲ_]9@  /999@  10#5!&'&'&'5! 5Mc4B X]9Vq=:@   91@ /̲]촍]0!533T9 >@  91@ /2̲]촍]0#5!533hՓL9 :@  91@ /̲]촍]0#5!53hL9+#1@%!$1@  #/2203432>3234&#"!4&#"!}x5%^qZHZlK--Xh|ŕnc%5@'#&1@  $/2220#53432>3234&#"!4&#"!}x5%^qZHZl[K--Xh|ŕnc#1@%!$1@  "/220#53432>324&#"!4&#"!}x5%^ZHZl[K--Xh&|ŕnc= -@   <<1@  /<<0!!5!3!!!KK?1@   <<1@  /2<<0#5!!5!3!!!KK? -@   <<1@  /<<0)5!!5!3!!@KK?=X>@ <<<<1@  /2<<<220%!!5!3!3!!!=KøL??XB@  <<<<1@  /22<<<220#5!!5!3!3!!!%!KøL=??>@  <<<<1@  /2<<<<<0)5!!5!3!3!!!0KøL=??Oq %@   1/203!3!$Uq"KOq *@    1@  /220#53!3!$U"Kq %@  1 /20)53!!kUޓK=C  1@ B/0KSX@Y!!!tFs0hB~ F  1@ B /20KSX@Y!5!!!tFlhhB~BC  1@ B/0KSX@Y!5!!tFlh0B~B+ 8@!  <<1@    /2<20327654'&+!!!2/!m]%i ; @ED\qQE=4."RJrCEoJRXErrJS9[ZZ 1SV/ { 2Ʀ1 "p_88_p`88*#5!5&'.4767675!5!!2>4."RJrCEoJRXErrJS9[ZZ 1SV/ { 2Ʀ1 "p_88_p`88O(#5!5&'.4767675!5!2>4."RJrCEoJRXErrJSQ[ZZ 1SV/ { 2Ʀ1 {"p_88_p`88Q %@   1/0!!#!3BQ *@  1@  /20#5!!#!3ԓ} %@   1/0#5!!#!+Q (@   <1 /0!!#3!3OQ -@   <1@   /20#5!!#3!3ԓ} (@    <1 /0#5!!#3!B /@   <<1@   /20!!!5!3z;  K"qѓB3@   <<1@  /220!53!!5!3z;7 K"ѓm /@    <<1@  /20!53!!5!z;7 K"ѓ+q &B@%(E# E'ܲ@ ]<<ܲ@]1@ # $ /<<02>4."&'.4767673! [ZZRJrCEoJRXErrJS"p_88_p`88~ 1SV/ { 2Ʀ1  (F@ *E#'E)ܲ@]<<ܲ@#]1@' (/2<<02>4."!5!5&'.4767673 [ZZlRJrCEoJRXErrJS"p_88_p`88 1SV/ { 2Ʀ1 O &B@(E# E&'ܲ@ ]<<ܲ@]1@ #  %/<<02>4."5&'.4767673!5 [ZZRJrCEoJRXErrJS0"p_88_p`88 1SV/ { 2Ʀ1 {q*!&'.4767675!5!!!2>4."RJrCEoJRNXErrJS9[ZZ 1SV/ 2Ʀ1 "p_88_p`88 ,%!5!5&'.4767675!5!!2>4."RJrCEoJRNXErrJSQ[ZZ 1SV/ 2Ʀ1 p_88_p`88O*)5!5&'.4767675!5!!2>4."0RJrCEoJRNXErrJSQ[ZZ 1SV/ 2Ʀ1 p_88_p`88 '' '' '' '' '' '' '' ''  :@   @ ? o ]9999991 2<0#'##'##'d2222222dddddV!#!3!3#3jժVV8`!##333#{}`9VVX{ %5#"&5332653!"&'5326Cuȸ||aQQRjBfca{+,*X10!5!-ЈX'3I(sInhX#'3h'OW`4X#'3v5]dDZX#'3 |;d07!X#(ẌI$@h$An4$B`$CnhX#7OhWh$Eh@4AnB`4X#7]vDdn4$J4E4@dAdZX%#7d|!70`$OnJEd@0<0^X133ֈXJ=_<~~3 r Um Q rZf55q=3=dd?y}s)3s\\?uLsLsyD{={\{fqqq/q999qqJ+o#7=V;=3X55^R\sd5^5bs#5`b?yyyyyys\;\\\3 LsLsLsLsLsLf {{{{{{{fqqqqq9999qqqqqqH==y{y{y{sfqsfqsfqsfq)q3 qqqqqq3sq3sq3sq3sqTx\9\9\9\9\9r\9?u9u9uuFLsqLsqLsqs/qJJJ+o+o+o+o#7#7#7DV={\3X{\3X{\3X/ }}ssfq3 }qqLu3s~\ 9 =LsNgvsq7r+d#7#7N={\3XTT\h3qT]hX\] ` d <qKsday{\9Lsqqy{y{{3sq3sq?LsqLsqTX9 ` d <q3squy{{LfHy{y{qq\9\9LsqLsqJJ+o#7,Gqqq{\3Xy{qLsqLsqLsqLsq=79qqy f u +o3XPP}  yq\9@sq J qefqqqqq|SA4Pq9qq q``9t*KM:+#qqGpPPOJI>>t+o7#7#7q=V=f3X3XXmXXXXLsPqq;VVqXXqvqq77:7/ <66JO<u1ufu]H^H 6&:uuuuuu  3s3soouuuuddLhuTzuuu%q7]yq$U $ zw(j#Lcxh!c+qc3x+x.pppp*pw<.::3efqesDy}uy{\Ls\?yLsLs{=LsN\FqSFq qSZkq=xJvkqJqqdGp;Gpq?qWWGpAOpLsq0q@GGrwxssFqU-~Od$s6sq,J7Opfq9Lsqs5UsssJs\\\T\J#y}}@e(!TLss#y{=6|<}o{p4kq5FA33L ;q;fq<=p;rR>Qdqtqq/4dq+o9998L07/3=;xs*` D3 GLsk7sS[2Lsq@R2@R2s<qsq pv9xssfq;XXX.j}!&4fG8=(5F!A!=2*ISsqsfq<=={=;yt|||\(5F?56].I6r|29y{y{{qLuqLuq(5F!ATX33LsqLsqLsqodq#=#=#=|4QfG8{=;{=;}q -qn6.3sGq/STL ZTL'AtLsqDVT>LLXv&tuA&7\\S&eLsR\Lsuu^x"6^Zq"qDq;' qqF92 F &q/qzw`DDcc/NDdc\\fcXCX.X0.XsXXEX.XXN*CCMXwBS(?99l9lC91***}} ffuuXK5k1CCOOLLLRLLLLLUL<L<LdL\W5kVz*******KKK))*CC1LLLRLLLRLjLL<L<Ld9qd==;;q;q=x==D=;==p==q==.qqB[B[{d{d7]xmxs[")>WE_IIY"~h~h@sx2OsOsxMo`P{P@@@@`NzBza\d>N c c]ccY]dji::PZ"ZPZ|ZPZ}PPZPZXZPPP|ZPP*FZnP\ZZZFdZWPPWFZdZddDPGd.e#edade%dvd-d/Cd$d/dWd/?d1<Nd/dBd/d-d-d/d/F.Z#d{ddddddd.nemdndyyyy'''''w'w'ww'w Xc^c^%H Ewyyyywwwwwwywwwwwwwwwyy^^^l4wl4w4y4yywyFFFF*F*F*FAA8F3F3FFFF*F*F*Fzzwuuuwwwuu&w&w&wwFF wwwFFGwyFyFFwFFFwwwFFGwy=Fy=FGwGw=F=FwFFFFFV+V+FFV+V+VY]YFFF"F"F"F"FGFGFGF F F F F wwww?w?w?wYSSwSwSSSFFFFYwyyyyMMwwdwSSyy4yFwwFFww```````FwFw     FFwwFF%w%!%!%w%w%!%!Y )#su` z    s 4 s 3  E p 2 O 3wq= {>fq$S9( 3qfyqyqy3/qqq222</=V3X5x=2ZLr u//SH||NYHG p+"M"M>G/Mmu>GVGVGTR>GnzhuuEuOGGOGOGmu\#=nnuV&7yGSG%nzu=nV&7yKySG%t9>GGGOGT_>G=nIzIIVz[quuIuEqOGOGFK\#^YGu@zV&7~77#7OG[[[[BBy{}}}sfq)q)q)q)q)qqqqqq/3sq\9\9???uMuMu9u9LsqLsqLsqLsqJJJJT+o+o+o+o+o#7#7#7#7y=y=DVDVDVDVDV{=;{=;={\3X{\3X{\3X#V={/&qy{y{y{y{y{y{y{y{y{y{y{y{qqqqqqqq\Z9D\9LsqLsqLsqLsqLsqLsqLsqNgvNgvNgvNgvNgv====FqFqFqFqFqFqFqFqyy'iSSSSSS0l7hx qqqqqqoE.k_FqFqSc<qqFqFqFqFqFqFqFqFqyy'i7hxk_FqFqFqFqFqFqFqyyy<pr\\D~{aNsVddddd%%%%9933W q q(()((()( 33?nn=V`Jd=n=dn8N(ffadp5Wnz5?5f5\5l5Y5S999og0u5W55^5b5?5f5\5l5Y5S999og"MVGOGuVGVs`u .;F_( ..D]1u!===P=&C&Cs#&<<oI HZ;jDN hR6nLsbBSV,y('y\XNND?yJ\}WJT9hgd(V FhZ $<|3uuWZ[O=;6Q^^b?fbfl\bya W{=w= =us)9~=}== ]=;;;9fqq y) ysedud    du,dudududvdvdd*ZZd-Opdduudwddxvxddddudud  dududuku7^H^^^@^^^uzz^uwududdud7u7y#_ZZ,dDX===,,ff+uPuuu+uPuuu+u+u+uyyy``>>**yyby*cc| a aXXJr;xxdxxd++* 8 8 P 8 x PFq 8#+7',,,,,,,,,,xxxxxxx||''''''''''''''''''''''q''''''''''llgg'''''''''''''''''pprppppppppp7p7Tpp''''3'''ppppp'''',h,d,,,,+,}}_}} ,,,B,d,,,,,,,,,,},,,dZd2E\,,,,,,,,,,,,,,,,,,,,,,,S,,,,,],,,,,m,,E,,,,A,,,U,,Q,0,,,U,,L,0,C,,X,,B,,X,,,x, ,,,,,,,,,,,,,,1,,,,,,,,,,,X,X,j,, T},y,},),,,,,d %6  dT YxEVIVVx+5X3ppppR >pTVSTWW/V0/0002p@TTTTpnnTVaaTT,f,z,z,z,z,xNNx>NnX~#9Uwlf,,,,,,,,,,                    uuuuuuuuuuuuuu++<uusunOss[YOO Bu xd xu xd xd xu xd xd xu xd xu xu,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,duwOwO::: u+u+u+u+u+u+u+u+u+u+u++u+u+u+u+k  77^^  7^uuHH''''$$"pMMu 9 u H#?{\3X@sy= DVh<GpPqbfr ,qssu@xC@~yyv{\{\ssg)?>8{\(oo:o\:o\csssss$d{=syNsNs6??,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,r+d pv9;<@>speKkT5L mLsqsq s&q:Bz<<|ff7S+o { { #{{{{seq#Sjxt  s&qu 9553wF\ Dq/ / ///}/o } <.VN1X?,XXuXXwwwwXCX.QX0QXsXXEXXXCMXwB.XsXX:j:j:j:j:j:jKH KH ************jj))k))k":jC:jp*XXXiXXXXXXXXXXX9p9lpl"9lplC:j9p:j1J:j:j*********}3}}3}jj 3# 3#  f^f^uBuuBu/KH 5kk kpSI:j1J8"CC:j..TT4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,c3s$f"=3LrDrlK{fqo/q5 "qqq+o7=HVhL=Xy}s)3s\?uLsLsyD{={\{fqqq/q999qqJ+o#7=V;=3XkZqAjds N:jH k :j:j:j********_9xxxxxxxxvxxvxxvxxxvxvxxxx,p:jj9Jqq9O99:::qd=dd=;;;;;;q;;;q=xxx==D=DD;;;====p==q======...qq,,,,,,,,.jn`#Zn`nn`n#Z`n3>?@<@<@ABPChDDFFGHIIJKPKLLM$MN0NO@OlOP$PQ|QQQRRSS0S`STUUUUVV8VPVhVVW|WWWXX<XlY4ZlZZZ[[[\\]]4]`]]____``$`<`T`x`bLbdb|bbbc chdde e,e\etffDfpffffgg,gDghggggghh,h<hii4iXi|iiiijj,jPjtjjjjjkk@kl lllm m0mTmxmmmn$nHnlnnnnoop$p<p`pxpppqdqrr<rTrlrrrsxtt@t`ttttu|vvvvww(wPwhwwwwwx$xHx`xxxxyLyzz4zdzzzz{{,{D{\{t{{{||$|<|T|l|||}}~~t8X|T`P0\t(@XD L@  8Ph0Pt4D\t<Tl $<Tl,D\t4Ld| $<Tl4xld| $<TlX8$ t,l,<äPňH,ȸhʤ<̌(x\ 0@\(԰ՔLLڐhܜX(ddL`lt` 0THX \hX, 0  T   < L d t   $      T $,@`|8L`|PpHT\,T(<Pd Lh@h<\ Dh$8  <    !!!,!@!T!!!""("t""##<#####$$$,$P$x$$%<%%&&(&(&h&&&&'L'`'t''( (4(\(l(|(() )<)L)\)))))*0*`*x*****++(+@+P+`+,,,$,4,,--h-x---...../t/00011(1@1X1p123t3456L6778`889:@:P:;`< <==>L?X?@@@@@@A8BBChCCDdEEFxG$GHdHtI$IIJhJKLMHMNOpOPXQ QRPRSXST`UU(U8UHUV$V4VDVTW$WX0X@XXXpXY(YYZxZZZZ[P[\P\h\\\]]]]^T^d_X```aabbb bhbxbbcccd8dde\eefhgghphiHijjjklhlmmnnnno@oPo`ooppqqqrHrrsLstu$u<uvvw<wLw\wlw|xxy<yTylyyzz{d{||}<}|}~0x<Tlxh4\,TXt8Ph<\8, ,`$pl84$`<Lx Dhx(8Ph,D\t4t$th8|8| 8DTdd0t ,<LP,\h x¨@tXŴTƜǤ<,ɠ<ʬ(˔̀(8ͬ͜dt$4P`ѴҨ4d՜ ֐׈$؜xl|h(8߈ߘdt\pH`L,T<dt,HtHh$Xx<,(08P,LH0Ld|,D ,D $@Lx\,HPdx D  D   D   @    < @Xp 8Ph @XhP4DTd@ dP\T@`<0h  \ !,!""`"##$T$$$%L%&&h&&''T''( ()*X++,\-8../T0012234845647789H::;>0>??|@@H@A(AB<BBClDDE8E`EFFFG0GHHIIJ@KKpLtLMNO\OP(PQQ|QRhRSSTT|ULUVVVWHXXXY(YxYZLZ[D[\d\]]\]^p^_$_`@`a ab bcctcd de(eef\fg8gghLhiHij(jk kkl@lm$mn no$oppxpqdqr4rrssssst0tHt`txtuuu0uHu`uxuuuuuvv v8vPvhvvvvww@w|wwx0xxxxxxyy,yDy\ylyyyzz(z@zXzzz{{{4{L{d{|{{{{{| |$|<||||}d}|}}~~,~~~~~ $<TlpLdx(@Xp0H`x t(@ 8 8Phh(@x0H`x 8tp @XpP8P(@ $<Tl4p4L(@Xp0H`x|`x 4Ld|h4L4Ld| $<Tl$`80,Tl$< 8 @X d|\t $<Tl48 8Ph 4L \t80H`x@,h0|\ d(HL€¸P`Ĩ0 0hxƈƘƨXȤX8Hʄ$˘˨˸8Hp̀ l8hΘ8Tτϸ@pьDlҰhX0Քp׬<(XDۀ۸\ܨpݘ0޸4ߌߠߴ`tX\pD\,,  pP Pd8X,D\t4Ld| $<Tt $<Tl,D\t$<Tl,D\t4Tl,D\t4Tt4Ld| $<Tl,D\t4Ld| $<Tl,D\t4Ld| $<Tl,D\t $<Tl,D\t $<Tl,D\t4Ld| $<Tl   8 P h        4 P l        , H d        8 P h        4 P l     4Ld0H`x,D\t $@\x $4L\t $<Tl,D\t4Ld| $<Tl,D\t,DTd,D\t0H`x0H`x0Hdt(@\l,,,,,,,,,,,,,,,,,Xh,D  t !,!`!"<"|""##T#l#l#l#l#l#l#l$&&(&@&`&|&&&'H''(((()X)))* *<*l***+$+\+++,,,4,X,,- -T-|-..,.h../8/8/8/8/8/8/8/8/8/8/8/8/8//01@112343h3334 4444445 5 545H5\5p555555566$67H78899:l;<;>`>@D@AxB BxCCCCDD@DxDDEFGGHDHIxIIIJKL4LLMN0OOP PPRSTTTUdV|WxX(Y@YZZ[t[\\t\\]]]]^_` `adbDbpcdde<ef@ffghhhhiPiijj0jkdll<lm<mmmmn n,nLnlnnnno o$o4oLolooooop pp4pTpdptppppppqqq<qdq|qqqqqqrrtttuuvdwwxzz8zhzz{{`|||}H}}~(~t~~@LH8pd 4L 8TpdL4t4,l,l$|d8t<|4`4xpX |4pDx80(0448L\<\,`Lx ptT,`p4`HPt$  @` XLdüĈŤ,Ɣ@DŽ x ɌxˤX̜p4lϠ,М Pєlӌ xD\ռ@t֨tDڴۜ܀@DހX|ߤL|<Xd0X,`<<p ``TP$\h,xh4 0 d|P0 h@tP<\| 4\|4Tt$pt,   , < L |   D `    $ D `      p    T   $Px| |"X$$$%%4%h%%&&L&&' 'D'h''''((@(`(((() ),)P)x)))* *P*|***+ +L+t+++, ,L,x,,,- -H-l---..@.l.../,/`///040l0011D1x112202\2223303d33344H4|445585l5566T6667,7\778(8889 9T9t999::$:@:\:x::::; ;H;\;x;;;;<< <<$>>>>??h??@tA AB8BCDE EEFF0F\FFFGG0G\GH$HILJKL,MN4PR STTUXVpWLXLYdZ0[\\t]^$^_`(`abbcd|ddee0e`eff<ffg g<glggh,hXhhiilijjXjkktllplmmnnoxpq0r\rsHssttLtttttu$uxv<vwxyXzxzz{T{{||d|||}},}@}\}x}}}}~ ~(~L~p~~~~ (Lp,P| (Lh@l8\(\ 8l (Lh@l8\(\ 8l@l@l,`LxH| \ (Lh@l8\(\ 8l@l@l,`LxH| \@l@l,`LxH| \,X \,`H| \LL(txXP4|hLtXpLhlP4Ld|`@Dd$Ì,hĀĘ$lż4ưD`ȨPɰXD$Τ8πXд,XфѰLҀҸ$P|Ө0`Ԑ<`՜4p֔X$`l| Lۀ۴Lܜ ݐPxޠ l0\|$ | HD p8DT0D(h4p<L@<Ld| $<Tl,D\t4Ld| $<Tl,D\t4L\l|h0H(x`< d      d   T d   ,T|4X| L` P,dTth LtX8Xx<`!$`$%&(&'(H()*+4+,-H-`--.$.|../ /`//00T0l00000011,1D1\1t1111122242L2d2|222223 3$3<3T333344,4D4\4t4444455545L5d5|555556 6$6<6T6l66666677,7D7\7t7777788848L8d8|889P9`9p99999:X:p:::;;;0;H;H;H;H;H;H;H;H;H;H;H;H;H;H;H;H;H;p;;<(<<>,>D>\>t>>>>???0?H?`?x?????@@ @8@P@h@@@@ATAB@BXBpBBBCC,CDCTCCCCDELEFFF4FLF\G8GHhHHHHHI\IJLJdJ|JJJKDKL,LDL\LtLLLLLMMM4MLM\N(NOO,OOPP(PQ8QQQRR(R8RSlST TTUTUlUUUUUUVV,VDVWWWWWWWWWWXX4XPXxXXXYYHYpYYYZZ<ZdZZZ[[0[X[[[[\(\P\x\\\]]D]l]]]^^8^`^^^__0_X____`$`L`x```aa@alaaabb8b`bbbcc,cXccccd dLdtdddee@efffggghh\hhij jXjkkpkl lmLmn`no@pp|pqqTqr\rs\sttuvv|vwwlwxxx x0x@xPx`xpxxxxxxxxyyy y0y@yPy`ypyyyyyyyyzzz z0z@zPz`zpzzzzzzzz{{{ {0{@{{||}}\}~X~p ,<L\l|(<X D|t,| $<Tl<\| l,Hd (D`| Xp $Dd|(TXt4lt |DpdD@L$@\`pdl |LhtDhp|PPtT0DX| 0Tx \8\(<Pdˆœ°$8T|ZT+h >2   : `   (Z4;b ;; 0    " F m " : %: h: ; ;Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain DejaVu SansDejaVu SansBookBookDejaVu SansDejaVu SansDejaVu SansDejaVu SansVersion 2.29Version 2.29DejaVuSansDejaVuSansDejaVu fonts teamDejaVu fonts teamhttp://dejavu.sourceforge.nethttp://dejavu.sourceforge.netFonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjung Bah (see below) Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Arev Fonts Copyright ------------------------------ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr.Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjung Bah (see below) Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Arev Fonts Copyright ------------------------------ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr.http://dejavu.sourceforge.net/wiki/index.php/Licensehttp://dejavu.sourceforge.net/wiki/index.php/LicenseDejaVu SansDejaVu SansBookBook~ZZ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ sfthyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflex Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccentuni021Auni021Buni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236dotlessjuni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BAuni02BBuni02BCuni02BDuni02BEuni02BFuni02C0uni02C1uni02C2uni02C3uni02C4uni02C5uni02C8uni02C9uni02CAuni02CBuni02CCuni02CDuni02CEuni02CFuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DEuni02DFuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02ECuni02EDuni02EEuni02F3uni02F7 gravecomb acutecombuni0302 tildecombuni0304uni0305uni0306uni0307uni0308 hookabovecombuni030Auni030Buni030Cuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0321uni0322 dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334uni0335uni0336uni0337uni0338uni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0342uni0343uni0344uni0345uni0346uni0347uni0348uni0349uni034Auni034Buni034Cuni034Duni034Euni034Funi0351uni0352uni0353uni0357uni0358uni035Auni035Cuni035Duni035Euni035Funi0360uni0361uni0362uni0370uni0371uni0372uni0373uni0374uni0375uni0376uni0377uni037Auni037Buni037Cuni037Duni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03CFuni03D0theta1Upsilon1uni03D3uni03D4phi1omega1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03E2uni03E3uni03E4uni03E5uni03E6uni03E7uni03E8uni03E9uni03EAuni03EBuni03ECuni03EDuni03EEuni03EFuni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni0400uni0401uni0402uni0403uni0404uni0405uni0406uni0407uni0408uni0409uni040Auni040Buni040Cuni040Duni040Euni040Funi0410uni0411uni0412uni0413uni0414uni0415uni0416uni0417uni0418uni0419uni041Auni041Buni041Cuni041Duni041Euni041Funi0420uni0421uni0422uni0423uni0424uni0425uni0426uni0427uni0428uni0429uni042Auni042Buni042Cuni042Duni042Euni042Funi0430uni0431uni0432uni0433uni0434uni0435uni0436uni0437uni0438uni0439uni043Auni043Buni043Cuni043Duni043Euni043Funi0440uni0441uni0442uni0443uni0444uni0445uni0446uni0447uni0448uni0449uni044Auni044Buni044Cuni044Duni044Euni044Funi0450uni0451uni0452uni0453uni0454uni0455uni0456uni0457uni0458uni0459uni045Auni045Buni045Cuni045Duni045Euni045Funi0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0487uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0490uni0491uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni0514uni0515uni0516uni0517uni0518uni0519uni051Auni051Buni051Cuni051Duni0520uni0521uni0522uni0523uni0524uni0525uni0531uni0532uni0533uni0534uni0535uni0536uni0537uni0538uni0539uni053Auni053Buni053Cuni053Duni053Euni053Funi0540uni0541uni0542uni0543uni0544uni0545uni0546uni0547uni0548uni0549uni054Auni054Buni054Cuni054Duni054Euni054Funi0550uni0551uni0552uni0553uni0554uni0555uni0556uni0559uni055Auni055Buni055Cuni055Duni055Euni055Funi0561uni0562uni0563uni0564uni0565uni0566uni0567uni0568uni0569uni056Auni056Buni056Cuni056Duni056Euni056Funi0570uni0571uni0572uni0573uni0574uni0575uni0576uni0577uni0578uni0579uni057Auni057Buni057Cuni057Duni057Euni057Funi0580uni0581uni0582uni0583uni0584uni0585uni0586uni0587uni0589uni058Auni05B0uni05B1uni05B2uni05B3uni05B4uni05B5uni05B6uni05B7uni05B8uni05B9uni05BAuni05BBuni05BCuni05BDuni05BEuni05BFuni05C0uni05C1uni05C2uni05C3uni05C6uni05C7uni05D0uni05D1uni05D2uni05D3uni05D4uni05D5uni05D6uni05D7uni05D8uni05D9uni05DAuni05DBuni05DCuni05DDuni05DEuni05DFuni05E0uni05E1uni05E2uni05E3uni05E4uni05E5uni05E6uni05E7uni05E8uni05E9uni05EAuni05F0uni05F1uni05F2uni05F3uni05F4uni0606uni0607uni0609uni060Auni060Cuni0615uni061Buni061Funi0621uni0622uni0623uni0624uni0625uni0626uni0627uni0628uni0629uni062Auni062Buni062Cuni062Duni062Euni062Funi0630uni0631uni0632uni0633uni0634uni0635uni0636uni0637uni0638uni0639uni063Auni0640uni0641uni0642uni0643uni0644uni0645uni0646uni0647uni0648uni0649uni064Auni064Buni064Cuni064Duni064Euni064Funi0650uni0651uni0652uni0653uni0654uni0655uni065Auni0660uni0661uni0662uni0663uni0664uni0665uni0666uni0667uni0668uni0669uni066Auni066Buni066Cuni066Duni066Euni066Funi0674uni0679uni067Auni067Buni067Cuni067Duni067Euni067Funi0680uni0681uni0682uni0683uni0684uni0685uni0686uni0687uni0691uni0692uni0695uni0698uni06A1uni06A4uni06A6uni06A9uni06AFuni06B5uni06BAuni06BFuni06C6uni06CCuni06CEuni06D5uni06F0uni06F1uni06F2uni06F3uni06F4uni06F5uni06F6uni06F7uni06F8uni06F9uni07C0uni07C1uni07C2uni07C3uni07C4uni07C5uni07C6uni07C7uni07C8uni07C9uni07CAuni07CBuni07CCuni07CDuni07CEuni07CFuni07D0uni07D1uni07D2uni07D3uni07D4uni07D5uni07D6uni07D7uni07D8uni07D9uni07DAuni07DBuni07DCuni07DDuni07DEuni07DFuni07E0uni07E1uni07E2uni07E3uni07E4uni07E5uni07E6uni07E7uni07EBuni07ECuni07EDuni07EEuni07EFuni07F0uni07F1uni07F2uni07F3uni07F4uni07F5uni07F8uni07F9uni07FAuni0E3Funi0E81uni0E82uni0E84uni0E87uni0E88uni0E8Auni0E8Duni0E94uni0E95uni0E96uni0E97uni0E99uni0E9Auni0E9Buni0E9Cuni0E9Duni0E9Euni0E9Funi0EA1uni0EA2uni0EA3uni0EA5uni0EA7uni0EAAuni0EABuni0EADuni0EAEuni0EAFuni0EB0uni0EB1uni0EB2uni0EB3uni0EB4uni0EB5uni0EB6uni0EB7uni0EB8uni0EB9uni0EBBuni0EBCuni0EBDuni0EC0uni0EC1uni0EC2uni0EC3uni0EC4uni0EC6uni0EC8uni0EC9uni0ECAuni0ECBuni0ECCuni0ECDuni0ED0uni0ED1uni0ED2uni0ED3uni0ED4uni0ED5uni0ED6uni0ED7uni0ED8uni0ED9uni0EDCuni0EDDuni10A0uni10A1uni10A2uni10A3uni10A4uni10A5uni10A6uni10A7uni10A8uni10A9uni10AAuni10ABuni10ACuni10ADuni10AEuni10AFuni10B0uni10B1uni10B2uni10B3uni10B4uni10B5uni10B6uni10B7uni10B8uni10B9uni10BAuni10BBuni10BCuni10BDuni10BEuni10BFuni10C0uni10C1uni10C2uni10C3uni10C4uni10C5uni10D0uni10D1uni10D2uni10D3uni10D4uni10D5uni10D6uni10D7uni10D8uni10D9uni10DAuni10DBuni10DCuni10DDuni10DEuni10DFuni10E0uni10E1uni10E2uni10E3uni10E4uni10E5uni10E6uni10E7uni10E8uni10E9uni10EAuni10EBuni10ECuni10EDuni10EEuni10EFuni10F0uni10F1uni10F2uni10F3uni10F4uni10F5uni10F6uni10F7uni10F8uni10F9uni10FAuni10FBuni10FCuni1401uni1402uni1403uni1404uni1405uni1406uni1407uni1409uni140Auni140Buni140Cuni140Duni140Euni140Funi1410uni1411uni1412uni1413uni1414uni1415uni1416uni1417uni1418uni1419uni141Auni141Buni141Duni141Euni141Funi1420uni1421uni1422uni1423uni1424uni1425uni1426uni1427uni1428uni1429uni142Auni142Buni142Cuni142Duni142Euni142Funi1430uni1431uni1432uni1433uni1434uni1435uni1437uni1438uni1439uni143Auni143Buni143Cuni143Duni143Euni143Funi1440uni1441uni1442uni1443uni1444uni1445uni1446uni1447uni1448uni1449uni144Auni144Cuni144Duni144Euni144Funi1450uni1451uni1452uni1454uni1455uni1456uni1457uni1458uni1459uni145Auni145Buni145Cuni145Duni145Euni145Funi1460uni1461uni1462uni1463uni1464uni1465uni1466uni1467uni1468uni1469uni146Auni146Buni146Cuni146Duni146Euni146Funi1470uni1471uni1472uni1473uni1474uni1475uni1476uni1477uni1478uni1479uni147Auni147Buni147Cuni147Duni147Euni147Funi1480uni1481uni1482uni1483uni1484uni1485uni1486uni1487uni1488uni1489uni148Auni148Buni148Cuni148Duni148Euni148Funi1490uni1491uni1492uni1493uni1494uni1495uni1496uni1497uni1498uni1499uni149Auni149Buni149Cuni149Duni149Euni149Funi14A0uni14A1uni14A2uni14A3uni14A4uni14A5uni14A6uni14A7uni14A8uni14A9uni14AAuni14ABuni14ACuni14ADuni14AEuni14AFuni14B0uni14B1uni14B2uni14B3uni14B4uni14B5uni14B6uni14B7uni14B8uni14B9uni14BAuni14BBuni14BCuni14BDuni14C0uni14C1uni14C2uni14C3uni14C4uni14C5uni14C6uni14C7uni14C8uni14C9uni14CAuni14CBuni14CCuni14CDuni14CEuni14CFuni14D0uni14D1uni14D2uni14D3uni14D4uni14D5uni14D6uni14D7uni14D8uni14D9uni14DAuni14DBuni14DCuni14DDuni14DEuni14DFuni14E0uni14E1uni14E2uni14E3uni14E4uni14E5uni14E6uni14E7uni14E8uni14E9uni14EAuni14ECuni14EDuni14EEuni14EFuni14F0uni14F1uni14F2uni14F3uni14F4uni14F5uni14F6uni14F7uni14F8uni14F9uni14FAuni14FBuni14FCuni14FDuni14FEuni14FFuni1500uni1501uni1502uni1503uni1504uni1505uni1506uni1507uni1510uni1511uni1512uni1513uni1514uni1515uni1516uni1517uni1518uni1519uni151Auni151Buni151Cuni151Duni151Euni151Funi1520uni1521uni1522uni1523uni1524uni1525uni1526uni1527uni1528uni1529uni152Auni152Buni152Cuni152Duni152Euni152Funi1530uni1531uni1532uni1533uni1534uni1535uni1536uni1537uni1538uni1539uni153Auni153Buni153Cuni153Duni153Euni1540uni1541uni1542uni1543uni1544uni1545uni1546uni1547uni1548uni1549uni154Auni154Buni154Cuni154Duni154Euni154Funi1550uni1552uni1553uni1554uni1555uni1556uni1557uni1558uni1559uni155Auni155Buni155Cuni155Duni155Euni155Funi1560uni1561uni1562uni1563uni1564uni1565uni1566uni1567uni1568uni1569uni156Auni1574uni1575uni1576uni1577uni1578uni1579uni157Auni157Buni157Cuni157Duni157Euni157Funi1580uni1581uni1582uni1583uni1584uni1585uni158Auni158Buni158Cuni158Duni158Euni158Funi1590uni1591uni1592uni1593uni1594uni1595uni1596uni15A0uni15A1uni15A2uni15A3uni15A4uni15A5uni15A6uni15A7uni15A8uni15A9uni15AAuni15ABuni15ACuni15ADuni15AEuni15AFuni15DEuni15E1uni1646uni1647uni166Euni166Funi1670uni1671uni1672uni1673uni1674uni1675uni1676uni1680uni1681uni1682uni1683uni1684uni1685uni1686uni1687uni1688uni1689uni168Auni168Buni168Cuni168Duni168Euni168Funi1690uni1691uni1692uni1693uni1694uni1695uni1696uni1697uni1698uni1699uni169Auni169Buni169Cuni1D00uni1D01uni1D02uni1D03uni1D04uni1D05uni1D06uni1D07uni1D08uni1D09uni1D0Auni1D0Buni1D0Cuni1D0Duni1D0Euni1D0Funi1D10uni1D11uni1D12uni1D13uni1D14uni1D16uni1D17uni1D18uni1D19uni1D1Auni1D1Buni1D1Cuni1D1Duni1D1Euni1D1Funi1D20uni1D21uni1D22uni1D23uni1D26uni1D27uni1D28uni1D29uni1D2Auni1D2Buni1D2Cuni1D2Duni1D2Euni1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Duni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D5Duni1D5Euni1D5Funi1D60uni1D61uni1D62uni1D63uni1D64uni1D65uni1D66uni1D67uni1D68uni1D69uni1D6Auni1D77uni1D78uni1D7Buni1D85uni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB8uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1DC4uni1DC5uni1DC6uni1DC7uni1DC8uni1DC9uni1E00uni1E01uni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E3Euni1E3Funi1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7FWgravewgraveWacutewacute Wdieresis wdieresisuni1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1E9Euni1E9Funi1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1Ygraveygraveuni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200Buni200Cuni200Duni200Euni200Funi2010uni2011 figuredashuni2015uni2016 underscoredbl quotereverseduni201Funi2023onedotenleadertwodotenleaderuni2027uni202Auni202Buni202Cuni202Duni202Euni202Funi2031minuteseconduni2034uni2035uni2036uni2037uni2038uni203B exclamdbluni203Duni203Euni203Funi2040uni2041uni2042uni2043uni2045uni2046uni2047uni2048uni2049uni204Auni204Buni204Cuni204Duni204Euni204Funi2050uni2051uni2052uni2053uni2054uni2055uni2056uni2057uni2058uni2059uni205Auni205Buni205Cuni205Duni205Euni205Funi2060uni2061uni2062uni2063uni2064uni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2071uni2074uni2075uni2076uni2077uni2078uni2079uni207Auni207Buni207Cuni207Duni207Euni207Funi2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni208Auni208Buni208Cuni208Duni208Euni2090uni2091uni2092uni2093uni2094uni20A0 colonmonetaryuni20A2lirauni20A5uni20A6pesetauni20A8uni20A9uni20AAdongEurouni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20D0uni20D1uni20D6uni20D7uni20DBuni20DCuni20E1uni2100uni2101uni2102uni2103uni2104uni2105uni2106uni2107uni2108uni2109uni210Buni210Cuni210Duni210Euni210Funi2110Ifrakturuni2112uni2113uni2114uni2115uni2116uni2117 weierstrassuni2119uni211Auni211BRfrakturuni211D prescriptionuni211Funi2120uni2121uni2123uni2124uni2125uni2126uni2127uni2128uni2129uni212Auni212Buni212Cuni212D estimateduni212Funi2130uni2131uni2132uni2133uni2134alephuni2136uni2137uni2138uni2139uni213Auni213Buni213Cuni213Duni213Euni213Funi2140uni2141uni2142uni2143uni2144uni2145uni2146uni2147uni2148uni2149uni214Buni214Eonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217Funi2180uni2181uni2182uni2183uni2184 arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21A9uni21AAuni21ABuni21ACuni21ADuni21AEuni21AFuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CCuni21CDuni21CEuni21CF arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblbothuni21D5uni21D6uni21D7uni21D8uni21D9uni21DAuni21DBuni21DCuni21DDuni21DEuni21DFuni21E0uni21E1uni21E2uni21E3uni21E4uni21E5uni21E6uni21E7uni21E8uni21E9uni21EAuni21EBuni21ECuni21EDuni21EEuni21EFuni21F0uni21F1uni21F2uni21F3uni21F4uni21F5uni21F6uni21F7uni21F8uni21F9uni21FAuni21FBuni21FCuni21FDuni21FEuni21FF universaluni2201 existentialuni2204emptysetgradientelement notelementuni220Asuchthatuni220Cuni220Duni220Euni2210uni2213uni2214uni2215uni2216 asteriskmathuni2218uni2219uni221Buni221C proportional orthogonalangleuni2221uni2222uni2223uni2224uni2225uni2226 logicaland logicalor intersectionunionuni222Cuni222Duni222Euni222Funi2230uni2231uni2232uni2233 thereforeuni2235uni2236uni2237uni2238uni2239uni223Auni223Bsimilaruni223Duni223Euni223Funi2240uni2241uni2242uni2243uni2244 congruentuni2246uni2247uni2249uni224Auni224Buni224Cuni224Duni224Euni224Funi2250uni2251uni2252uni2253uni2254uni2255uni2256uni2257uni2258uni2259uni225Auni225Buni225Cuni225Duni225Euni225F equivalenceuni2262uni2263uni2266uni2267uni2268uni2269uni226Auni226Buni226Cuni226Duni226Euni226Funi2270uni2271uni2272uni2273uni2274uni2275uni2276uni2277uni2278uni2279uni227Auni227Buni227Cuni227Duni227Euni227Funi2280uni2281 propersubsetpropersuperset notsubsetuni2285 reflexsubsetreflexsupersetuni2288uni2289uni228Auni228Buni228Cuni228Duni228Euni228Funi2290uni2291uni2292uni2293uni2294 circleplusuni2296circlemultiplyuni2298uni2299uni229Auni229Buni229Cuni229Duni229Euni229Funi22A0uni22A1uni22A2uni22A3uni22A4 perpendicularuni22A6uni22A7uni22A8uni22A9uni22AAuni22ABuni22ACuni22ADuni22AEuni22AFuni22B0uni22B1uni22B2uni22B3uni22B4uni22B5uni22B6uni22B7uni22B8uni22B9uni22BAuni22BBuni22BCuni22BDuni22BEuni22BFuni22C0uni22C1uni22C2uni22C3uni22C4dotmathuni22C6uni22C7uni22C8uni22C9uni22CAuni22CBuni22CCuni22CDuni22CEuni22CFuni22D0uni22D1uni22D2uni22D3uni22D4uni22D5uni22D6uni22D7uni22D8uni22D9uni22DAuni22DBuni22DCuni22DDuni22DEuni22DFuni22E0uni22E1uni22E2uni22E3uni22E4uni22E5uni22E6uni22E7uni22E8uni22E9uni22EAuni22EBuni22ECuni22EDuni22EEuni22EFuni22F0uni22F1uni22F2uni22F3uni22F4uni22F5uni22F6uni22F7uni22F8uni22F9uni22FAuni22FBuni22FCuni22FDuni22FEuni22FFuni2300uni2301houseuni2303uni2304uni2305uni2306uni2307uni2308uni2309uni230Auni230Buni230Cuni230Duni230Euni230F revlogicalnotuni2311uni2318uni2319uni231Cuni231Duni231Euni231F integraltp integralbtuni2324uni2325uni2326uni2327uni2328uni232Buni232Cuni2373uni2374uni2375uni237Auni237Duni2387uni2394uni239Buni239Cuni239Duni239Euni239Funi23A0uni23A1uni23A2uni23A3uni23A4uni23A5uni23A6uni23A7uni23A8uni23A9uni23AAuni23ABuni23ACuni23ADuni23AEuni23CEuni23CFuni23E3uni23E5uni2422uni2423uni2460uni2461uni2462uni2463uni2464uni2465uni2466uni2467uni2468uni2469SF100000uni2501SF110000uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250BSF010000uni250Duni250Euni250FSF030000uni2511uni2512uni2513SF020000uni2515uni2516uni2517SF040000uni2519uni251Auni251BSF080000uni251Duni251Euni251Funi2520uni2521uni2522uni2523SF090000uni2525uni2526uni2527uni2528uni2529uni252Auni252BSF060000uni252Duni252Euni252Funi2530uni2531uni2532uni2533SF070000uni2535uni2536uni2537uni2538uni2539uni253Auni253BSF050000uni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254Buni254Cuni254Duni254Euni254FSF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000uni256Duni256Euni256Funi2570uni2571uni2572uni2573uni2574uni2575uni2576uni2577uni2578uni2579uni257Auni257Buni257Cuni257Duni257Euni257Fupblockuni2581uni2582uni2583dnblockuni2585uni2586uni2587blockuni2589uni258Auni258Blfblockuni258Duni258Euni258Frtblockltshadeshadedkshadeuni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259F filledboxH22073uni25A2uni25A3uni25A4uni25A5uni25A6uni25A7uni25A8uni25A9H18543H18551 filledrectuni25ADuni25AEuni25AFuni25B0uni25B1triagupuni25B3uni25B4uni25B5uni25B6uni25B7uni25B8uni25B9triagrtuni25BBtriagdnuni25BDuni25BEuni25BFuni25C0uni25C1uni25C2uni25C3triaglfuni25C5uni25C6uni25C7uni25C8uni25C9circleuni25CCuni25CDuni25CEH18533uni25D0uni25D1uni25D2uni25D3uni25D4uni25D5uni25D6uni25D7 invbullet invcircleuni25DAuni25DBuni25DCuni25DDuni25DEuni25DFuni25E0uni25E1uni25E2uni25E3uni25E4uni25E5 openbulletuni25E7uni25E8uni25E9uni25EAuni25EBuni25ECuni25EDuni25EEuni25EFuni25F0uni25F1uni25F2uni25F3uni25F4uni25F5uni25F6uni25F7uni25F8uni25F9uni25FAuni25FBuni25FCuni25FDuni25FEuni25FFuni2600uni2601uni2602uni2603uni2604uni2605uni2606uni2607uni2608uni2609uni260Auni260Buni260Cuni260Duni260Euni260Funi2610uni2611uni2612uni2613uni2614uni2615uni2616uni2617uni2618uni2619uni261Auni261Buni261Cuni261Duni261Euni261Funi2620uni2621uni2622uni2623uni2624uni2625uni2626uni2627uni2628uni2629uni262Auni262Buni262Cuni262Duni262Euni262Funi2630uni2631uni2632uni2633uni2634uni2635uni2636uni2637uni2638uni2639 smileface invsmilefacesununi263Duni263Euni263Ffemaleuni2641maleuni2643uni2644uni2645uni2646uni2647uni2648uni2649uni264Auni264Buni264Cuni264Duni264Euni264Funi2650uni2651uni2652uni2653uni2654uni2655uni2656uni2657uni2658uni2659uni265Auni265Buni265Cuni265Duni265Euni265Fspadeuni2661uni2662clubuni2664heartdiamonduni2667uni2668uni2669 musicalnotemusicalnotedbluni266Cuni266Duni266Euni266Funi2670uni2671uni2672uni2673uni2674uni2675uni2676uni2677uni2678uni2679uni267Auni267Buni267Cuni267Duni267Euni267Funi2680uni2681uni2682uni2683uni2684uni2685uni2686uni2687uni2688uni2689uni268Auni268Buni268Cuni268Duni268Euni268Funi2690uni2691uni2692uni2693uni2694uni2695uni2696uni2697uni2698uni2699uni269Auni269Buni269Cuni26A0uni26A1uni26A2uni26A3uni26A4uni26A5uni26A6uni26A7uni26A8uni26A9uni26AAuni26ABuni26ACuni26ADuni26AEuni26AFuni26B0uni26B1uni26B2uni26B3uni26B4uni26B5uni26B6uni26B7uni26B8uni2701uni2702uni2703uni2704uni2706uni2707uni2708uni2709uni270Cuni270Duni270Euni270Funi2710uni2711uni2712uni2713uni2714uni2715uni2716uni2717uni2718uni2719uni271Auni271Buni271Cuni271Duni271Euni271Funi2720uni2721uni2722uni2723uni2724uni2725uni2726uni2727uni2729uni272Auni272Buni272Cuni272Duni272Euni272Funi2730uni2731uni2732uni2733uni2734uni2735uni2736uni2737uni2738uni2739uni273Auni273Buni273Cuni273Duni273Euni273Funi2740uni2741uni2742uni2743uni2744uni2745uni2746uni2747uni2748uni2749uni274Auni274Buni274Duni274Funi2750uni2751uni2752uni2756uni2758uni2759uni275Auni275Buni275Cuni275Duni275Euni2761uni2762uni2763uni2764uni2765uni2766uni2767uni2768uni2769uni276Auni276Buni276Cuni276Duni276Euni276Funi2770uni2771uni2772uni2773uni2774uni2775uni2776uni2777uni2778uni2779uni277Auni277Buni277Cuni277Duni277Euni277Funi2780uni2781uni2782uni2783uni2784uni2785uni2786uni2787uni2788uni2789uni278Auni278Buni278Cuni278Duni278Euni278Funi2790uni2791uni2792uni2793uni2794uni2798uni2799uni279Auni279Buni279Cuni279Duni279Euni279Funi27A0uni27A1uni27A2uni27A3uni27A4uni27A5uni27A6uni27A7uni27A8uni27A9uni27AAuni27ABuni27ACuni27ADuni27AEuni27AFuni27B1uni27B2uni27B3uni27B4uni27B5uni27B6uni27B7uni27B8uni27B9uni27BAuni27BBuni27BCuni27BDuni27BEuni27C5uni27C6uni27E0uni27E6uni27E7uni27E8uni27E9uni27EAuni27EBuni27F0uni27F1uni27F2uni27F3uni27F4uni27F5uni27F6uni27F7uni27F8uni27F9uni27FAuni27FBuni27FCuni27FDuni27FEuni27FFuni2800uni2801uni2802uni2803uni2804uni2805uni2806uni2807uni2808uni2809uni280Auni280Buni280Cuni280Duni280Euni280Funi2810uni2811uni2812uni2813uni2814uni2815uni2816uni2817uni2818uni2819uni281Auni281Buni281Cuni281Duni281Euni281Funi2820uni2821uni2822uni2823uni2824uni2825uni2826uni2827uni2828uni2829uni282Auni282Buni282Cuni282Duni282Euni282Funi2830uni2831uni2832uni2833uni2834uni2835uni2836uni2837uni2838uni2839uni283Auni283Buni283Cuni283Duni283Euni283Funi2840uni2841uni2842uni2843uni2844uni2845uni2846uni2847uni2848uni2849uni284Auni284Buni284Cuni284Duni284Euni284Funi2850uni2851uni2852uni2853uni2854uni2855uni2856uni2857uni2858uni2859uni285Auni285Buni285Cuni285Duni285Euni285Funi2860uni2861uni2862uni2863uni2864uni2865uni2866uni2867uni2868uni2869uni286Auni286Buni286Cuni286Duni286Euni286Funi2870uni2871uni2872uni2873uni2874uni2875uni2876uni2877uni2878uni2879uni287Auni287Buni287Cuni287Duni287Euni287Funi2880uni2881uni2882uni2883uni2884uni2885uni2886uni2887uni2888uni2889uni288Auni288Buni288Cuni288Duni288Euni288Funi2890uni2891uni2892uni2893uni2894uni2895uni2896uni2897uni2898uni2899uni289Auni289Buni289Cuni289Duni289Euni289Funi28A0uni28A1uni28A2uni28A3uni28A4uni28A5uni28A6uni28A7uni28A8uni28A9uni28AAuni28ABuni28ACuni28ADuni28AEuni28AFuni28B0uni28B1uni28B2uni28B3uni28B4uni28B5uni28B6uni28B7uni28B8uni28B9uni28BAuni28BBuni28BCuni28BDuni28BEuni28BFuni28C0uni28C1uni28C2uni28C3uni28C4uni28C5uni28C6uni28C7uni28C8uni28C9uni28CAuni28CBuni28CCuni28CDuni28CEuni28CFuni28D0uni28D1uni28D2uni28D3uni28D4uni28D5uni28D6uni28D7uni28D8uni28D9uni28DAuni28DBuni28DCuni28DDuni28DEuni28DFuni28E0uni28E1uni28E2uni28E3uni28E4uni28E5uni28E6uni28E7uni28E8uni28E9uni28EAuni28EBuni28ECuni28EDuni28EEuni28EFuni28F0uni28F1uni28F2uni28F3uni28F4uni28F5uni28F6uni28F7uni28F8uni28F9uni28FAuni28FBuni28FCuni28FDuni28FEuni28FFuni2906uni2907uni290Auni290Buni2940uni2941uni2983uni2984uni29CEuni29CFuni29D0uni29D1uni29D2uni29D3uni29D4uni29D5uni29EBuni29FAuni29FBuni2A00uni2A01uni2A02uni2A0Cuni2A0Duni2A0Euni2A0Funi2A10uni2A11uni2A12uni2A13uni2A14uni2A15uni2A16uni2A17uni2A18uni2A19uni2A1Auni2A1Buni2A1Cuni2A2Funi2A7Duni2A7Euni2A7Funi2A80uni2A81uni2A82uni2A83uni2A84uni2A85uni2A86uni2A87uni2A88uni2A89uni2A8Auni2A8Buni2A8Cuni2A8Duni2A8Euni2A8Funi2A90uni2A91uni2A92uni2A93uni2A94uni2A95uni2A96uni2A97uni2A98uni2A99uni2A9Auni2A9Buni2A9Cuni2A9Duni2A9Euni2A9Funi2AA0uni2AAEuni2AAFuni2AB0uni2AB1uni2AB2uni2AB3uni2AB4uni2AB5uni2AB6uni2AB7uni2AB8uni2AB9uni2ABAuni2AF9uni2AFAuni2B00uni2B01uni2B02uni2B03uni2B04uni2B05uni2B06uni2B07uni2B08uni2B09uni2B0Auni2B0Buni2B0Cuni2B0Duni2B0Euni2B0Funi2B10uni2B11uni2B12uni2B13uni2B14uni2B15uni2B16uni2B17uni2B18uni2B19uni2B1Auni2B1Funi2B20uni2B21uni2B22uni2B23uni2B24uni2B53uni2B54uni2C60uni2C61uni2C62uni2C63uni2C64uni2C65uni2C66uni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C6Duni2C6Euni2C6Funi2C71uni2C72uni2C73uni2C74uni2C75uni2C76uni2C77uni2C79uni2C7Auni2C7Buni2C7Cuni2C7Duni2D30uni2D31uni2D32uni2D33uni2D34uni2D35uni2D36uni2D37uni2D38uni2D39uni2D3Auni2D3Buni2D3Cuni2D3Duni2D3Euni2D3Funi2D40uni2D41uni2D42uni2D43uni2D44uni2D45uni2D46uni2D47uni2D48uni2D49uni2D4Auni2D4Buni2D4Cuni2D4Duni2D4Euni2D4Funi2D50uni2D51uni2D52uni2D53uni2D54uni2D55uni2D56uni2D57uni2D58uni2D59uni2D5Auni2D5Buni2D5Cuni2D5Duni2D5Euni2D5Funi2D60uni2D61uni2D62uni2D63uni2D64uni2D65uni2D6Funi2E18uni2E22uni2E23uni2E24uni2E25uni2E2Euni4DC0uni4DC1uni4DC2uni4DC3uni4DC4uni4DC5uni4DC6uni4DC7uni4DC8uni4DC9uni4DCAuni4DCBuni4DCCuni4DCDuni4DCEuni4DCFuni4DD0uni4DD1uni4DD2uni4DD3uni4DD4uni4DD5uni4DD6uni4DD7uni4DD8uni4DD9uni4DDAuni4DDBuni4DDCuni4DDDuni4DDEuni4DDFuni4DE0uni4DE1uni4DE2uni4DE3uni4DE4uni4DE5uni4DE6uni4DE7uni4DE8uni4DE9uni4DEAuni4DEBuni4DECuni4DEDuni4DEEuni4DEFuni4DF0uni4DF1uni4DF2uni4DF3uni4DF4uni4DF5uni4DF6uni4DF7uni4DF8uni4DF9uni4DFAuni4DFBuni4DFCuni4DFDuni4DFEuni4DFFuniA644uniA645uniA646uniA647uniA64CuniA64DuniA650uniA651uniA654uniA655uniA656uniA657uniA662uniA663uniA664uniA665uniA666uniA667uniA668uniA669uniA66AuniA66BuniA66CuniA66DuniA66EuniA68AuniA68BuniA68CuniA68DuniA694uniA695uniA708uniA709uniA70AuniA70BuniA70CuniA70DuniA70EuniA70FuniA710uniA711uniA712uniA713uniA714uniA715uniA716uniA71BuniA71CuniA71DuniA71EuniA71FuniA726uniA727uniA728uniA729uniA72AuniA72BuniA730uniA731uniA732uniA733uniA734uniA735uniA736uniA737uniA738uniA739uniA73AuniA73BuniA73CuniA73DuniA73EuniA73FuniA746uniA747uniA748uniA749uniA74AuniA74BuniA74EuniA74FuniA780uniA781uniA782uniA783uniA789uniA78AuniA78BuniA78CuniA7FBuniA7FCuniA7FDuniA7FEuniA7FFuniF000uniF001uniF6C5uniFB00uniFB03uniFB04uniFB05uniFB06uniFB13uniFB14uniFB15uniFB16uniFB17uniFB1DuniFB1EuniFB1FuniFB20uniFB21uniFB22uniFB23uniFB24uniFB25uniFB26uniFB27uniFB28uniFB29uniFB2AuniFB2BuniFB2CuniFB2DuniFB2EuniFB2FuniFB30uniFB31uniFB32uniFB33uniFB34uniFB35uniFB36uniFB38uniFB39uniFB3AuniFB3BuniFB3CuniFB3EuniFB40uniFB41uniFB43uniFB44uniFB46uniFB47uniFB48uniFB49uniFB4AuniFB4BuniFB4CuniFB4DuniFB4EuniFB4FuniFB52uniFB53uniFB54uniFB55uniFB56uniFB57uniFB58uniFB59uniFB5AuniFB5BuniFB5CuniFB5DuniFB5EuniFB5FuniFB60uniFB61uniFB62uniFB63uniFB64uniFB65uniFB66uniFB67uniFB68uniFB69uniFB6AuniFB6BuniFB6CuniFB6DuniFB6EuniFB6FuniFB70uniFB71uniFB72uniFB73uniFB74uniFB75uniFB76uniFB77uniFB78uniFB79uniFB7AuniFB7BuniFB7CuniFB7DuniFB7EuniFB7FuniFB80uniFB81uniFB8AuniFB8BuniFB8CuniFB8DuniFB8EuniFB8FuniFB90uniFB91uniFB92uniFB93uniFB94uniFB95uniFB9EuniFB9FuniFBD9uniFBDAuniFBE8uniFBE9uniFBFCuniFBFDuniFBFEuniFBFFuniFE00uniFE01uniFE02uniFE03uniFE04uniFE05uniFE06uniFE07uniFE08uniFE09uniFE0AuniFE0BuniFE0CuniFE0DuniFE0EuniFE0FuniFE20uniFE21uniFE22uniFE23uniFE70uniFE71uniFE72uniFE73uniFE74uniFE76uniFE77uniFE78uniFE79uniFE7AuniFE7BuniFE7CuniFE7DuniFE7EuniFE7FuniFE80uniFE81uniFE82uniFE83uniFE84uniFE85uniFE86uniFE87uniFE88uniFE89uniFE8AuniFE8BuniFE8CuniFE8DuniFE8EuniFE8FuniFE90uniFE91uniFE92uniFE93uniFE94uniFE95uniFE96uniFE97uniFE98uniFE99uniFE9AuniFE9BuniFE9CuniFE9DuniFE9EuniFE9FuniFEA0uniFEA1uniFEA2uniFEA3uniFEA4uniFEA5uniFEA6uniFEA7uniFEA8uniFEA9uniFEAAuniFEABuniFEACuniFEADuniFEAEuniFEAFuniFEB0uniFEB1uniFEB2uniFEB3uniFEB4uniFEB5uniFEB6uniFEB7uniFEB8uniFEB9uniFEBAuniFEBBuniFEBCuniFEBDuniFEBEuniFEBFuniFEC0uniFEC1uniFEC2uniFEC3uniFEC4uniFEC5uniFEC6uniFEC7uniFEC8uniFEC9uniFECAuniFECBuniFECCuniFECDuniFECEuniFECFuniFED0uniFED1uniFED2uniFED3uniFED4uniFED5uniFED6uniFED7uniFED8uniFED9uniFEDAuniFEDBuniFEDCuniFEDDuniFEDEuniFEDFuniFEE0uniFEE1uniFEE2uniFEE3uniFEE4uniFEE5uniFEE6uniFEE7uniFEE8uniFEE9uniFEEAuniFEEBuniFEECuniFEEDuniFEEEuniFEEFuniFEF0uniFEF1uniFEF2uniFEF3uniFEF4uniFEF5uniFEF6uniFEF7uniFEF8uniFEF9uniFEFAuniFEFBuniFEFCuniFEFFuniFFF9uniFFFAuniFFFBuniFFFCuniFFFDu1D300u1D301u1D302u1D303u1D304u1D305u1D306u1D307u1D308u1D309u1D30Au1D30Bu1D30Cu1D30Du1D30Eu1D30Fu1D310u1D311u1D312u1D313u1D314u1D315u1D316u1D317u1D318u1D319u1D31Au1D31Bu1D31Cu1D31Du1D31Eu1D31Fu1D320u1D321u1D322u1D323u1D324u1D325u1D326u1D327u1D328u1D329u1D32Au1D32Bu1D32Cu1D32Du1D32Eu1D32Fu1D330u1D331u1D332u1D333u1D334u1D335u1D336u1D337u1D338u1D339u1D33Au1D33Bu1D33Cu1D33Du1D33Eu1D33Fu1D340u1D341u1D342u1D343u1D344u1D345u1D346u1D347u1D348u1D349u1D34Au1D34Bu1D34Cu1D34Du1D34Eu1D34Fu1D350u1D351u1D352u1D353u1D354u1D355u1D356u1D538u1D539u1D53Bu1D53Cu1D53Du1D53Eu1D540u1D541u1D542u1D543u1D544u1D546u1D54Au1D54Bu1D54Cu1D54Du1D54Eu1D54Fu1D550u1D552u1D553u1D554u1D555u1D556u1D557u1D558u1D559u1D55Au1D55Bu1D55Cu1D55Du1D55Eu1D55Fu1D560u1D561u1D562u1D563u1D564u1D565u1D566u1D567u1D568u1D569u1D56Au1D56Bu1D5A0u1D5A1u1D5A2u1D5A3u1D5A4u1D5A5u1D5A6u1D5A7u1D5A8u1D5A9u1D5AAu1D5ABu1D5ACu1D5ADu1D5AEu1D5AFu1D5B0u1D5B1u1D5B2u1D5B3u1D5B4u1D5B5u1D5B6u1D5B7u1D5B8u1D5B9u1D5BAu1D5BBu1D5BCu1D5BDu1D5BEu1D5BFu1D5C0u1D5C1u1D5C2u1D5C3u1D5C4u1D5C5u1D5C6u1D5C7u1D5C8u1D5C9u1D5CAu1D5CBu1D5CCu1D5CDu1D5CEu1D5CFu1D5D0u1D5D1u1D5D2u1D5D3u1D7D8u1D7D9u1D7DAu1D7DBu1D7DCu1D7DDu1D7DEu1D7DFu1D7E0u1D7E1u1D7E2u1D7E3u1D7E4u1D7E5u1D7E6u1D7E7u1D7E8u1D7E9u1D7EAu1D7EB dlLtcaronDieresisAcuteTildeGrave CircumflexCaron uni0311.caseBreve Dotaccent Hungarumlaut Doubleacute arabic_dot arabic_2dots arabic_3dotsarabic_3dots_aarabic_2dots_a arabic_4dots uni066E.fina uni066E.init uni066E.medi uni06A1.fina uni06A1.init uni06A1.medi uni066F.fina uni066F.init uni066F.medi uni06BA.init uni06BA.medi arabic_ring uni067C.fina uni067C.init uni067C.medi uni067D.fina uni067D.init uni067D.medi uni0681.fina uni0681.init uni0681.medi uni0682.fina uni0682.init uni0682.medi uni0685.fina uni0685.init uni0685.medi uni06BF.fina uni06BF.init uni06BF.mediarabic_gaf_barEng.altuni0268.dotlessuni029D.dotless uni03080304 uni03040308 uni03070304 uni03080301 uni03080300 uni03040301 uni03040300 uni03030304 uni0308030C uni03030308 uni030C0307 uni03030301 uni03020301 uni03020300 uni03020303 uni03060303 uni03060301 uni03060300 uni03060309 uni03020309 uni03010307 brailledotJ.alt uni0695.finauniFEAE.fina.longstart uni06B5.fina uni06B5.init uni06B5.medi uni06CE.fina uni06CE.init uni06CE.medi uni0692.final.alt uni06D5.finauni0478.monographuni0479.monographiogonek.dotlessuni2148.dotlessuni2149.dotlessuni1E2D.dotlessuni1ECB.dotlessdcoI.alt arrow.base uni0651064B uni0651064C uni064B0651 uni0651064E uni0651064F uni064E0651 uni0654064E uni0654064F uni07CA.fina uni07CA.medi uni07CA.init uni07CB.fina uni07CB.medi uni07CB.init uni07CC.fina uni07CC.medi uni07CC.init uni07CD.fina uni07CD.medi uni07CD.init uni07CE.fina uni07CE.medi uni07CE.init uni07CF.fina uni07CF.medi uni07CF.init uni07D0.fina uni07D0.medi uni07D0.init uni07D1.fina uni07D1.medi uni07D1.init uni07D2.fina uni07D2.medi uni07D2.init uni07D3.fina uni07D3.medi uni07D3.init uni07D4.fina uni07D4.medi uni07D4.init uni07D5.fina uni07D5.medi uni07D5.init uni07D6.fina uni07D6.medi uni07D6.init uni07D7.fina uni07D7.medi uni07D7.init uni07D8.fina uni07D8.medi uni07D8.init uni07D9.fina uni07D9.medi uni07D9.init uni07DA.fina uni07DA.medi uni07DA.init uni07DB.fina uni07DB.medi uni07DB.init uni07DC.fina uni07DC.medi uni07DC.init uni07DD.fina uni07DD.medi uni07DD.init uni07DE.fina uni07DE.medi uni07DE.init uni07DF.fina uni07DF.medi uni07DF.init uni07E0.fina uni07E0.medi uni07E0.init uni07E1.fina uni07E1.medi uni07E1.init uni07E2.fina uni07E2.medi uni07E2.init uni07E3.fina uni07E3.medi uni07E3.init uni07E4.fina uni07E4.medi uni07E4.init uni07E5.fina uni07E5.medi uni07E5.init uni07E6.fina uni07E6.medi uni07E6.init uni07E7.fina uni07E7.medi uni07E7.init Ringabove uni2630.alt uni2631.alt uni2632.alt uni2633.alt uni2634.alt uni2635.alt uni2636.alt uni2637.alt uni047E.diacuni048A.brevelessuni048B.brevelessy.alt uni02E5.5 uni02E6.5 uni02E7.5 uni02E8.5 uni02E9.5 uni02E5.4 uni02E6.4 uni02E7.4 uni02E8.4 uni02E9.4 uni02E5.3 uni02E6.3 uni02E7.3 uni02E8.3 uni02E9.3 uni02E5.2 uni02E6.2 uni02E7.2 uni02E8.2 uni02E9.2 uni02E5.1 uni02E6.1 uni02E7.1 uni02E8.1 uni02E9.1stem@%2%%A:B2SAS//2ݖ}ٻ֊A}G}G͖2ƅ%]%]@@%d%d%A2dA  d   A(]%]@%..%A  %d%@~}}~}}|d{T{%zyxw v utsrqponl!kjBjSih}gBfedcba:`^ ][ZYX YX WW2VUTUBTSSRQJQP ONMNMLKJKJIJI IH GFEDC-CBAK@?>=>=<=<; <@; :987876765 65 43 21 21 0/ 0 / .- .- ,2+*%+d*)*%)('%(A'%&% &% $#"!! d d BBBdB-B}d       -d@--d++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++allegro-5.0.10/examples/data/cursor.tga0000644000175000001440000000064011057522251017147 0ustar tjadenusers  TRUEVISION-XFILE.allegro-5.0.10/examples/data/DejaVuSans.LICENSE0000644000175000001440000001132011537247274020155 0ustar tjadenusersFonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Arev Fonts Copyright ------------------------------ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr. $Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ allegro-5.0.10/examples/ex_utf8.c0000644000175000001440000010311712152725670015764 0ustar tjadenusers/* * Example program for the Allegro library. * * Test UTF-8 string routines. */ /* TODO: we should also be checking on inputs with surrogate characters * (which are not allowed) */ #include #include #include #include #include "common.c" #ifdef ALLEGRO_MSVC #pragma warning (disable: 4066) #endif /* Some unicode characters */ #define U_ae 0x00e6 /* æ */ #define U_i_acute 0x00ed /* í */ #define U_eth 0x00f0 /* ð */ #define U_o_dia 0x00f6 /* ö */ #define U_thorn 0x00fe /* þ */ #define U_z_bar 0x01b6 /* ƶ */ #define U_schwa 0x0259 /* ə */ #define U_beta 0x03b2 /* β */ #define U_1d08 0x1d08 /* ᴈ */ #define U_1ff7 0x1ff7 /* ῷ */ #define U_2051 0x2051 /* ⁑ */ #define U_euro 0x20ac /* € */ typedef void (*test_t)(void); int error = 0; #define CHECK(x) \ do { \ bool ok = (x); \ if (!ok) { \ log_printf("FAIL %s\n", #x); \ error++; \ } else { \ log_printf("OK %s\n", #x); \ } \ } while (0) /* Test that we can create and destroy strings and get their data and size. */ static void t1(void) { ALLEGRO_USTR *us1 = al_ustr_new(""); ALLEGRO_USTR *us2 = al_ustr_new("áƵ"); CHECK(0 == strcmp(al_cstr(us1), "")); CHECK(0 == strcmp(al_cstr(us2), "áƵ")); CHECK(4 == al_ustr_size(us2)); al_ustr_free(us1); al_ustr_free(us2); } static void t2(void) { CHECK(0 == al_ustr_size(al_ustr_empty_string())); CHECK(0 == strcmp(al_cstr(al_ustr_empty_string()), "")); } /* Test that we make strings which reference other C strings. */ /* No memory needs to be freed. */ static void t3(void) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_cstr(&info, "A static string."); CHECK(0 == strcmp(al_cstr(us), "A static string.")); } /* Test that we can make strings which reference arbitrary memory blocks. */ /* No memory needs to be freed. */ static void t4(void) { const char s[] = "This contains an embedded NUL: \0 <-- here"; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, s, sizeof(s)); CHECK(al_ustr_size(us) == sizeof(s)); CHECK(0 == memcmp(al_cstr(us), s, sizeof(s))); } /* Test that we can make strings which reference (parts of) other strings. */ static void t5(void) { ALLEGRO_USTR *us1; const ALLEGRO_USTR *us2; ALLEGRO_USTR_INFO us2_info; us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); us2 = al_ref_ustr(&us2_info, us1, 36, 36 + 4); CHECK(0 == memcmp(al_cstr(us2), "þæ", al_ustr_size(us2))); /* Start pos underflow */ us2 = al_ref_ustr(&us2_info, us1, -10, 7); CHECK(0 == memcmp(al_cstr(us2), "aábdð", al_ustr_size(us2))); /* End pos overflow */ us2 = al_ref_ustr(&us2_info, us1, 36, INT_MAX); CHECK(0 == memcmp(al_cstr(us2), "þæö", al_ustr_size(us2))); /* Start > end */ us2 = al_ref_ustr(&us2_info, us1, 36 + 4, 36); CHECK(0 == al_ustr_size(us2)); al_ustr_free(us1); } /* Test al_ustr_dup. */ static void t6(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); ALLEGRO_USTR *us2 = al_ustr_dup(us1); CHECK(al_ustr_size(us1) == al_ustr_size(us2)); CHECK(0 == memcmp(al_cstr(us1), al_cstr(us2), al_ustr_size(us1))); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_dup_substr. */ static void t7(void) { ALLEGRO_USTR *us1; ALLEGRO_USTR *us2; us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); /* Cut out part of a string. Check for NUL terminator. */ us2 = al_ustr_dup_substr(us1, 36, 36 + 4); CHECK(al_ustr_size(us2) == 4); CHECK(0 == strcmp(al_cstr(us2), "þæ")); al_ustr_free(us2); /* Under and overflow */ us2 = al_ustr_dup_substr(us1, INT_MIN, INT_MAX); CHECK(al_ustr_size(us2) == al_ustr_size(us1)); CHECK(0 == strcmp(al_cstr(us2), al_cstr(us1))); al_ustr_free(us2); /* Start > end */ us2 = al_ustr_dup_substr(us1, INT_MAX, INT_MIN); CHECK(0 == al_ustr_size(us2)); al_ustr_free(us2); al_ustr_free(us1); } /* Test al_ustr_append, al_ustr_append_cstr. */ static void t8(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjklm"); ALLEGRO_USTR *us2 = al_ustr_new("noóprstuú"); CHECK(al_ustr_append(us1, us2)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuú")); CHECK(al_ustr_append_cstr(us1, "vxyýþæö")); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuúvxyýþæö")); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_append with aliased strings. */ static void t9(void) { ALLEGRO_USTR *us1; ALLEGRO_USTR_INFO us2_info; const ALLEGRO_USTR *us2; /* Append a string to itself. */ us1 = al_ustr_new("aábdðeéfghiíjklm"); CHECK(al_ustr_append(us1, us1)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmaábdðeéfghiíjklm")); al_ustr_free(us1); /* Append a substring of a string to itself. */ us1 = al_ustr_new("aábdðeéfghiíjklm"); us2 = al_ref_ustr(&us2_info, us1, 5, 5 + 11); /* ð...í */ CHECK(al_ustr_append(us1, us2)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmðeéfghií")); al_ustr_free(us1); } /* Test al_ustr_equal. */ static void t10(void) { ALLEGRO_USTR *us1; ALLEGRO_USTR *us2; const ALLEGRO_USTR *us3; ALLEGRO_USTR_INFO us3_info; const char us3_data[] = "aábdð\0eéfgh"; us1 = al_ustr_new("aábdð"); us2 = al_ustr_dup(us1); us3 = al_ref_buffer(&us3_info, us3_data, sizeof(us3_data)); CHECK(al_ustr_equal(us1, us2)); CHECK(!al_ustr_equal(us1, al_ustr_empty_string())); /* Check comparison doesn't stop at embedded NUL. */ CHECK(!al_ustr_equal(us1, us3)); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_insert. */ static void t11(void) { ALLEGRO_USTR *us1; ALLEGRO_USTR *us2; size_t sz; /* Insert in middle. */ us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); us2 = al_ustr_new("lmnoó"); al_ustr_insert(us1, 18, us2); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuúvxyýþæö")); /* Insert into itself. */ al_ustr_insert(us2, 3, us2); CHECK(0 == strcmp(al_cstr(us2), "lmnlmnoóoó")); /* Insert before start (not allowed). */ CHECK(!al_ustr_insert(us2, -1, us2)); /* Insert past end (will be padded with NULs). */ sz = al_ustr_size(us2); al_ustr_insert(us2, sz + 3, us2); CHECK(al_ustr_size(us2) == sz + sz + 3); CHECK(0 == memcmp(al_cstr(us2), "lmnlmnoóoó\0\0\0lmnlmnoóoó", sz + sz + 3)); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_insert_cstr. */ static void t12(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábeéf"); CHECK(al_ustr_insert_cstr(us1, 4, "dð")); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéf")); al_ustr_free(us1); } /* Test al_ustr_remove_range. */ static void t13(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); /* Remove from middle of string. */ CHECK(al_ustr_remove_range(us1, 5, 30)); CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); /* Removing past end. */ CHECK(al_ustr_remove_range(us1, 100, 120)); CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); /* Start > End. */ CHECK(! al_ustr_remove_range(us1, 3, 0)); CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); al_ustr_free(us1); } /* Test al_ustr_truncate. */ static void t14(void) { ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); /* Truncate from middle of string. */ CHECK(al_ustr_truncate(us1, 30)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); /* Truncate past end (allowed). */ CHECK(al_ustr_truncate(us1, 100)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); /* Truncate before start (not allowed). */ CHECK(! al_ustr_truncate(us1, -1)); CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); al_ustr_free(us1); } /* Test whitespace trim functions. */ static void t15(void) { ALLEGRO_USTR *us1 = al_ustr_new(" \f\n\r\t\vhello \f\n\r\t\v"); ALLEGRO_USTR *us2 = al_ustr_new(" \f\n\r\t\vhello \f\n\r\t\v"); CHECK(al_ustr_ltrim_ws(us1)); CHECK(0 == strcmp(al_cstr(us1), "hello \f\n\r\t\v")); CHECK(al_ustr_rtrim_ws(us1)); CHECK(0 == strcmp(al_cstr(us1), "hello")); CHECK(al_ustr_trim_ws(us2)); CHECK(0 == strcmp(al_cstr(us2), "hello")); al_ustr_free(us1); al_ustr_free(us2); } /* Test whitespace trim functions (edge cases). */ static void t16(void) { ALLEGRO_USTR *us1; /* Check return value when passed empty strings. */ us1 = al_ustr_new(""); CHECK(al_ustr_ltrim_ws(us1)); CHECK(al_ustr_rtrim_ws(us1)); CHECK(al_ustr_trim_ws(us1)); al_ustr_free(us1); /* Check nothing bad happens if the whole string is whitespace. */ us1 = al_ustr_new(" \f\n\r\t\v"); CHECK(al_ustr_ltrim_ws(us1)); CHECK(al_ustr_size(us1) == 0); al_ustr_free(us1); us1 = al_ustr_new(" \f\n\r\t\v"); CHECK(al_ustr_rtrim_ws(us1)); CHECK(al_ustr_size(us1) == 0); al_ustr_free(us1); us1 = al_ustr_new(" \f\n\r\t\v"); CHECK(al_ustr_trim_ws(us1)); CHECK(al_ustr_size(us1) == 0); al_ustr_free(us1); } /* Test al_utf8_width. */ static void t17(void) { CHECK(al_utf8_width(0x000000) == 1); CHECK(al_utf8_width(0x00007f) == 1); CHECK(al_utf8_width(0x000080) == 2); CHECK(al_utf8_width(0x0007ff) == 2); CHECK(al_utf8_width(0x000800) == 3); CHECK(al_utf8_width(0x00ffff) == 3); CHECK(al_utf8_width(0x010000) == 4); CHECK(al_utf8_width(0x10ffff) == 4); /* These are illegal. */ CHECK(al_utf8_width(0x110000) == 0); CHECK(al_utf8_width(0xffffff) == 0); } /* Test al_utf8_encode. */ static void t18(void) { char buf[4]; CHECK(al_utf8_encode(buf, 0) == 1); CHECK(0 == memcmp(buf, "\x00", 1)); CHECK(al_utf8_encode(buf, 0x7f) == 1); CHECK(0 == memcmp(buf, "\x7f", 1)); CHECK(al_utf8_encode(buf, 0x80) == 2); CHECK(0 == memcmp(buf, "\xC2\x80", 2)); CHECK(al_utf8_encode(buf, 0x7ff) == 2); CHECK(0 == memcmp(buf, "\xDF\xBF", 2)); CHECK(al_utf8_encode(buf, 0x000800) == 3); CHECK(0 == memcmp(buf, "\xE0\xA0\x80", 3)); CHECK(al_utf8_encode(buf, 0x00ffff) == 3); CHECK(0 == memcmp(buf, "\xEF\xBF\xBF", 3)); CHECK(al_utf8_encode(buf, 0x010000) == 4); CHECK(0 == memcmp(buf, "\xF0\x90\x80\x80", 4)); CHECK(al_utf8_encode(buf, 0x10ffff) == 4); CHECK(0 == memcmp(buf, "\xF4\x8f\xBF\xBF", 4)); /* These are illegal. */ CHECK(al_utf8_encode(buf, 0x110000) == 0); CHECK(al_utf8_encode(buf, 0xffffff) == 0); } /* Test al_ustr_insert_chr. */ static void t19(void) { ALLEGRO_USTR *us = al_ustr_new(""); CHECK(al_ustr_insert_chr(us, 0, 'a') == 1); CHECK(al_ustr_insert_chr(us, 0, U_ae) == 2); CHECK(al_ustr_insert_chr(us, 2, U_euro) == 3); CHECK(0 == strcmp(al_cstr(us), "æ€a")); /* Past end. */ CHECK(al_ustr_insert_chr(us, 8, U_o_dia) == 2); CHECK(0 == memcmp(al_cstr(us), "æ€a\0\0ö", 9)); /* Invalid code points. */ CHECK(al_ustr_insert_chr(us, 0, -1) == 0); CHECK(al_ustr_insert_chr(us, 0, 0x110000) == 0); al_ustr_free(us); } /* Test al_ustr_append_chr. */ static void t20(void) { ALLEGRO_USTR *us = al_ustr_new(""); CHECK(al_ustr_append_chr(us, 'a') == 1); CHECK(al_ustr_append_chr(us, U_ae) == 2); CHECK(al_ustr_append_chr(us, U_euro) == 3); CHECK(0 == strcmp(al_cstr(us), "aæ€")); /* Invalid code points. */ CHECK(al_ustr_append_chr(us, -1) == 0); CHECK(al_ustr_append_chr(us, 0x110000) == 0); al_ustr_free(us); } /* Test al_ustr_get. */ static void t21(void) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us; us = al_ref_buffer(&info, "", 1); CHECK(al_ustr_get(us, 0) == 0); us = al_ref_cstr(&info, "\x7f"); CHECK(al_ustr_get(us, 0) == 0x7f); us = al_ref_cstr(&info, "\xC2\x80"); CHECK(al_ustr_get(us, 0) == 0x80); us = al_ref_cstr(&info, "\xDF\xBf"); CHECK(al_ustr_get(us, 0) == 0x7ff); us = al_ref_cstr(&info, "\xE0\xA0\x80"); CHECK(al_ustr_get(us, 0) == 0x800); us = al_ref_cstr(&info, "\xEF\xBF\xBF"); CHECK(al_ustr_get(us, 0) == 0xffff); us = al_ref_cstr(&info, "\xF0\x90\x80\x80"); CHECK(al_ustr_get(us, 0) == 0x010000); us = al_ref_cstr(&info, "\xF4\x8F\xBF\xBF"); CHECK(al_ustr_get(us, 0) == 0x10ffff); } /* Test al_ustr_get on invalid sequences. */ static void t22(void) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us; /* Empty string. */ al_set_errno(0); CHECK(al_ustr_get(al_ustr_empty_string(), 0) < 0); CHECK(al_get_errno() == ERANGE); /* 5-byte sequence. */ us = al_ref_cstr(&info, "\xf8\x88\x80\x80\x80"); al_set_errno(0); CHECK(al_ustr_get(us, 0) < 0); CHECK(al_get_errno() == EILSEQ); /* Start in trail byte. */ us = al_ref_cstr(&info, "ð"); al_set_errno(0); CHECK(al_ustr_get(us, 1) < 0); CHECK(al_get_errno() == EILSEQ); /* Truncated 3-byte sequence. */ us = al_ref_cstr(&info, "\xEF\xBF"); al_set_errno(0); CHECK(al_ustr_get(us, 0) < 0); CHECK(al_get_errno() == EILSEQ); } /* Test al_ustr_get on invalid sequences (part 2). */ /* Get more ideas for tests from * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */ static void t23(void) { ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us; /* Examples of an overlong ASCII character */ us = al_ref_cstr(&info, "\xc0\xaf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xe0\x80\xaf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf0\x80\x80\xaf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf8\x80\x80\x80\xaf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80\xaf"); CHECK(al_ustr_get(us, 0) < 0); /* Maximum overlong sequences */ us = al_ref_cstr(&info, "\xc1\xbf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xe0\x9f\xbf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf0\x8f\xbf\xbf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf8\x87\xbf\xbf\xbf"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xfc\x83\xbf\xbf\xbf\xbf"); CHECK(al_ustr_get(us, 0) < 0); /* Overlong representation of the NUL character */ us = al_ref_cstr(&info, "\xc0\x80"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xe0\x80\x80"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf0\x80\x80"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xf8\x80\x80\x80"); CHECK(al_ustr_get(us, 0) < 0); us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80"); CHECK(al_ustr_get(us, 0) < 0); } /* Test al_ustr_next. */ static void t24(void) { const char str[] = "a\0þ€\xf4\x8f\xbf\xbf"; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); int pos = 0; CHECK(al_ustr_next(us, &pos)); /* a */ CHECK(pos == 1); CHECK(al_ustr_next(us, &pos)); /* NUL */ CHECK(pos == 2); CHECK(al_ustr_next(us, &pos)); /* þ */ CHECK(pos == 4); CHECK(al_ustr_next(us, &pos)); /* € */ CHECK(pos == 7); CHECK(al_ustr_next(us, &pos)); /* U+10FFFF */ CHECK(pos == 11); CHECK(! al_ustr_next(us, &pos)); /* end */ CHECK(pos == 11); } /* Test al_ustr_next with invalid input. */ static void t25(void) { const char str[] = "þ\xf4\x8f\xbf."; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); int pos; /* Starting in middle of a sequence. */ pos = 1; CHECK(al_ustr_next(us, &pos)); CHECK(pos == 2); /* Unexpected end of 4-byte sequence. */ CHECK(al_ustr_next(us, &pos)); CHECK(pos == 5); } /* Test al_ustr_prev. */ static void t26(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); int pos = al_ustr_size(us); CHECK(al_ustr_prev(us, &pos)); /* U+10FFFF */ CHECK(pos == 6); CHECK(al_ustr_prev(us, &pos)); /* € */ CHECK(pos == 3); CHECK(al_ustr_prev(us, &pos)); /* þ */ CHECK(pos == 1); CHECK(al_ustr_prev(us, &pos)); /* a */ CHECK(pos == 0); CHECK(!al_ustr_prev(us, &pos)); /* begin */ CHECK(pos == 0); al_ustr_free(us); } /* Test al_ustr_length. */ static void t27(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); CHECK(0 == al_ustr_length(al_ustr_empty_string())); CHECK(4 == al_ustr_length(us)); al_ustr_free(us); } /* Test al_ustr_offset. */ static void t28(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); CHECK(al_ustr_offset(us, 0) == 0); CHECK(al_ustr_offset(us, 1) == 1); CHECK(al_ustr_offset(us, 2) == 3); CHECK(al_ustr_offset(us, 3) == 6); CHECK(al_ustr_offset(us, 4) == 10); CHECK(al_ustr_offset(us, 5) == 10); CHECK(al_ustr_offset(us, -1) == 6); CHECK(al_ustr_offset(us, -2) == 3); CHECK(al_ustr_offset(us, -3) == 1); CHECK(al_ustr_offset(us, -4) == 0); CHECK(al_ustr_offset(us, -5) == 0); al_ustr_free(us); } /* Test al_ustr_get_next. */ static void t29(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€"); int pos; pos = 0; CHECK(al_ustr_get_next(us, &pos) == 'a'); CHECK(al_ustr_get_next(us, &pos) == U_thorn); CHECK(al_ustr_get_next(us, &pos) == U_euro); CHECK(al_ustr_get_next(us, &pos) == -1); CHECK(pos == (int) al_ustr_size(us)); /* Start in the middle of þ. */ pos = 2; CHECK(al_ustr_get_next(us, &pos) == -2); CHECK(al_ustr_get_next(us, &pos) == U_euro); al_ustr_free(us); } /* Test al_ustr_prev_get. */ static void t30(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€"); int pos; pos = al_ustr_size(us); CHECK(al_ustr_prev_get(us, &pos) == U_euro); CHECK(al_ustr_prev_get(us, &pos) == U_thorn); CHECK(al_ustr_prev_get(us, &pos) == 'a'); CHECK(al_ustr_prev_get(us, &pos) == -1); /* Start in the middle of þ. */ pos = 2; CHECK(al_ustr_prev_get(us, &pos) == U_thorn); al_ustr_free(us); } /* Test al_ustr_find_chr. */ static void t31(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); /* Find ASCII. */ CHECK(al_ustr_find_chr(us, 0, 'e') == 7); CHECK(al_ustr_find_chr(us, 7, 'e') == 7); /* start_pos is inclusive */ CHECK(al_ustr_find_chr(us, 8, 'e') == 23); CHECK(al_ustr_find_chr(us, 0, '.') == -1); /* Find non-ASCII. */ CHECK(al_ustr_find_chr(us, 0, U_eth) == 5); CHECK(al_ustr_find_chr(us, 5, U_eth) == 5); /* start_pos is inclusive */ CHECK(al_ustr_find_chr(us, 6, U_eth) == 21); CHECK(al_ustr_find_chr(us, 0, U_z_bar) == -1); al_ustr_free(us); } /* Test al_ustr_rfind_chr. */ static void t32(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); int end = al_ustr_size(us); /* Find ASCII. */ CHECK(al_ustr_rfind_chr(us, end, 'e') == 23); CHECK(al_ustr_rfind_chr(us, 23, 'e') == 7); /* end_pos exclusive */ CHECK(al_ustr_rfind_chr(us, end, '.') == -1); /* Find non-ASCII. */ CHECK(al_ustr_rfind_chr(us, end, U_i_acute) == 30); CHECK(al_ustr_rfind_chr(us, end - 1, U_i_acute) == 14); /* end_pos exclusive */ CHECK(al_ustr_rfind_chr(us, end, U_z_bar) == -1); al_ustr_free(us); } /* Test al_ustr_find_set, al_ustr_find_set_cstr. */ static void t33(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); /* al_ustr_find_set_cstr is s simple wrapper for al_ustr_find_set * so we test using that. */ /* Find ASCII. */ CHECK(al_ustr_find_set_cstr(us, 0, "gfe") == 7); CHECK(al_ustr_find_set_cstr(us, 7, "gfe") == 7); /* start_pos inclusive */ CHECK(al_ustr_find_set_cstr(us, 0, "") == -1); CHECK(al_ustr_find_set_cstr(us, 0, "xyz") == -1); /* Find non-ASCII. */ CHECK(al_ustr_find_set_cstr(us, 0, "éðf") == 5); CHECK(al_ustr_find_set_cstr(us, 5, "éðf") == 5); /* start_pos inclusive */ CHECK(al_ustr_find_set_cstr(us, 0, "ẋỹƶ") == -1); al_ustr_free(us); } /* Test al_ustr_find_set, al_ustr_find_set_cstr (invalid values). */ static void t34(void) { ALLEGRO_USTR *us = al_ustr_new("a\x80ábdðeéfghií"); /* Invalid byte sequence in search string. */ CHECK(al_ustr_find_set_cstr(us, 0, "gfe") == 8); /* Invalid byte sequence in accept set. */ CHECK(al_ustr_find_set_cstr(us, 0, "é\x80ðf") == 6); al_ustr_free(us); } /* Test al_ustr_find_cset, al_ustr_find_cset_cstr. */ static void t35(void) { ALLEGRO_USTR *us; /* al_ustr_find_cset_cstr is s simple wrapper for al_ustr_find_cset * so we test using that. */ /* Find ASCII. */ us = al_ustr_new("alphabetagamma"); CHECK(al_ustr_find_cset_cstr(us, 0, "alphbet") == 9); CHECK(al_ustr_find_cset_cstr(us, 9, "alphbet") == 9); CHECK(al_ustr_find_cset_cstr(us, 0, "") == -1); CHECK(al_ustr_find_cset_cstr(us, 0, "alphbetgm") == -1); al_ustr_free(us); /* Find non-ASCII. */ us = al_ustr_new("αλφαβεταγαμμα"); CHECK(al_ustr_find_cset_cstr(us, 0, "αλφβετ") == 16); CHECK(al_ustr_find_cset_cstr(us, 16, "αλφβετ") == 16); CHECK(al_ustr_find_cset_cstr(us, 0, "αλφβετγμ") == -1); al_ustr_free(us); } /* Test al_ustr_find_cset, al_ustr_find_set_cstr (invalid values). */ static void t36(void) { ALLEGRO_USTR *us = al_ustr_new("a\x80ábdðeéfghií"); /* Invalid byte sequence in search string. */ CHECK(al_ustr_find_cset_cstr(us, 0, "aábd") == 6); /* Invalid byte sequence in reject set. */ CHECK(al_ustr_find_cset_cstr(us, 0, "a\x80ábd") == 6); al_ustr_free(us); } /* Test al_ustr_find_str, al_ustr_find_cstr. */ static void t37(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); /* al_ustr_find_cstr is s simple wrapper for al_ustr_find_str * so we test using that. */ CHECK(al_ustr_find_cstr(us, 0, "") == 0); CHECK(al_ustr_find_cstr(us, 10, "") == 10); CHECK(al_ustr_find_cstr(us, 0, "ábd") == 1); CHECK(al_ustr_find_cstr(us, 10, "ábd") == 17); CHECK(al_ustr_find_cstr(us, 0, "ábz") == -1); al_ustr_free(us); } /* Test al_ustr_rfind_str, al_ustr_rfind_cstr. */ static void t38(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); int end = al_ustr_size(us); /* al_ustr_find_cstr is s simple wrapper for al_ustr_find_str * so we test using that. */ CHECK(al_ustr_rfind_cstr(us, 0, "") == 0); CHECK(al_ustr_rfind_cstr(us, 1, "") == 1); CHECK(al_ustr_rfind_cstr(us, end, "hií") == end - 4); CHECK(al_ustr_rfind_cstr(us, end - 1, "hií") == 12); CHECK(al_ustr_rfind_cstr(us, end, "ábz") == -1); al_ustr_free(us); } /* Test al_ustr_new_from_buffer, al_cstr_dup. */ static void t39(void) { const char s1[] = "Корабът ми на въздушна възглавница\0е пълен със змиорки"; ALLEGRO_USTR *us; char *s2; us = al_ustr_new_from_buffer(s1, sizeof(s1) - 1); /* missing NUL term. */ s2 = al_cstr_dup(us); al_ustr_free(us); CHECK(0 == strcmp(s1, s2)); CHECK(0 == memcmp(s1, s2, sizeof(s1))); /* including NUL terminator */ al_free(s2); } /* Test al_ustr_assign, al_ustr_assign_cstr. */ static void t40(void) { ALLEGRO_USTR *us1 = al_ustr_new("我隻氣墊船裝滿晒鱔"); ALLEGRO_USTR *us2 = al_ustr_new("Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια"); CHECK(al_ustr_assign(us1, us2)); CHECK(0 == strcmp(al_cstr(us1), "Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια")); CHECK(al_ustr_assign_cstr(us1, "私のホバークラフトは鰻でいっぱいです")); CHECK(54 == al_ustr_size(us1)); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_assign_cstr. */ static void t41(void) { ALLEGRO_USTR *us1 = al_ustr_new("Моја лебдилица је пуна јегуља"); ALLEGRO_USTR *us2 = al_ustr_new(""); CHECK(al_ustr_assign_substr(us2, us1, 9, 27)); CHECK(0 == strcmp(al_cstr(us2), "лебдилица")); /* Start > End */ CHECK(al_ustr_assign_substr(us2, us1, 9, 0)); CHECK(0 == strcmp(al_cstr(us2), "")); /* Start, end out of bounds */ CHECK(al_ustr_assign_substr(us2, us1, -INT_MAX, INT_MAX)); CHECK(0 == strcmp(al_cstr(us2), "Моја лебдилица је пуна јегуља")); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_set_chr. */ static void t42(void) { ALLEGRO_USTR *us = al_ustr_new("abcdef"); /* Same size (ASCII). */ CHECK(al_ustr_set_chr(us, 1, 'B') == 1); CHECK(0 == strcmp(al_cstr(us), "aBcdef")); CHECK(6 == al_ustr_size(us)); /* Enlarge to 2-bytes. */ CHECK(al_ustr_set_chr(us, 1, U_beta) == 2); CHECK(0 == strcmp(al_cstr(us), "aβcdef")); CHECK(7 == al_ustr_size(us)); /* Enlarge to 3-bytes. */ CHECK(al_ustr_set_chr(us, 5, U_1d08) == 3); CHECK(0 == strcmp(al_cstr(us), "aβcdᴈf")); CHECK(9 == al_ustr_size(us)); /* Reduce to 2-bytes. */ CHECK(al_ustr_set_chr(us, 5, U_schwa) == 2); CHECK(0 == strcmp(al_cstr(us), "aβcdəf")); CHECK(8 == al_ustr_size(us)); /* Set at end of string. */ CHECK(al_ustr_set_chr(us, al_ustr_size(us), U_1ff7) == 3); CHECK(0 == strcmp(al_cstr(us), "aβcdəfῷ")); CHECK(11 == al_ustr_size(us)); /* Set past end of string. */ CHECK(al_ustr_set_chr(us, al_ustr_size(us) + 2, U_2051) == 3); CHECK(0 == memcmp(al_cstr(us), "aβcdəfῷ\0\0⁑", 16)); CHECK(16 == al_ustr_size(us)); /* Set before start of string (not allowed). */ CHECK(al_ustr_set_chr(us, -1, U_2051) == 0); CHECK(16 == al_ustr_size(us)); al_ustr_free(us); } /* Test al_ustr_remove_chr. */ static void t43(void) { ALLEGRO_USTR *us = al_ustr_new("«aβῷ»"); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«βῷ»")); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«ῷ»")); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«»")); /* Not at beginning of code point. */ CHECK(! al_ustr_remove_chr(us, 1)); /* Out of bounds. */ CHECK(! al_ustr_remove_chr(us, -1)); CHECK(! al_ustr_remove_chr(us, al_ustr_size(us))); al_ustr_free(us); } /* Test al_ustr_replace_range. */ static void t44(void) { ALLEGRO_USTR *us1 = al_ustr_new("Šis kungs par visu samaksās"); ALLEGRO_USTR *us2 = al_ustr_new("ī kundze"); CHECK(al_ustr_replace_range(us1, 2, 10, us2)); CHECK(0 == strcmp(al_cstr(us1), "Šī kundze par visu samaksās")); /* Insert into itself. */ CHECK(al_ustr_replace_range(us1, 5, 11, us1)); CHECK(0 == strcmp(al_cstr(us1), "Šī Šī kundze par visu samaksās par visu samaksās")); al_ustr_free(us1); al_ustr_free(us2); } /* Test al_ustr_replace_range (part 2). */ static void t45(void) { ALLEGRO_USTR *us1 = al_ustr_new("abcdef"); ALLEGRO_USTR *us2 = al_ustr_new("ABCDEF"); /* Start1 < 0 [not allowed] */ CHECK(! al_ustr_replace_range(us1, -1, 1, us2)); /* Start1 > end(us1) [padded] */ CHECK(al_ustr_replace_range(us1, 8, 100, us2)); CHECK(0 == memcmp(al_cstr(us1), "abcdef\0\0ABCDEF", 15)); /* Start1 > end1 [not allowed] */ CHECK(! al_ustr_replace_range(us1, 8, 1, us2)); CHECK(0 == memcmp(al_cstr(us1), "abcdef\0\0ABCDEF", 15)); al_ustr_free(us1); al_ustr_free(us2); } extern bool call_vappendf(ALLEGRO_USTR *us, const char *fmt, ...); /* Test al_ustr_newf, al_ustr_appendf, al_ustr_vappendf. */ static void t46(void) { ALLEGRO_USTR *us; us = al_ustr_newf("%s %c %.2f %.02d", "hõljuk", 'c', ALLEGRO_PI, 42); CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42")); CHECK(al_ustr_appendf(us, " %s", "Luftchüssiboot")); CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42 Luftchüssiboot")); CHECK(call_vappendf(us, " %s", "χόβερκράφτ")); CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42 Luftchüssiboot χόβερκράφτ")); al_ustr_free(us); us = al_ustr_new(""); call_vappendf(us, "%s", "test"); CHECK(0 == strcmp(al_cstr(us), "test")); al_ustr_free(us); } bool call_vappendf(ALLEGRO_USTR *us, const char *fmt, ...) { va_list ap; bool rc; va_start(ap, fmt); rc = al_ustr_vappendf(us, fmt, ap); va_end(ap); return rc; } /* Test al_ustr_compare, al_ustr_ncompare. */ static void t47(void) { ALLEGRO_USTR_INFO i1; ALLEGRO_USTR_INFO i2; CHECK(al_ustr_compare( al_ref_cstr(&i1, "Thú mỏ vịt"), al_ref_cstr(&i2, "Thú mỏ vịt")) == 0); CHECK(al_ustr_compare( al_ref_cstr(&i1, "Thú mỏ vị"), al_ref_cstr(&i2, "Thú mỏ vịt")) < 0); CHECK(al_ustr_compare( al_ref_cstr(&i1, "Thú mỏ vịt"), al_ref_cstr(&i2, "Thú mỏ vit")) > 0); CHECK(al_ustr_compare( al_ref_cstr(&i1, "abc"), al_ref_cstr(&i2, "abc\001")) < 0); CHECK(al_ustr_compare( al_ref_cstr(&i1, "abc\001"), al_ref_cstr(&i2, "abc")) > 0); CHECK(al_ustr_ncompare( al_ref_cstr(&i1, "Thú mỏ vịt"), al_ref_cstr(&i2, "Thú mỏ vit"), 8) == 0); CHECK(al_ustr_ncompare( al_ref_cstr(&i1, "Thú mỏ vịt"), al_ref_cstr(&i2, "Thú mỏ vit"), 9) > 0); CHECK(al_ustr_ncompare( al_ref_cstr(&i1, "Thú mỏ vịt"), al_ref_cstr(&i2, "platypus"), 0) == 0); CHECK(al_ustr_ncompare( al_ref_cstr(&i1, "abc"), al_ref_cstr(&i2, "abc\001"), 4) < 0); CHECK(al_ustr_ncompare( al_ref_cstr(&i1, "abc\001"), al_ref_cstr(&i2, "abc"), 4) > 0); } /* Test al_ustr_has_prefix, al_ustr_has_suffix. */ static void t48(void) { ALLEGRO_USTR_INFO i1; const ALLEGRO_USTR *us1 = al_ref_cstr(&i1, "Thú mỏ vịt"); /* The _cstr versions are simple wrappers around the real functions so its * okay to test them only. */ CHECK(al_ustr_has_prefix_cstr(us1, "")); CHECK(al_ustr_has_prefix_cstr(us1, "Thú")); CHECK(! al_ustr_has_prefix_cstr(us1, "Thú mỏ vịt.")); CHECK(al_ustr_has_suffix_cstr(us1, "")); CHECK(al_ustr_has_suffix_cstr(us1, "vịt")); CHECK(! al_ustr_has_suffix_cstr(us1, "Thú mỏ vịt.")); } /* Test al_ustr_find_replace, al_ustr_find_replace_cstr. */ static void t49(void) { ALLEGRO_USTR *us; ALLEGRO_USTR_INFO findi; ALLEGRO_USTR_INFO repli; const ALLEGRO_USTR *find; const ALLEGRO_USTR *repl; us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); find = al_ref_cstr(&findi, "ðeéf"); repl = al_ref_cstr(&repli, "deef"); CHECK(al_ustr_find_replace(us, 0, find, repl)); CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíaábddeefghií")); find = al_ref_cstr(&findi, "aá"); repl = al_ref_cstr(&repli, "AÁ"); CHECK(al_ustr_find_replace(us, 14, find, repl)); CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíAÁbddeefghií")); CHECK(al_ustr_find_replace_cstr(us, 0, "dd", "đ")); CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií")); /* Not allowed */ find = al_ustr_empty_string(); CHECK(! al_ustr_find_replace(us, 0, find, repl)); CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií")); al_ustr_free(us); } /* Test UTF-16 conversion. */ static void t50(void) { ALLEGRO_USTR *us; char utf8[] = "⅛-note: 𝅘𝅥𝅮, domino: 🁡"; uint16_t *utf16; size_t s; uint16_t little[8]; /* Only native byte order supported right now, so have to specify * elements as uint16_t and not as char. */ uint16_t utf16_ref[] = { 0x215b, 0x002d, 0x006e, 0x006f, 0x0074, 0x0065, 0x003a, 0x0020, 0xd834, 0xdd60, 0x002c, 0x0020, 0x0064, 0x006f, 0x006d, 0x0069, 0x006e, 0x006f, 0x003a, 0x0020, 0xd83c, 0xdc61, 0x0000}; uint16_t truncated[] = { 0x215b, 0x002d, 0x006e, 0x006f, 0x0074, 0x0065, 0x003a, 0x0000}; us = al_ustr_new_from_utf16(utf16_ref); CHECK(20 == al_ustr_length(us)); CHECK(0 == strcmp(utf8, al_cstr(us))); al_ustr_free(us); us = al_ustr_new(utf8); s = al_ustr_size_utf16(us); CHECK(46 == s); utf16 = malloc(s); al_ustr_encode_utf16(us, utf16, s); CHECK(0 == memcmp(utf16, utf16_ref, s)); free(utf16); s = al_ustr_encode_utf16(us, little, sizeof little); CHECK(16 == s); CHECK(0 == memcmp(truncated, little, s)); al_ustr_free(us); } /* Test al_ustr_to_buffer */ static void t51(void) { char str[256]; const ALLEGRO_USTR *us; ALLEGRO_USTR_INFO info; us = al_ref_buffer(&info, "Allegro", 3); al_ustr_to_buffer(us, str, 10); CHECK(0 == memcmp(str, "All", 4)); al_ustr_to_buffer(us, str, 4); CHECK(0 == memcmp(str, "All", 4)); al_ustr_to_buffer(us, str, 3); CHECK(0 == memcmp(str, "Al", 3)); } /*---------------------------------------------------------------------------*/ const test_t all_tests[] = { NULL, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51 }; #define NUM_TESTS (int)(sizeof(all_tests) / sizeof(all_tests[0])) int main(int argc, const char *argv[]) { int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log_monospace(); if (argc < 2) { for (i = 1; i < NUM_TESTS; i++) { log_printf("# t%d\n\n", i); all_tests[i](); log_printf("\n"); } } else { i = atoi(argv[1]); if (i > 0 && i < NUM_TESTS) { all_tests[i](); } } log_printf("Done\n"); close_log(true); if (error) { exit(EXIT_FAILURE); } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_logo.c0000644000175000001440000003651712152725670016047 0ustar tjadenusers/* Demo program which creates a logo by direct pixel manipulation of * bitmaps. Also uses alpha blending to create a real-time flash * effect (likely not visible with displays using memory bitmaps as it * is too slow). */ #include #include #include #include #include #include #include #include "common.c" #ifdef ALLEGRO_MSVC #define snprintf _snprintf #endif static ALLEGRO_BITMAP *logo, *logo_flash; static int logo_x, logo_y; static ALLEGRO_FONT *font; static int cursor; static int selection; static bool regenerate = 0, editing = 0; static ALLEGRO_CONFIG *config; static ALLEGRO_COLOR white; static double anim; static float clamp(float x) { if (x < 0) return 0; if (x > 1) return 1; return x; } static char const *param_names[] = { "text", "font", "size", "shadow", "blur", "factor", "red", "green", "blue", NULL }; /* Note: To regenerate something close to the official Allegro logo, * you need to obtain the non-free "Utopia Regular Italic" font. Then * replace "DejaVuSans.ttf" with "putri.pfa" below. */ static char param_values[][256] = { "Allegro", "data/DejaVuSans.ttf", "140", "10", "2", "0.5", "1.1", "1.5", "5" }; /* Generates a bitmap with transparent background and the logo text. * The bitmap will have screen size. If 'bumpmap' is not NULL, it will * contain another bitmap which is a white, blurred mask of the logo * which we use for the flash effect. */ static ALLEGRO_BITMAP *generate_logo(char const *text, char const *fontname, int font_size, float shadow_offset, float blur_radius, float blur_factor, float light_red, float light_green, float light_blue, ALLEGRO_BITMAP **bumpmap) { ALLEGRO_COLOR transparent = al_map_rgba_f(0, 0, 0, 0); int xp, yp, w, h, i, j, x, y, br, bw, dw, dh; ALLEGRO_COLOR c; ALLEGRO_FONT *logofont; ALLEGRO_STATE state; ALLEGRO_BITMAP *blur, *light, *logo; int left, right, top, bottom; float cx, cy; dw = al_get_bitmap_width(al_get_target_bitmap()); dh = al_get_bitmap_height(al_get_target_bitmap()); cx = dw * 0.5; cy = dh * 0.5; logofont = al_load_font(fontname, -font_size, 0); al_get_text_dimensions(logofont, text, &xp, &yp, &w, &h); al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); /* Cheap blur effect to create a bump map. */ blur = al_create_bitmap(dw, dh); al_set_target_bitmap(blur); al_clear_to_color(transparent); br = blur_radius; bw = br * 2 + 1; c = al_map_rgba_f(1, 1, 1, 1.0 / (bw * bw * blur_factor)); al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (i = -br; i <= br; i++) { for (j = -br; j <= br; j++) { al_draw_text(logofont, c, cx - xp * 0.5 - w * 0.5 + i, cy - yp * 0.5 - h * 0.5 + j, 0, text); } } left = cx - xp * 0.5 - w * 0.5 - br + xp; top = cy - yp * 0.5 - h * 0.5 - br + yp; right = left + w + br * 2; bottom = top + h + br * 2; if (left < 0) left = 0; if (top < 0) top = 0; if (right > dw - 1) right = dw - 1; if (bottom > dh - 1) bottom = dh - 1; /* Cheap light effect. */ light = al_create_bitmap(dw, dh); al_set_target_bitmap(light); al_clear_to_color(transparent); al_lock_bitmap(blur, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); al_lock_bitmap_region(light, left, top, 1 + right - left, 1 + bottom - top, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); for (y = top; y <= bottom; y++) { for (x = left; x <= right; x++) { float r1, g1, b1, a1; float r2, g2, b2, a2; float r, g, b, a; float d; ALLEGRO_COLOR c = al_get_pixel(blur, x, y); ALLEGRO_COLOR c1 = al_get_pixel(blur, x - 1, y - 1); ALLEGRO_COLOR c2 = al_get_pixel(blur, x + 1, y + 1); al_unmap_rgba_f(c, &r, &g, &b, &a); al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1); al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2); d = r2 - r1 + 0.5; r = clamp(d * light_red); g = clamp(d * light_green); b = clamp(d * light_blue); c = al_map_rgba_f(r, g, b, a); al_put_pixel(x, y, c); } } al_unlock_bitmap(light); al_unlock_bitmap(blur); if (bumpmap) *bumpmap = blur; else al_destroy_bitmap(blur); /* Create final logo */ logo = al_create_bitmap(dw, dh); al_set_target_bitmap(logo); al_clear_to_color(transparent); /* Draw a shadow. */ c = al_map_rgba_f(0, 0, 0, 0.5 / 9); al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (i = -1; i <= 1; i++) for (j = -1; j <= 1; j++) al_draw_text(logofont, c, cx - xp * 0.5 - w * 0.5 + shadow_offset + i, cy - yp * 0.5 - h * 0.5 + shadow_offset + j, 0, text); /* Then draw the lit text we made before on top. */ al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_bitmap(light, 0, 0, 0); al_destroy_bitmap(light); al_restore_state(&state); al_destroy_font(logofont); return logo; } /* Draw the checkerboard background. */ static void draw_background(void) { ALLEGRO_COLOR c[2]; int i, j; c[0] = al_map_rgba(0xaa, 0xaa, 0xaa, 0xff); c[1] = al_map_rgba(0x99, 0x99, 0x99, 0xff); for (i = 0; i < 640 / 16; i++) { for (j = 0; j < 480 / 16; j++) { al_draw_filled_rectangle(i * 16, j * 16, i * 16 + 16, j * 16 + 16, c[(i + j) & 1]); } } } /* Print out the current logo parameters. */ static void print_parameters(void) { int i; ALLEGRO_STATE state; ALLEGRO_COLOR normal = al_map_rgba_f(0, 0, 0, 1); ALLEGRO_COLOR light = al_map_rgba_f(0, 0, 1, 1); ALLEGRO_COLOR label = al_map_rgba_f(0.2, 0.2, 0.2, 1); int th; al_store_state(&state, ALLEGRO_STATE_BLENDER); th = al_get_font_line_height(font) + 3; for (i = 0; param_names[i]; i++) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, label, 2, 2 + i * th, 0, "%s", param_names[i]); } for (i = 0; param_names[i]; i++) { int y = 2 + i * th; al_draw_filled_rectangle(75, y, 375, y + th - 2, al_map_rgba_f(0.5, 0.5, 0.5, 0.5)); al_draw_textf(font, i == selection ? light : normal, 75, y, 0, "%s", param_values[i]); if (i == selection && editing && (((int)(al_get_time() * 2)) & 1)) { int x = 75 + al_get_text_width(font, param_values[i]); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_line(x, y, x, y + th, white, 0); } } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, normal, 400, 2, 0, "%s", "R - Randomize"); al_draw_textf(font, normal, 400, 2 + th, 0, "%s", "S - Save as logo.png"); al_draw_textf(font, normal, 2, 480 - th * 2 - 2, 0, "%s", "To modify, press Return, then enter value, " "then Return again."); al_draw_textf(font, normal, 2, 480 - th - 2, 0, "%s", "Use cursor up/down to " "select the value to modify."); al_restore_state(&state); } static char const *rnum(float min, float max) { static char s[256]; double x = rand() / (double)RAND_MAX; x = min + x * (max - min); snprintf(s, sizeof s, "%.1f", x); return s; } static void randomize(void) { strcpy(param_values[3], rnum(2, 12)); strcpy(param_values[4], rnum(1, 8)); strcpy(param_values[5], rnum(0.1, 1)); strcpy(param_values[6], rnum(0, 5)); strcpy(param_values[7], rnum(0, 5)); strcpy(param_values[8], rnum(0, 5)); regenerate = true; } static void save(void) { al_save_bitmap("logo.png", logo); } static void mouse_click(int x, int y) { int th = al_get_font_line_height(font) + 3; int sel = (y - 2) / th; int i; if (x < 400) { for (i = 0; param_names[i]; i++) { if (sel == i) { selection = i; cursor = 0; editing = true; } } } else if (x < 500) { if (sel == 0) randomize(); if (sel == 1) save(); } } static void render(void) { double t = al_get_time(); if (regenerate) { al_destroy_bitmap(logo); al_destroy_bitmap(logo_flash); logo = NULL; regenerate = false; } if (!logo) { /* Generate a new logo. */ ALLEGRO_BITMAP *fullflash; ALLEGRO_BITMAP *fulllogo = generate_logo(param_values[0], param_values[1], strtol(param_values[2], NULL, 10), strtod(param_values[3], NULL), strtod(param_values[4], NULL), strtod(param_values[5], NULL), strtod(param_values[6], NULL), strtod(param_values[7], NULL), strtod(param_values[8], NULL), &fullflash); ALLEGRO_BITMAP *crop; int x, y, left = 640, top = 480, right = -1, bottom = -1; /* Crop out the non-transparent part. */ al_lock_bitmap(fulllogo, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); for (y = 0; y < 480; y++) { for (x = 0; x < 640; x++) { ALLEGRO_COLOR c = al_get_pixel(fulllogo, x, y); float r, g, b, a; al_unmap_rgba_f(c, &r, &g, &b, &a); if (a > 0) { if (x < left) left = x; if (y < top) top = y; if (x > right) right = x; if (y > bottom) bottom = y; } } } al_unlock_bitmap(fulllogo); if (right < left) right = left; if (bottom < top) bottom = top; crop = al_create_sub_bitmap(fulllogo, left, top, 1 + right - left, 1 + bottom - top); logo = al_clone_bitmap(crop); al_destroy_bitmap(crop); al_destroy_bitmap(fulllogo); crop = al_create_sub_bitmap(fullflash, left, top, 1 + right - left, 1 + bottom - top); logo_flash = al_clone_bitmap(crop); al_destroy_bitmap(crop); al_destroy_bitmap(fullflash); logo_x = left; logo_y = top; anim = t; } draw_background(); /* For half a second, display our flash animation. */ if (t - anim < 0.5) { ALLEGRO_STATE state; int i, j; float f = sin(ALLEGRO_PI * ((t - anim) / 0.5)); ALLEGRO_COLOR c = al_map_rgb_f(f * 0.3, f * 0.3, f * 0.3); al_store_state(&state, ALLEGRO_STATE_BLENDER); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_tinted_bitmap(logo, al_map_rgba_f(1, 1, 1, 1 - f), logo_x, logo_y, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (j = -2; j <= 2; j += 2) { for (i = -2; i <= 2; i += 2) { al_draw_tinted_bitmap(logo_flash, c, logo_x + i, logo_y + j, 0); } } al_restore_state(&state); } else al_draw_bitmap(logo, logo_x, logo_y, 0); print_parameters(); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; int redraw = 0, i; bool quit = false; if (!al_init()) { abort_example("Could not initialise Allegro\n"); } al_init_primitives_addon(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); al_init_ttf_addon(); srand(time(NULL)); white = al_map_rgba_f(1, 1, 1, 1); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display\n"); } al_set_window_title(display, "Allegro Logo Generator"); al_install_keyboard(); /* Read logo parameters from logo.ini (if it exists). */ config = al_load_config_file("logo.ini"); if (!config) config = al_create_config(); for (i = 0; param_names[i]; i++) { char const *value = al_get_config_value(config, "logo", param_names[i]); if (value) strncpy(param_values[i], value, sizeof(param_values[i])); } font = al_load_font("data/DejaVuSans.ttf", 12, 0); if (!font) { abort_example("Could not load font\n"); } timer = al_create_timer(1.0 / 60); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (!quit) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { quit = true; } else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { if (editing) { regenerate = true; editing = false; } else { cursor = 0; editing = true; } } else if (event.keyboard.keycode == ALLEGRO_KEY_UP) { if (selection > 0) { selection--; cursor = 0; editing = false; } } else if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { if (param_names[selection + 1]) { selection++; cursor = 0; editing = false; } } else { int c = event.keyboard.unichar; if (editing) { if (c >= 32) { ALLEGRO_USTR *u = al_ustr_new(param_values[selection]); al_ustr_set_chr(u, cursor, c); cursor++; al_ustr_set_chr(u, cursor, 0); strncpy(param_values[selection], al_cstr(u), sizeof param_values[selection]); al_ustr_free(u); } } else { if (c == 'r') randomize(); if (c == 's') save(); } } } if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { if (event.mouse.button == 1) { mouse_click(event.mouse.x, event.mouse.y); } } if (event.type == ALLEGRO_EVENT_TIMER) redraw++; if (redraw && al_is_event_queue_empty(queue)) { redraw = 0; render(); al_flip_display(); } } /* Write modified parameters back to logo.ini. */ for (i = 0; param_names[i]; i++) { al_set_config_value(config, "logo", param_names[i], param_values[i]); } al_save_config_file("logo.ini", config); al_destroy_config(config); return 0; } allegro-5.0.10/examples/ex_resize.c0000644000175000001440000000441012152725670016373 0ustar tjadenusers#include "allegro5/allegro.h" #include #include "common.c" static void redraw(void) { ALLEGRO_COLOR black, white; int w, h; white = al_map_rgba_f(1, 1, 1, 1); black = al_map_rgba_f(0, 0, 0, 1); al_clear_to_color(white); w = al_get_bitmap_width(al_get_target_bitmap()); h = al_get_bitmap_height(al_get_target_bitmap()); al_draw_line(0, h, w / 2, 0, black, 0); al_draw_line(w / 2, 0, w, h, black, 0); al_draw_line(w / 4, h / 2, 3 * w / 4, h / 2, black, 0); al_flip_display(); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; int rs = 100; bool resize = false; /* Initialize Allegro and create an event queue. */ if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); events = al_create_event_queue(); /* Setup a display driver and register events from it. */ al_set_new_display_flags(ALLEGRO_RESIZABLE); display = al_create_display(rs, rs); if (!display) { abort_example("Could not create display.\n"); } al_register_event_source(events, al_get_display_event_source(display)); timer = al_create_timer(0.1); al_start_timer(timer); /* Setup a keyboard driver and register events from it. */ al_install_keyboard(); al_register_event_source(events, al_get_keyboard_event_source()); al_register_event_source(events, al_get_timer_event_source(timer)); /* Display a pulsating window until a key or the closebutton is pressed. */ redraw(); while (true) { if (resize) { int s; rs += 10; if (rs == 300) rs = 100; s = rs; if (s > 200) s = 400 - s; al_resize_display(display, s, s); redraw(); resize = false; } al_wait_for_event(events, &event); if (event.type == ALLEGRO_EVENT_TIMER) { resize = true; } else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { break; } } return 0; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/examples/ex_scale.c0000644000175000001440000001136712152725670016172 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. */ #include #include "allegro5/allegro_image.h" #include #include "common.c" int main(void) { const int display_w = 640; const int display_h = 480; ALLEGRO_DISPLAY *dpy; ALLEGRO_BITMAP *buf; ALLEGRO_BITMAP *bmp; ALLEGRO_BITMAP *mem_bmp; ALLEGRO_BITMAP *src_bmp; int bmp_w; int bmp_h; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; double theta = 0; double k = 1.0; int mode = 0; bool wide_mode = false; bool mem_src_mode = false; bool trans_mode = false; int flags = 0; bool clip_mode = false; ALLEGRO_COLOR tint; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); open_log(); log_printf("Press 'w' to toggle wide mode.\n"); log_printf("Press 's' to toggle memory source bitmap.\n"); log_printf("Press space to toggle drawing to backbuffer or off-screen bitmap.\n"); log_printf("Press 't' to toggle translucency.\n"); log_printf("Press 'h' to toggle horizontal flipping.\n"); log_printf("Press 'v' to toggle vertical flipping.\n"); log_printf("Press 'c' to toggle clipping.\n"); log_printf("\n"); dpy = al_create_display(display_w, display_h); if (!dpy) { abort_example("Unable to set any graphic mode\n"); } buf = al_create_bitmap(display_w, display_h); if (!buf) { abort_example("Unable to create buffer\n\n"); } bmp = al_load_bitmap("data/mysha.pcx"); if (!bmp) { abort_example("Unable to load image\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); mem_bmp = al_load_bitmap("data/mysha.pcx"); if (!mem_bmp) { abort_example("Unable to load image\n"); } bmp_w = al_get_bitmap_width(bmp); bmp_h = al_get_bitmap_height(bmp); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); while (true) { if (al_get_next_event(queue, &event)) { if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.unichar == ' ') { mode = !mode; if (mode == 0) log_printf("Drawing to off-screen buffer\n"); else log_printf("Drawing to display backbuffer\n"); } if (event.keyboard.unichar == 'w') wide_mode = !wide_mode; if (event.keyboard.unichar == 's') { mem_src_mode = !mem_src_mode; if (mem_src_mode) log_printf("Source is memory bitmap\n"); else log_printf("Source is display bitmap\n"); } if (event.keyboard.unichar == 't') trans_mode = !trans_mode; if (event.keyboard.unichar == 'h') flags ^= ALLEGRO_FLIP_HORIZONTAL; if (event.keyboard.unichar == 'v') flags ^= ALLEGRO_FLIP_VERTICAL; if (event.keyboard.unichar == 'c') clip_mode = !clip_mode; } } /* * mode 0 = draw scaled to off-screen buffer before * blitting to display backbuffer * mode 1 = draw scaled to display backbuffer */ if (mode == 0) { al_set_target_bitmap(buf); } else { al_set_target_backbuffer(dpy); } src_bmp = (mem_src_mode) ? mem_bmp : bmp; k = (wide_mode) ? 2.0 : 1.0; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); tint = al_map_rgba_f(1, 1, 1, 1); if (mode == 0) al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); else al_clear_to_color(al_map_rgba_f(0, 0, 1, 1)); if (trans_mode) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); tint = al_map_rgba_f(1, 1, 1, 0.5); } if (clip_mode) { al_set_clipping_rectangle(50, 50, display_w - 100, display_h - 100); } else { al_set_clipping_rectangle(0, 0, display_w, display_h); } al_draw_tinted_scaled_bitmap(src_bmp, tint, 0, 0, bmp_w, bmp_h, display_w/2, display_h/2, k * cos(theta) * display_w/2, k * sin(theta) * display_h/2, flags); if (mode == 0) { al_set_target_backbuffer(dpy); al_set_clipping_rectangle(0, 0, display_w, display_h); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(buf, 0, 0, 0); } al_flip_display(); al_rest(0.01); theta += 0.01; } al_destroy_bitmap(bmp); al_destroy_bitmap(mem_bmp); al_destroy_bitmap(buf); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_native_filechooser.c0000644000175000001440000002447512152725670020757 0ustar tjadenusers/* * Example program for the Allegro library. * * The native file dialog addon only supports a blocking interface. This * example makes the blocking call from another thread, using a user event * source to communicate back to the main program. */ #include #include #include #include #include #include #include "common.c" /* To communicate from a separate thread, we need a user event. */ #define ASYNC_DIALOG_EVENT1 ALLEGRO_GET_EVENT_TYPE('e', 'N', 'F', '1') #define ASYNC_DIALOG_EVENT2 ALLEGRO_GET_EVENT_TYPE('e', 'N', 'F', '2') typedef struct { ALLEGRO_DISPLAY *display; ALLEGRO_FILECHOOSER *file_dialog; ALLEGRO_EVENT_SOURCE event_source; ALLEGRO_THREAD *thread; } AsyncDialog; ALLEGRO_TEXTLOG *textlog; static void message(char const *format, ...) { char str[1024]; va_list args; va_start(args, format); vsnprintf(str, sizeof str, format, args); va_end(args); al_append_native_text_log(textlog, "%s", str); } /* Our thread to show the native file dialog. */ static void *async_file_dialog_thread_func(ALLEGRO_THREAD *thread, void *arg) { AsyncDialog *data = arg; ALLEGRO_EVENT event; (void)thread; /* The next line is the heart of this example - we display the * native file dialog. */ al_show_native_file_dialog(data->display, data->file_dialog); /* We emit an event to let the main program know that the thread has * finished. */ event.user.type = ASYNC_DIALOG_EVENT1; al_emit_user_event(&data->event_source, &event, NULL); return NULL; } /* A thread to show the message boxes. */ static void *message_box_thread(ALLEGRO_THREAD *thread, void *arg) { AsyncDialog *data = arg; ALLEGRO_EVENT event; int button; (void)thread; button = al_show_native_message_box(data->display, "Warning", "Click Detected", "That does nothing. Stop clicking there.", "Oh no!|Don't press|Ok", ALLEGRO_MESSAGEBOX_WARN); if (button == 2) { button = al_show_native_message_box(data->display, "Error", "Hey!", "Stop it! I told you not to click there.", NULL, ALLEGRO_MESSAGEBOX_ERROR); } event.user.type = ASYNC_DIALOG_EVENT2; al_emit_user_event(&data->event_source, &event, NULL); return NULL; } /* Function to start the new thread. */ static AsyncDialog *spawn_async_file_dialog(ALLEGRO_DISPLAY *display, const char *initial_path) { AsyncDialog *data = malloc(sizeof *data); data->file_dialog = al_create_native_file_dialog( initial_path, "Choose files", NULL, ALLEGRO_FILECHOOSER_MULTIPLE); al_init_user_event_source(&data->event_source); data->display = display; data->thread = al_create_thread(async_file_dialog_thread_func, data); al_start_thread(data->thread); return data; } static AsyncDialog *spawn_async_message_dialog(ALLEGRO_DISPLAY *display) { AsyncDialog *data = calloc(1, sizeof *data); al_init_user_event_source(&data->event_source); data->display = display; data->thread = al_create_thread(message_box_thread, data); al_start_thread(data->thread); return data; } static void stop_async_dialog(AsyncDialog *data) { if (data) { al_destroy_thread(data->thread); al_destroy_user_event_source(&data->event_source); if (data->file_dialog) al_destroy_native_file_dialog(data->file_dialog); free(data); } } /* Helper function to display the result from a file dialog. */ static void show_files_list(ALLEGRO_FILECHOOSER *dialog, const ALLEGRO_FONT *font, ALLEGRO_COLOR info) { ALLEGRO_BITMAP *target = al_get_target_bitmap(); int count = al_get_native_file_dialog_count(dialog); int th = al_get_font_line_height(font); float x = al_get_bitmap_width(target) / 2; float y = al_get_bitmap_height(target) / 2 - (count * th) / 2; int i; for (i = 0; i < count; i++) { const char *name = al_get_native_file_dialog_path(dialog, i); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, info, x, y + i * th, ALLEGRO_ALIGN_CENTRE, name, 0, 0); } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_FONT *font; ALLEGRO_COLOR background, active, inactive, info; AsyncDialog *old_dialog = NULL; AsyncDialog *cur_dialog = NULL; AsyncDialog *message_box = NULL; bool redraw = false; bool close_log = false; int button; bool message_log = true; if (!al_init()) { abort_example("Could not init Allegro.\n"); } if (!al_init_native_dialog_addon()) { abort_example("Could not init native dialog addon.\n"); } textlog = al_open_native_text_log("Log", 0); message("Starting up log window.\n"); al_init_image_addon(); al_init_font_addon(); background = al_color_name("white"); active = al_color_name("black"); inactive = al_color_name("gray"); info = al_color_name("red"); al_install_mouse(); al_install_keyboard(); message("Creating 640x480 window..."); display = al_create_display(640, 480); if (!display) { message("failure.\n"); abort_example("Error creating display\n"); } message("success.\n"); message("Loading font '%s'...", "data/fixed_font.tga"); font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { message("failure.\n"); abort_example("Error loading data/fixed_font.tga\n"); } message("success.\n"); timer = al_create_timer(1.0 / 30); restart: message("Starting main loop.\n"); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); if (textlog) { al_register_event_source(queue, al_get_native_text_log_event_source( textlog)); } al_start_timer(timer); while (1) { float h = al_get_display_height(display); ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE && !cur_dialog) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE && !cur_dialog) break; } /* When a mouse button is pressed, and no native dialog is * shown already, we show a new one. */ if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { message("Mouse clicked at %d,%d.\n", event.mouse.x, event.mouse.y); if (event.mouse.y > 30) { if (event.mouse.y > h - 30) { message_log = !message_log; if (message_log) { textlog = al_open_native_text_log("Log", 0); if (textlog) { al_register_event_source(queue, al_get_native_text_log_event_source(textlog)); } } else { close_log = true; } } else if (!message_box) { message_box = spawn_async_message_dialog(display); al_register_event_source(queue, &message_box->event_source); } } else if (!cur_dialog) { const char *last_path = NULL; /* If available, use the path from the last dialog as * initial path for the new one. */ if (old_dialog) { last_path = al_get_native_file_dialog_path( old_dialog->file_dialog, 0); } cur_dialog = spawn_async_file_dialog(display, last_path); al_register_event_source(queue, &cur_dialog->event_source); } } /* We receive this event from the other thread when the dialog is * closed. */ if (event.type == ASYNC_DIALOG_EVENT1) { al_unregister_event_source(queue, &cur_dialog->event_source); /* If files were selected, we replace the old files list. * Otherwise the dialog was cancelled, and we keep the old results. */ if (al_get_native_file_dialog_count(cur_dialog->file_dialog) > 0) { if (old_dialog) stop_async_dialog(old_dialog); old_dialog = cur_dialog; } else { stop_async_dialog(cur_dialog); } cur_dialog = NULL; } if (event.type == ASYNC_DIALOG_EVENT2) { al_unregister_event_source(queue, &message_box->event_source); stop_async_dialog(message_box); message_box = NULL; } if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { close_log = true; } if (event.type == ALLEGRO_EVENT_TIMER) { redraw = true; } if (redraw && al_is_event_queue_empty(queue)) { float x = al_get_display_width(display) / 2; float y = 0; redraw = false; al_clear_to_color(background); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, cur_dialog ? inactive : active, x, y, ALLEGRO_ALIGN_CENTRE, "Open"); al_draw_textf(font, cur_dialog ? inactive : active, x, h - 30, ALLEGRO_ALIGN_CENTRE, message_log ? "Close Message Log" : "Open Message Log"); if (old_dialog) show_files_list(old_dialog->file_dialog, font, info); al_flip_display(); } if (close_log && textlog) { close_log = false; message_log = false; al_unregister_event_source(queue, al_get_native_text_log_event_source(textlog)); al_close_native_text_log(textlog); textlog = NULL; } } message("Exiting.\n"); al_destroy_event_queue(queue); button = al_show_native_message_box(display, "Warning", "Are you sure?", "If you click yes then this example will inevitably close." " This is your last chance to rethink your decision." " Do you really want to quit?", NULL, ALLEGRO_MESSAGEBOX_YES_NO | ALLEGRO_MESSAGEBOX_QUESTION); if (button != 1) goto restart; stop_async_dialog(old_dialog); stop_async_dialog(cur_dialog); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_font.c0000644000175000001440000000632712152725670016051 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "common.c" #define EURO "\xe2\x82\xac" static void wait_for_esc(ALLEGRO_DISPLAY *display) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_BITMAP *screen_clone; al_install_keyboard(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); screen_clone = al_clone_bitmap(al_get_target_bitmap()); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; } else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { int x = event.display.x; int y = event.display.y; int w = event.display.width; int h = event.display.height; al_draw_bitmap_region(screen_clone, x, y, w, h, x, y, 0); al_update_display_region(x, y, w, h); } } al_destroy_bitmap(screen_clone); al_destroy_event_queue(queue); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bitmap, *font_bitmap; ALLEGRO_FONT *f1, *f2, *f3; int ranges[] = { 0x0020, 0x007F, /* ASCII */ 0x00A1, 0x00FF, /* Latin 1 */ 0x0100, 0x017F, /* Extended-A */ 0x20AC, 0x20AC}; /* Euro */ if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, true, ALLEGRO_SUGGEST); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(320, 200); if (!display) { abort_example("Failed to create display\n"); } bitmap = al_load_bitmap("data/mysha.pcx"); if (!bitmap) { abort_example("Failed to load mysha.pcx\n"); } f1 = al_load_font("data/bmpfont.tga", 0, 0); if (!f1) { abort_example("Failed to load bmpfont.tga\n"); } font_bitmap = al_load_bitmap("data/a4_font.tga"); if (!font_bitmap) { abort_example("Failed to load a4_font.tga\n"); } f2 = al_grab_font_from_bitmap(font_bitmap, 4, ranges); f3 = al_create_builtin_font(); if (!f3) { abort_example("Failed to create builtin font.\n"); } /* Draw background */ al_draw_bitmap(bitmap, 0, 0, 0); /* Draw red text */ al_draw_textf(f1, al_map_rgb(255, 0, 0), 10, 10, 0, "red"); /* Draw green text */ al_draw_textf(f1, al_map_rgb(0, 255, 0), 120, 10, 0, "green"); /* Draw a unicode symbol */ al_draw_textf(f2, al_map_rgb(0, 0, 255), 60, 60, 0, "Mysha's 0.02" EURO); /* Draw a yellow text with the builtin font */ al_draw_textf(f3, al_map_rgb(255, 255, 0), 160, 160, ALLEGRO_ALIGN_CENTER, "a string from builtin font data"); al_flip_display(); wait_for_esc(display); al_destroy_bitmap(bitmap); al_destroy_bitmap(font_bitmap); al_destroy_font(f1); al_destroy_font(f2); al_destroy_font(f3); return 0; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/examples/ex_user_events.c0000644000175000001440000000600712152725670017440 0ustar tjadenusers/* * Example program for the Allegro library. */ #include #include "allegro5/allegro.h" #include "common.c" #define MY_SIMPLE_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('m', 's', 'e', 't') #define MY_COMPLEX_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('m', 'c', 'e', 't') /* Just some fantasy event, supposedly used in an RPG - it's just to show that * in practice, the 4 user fields we have now never will be enough. */ typedef struct MY_EVENT { int id; int type; /* For example "attack" or "buy". */ int x, y, z; /* Position in the game world the event takes place. */ int server_time; /* Game time in ticks the event takes place. */ int source_unit_id; /* E.g. attacker or seller. */ int destination_unit_id; /* E.g. defender of buyer. */ int item_id; /* E.g. weapon used or item sold. */ int amount; /* Gold the item is sold for. */ } MY_EVENT; static MY_EVENT *new_event(int id) { MY_EVENT *event = calloc(1, sizeof *event); event->id = id; return event; } static void my_event_dtor(ALLEGRO_USER_EVENT *event) { log_printf("my_event_dtor: %p\n", (void *) event->data1); free((void *) event->data1); } int main(void) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_SOURCE user_src; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT user_event; ALLEGRO_EVENT event; if (!al_init()) { abort_example("Could not init Allegro.\n"); } timer = al_create_timer(0.5); if (!timer) { abort_example("Could not install timer.\n"); } open_log(); al_init_user_event_source(&user_src); queue = al_create_event_queue(); al_register_event_source(queue, &user_src); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (true) { al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_TIMER) { int n = event.timer.count; log_printf("Got timer event %d\n", n); user_event.user.type = MY_SIMPLE_EVENT_TYPE; user_event.user.data1 = n; al_emit_user_event(&user_src, &user_event, NULL); user_event.user.type = MY_COMPLEX_EVENT_TYPE; user_event.user.data1 = (intptr_t)new_event(n); al_emit_user_event(&user_src, &user_event, my_event_dtor); } else if (event.type == MY_SIMPLE_EVENT_TYPE) { int n = (int) event.user.data1; ALLEGRO_ASSERT(event.user.source == &user_src); al_unref_user_event(&event.user); log_printf("Got simple user event %d\n", n); if (n == 5) { break; } } else if (event.type == MY_COMPLEX_EVENT_TYPE) { MY_EVENT *my_event = (void *)event.user.data1; ALLEGRO_ASSERT(event.user.source == &user_src); log_printf("Got complex user event %d\n", my_event->id); al_unref_user_event(&event.user); } } al_destroy_user_event_source(&user_src); al_destroy_event_queue(queue); al_destroy_timer(timer); log_printf("Done.\n"); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_ogre3d.cpp0000644000175000001440000003020112152725670016612 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * Windows support by AMCerasoli. * * This is a test program to see if Allegro can be used alongside the OGRE * graphics library. It currently only works on Linux/GLX and Windows. * To run, you will need to have OGRE plugins.cfg and resources.cfg files in * the current directory. * * Inputs: W A S D, mouse * * This code is based on the samples in the OGRE distribution. */ #include #include #ifdef ALLEGRO_WINDOWS #include #endif #include /* * Ogre 1.7 (and, optionally, earlier versions) uses the FreeImage library to * handle image loading. FreeImage bundles its own copies of common libraries * like libjpeg and libpng, which can conflict with the system copies of those * libraries that allegro_image uses. That means we can't use allegro_image * safely, nor any of the addons which depend on it. * * One solution would be to write a codec for Ogre that avoids FreeImage, or * write allegro_image handlers using FreeImage. The latter would probably be * easier and useful for other reasons. */ using namespace Ogre; const int WIDTH = 640; const int HEIGHT = 480; const float MOVE_SPEED = 1500.0; class Application { protected: Root *mRoot; RenderWindow *mWindow; SceneManager *mSceneMgr; Camera *mCamera; public: void setup(ALLEGRO_DISPLAY *display) { createRoot(); defineResources(); setupRenderSystem(); createRenderWindow(display); initializeResourceGroups(); chooseSceneManager(); createCamera(); createViewports(); createScene(); } Application() { mRoot = NULL; } ~Application() { delete mRoot; } private: void createRoot() { mRoot = new Root(); } void defineResources() { String secName, typeName, archName; ConfigFile cf; cf.load("resources.cfg"); ConfigFile::SectionIterator seci = cf.getSectionIterator(); while (seci.hasMoreElements()) { secName = seci.peekNextKey(); ConfigFile::SettingsMultiMap *settings = seci.getNext(); ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { typeName = i->first; archName = i->second; ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } } void setupRenderSystem() { if (!mRoot->restoreConfig() && !mRoot->showConfigDialog()) { throw Exception(52, "User canceled the config dialog!", "Application::setupRenderSystem()"); } } void createRenderWindow(ALLEGRO_DISPLAY *display) { int w = al_get_display_width(display); int h = al_get_display_height(display); // Initialise Ogre without creating a window. mRoot->initialise(false); Ogre::NameValuePairList misc; #ifdef ALLEGRO_WINDOWS unsigned long winHandle = reinterpret_cast(al_get_win_window_handle(display)); unsigned long winGlContext = reinterpret_cast(wglGetCurrentContext()); misc["externalWindowHandle"] = StringConverter::toString(winHandle); misc["externalGLContext"] = StringConverter::toString(winGlContext); misc["externalGLControl"] = String("True"); #else misc["currentGLContext"] = String("True"); #endif mWindow = mRoot->createRenderWindow("MainRenderWindow", w, h, false, &misc); } void initializeResourceGroups() { TextureManager::getSingleton().setDefaultNumMipmaps(5); ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); } virtual void chooseSceneManager() { mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager"); } virtual void createCamera() { mCamera = mSceneMgr->createCamera("PlayerCam"); mCamera->setPosition(Vector3(-300, 300, -300)); mCamera->lookAt(Vector3(0, 0, 0)); mCamera->setNearClipDistance(5); } virtual void createViewports() { // Create one viewport, entire window. Viewport *vp = mWindow->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0, 0.25, 0.5)); // Alter the camera aspect ratio to match the viewport. mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); } virtual void createScene() = 0; public: void render() { const bool swap_buffers = false; mWindow->update(swap_buffers); mRoot->renderOneFrame(); al_flip_display(); } }; class Example : public Application { private: ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; double startTime; double lastRenderTime; double lastMoveTime; bool lmb; bool rmb; bool forward; bool back; bool left; bool right; float current_speed; Vector3 last_translate; public: Example(ALLEGRO_DISPLAY *display); ~Example(); void setup(); void mainLoop(); private: void createScene(); void moveCamera(double timestamp, Radian rot_x, Radian rot_y, Vector3 & translate); void animate(double now); void nextFrame(); }; Example::Example(ALLEGRO_DISPLAY *display) : display(display), queue(NULL), timer(NULL), startTime(0.0), lastRenderTime(0.0), lastMoveTime(0.0), lmb(false), rmb(false), forward(false), back(false), left(false), right(false), current_speed(0), last_translate(Vector3::ZERO) { } Example::~Example() { if (timer) al_destroy_timer(timer); if (queue) al_destroy_event_queue(queue); } void Example::createScene() { // Enable shadows. mSceneMgr->setAmbientLight(ColourValue(0.5, 0.25, 0.0)); //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); // slower mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); // faster // Create the character. Entity *ent1 = mSceneMgr->createEntity("Ninja", "ninja.mesh"); ent1->setCastShadows(true); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent1); AnimationState *anim1 = ent1->getAnimationState("Walk"); anim1->setLoop(true); anim1->setEnabled(true); // Create the ground. Plane plane(Vector3::UNIT_Y, 0); MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 20, 20, true, 1, 5, 5, Vector3::UNIT_Z); Entity *ent2 = mSceneMgr->createEntity("GroundEntity", "ground"); ent2->setMaterialName("Examples/Rockwall"); ent2->setCastShadows(false); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent2); // Create a light. Light *light = mSceneMgr->createLight("Light1"); light->setType(Light::LT_POINT); light->setPosition(Vector3(0, 150, 250)); light->setDiffuseColour(1.0, 1.0, 1.0); light->setSpecularColour(1.0, 0.0, 0.0); } void Example::setup() { Application::setup(display); const double BPS = 60.0; timer = al_create_timer(1.0 / BPS); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(display)); } void Example::mainLoop() { bool redraw = true; startTime = lastMoveTime = al_get_time(); al_start_timer(timer); for (;;) { ALLEGRO_EVENT event; if (al_is_event_queue_empty(queue) && redraw) { nextFrame(); redraw = false; } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } Radian rot_x(0); Radian rot_y(0); Vector3 translate(Vector3::ZERO); switch (event.type) { case ALLEGRO_EVENT_TIMER: redraw = true; break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: if (event.mouse.button == 1) lmb = true; if (event.mouse.button == 2) rmb = true; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: if (event.mouse.button == 1) lmb = false; if (event.mouse.button == 2) rmb = false; if (!lmb && !rmb) al_show_mouse_cursor(display); break; case ALLEGRO_EVENT_MOUSE_AXES: if (lmb) { rot_x = Degree(-event.mouse.dx * 0.13); rot_y = Degree(-event.mouse.dy * 0.13); } if (rmb) { translate.x = event.mouse.dx * 0.5; translate.y = event.mouse.dy * -0.5; } if (lmb || rmb) { al_hide_mouse_cursor(display); al_set_mouse_xy(display, al_get_display_width(display)/2, al_get_display_height(display)/2); } break; case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_UP: { const bool is_down = (event.type == ALLEGRO_EVENT_KEY_DOWN); if (event.keyboard.keycode == ALLEGRO_KEY_W) forward = is_down; if (event.keyboard.keycode == ALLEGRO_KEY_S) back = is_down; if (event.keyboard.keycode == ALLEGRO_KEY_A) left = is_down; if (event.keyboard.keycode == ALLEGRO_KEY_D) right = is_down; break; } case ALLEGRO_EVENT_DISPLAY_RESIZE: { al_acknowledge_resize(event.display.source); int w = al_get_display_width(display); int h = al_get_display_height(display); mWindow->resize(w, h); mCamera->setAspectRatio(Real(w) / Real(h)); redraw = true; break; } } moveCamera(event.any.timestamp, rot_x, rot_y, translate); } } void Example::moveCamera(double timestamp, Radian rot_x, Radian rot_y, Vector3 & translate) { const double time_since_move = timestamp - lastMoveTime; const float move_scale = MOVE_SPEED * time_since_move; if (forward) { translate.z = -move_scale; } if (back) { translate.z = move_scale; } if (left) { translate.x = -move_scale; } if (right) { translate.x = move_scale; } if (translate == Vector3::ZERO) { // Continue previous motion but dampen. translate = last_translate; current_speed -= time_since_move * 0.3; } else { // Ramp up. current_speed += time_since_move; } if (current_speed > 1.0) current_speed = 1.0; if (current_speed < 0.0) current_speed = 0.0; translate *= current_speed; mCamera->yaw(rot_x); mCamera->pitch(rot_y); mCamera->moveRelative(translate); last_translate = translate; lastMoveTime = timestamp; } void Example::animate(double now) { const double dt0 = now - startTime; const double dt = now - lastRenderTime; // Animate the character. Entity *ent = mSceneMgr->getEntity("Ninja"); AnimationState *anim = ent->getAnimationState("Walk"); anim->addTime(dt); // Move the light around. Light *light = mSceneMgr->getLight("Light1"); light->setPosition(Vector3(300 * cos(dt0), 300, 300 * sin(dt0))); } void Example::nextFrame() { const double now = al_get_time(); animate(now); render(); lastRenderTime = now; } int main(int argc, char *argv[]) { (void)argc; (void)argv; ALLEGRO_DISPLAY *display; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_RESIZABLE); display = al_create_display(WIDTH, HEIGHT); if (!display) { abort_example("Error creating display\n"); } al_set_window_title(display, "My window"); { Example app(display); app.setup(); app.mainLoop(); } al_uninstall_system(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_mouse_events.c0000644000175000001440000001062212152725670017610 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "common.c" #define NUM_BUTTONS 5 static int actual_buttons; static void draw_mouse_button(int but, bool down) { const int offset[NUM_BUTTONS] = {0, 70, 35, 105, 140}; ALLEGRO_COLOR grey; ALLEGRO_COLOR black; int x; int y; x = 400 + offset[but]; y = 130; grey = al_map_rgb(0xe0, 0xe0, 0xe0); black = al_map_rgb(0, 0, 0); al_draw_filled_rectangle(x, y, x + 27, y + 42, grey); al_draw_rectangle(x + 0.5, y + 0.5, x + 26.5, y + 41.5, black, 0); if (down) { al_draw_filled_rectangle(x + 2, y + 2, x + 25, y + 40, black); } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *cursor; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; ALLEGRO_FONT *font; int mx = 0; int my = 0; int mz = 0; int mw = 0; int mmx = 0; int mmy = 0; int mmz = 0; int mmw = 0; bool in = true; bool buttons[NUM_BUTTONS] = {false}; int i; float p = 0.0; ALLEGRO_COLOR black; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); actual_buttons = al_get_mouse_num_buttons(); if (actual_buttons > NUM_BUTTONS) actual_buttons = NUM_BUTTONS; al_set_new_display_flags(ALLEGRO_RESIZABLE); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } al_hide_mouse_cursor(display); cursor = al_load_bitmap("data/cursor.tga"); if (!cursor) { abort_example("Error loading cursor.tga\n"); } font = al_load_font("data/fixed_font.tga", 1, 0); if (!font) { abort_example("data/fixed_font.tga not found\n"); } black = al_map_rgb_f(0, 0, 0); queue = al_create_event_queue(); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); while (1) { if (al_is_event_queue_empty(queue)) { al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); for (i = 0; i < actual_buttons; i++) { draw_mouse_button(i, buttons[i]); } al_draw_bitmap(cursor, mx, my, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, black, 5, 5, 0, "dx %i, dy %i, dz %i, dw %i", mmx, mmy, mmz, mmw); al_draw_textf(font, black, 5, 25, 0, "x %i, y %i, z %i, w %i", mx, my, mz, mw); al_draw_textf(font, black, 5, 45, 0, "p = %g", p); al_draw_textf(font, black, 5, 65, 0, "%s", in ? "in" : "out"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); mmx = mmy = mmz = 0; al_flip_display(); } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_MOUSE_AXES: mx = event.mouse.x; my = event.mouse.y; mz = event.mouse.z; mw = event.mouse.w; mmx = event.mouse.dx; mmy = event.mouse.dy; mmz = event.mouse.dz; mmw = event.mouse.dw; p = event.mouse.pressure; break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: if (event.mouse.button-1 < NUM_BUTTONS) { buttons[event.mouse.button-1] = true; } p = event.mouse.pressure; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: if (event.mouse.button-1 < NUM_BUTTONS) { buttons[event.mouse.button-1] = false; } p = event.mouse.pressure; break; case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: in = true; break; case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: in = false; break; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { goto done; } break; case ALLEGRO_EVENT_DISPLAY_RESIZE: al_acknowledge_resize(event.display.source); break; case ALLEGRO_EVENT_DISPLAY_CLOSE: goto done; } } done: al_destroy_event_queue(queue); return 0; } /* vim: set sw=3 sts=3 et: */ allegro-5.0.10/examples/ex_noframe.c0000644000175000001440000000467512152725670016536 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bitmap; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; bool down = false; int down_x = 0, down_y = 0; ALLEGRO_TIMER *timer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_mouse(); al_install_keyboard(); al_init_image_addon(); al_set_new_display_flags(ALLEGRO_FRAMELESS); display = al_create_display(300, 200); if (!display) { abort_example("Error creating display\n"); } bitmap = al_load_bitmap("data/fakeamp.bmp"); if (!bitmap) { abort_example("Error loading fakeamp.bmp\n"); } timer = al_create_timer(1.0f/30.0f); events = al_create_event_queue(); al_register_event_source(events, al_get_mouse_event_source()); al_register_event_source(events, al_get_keyboard_event_source()); al_register_event_source(events, al_get_display_event_source(display)); al_register_event_source(events, al_get_timer_event_source(timer)); al_start_timer(timer); for (;;) { al_wait_for_event(events, &event); if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { if (event.mouse.button == 1 && event.mouse.x) { down = true; down_x = event.mouse.x; down_y = event.mouse.y; } if (event.mouse.button == 2) { al_set_display_flag(display, ALLEGRO_FRAMELESS, !(al_get_display_flags(display) & ALLEGRO_FRAMELESS)); } } else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { if (event.mouse.button == 1) { down = false; } } else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { if (down) { int cx, cy; if (al_get_mouse_cursor_position(&cx, &cy)) { al_set_window_position(display, cx - down_x, cy - down_y); } } } else if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } else if (event.type == ALLEGRO_EVENT_TIMER) { al_draw_bitmap(bitmap, 0, 0, 0); al_flip_display(); } } al_destroy_timer(timer); al_destroy_event_queue(events); al_destroy_display(display); return 0; } allegro-5.0.10/examples/ex_expose.c0000644000175000001440000000525212152725670016402 0ustar tjadenusers#include #include #include #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bitmap; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_init_image_addon(); al_install_keyboard(); al_install_mouse(); al_set_new_display_flags(ALLEGRO_RESIZABLE | ALLEGRO_GENERATE_EXPOSE_EVENTS); al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, true, ALLEGRO_REQUIRE); display = al_create_display(320, 200); if (!display) { abort_example("Error creating display\n"); } bitmap = al_load_bitmap("data/mysha.pcx"); if (!bitmap) { abort_example("mysha.pcx not found or failed to load\n"); } al_draw_bitmap(bitmap, 0, 0, 0); al_flip_display(); timer = al_create_timer(0.1); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (true) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { al_acknowledge_resize(event.display.source); } if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { int x = event.display.x, y = event.display.y, w = event.display.width, h = event.display.height; /* Draw a red rectangle over the damaged area. */ al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_filled_rectangle(x, y, x + w, y + h, al_map_rgba_f(1, 0, 0, 1)); al_flip_display(); } if (event.type == ALLEGRO_EVENT_TIMER) { /* Slowly restore the original bitmap. */ int x, y; al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); for (y = 0; y < al_get_display_height(display); y += 200) { for (x = 0; x < al_get_display_width(display); x += 320) { al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 1, 1, 0.1), x, y, 0); } } al_flip_display(); } } al_destroy_event_queue(queue); al_destroy_bitmap(bitmap); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_physfs.c0000644000175000001440000000721512152725670016414 0ustar tjadenusers/* * Example program for Allegro library. * * Demonstrate PhysicsFS addon. */ #include #include #include #include #include #include "common.c" static void show_image(ALLEGRO_BITMAP *bmp) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); while (true) { al_draw_bitmap(bmp, 0, 0, 0); al_flip_display(); al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } al_destroy_event_queue(queue); } static void print_file(ALLEGRO_FS_ENTRY *entry) { int mode = al_get_fs_entry_mode(entry); time_t now = time(NULL); time_t atime = al_get_fs_entry_atime(entry); time_t ctime = al_get_fs_entry_ctime(entry); time_t mtime = al_get_fs_entry_mtime(entry); const char *name = al_get_fs_entry_name(entry); off_t size = al_get_fs_entry_size(entry); log_printf("%-36s %s%s%s%s%s%s %8u %8u %8u %8u\n", name, mode & ALLEGRO_FILEMODE_READ ? "r" : ".", mode & ALLEGRO_FILEMODE_WRITE ? "w" : ".", mode & ALLEGRO_FILEMODE_EXECUTE ? "x" : ".", mode & ALLEGRO_FILEMODE_HIDDEN ? "h" : ".", mode & ALLEGRO_FILEMODE_ISFILE ? "f" : ".", mode & ALLEGRO_FILEMODE_ISDIR ? "d" : ".", (unsigned)(now - ctime), (unsigned)(now - mtime), (unsigned)(now - atime), (unsigned)size); } static void listdir(ALLEGRO_FS_ENTRY *entry) { ALLEGRO_FS_ENTRY *next; al_open_directory(entry); while (1) { next = al_read_directory(entry); if (!next) break; print_file(next); if (al_get_fs_entry_mode(next) & ALLEGRO_FILEMODE_ISDIR) listdir(next); al_destroy_fs_entry(next); } al_close_directory(entry); } int main(int argc, const char *argv[]) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bmp; ALLEGRO_FS_ENTRY *entry; int i; if (!al_init()) { abort_example("Could not init Allegro\n"); } al_init_image_addon(); al_install_keyboard(); open_log_monospace(); /* Set up PhysicsFS. */ if (!PHYSFS_init(argv[0])) { abort_example("Could not init PhysFS\n"); } // This creates a ~/.allegro directory, which is very annoying to say the // least - and no need for it in this example. // if (!PHYSFS_setSaneConfig("allegro", "ex_physfs", NULL, 0, 0)) // return 1; if (!PHYSFS_addToSearchPath("data/ex_physfs.zip", 1)) { abort_example("Could load the zip file\n"); } for (i = 1; i < argc; i++) { if (!PHYSFS_addToSearchPath(argv[i], 1)) { abort_example("Couldn't add %s\n", argv[i]); } } display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } /* Make future calls to al_fopen() on this thread go to the PhysicsFS * backend. */ al_set_physfs_file_interface(); /* List the contents of our example zip recursively. */ log_printf("%-36s %-6s %8s %8s %8s %8s\n", "name", "flags", "ctime", "mtime", "atime", "size"); log_printf( "------------------------------------ " "------ " "-------- " "-------- " "-------- " "--------\n"); entry = al_create_fs_entry(""); listdir(entry); al_destroy_fs_entry(entry); bmp = al_load_bitmap("02.bmp"); if (bmp) { show_image(bmp); al_destroy_bitmap(bmp); } PHYSFS_deinit(); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_display_events.c0000644000175000001440000000672412152725670020135 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "common.c" #define MAX_EVENTS 23 static char events[MAX_EVENTS][1024]; static void add_event(char const *f, ...) { va_list args; memmove(events[1], events[0], (MAX_EVENTS - 1) * 1024); va_start(args, f); vsnprintf(events[0], 1024, f, args); va_end(args); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; ALLEGRO_FONT *font; int i; ALLEGRO_COLOR color, black, red, blue; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); al_set_new_display_flags(ALLEGRO_RESIZABLE); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } font = al_load_font("data/fixed_font.tga", 1, 0); if (!font) { abort_example("data/fixed_font.tga not found\n"); } black = al_map_rgb_f(0, 0, 0); red = al_map_rgb_f(1, 0, 0); blue = al_map_rgb_f(0, 0, 1); queue = al_create_event_queue(); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); while (1) { if (al_is_event_queue_empty(queue)) { float x = 8, y = 28; al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); al_draw_textf(font, blue, 8, 8, 0, "Display events (newest on top)"); color = red; for (i = 0; i < MAX_EVENTS; i++) { if (!events[i]) continue; al_draw_textf(font, color, x, y, 0, "%s", events[i]); color = black; y += 20; } al_flip_display(); } al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: add_event("ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY"); break; case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: add_event("ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY"); break; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { goto done; } break; case ALLEGRO_EVENT_DISPLAY_RESIZE: add_event("ALLEGRO_EVENT_DISPLAY_RESIZE x=%d, y=%d, " "width=%d, height=%d", event.display.x, event.display.y, event.display.width, event.display.height); al_acknowledge_resize(event.display.source); break; case ALLEGRO_EVENT_DISPLAY_CLOSE: add_event("ALLEGRO_EVENT_DISPLAY_CLOSE"); break; case ALLEGRO_EVENT_DISPLAY_LOST: add_event("ALLEGRO_EVENT_DISPLAY_LOST"); break; case ALLEGRO_EVENT_DISPLAY_FOUND: add_event("ALLEGRO_EVENT_DISPLAY_FOUND"); break; case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: add_event("ALLEGRO_EVENT_DISPLAY_SWITCH_OUT"); break; case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: add_event("ALLEGRO_EVENT_DISPLAY_SWITCH_IN"); break; } } done: al_destroy_event_queue(queue); return 0; } /* vim: set sw=3 sts=3 et: */ allegro-5.0.10/examples/ex_opengl_pixel_shader.c0000644000175000001440000000646311546006145021112 0ustar tjadenusers#include #include #include #include #include "common.c" GLhandleARB tinter; GLhandleARB tinter_shader; int main(void) { float r = 0.5, g = 0.5, b = 1, ratio = 0; int dir = 1; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *mysha; ALLEGRO_BITMAP *buffer; const char *tinter_shader_src[] = { "uniform sampler2D backBuffer;", "uniform float r;", "uniform float g;", "uniform float b;", "uniform float ratio;", "void main() {", " vec4 color;", " float avg, dr, dg, db;", " color = texture2D(backBuffer, gl_TexCoord[0].st);", " avg = (color.r + color.g + color.b) / 3.0;", " dr = avg * r;", " dg = avg * g;", " db = avg * b;", " color.r = color.r - (ratio * (color.r - dr));", " color.g = color.g - (ratio * (color.g - dg));", " color.b = color.b - (ratio * (color.b - db));", " gl_FragColor = color;", "}" }; const int TINTER_LEN = 18; double start; GLint loc; if (!al_init()) { abort_example("Could not init Allegro\n"); } al_install_keyboard(); al_init_image_addon(); al_set_new_display_flags(ALLEGRO_OPENGL); display = al_create_display(320, 200); if (!display) { abort_example("Error creating display\n"); } mysha = al_load_bitmap("data/mysha.pcx"); if (!mysha) { abort_example("Could not load image.\n"); } buffer = al_create_bitmap(320, 200); if (!al_have_opengl_extension("GL_EXT_framebuffer_object") && !al_have_opengl_extension("GL_ARB_fragment_shader")) { abort_example("Fragment shaders not supported.\n"); } tinter_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); glShaderSourceARB(tinter_shader, TINTER_LEN, tinter_shader_src, NULL); glCompileShaderARB(tinter_shader); tinter = glCreateProgramObjectARB(); glAttachObjectARB(tinter, tinter_shader); glLinkProgramARB(tinter); loc = glGetUniformLocationARB(tinter, "backBuffer"); glUniform1iARB(loc, al_get_opengl_texture(buffer)); start = al_get_time(); while (1) { double now, diff; ALLEGRO_KEYBOARD_STATE state; al_get_keyboard_state(&state); if (al_key_down(&state, ALLEGRO_KEY_ESCAPE)) { break; } now = al_get_time(); diff = now - start; start = now; ratio += diff * 0.5 * dir; if (dir < 0 && ratio < 0) { ratio = 0; dir = -dir; } else if (dir > 0 && ratio > 1) { ratio = 1; dir = -dir; } al_set_target_bitmap(buffer); glUseProgramObjectARB(tinter); loc = glGetUniformLocationARB(tinter, "ratio"); glUniform1fARB(loc, ratio); loc = glGetUniformLocationARB(tinter, "r"); glUniform1fARB(loc, r); loc = glGetUniformLocationARB(tinter, "g"); glUniform1fARB(loc, g); loc = glGetUniformLocationARB(tinter, "b"); glUniform1fARB(loc, b); al_draw_bitmap(mysha, 0, 0, 0); glUseProgramObjectARB(0); al_set_target_backbuffer(display); al_draw_bitmap(buffer, 0, 0, 0); al_flip_display(); al_rest(0.001); } glDetachObjectARB(tinter, tinter_shader); glDeleteObjectARB(tinter_shader); al_uninstall_system(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_threads2.c0000644000175000001440000002430212152725670016610 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * In this example, threads render to their own memory buffers, while the * main thread handles events and drawing (copying from the memory buffers * to the display). * * Click on an image to pause its thread. */ #include #include #include "common.c" /* feel free to bump these up */ #define NUM_THREADS 9 #define IMAGES_PER_ROW 3 /* size of each fractal image */ #define W 120 #define H 120 typedef struct ThreadInfo { ALLEGRO_BITMAP *bitmap; ALLEGRO_MUTEX *mutex; ALLEGRO_COND *cond; bool is_paused; int random_seed; double target_x, target_y; } ThreadInfo; typedef struct Viewport { double centre_x; double centre_y; double x_extent; double y_extent; double zoom; } Viewport; static ThreadInfo thread_info[NUM_THREADS]; unsigned char sin_lut[256]; static double cabs2(double re, double im) { return re*re + im*im; } static int mandel(double cre, double cim, int MAX_ITER) { const float Z_MAX2 = 4.0; double zre = cre, zim = cim; int iter; for (iter = 0; iter < MAX_ITER; iter++) { double z1re, z1im; z1re = zre * zre - zim * zim; z1im = 2 * zre * zim; z1re += cre; z1im += cim; if (cabs2(z1re, z1im) > Z_MAX2) { return iter + 1; /* outside set */ } zre = z1re; zim = z1im; } return 0; /* inside set */ } /* local_rand: * Simple rand() replacement with guaranteed randomness in the lower 16 bits. * We just need a RNG with a thread-safe interface. */ static int local_rand(int *seed) { const int LOCAL_RAND_MAX = 0xFFFF; *seed = (*seed + 1) * 1103515245 + 12345; return ((*seed >> 16) & LOCAL_RAND_MAX); } static void random_palette(unsigned char palette[256][3], int *seed) { unsigned char rmax = 128 + local_rand(seed) % 128; unsigned char gmax = 128 + local_rand(seed) % 128; unsigned char bmax = 128 + local_rand(seed) % 128; int i; for (i = 0; i < 256; i++) { palette[i][0] = rmax * i / 256; palette[i][1] = gmax * i / 256; palette[i][2] = bmax * i / 256; } } static void draw_mandel_line(ALLEGRO_BITMAP *bitmap, const Viewport *viewport, unsigned char palette[256][3], const int y) { ALLEGRO_LOCKED_REGION *lr; unsigned char *rgb; double xlower, ylower; double xscale, yscale; double im; double re; int w, h; int x; int n = 512 / pow(2, viewport->zoom); w = al_get_bitmap_width(bitmap); h = al_get_bitmap_height(bitmap); if (!(lr = al_lock_bitmap_region(bitmap, 0, y, w, 1, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, ALLEGRO_LOCK_WRITEONLY))) { abort_example("draw_mandel_line: al_lock_bitmap_region failed\n"); } xlower = viewport->centre_x - viewport->x_extent / 2.0 * viewport->zoom; ylower = viewport->centre_y - viewport->y_extent / 2.0 * viewport->zoom; xscale = viewport->x_extent / w * viewport->zoom; yscale = viewport->y_extent / h * viewport->zoom; re = xlower; im = ylower + y * yscale; rgb = lr->data; for (x = 0; x < w; x++) { int i = mandel(re, im, n); int v = sin_lut[(int)(i * 64 / n)]; rgb[0] = palette[v][0]; rgb[1] = palette[v][1]; rgb[2] = palette[v][2]; rgb += 3; re += xscale; } al_unlock_bitmap(bitmap); } static void *thread_func(ALLEGRO_THREAD *thr, void *arg) { ThreadInfo *info = (ThreadInfo *) arg; Viewport viewport; unsigned char palette[256][3]; int y, h; y = 0; h = al_get_bitmap_height(info->bitmap); viewport.centre_x = info->target_x; viewport.centre_y = info->target_y; viewport.x_extent = 3.0; viewport.y_extent = 3.0; viewport.zoom = 1.0; info->target_x = 0; info->target_y = 0; while (!al_get_thread_should_stop(thr)) { al_lock_mutex(info->mutex); while (info->is_paused) { al_wait_cond(info->cond, info->mutex); /* We might be awoken because the program is terminating. */ if (al_get_thread_should_stop(thr)) { break; } } if (!info->is_paused) { if (y == 0) { random_palette(palette, &info->random_seed); } draw_mandel_line(info->bitmap, &viewport, palette, y); y++; if (y >= h) { double z = viewport.zoom; y = 0; viewport.centre_x += z * viewport.x_extent * info->target_x; viewport.centre_y += z * viewport.y_extent * info->target_y; info->target_x = 0; info->target_y = 0; viewport.zoom *= 0.99; } } al_unlock_mutex(info->mutex); al_rest(0); } return NULL; } static void show_images(void) { int x = 0; int y = 0; int i; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); for (i = 0; i < NUM_THREADS; i++) { /* for lots of threads, this is not good enough */ al_lock_mutex(thread_info[i].mutex); al_draw_bitmap(thread_info[i].bitmap, x * W, y * H, 0); al_unlock_mutex(thread_info[i].mutex); x++; if (x == IMAGES_PER_ROW) { x = 0; y++; } } al_flip_display(); } static void set_target(int n, double x, double y) { thread_info[n].target_x = x; thread_info[n].target_y = y; } static void toggle_pausedness(int n) { ThreadInfo *info = &thread_info[n]; al_lock_mutex(info->mutex); info->is_paused = !info->is_paused; al_broadcast_cond(info->cond); al_unlock_mutex(info->mutex); } int main(void) { ALLEGRO_THREAD *thread[NUM_THREADS]; ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; bool need_draw; int i; for (i = 0; i < 256; i++) { sin_lut[i] = 128 + (int) (127.0 * sin(i / 8.0)); } if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); display = al_create_display(W * IMAGES_PER_ROW, H * NUM_THREADS / IMAGES_PER_ROW); if (!display) { abort_example("Error creating display\n"); } timer = al_create_timer(1.0/3); if (!timer) { abort_example("Error creating timer\n"); } queue = al_create_event_queue(); if (!queue) { abort_example("Error creating event queue\n"); } al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); /* Note: * Right now, A5 video displays can only be accessed from the thread which * created them (at least for OpenGL). To lift this restriction, we could * keep track of the current OpenGL context for each thread and make all * functions accessing the display check for it.. not sure it's worth the * additional complexity though. */ al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_888); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); for (i = 0; i < NUM_THREADS; i++) { thread_info[i].bitmap = al_create_bitmap(W, H); if (!thread_info[i].bitmap) { goto Error; } thread_info[i].mutex = al_create_mutex(); if (!thread_info[i].mutex) { goto Error; } thread_info[i].cond = al_create_cond(); if (!thread_info[i].cond) { goto Error; } thread_info[i].is_paused = false; thread_info[i].random_seed = i; thread[i] = al_create_thread(thread_func, &thread_info[i]); if (!thread[i]) { goto Error; } } set_target(0, -0.56062033041600878303, -0.56064322926933807256); set_target(1, -0.57798076669230014080, -0.63449861991138123418); set_target(2, 0.36676836392830602929, -0.59081385302214906030); set_target(3, -1.48319283039401317303, -0.00000000200514696273); set_target(4, -0.74052910500707636032, 0.18340899525730713915); set_target(5, 0.25437906525768350097, -0.00046678223345789554); set_target(6, -0.56062033041600878303, 0.56064322926933807256); set_target(7, -0.57798076669230014080, 0.63449861991138123418); set_target(8, 0.36676836392830602929, 0.59081385302214906030); for (i = 0; i < NUM_THREADS; i++) { al_start_thread(thread[i]); } al_start_timer(timer); need_draw = true; while (true) { if (need_draw && al_is_event_queue_empty(queue)) { show_images(); need_draw = false; } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_TIMER) { need_draw = true; } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { int n = (event.mouse.y / H) * IMAGES_PER_ROW + (event.mouse.x / W); if (n < NUM_THREADS) { double x = event.mouse.x - (event.mouse.x / W) * W; double y = event.mouse.y - (event.mouse.y / H) * H; /* Center to the mouse click position. */ if (thread_info[n].is_paused) { thread_info[n].target_x = x / W - 0.5; thread_info[n].target_y = y / H - 0.5; } toggle_pausedness(n); } } else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { need_draw = true; } else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } need_draw = true; } } for (i = 0; i < NUM_THREADS; i++) { /* Set the flag to stop the thread. The thread might be waiting on a * condition variable, so signal the condition to force it to wake up. */ al_set_thread_should_stop(thread[i]); al_lock_mutex(thread_info[i].mutex); al_broadcast_cond(thread_info[i].cond); al_unlock_mutex(thread_info[i].mutex); /* al_destroy_thread() implicitly joins the thread, so this call is not * strictly necessary. */ al_join_thread(thread[i], NULL); al_destroy_thread(thread[i]); } al_destroy_event_queue(queue); al_destroy_timer(timer); al_destroy_display(display); return 0; Error: return 1; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_vsync.c0000644000175000001440000001144612152725670016243 0ustar tjadenusers/* Tests vsync. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "common.c" int vsync, fullscreen, frequency; static int option(ALLEGRO_CONFIG *config, char *name, int v) { char const *value; char str[256]; value = al_get_config_value(config, "settings", name); if (value) v = strtol(value, NULL, 0); sprintf(str, "%d", v); al_set_config_value(config, "settings", name, str); return v; } static bool display_warning(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_FONT *font) { ALLEGRO_EVENT event; float x = 320.0; float h = al_get_font_line_height(font); ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); for (;;) { float y = 200.0; al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_text(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "Do not continue if you suffer from photosensitive epilepsy"); al_draw_text(font, white, x, y + 15, ALLEGRO_ALIGN_CENTRE, "or simply hate flashing screens."); al_draw_text(font, white, x, y + 40, ALLEGRO_ALIGN_CENTRE, "Press Escape to quit or Enter to continue."); y += 100; al_draw_text(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "Parameters from ex_vsync.ini:"); y += h; al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "vsync: %d", vsync); y += h; al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "fullscreen: %d", fullscreen); y += h; al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "frequency: %d", frequency); al_flip_display(); al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { return true; } if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { return false; } } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { return true; } } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; ALLEGRO_CONFIG *config; ALLEGRO_EVENT_QUEUE *queue; bool write = false; bool flip = false; bool quit; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_font_addon(); al_init_image_addon(); al_install_keyboard(); al_install_mouse(); /* Read parameters from ex_vsync.ini. */ config = al_load_config_file("ex_vsync.ini"); if (!config) { config = al_create_config(); write = true; } /* 0 -> Driver chooses. * 1 -> Force vsync on. * 2 -> Force vsync off. */ vsync = option(config, "vsync", 0); fullscreen = option(config, "fullscreen", 0); frequency = option(config, "frequency", 0); /* Write the file back (so a template is generated on first run). */ if (write) { al_save_config_file("ex_vsync.ini", config); } al_destroy_config(config); /* Vsync 1 means force on, 2 means forced off. */ if (vsync) al_set_new_display_option(ALLEGRO_VSYNC, vsync, ALLEGRO_SUGGEST); /* Force fullscreen mode. */ if (fullscreen) { al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); /* Set a monitor frequency. */ if (frequency) al_set_new_display_refresh_rate(frequency); } display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } font = al_load_font("data/a4_font.tga", 0, 0); if (!font) { abort_example("Failed to load a4_font.tga\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); quit = display_warning(queue, font); al_flush_event_queue(queue); while (!quit) { ALLEGRO_EVENT event; /* With vsync, this will appear as a 50% gray screen (maybe * flickering a bit depending on monitor frequency). * Without vsync, there will be black/white shearing all over. */ if (flip) al_clear_to_color(al_map_rgb_f(1, 1, 1)); else al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_flip_display(); flip = !flip; while (al_get_next_event(queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: quit = true; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) quit = true; } } /* Let's not go overboard and limit flipping at 1000 Hz. Without * this my system locks up and requires a hard reboot :P */ al_rest(0.001); } al_destroy_font(font); al_destroy_event_queue(queue); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_rotate.c0000644000175000001440000001113712152725670016374 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. */ #include #include "allegro5/allegro_image.h" #include #include "common.c" int main(void) { const int display_w = 640; const int display_h = 480; ALLEGRO_DISPLAY *dpy; ALLEGRO_BITMAP *buf; ALLEGRO_BITMAP *bmp; ALLEGRO_BITMAP *mem_bmp; ALLEGRO_BITMAP *src_bmp; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; double theta = 0; double k = 1.0; int mode = 0; bool wide_mode = false; bool mem_src_mode = false; bool trans_mode = false; int flags = 0; bool clip_mode = false; ALLEGRO_COLOR trans; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); open_log(); log_printf("Press 'w' to toggle wide mode.\n"); log_printf("Press 's' to toggle memory source bitmap.\n"); log_printf("Press space to toggle drawing to backbuffer or off-screen bitmap.\n"); log_printf("Press 't' to toggle translucency.\n"); log_printf("Press 'h' to toggle horizontal flipping.\n"); log_printf("Press 'v' to toggle vertical flipping.\n"); log_printf("Press 'c' to toggle clipping.\n"); log_printf("\n"); dpy = al_create_display(display_w, display_h); if (!dpy) { abort_example("Unable to set any graphic mode\n"); } buf = al_create_bitmap(display_w, display_h); if (!buf) { abort_example("Unable to create buffer\n\n"); } bmp = al_load_bitmap("data/mysha.pcx"); if (!bmp) { abort_example("Unable to load image\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); mem_bmp = al_load_bitmap("data/mysha.pcx"); if (!mem_bmp) { abort_example("Unable to load image\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); while (true) { if (al_get_next_event(queue, &event)) { if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.unichar == ' ') { mode = !mode; if (mode == 0) log_printf("Drawing to off-screen buffer\n"); else log_printf("Drawing to display backbuffer\n"); } if (event.keyboard.unichar == 'w') wide_mode = !wide_mode; if (event.keyboard.unichar == 's') { mem_src_mode = !mem_src_mode; if (mem_src_mode) log_printf("Source is memory bitmap\n"); else log_printf("Source is display bitmap\n"); } if (event.keyboard.unichar == 't') trans_mode = !trans_mode; if (event.keyboard.unichar == 'h') flags ^= ALLEGRO_FLIP_HORIZONTAL; if (event.keyboard.unichar == 'v') flags ^= ALLEGRO_FLIP_VERTICAL; if (event.keyboard.unichar == 'c') clip_mode = !clip_mode; } } /* * mode 0 = draw scaled to off-screen buffer before * blitting to display backbuffer * mode 1 = draw scaled to display backbuffer */ if (mode == 0) { al_set_target_bitmap(buf); } else { al_set_target_backbuffer(dpy); } src_bmp = (mem_src_mode) ? mem_bmp : bmp; k = (wide_mode) ? 2.0 : 1.0; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); trans = al_map_rgba_f(1, 1, 1, 1); if (mode == 0) al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); else al_clear_to_color(al_map_rgba_f(0, 0, 1, 1)); if (trans_mode) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); trans = al_map_rgba_f(1, 1, 1, 0.5); } if (clip_mode) { al_set_clipping_rectangle(50, 50, display_w - 100, display_h - 100); } else { al_set_clipping_rectangle(0, 0, display_w, display_h); } al_draw_tinted_scaled_rotated_bitmap(src_bmp, trans, 50, 50, display_w/2, display_h/2, k, k, theta, flags); if (mode == 0) { al_set_target_backbuffer(dpy); al_set_clipping_rectangle(0, 0, display_w, display_h); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(buf, 0, 0, 0); } al_flip_display(); al_rest(0.01); theta -= 0.01; } al_destroy_bitmap(bmp); al_destroy_bitmap(mem_bmp); al_destroy_bitmap(buf); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_file_slice.c0000644000175000001440000000544012152725670017174 0ustar tjadenusers/* * ex_file_slice - Use slices to pack many objects into a single file. * * This example packs two strings into a single file, and then uses a * file slice to open them one at a time. While this usage is contrived, * the same principle can be used to pack multiple images (for example) * into a single file, and later read them back via Allegro's image loader. * */ #include "allegro5/allegro.h" #include "common.c" #define BUFFER_SIZE 1024 static void pack_object(ALLEGRO_FILE *file, const void *object, size_t len) { /* First write the length of the object, so we know how big to make the slice when it is opened later. */ al_fwrite32le(file, len); al_fwrite(file, object, len); } static ALLEGRO_FILE *get_next_chunk(ALLEGRO_FILE *file) { /* Reads the length of the next chunk, and if not at end of file, returns a slice that represents that portion of the file. */ const uint32_t length = al_fread32le(file); return !al_feof(file) ? al_fopen_slice(file, length, "rw") : NULL; } int main(int argc, const char *argv[]) { ALLEGRO_FILE *master, *slice; ALLEGRO_PATH *tmp_path; const char *first_string = "Hello, World!"; const char *second_string = "The quick brown fox jumps over the lazy dog."; char buffer[BUFFER_SIZE]; (void) argc, (void) argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); master = al_make_temp_file("ex_file_slice_XXXX", &tmp_path); if (!master) { abort_example("Unable to create temporary file\n"); } /* Pack both strings into the master file. */ pack_object(master, first_string, strlen(first_string)); pack_object(master, second_string, strlen(second_string)); /* Seek back to the beginning of the file, as if we had just opened it */ al_fseek(master, 0, ALLEGRO_SEEK_SET); /* Loop through the main file, opening a slice for each object */ while ((slice = get_next_chunk(master))) { /* Note: While the slice is open, we must avoid using the master file! If you were dealing with packed images, this is where you would pass 'slice' to al_load_bitmap_f(). */ if (al_fsize(slice) < BUFFER_SIZE) { /* We could have used al_fgets(), but just to show that the file slice is constrained to the string object, we'll read the entire slice. */ al_fread(slice, buffer, al_fsize(slice)); buffer[al_fsize(slice)] = 0; log_printf("Chunk of size %d: '%s'\n", (int) al_fsize(slice), buffer); } /* The slice must be closed before the next slice is opened. Closing the slice will advanced the master file to the end of the slice. */ al_fclose(slice); } al_fclose(master); al_remove_filename(al_path_cstr(tmp_path, '/')); close_log(true); return 0; } allegro-5.0.10/examples/ex_threads.c0000644000175000001440000001277412152725670016540 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * In this example, each thread handles its own window and event queue. */ #include #include #include #include "common.c" #define MAX_THREADS 100 #define MAX_BACKGROUNDS 10 #define MAX_SQUARES 25 typedef struct Background { double rmax; double gmax; double bmax; } Background; typedef struct Square { float cx, cy; float dx, dy; float size, dsize; float rot, drot; float life, dlife; } Square; static float rand01(void) { return (rand() % 10000) / 10000.0; } static float rand11(void) { return (-10000 + (rand() % 20000)) / 20000.0; } static void gen_square(Square *sq, int w, int h) { sq->cx = rand() % w; sq->cy = rand() % h; sq->dx = 3.0 * rand11(); sq->dy = 3.0 * rand11(); sq->size = 10 + (rand() % 10); sq->dsize = rand11(); sq->rot = ALLEGRO_PI * rand01(); sq->drot = rand11() / 3.0; sq->life = 0.0; sq->dlife = (ALLEGRO_PI / 100.0) + (ALLEGRO_PI / 30.0) * rand01(); } static void animate_square(Square *sq) { sq->cx += sq->dx; sq->cy += sq->dy; sq->size += sq->dsize; sq->rot += sq->drot; sq->life += sq->dlife; if (sq->size < 1.0 || sq->life > ALLEGRO_PI) { ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); gen_square(sq, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp)); } } static void draw_square(Square *sq) { ALLEGRO_TRANSFORM trans; float alpha; float size; ALLEGRO_COLOR tint; al_build_transform(&trans, sq->cx, sq->cy, 1.0, 1.0, sq->rot); al_use_transform(&trans); alpha = sin(sq->life); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); tint = al_map_rgba_f(0.5, 0.3, 0, alpha); size = sq->size; al_draw_filled_rounded_rectangle(-size, -size, size, size, 3, 3, tint); size *= 1.1; al_draw_rounded_rectangle(-size, -size, size, size, 3, 3, tint, 2); } static void *thread_func(ALLEGRO_THREAD *thr, void *arg) { const int INITIAL_WIDTH = 300; const int INITIAL_HEIGHT = 300; const Background *background = (Background *) arg; ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue = NULL; ALLEGRO_TIMER *timer = NULL; ALLEGRO_EVENT event; ALLEGRO_STATE state; Square squares[MAX_SQUARES]; double theta = 0.0; bool redraw = true; int i; (void)thr; al_set_new_display_flags(ALLEGRO_RESIZABLE); display = al_create_display(INITIAL_WIDTH, INITIAL_HEIGHT); if (!display) { goto Quit; } queue = al_create_event_queue(); if (!queue) { goto Quit; } timer = al_create_timer(0.1); if (!timer) { goto Quit; } al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_timer_event_source(timer)); for (i = 0; i < MAX_SQUARES; i++) { gen_square(&squares[i], INITIAL_WIDTH, INITIAL_HEIGHT); } al_start_timer(timer); while (true) { if (al_is_event_queue_empty(queue) && redraw) { double r = 0.7 + 0.3 * (sin(theta) + 1.0) / 2.0; ALLEGRO_COLOR c = al_map_rgb_f( background->rmax * r, background->gmax * r, background->bmax * r ); al_clear_to_color(c); al_store_state(&state, ALLEGRO_STATE_BLENDER | ALLEGRO_STATE_TRANSFORM); for (i = 0; i < MAX_SQUARES; i++) { draw_square(&squares[i]); } al_restore_state(&state); al_flip_display(); redraw = false; } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_TIMER) { for (i = 0; i < MAX_SQUARES; i++) { animate_square(&squares[i]); } theta += 0.1; redraw = true; } else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { al_acknowledge_resize(event.display.source); } } Quit: if (timer) { al_destroy_timer(timer); } if (queue) { al_destroy_event_queue(queue); } if (display) { al_destroy_display(display); } return NULL; } int main(int argc, const char *argv[]) { ALLEGRO_THREAD *thread[MAX_THREADS]; Background background[MAX_BACKGROUNDS] = { { 1.0, 0.5, 0.5 }, { 0.5, 1.0, 0.5 }, { 0.5, 0.5, 1.0 }, { 1.0, 1.0, 0.5 }, { 0.5, 1.0, 1.0 }, { 1.0, 0.7, 0.5 }, { 0.5, 1.0, 0.7 }, { 0.7, 0.5, 1.0 }, { 1.0, 0.7, 0.5 }, { 0.5, 0.7, 1.0 } }; int num_threads; int i; if (argc > 1) { num_threads = strtol(argv[1], NULL, 10); if (num_threads > MAX_THREADS) num_threads = MAX_THREADS; else if (num_threads < 1) num_threads = 1; } else { num_threads = 3; } if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); for (i = 0; i < num_threads; i++) { thread[i] = al_create_thread(thread_func, &background[i % MAX_BACKGROUNDS]); } for (i = 0; i < num_threads; i++) { al_start_thread(thread[i]); } for (i = 0; i < num_threads; i++) { al_join_thread(thread[i], NULL); al_destroy_thread(thread[i]); } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_bitmap_target.c0000644000175000001440000001134112152725670017715 0ustar tjadenusers/* An example comparing FPS when drawing to a bitmap with the * ALLEGRO_FORCE_LOCKING flag and without. Mainly meant as a test how much * speedup direct drawing can give over the slow locking. */ #include #include #include #include #include #include #include #include "common.c" const int W = 300, H = 300; /* Size of target bitmap. */ const int RW = 50, RH = 50; /* Size of rectangle we draw to it. */ ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *target; /* The target bitmap. */ float x, y, dx, dy; /* Position and velocity of moving rectangle. */ double last_time; /* For controling speed. */ bool quit; /* Flag to record Esc key or X button. */ ALLEGRO_FONT *myfont; /* Our font. */ ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */ /* Print some text with a shadow. */ static void print(int x, int y, char const *format, ...) { va_list list; char message[1024]; va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_text(myfont, al_map_rgb(0, 0, 0), x + 2, y + 2, 0, message); al_draw_text(myfont, al_map_rgb(255, 255, 255), x, y, 0, message); } /* Draw our example scene. */ static void draw(void) { float xs, ys, a; double dt = 0; double t = al_get_time(); if (last_time > 0) { dt = t - last_time; } last_time = t; al_set_target_bitmap(target); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_filled_rectangle(x, y, x + RW, y + RH, al_map_rgba_f(1, 0, 0, 1)); al_draw_filled_rectangle(0, 0, W, H, al_map_rgba_f(1, 1, 0, 0.1)); x += dx * dt; if (x < 0) { x = 0; dx = -dx; } if (x + RW > W) { x = W - RW; dx = -dx; } y += dy * dt; if (y < 0) { y = 0; dy = -dy; } if (y + RH > H) { y = H - RH; dy = -dy; } al_set_target_backbuffer(display); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_clear_to_color(al_map_rgba_f(0, 0, 1, 1)); xs = 1 + 0.2 * sin(t * ALLEGRO_PI * 2); ys = 1 + 0.2 * sin(t * ALLEGRO_PI * 2); a = t * ALLEGRO_PI * 2 / 3; al_draw_scaled_rotated_bitmap(target, W / 2, H / 2, 320, 240, xs, ys, a, 0); } /* Run the FPS test. */ static void run(void) { ALLEGRO_EVENT event; int frames = 0; double start; target = al_create_bitmap(W, H); al_set_target_bitmap(target); al_clear_to_color(al_map_rgba_f(1, 1, 0, 1)); al_set_target_backbuffer(display); dx = 81; dy = 63; start = al_get_time(); while (true) { /* Check for ESC key or close button event and quit in either case. */ if (!al_is_event_queue_empty(queue)) { while (al_get_next_event(queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: quit = true; goto done; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { quit = true; goto done; } if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { goto done; } break; } } } draw(); print(0, 0, "FPS: %.1f", frames / (al_get_time() - start)); if (al_get_new_bitmap_flags() & ALLEGRO_FORCE_LOCKING) { print(0, al_get_font_line_height(myfont), "using forced bitmap locking"); } else { print(0, al_get_font_line_height(myfont), "drawing directly to bitmap"); } print(0, al_get_font_line_height(myfont) * 2, "Press SPACE to toggle drawing method."); al_flip_display(); frames++; } done: al_destroy_bitmap(target); } int main(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); myfont = al_load_font("data/font.tga", 0, 0); if (!myfont) { abort_example("font.tga not found\n"); } while (!quit) { if (al_get_new_bitmap_flags() & ALLEGRO_FORCE_LOCKING) al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); else al_set_new_bitmap_flags(ALLEGRO_FORCE_LOCKING); run(); } al_destroy_event_queue(queue); return 0; } allegro-5.0.10/examples/ex_mouse_focus.c0000644000175000001440000000456212152725670017431 0ustar tjadenusers/* * Example program for the Allegro library. * * This program tests if the ALLEGRO_MOUSE_STATE `display' field * is set correctly. */ #include #include "allegro5/allegro.h" #include "common.c" static ALLEGRO_DISPLAY *display1; static ALLEGRO_DISPLAY *display2; static void redraw(ALLEGRO_COLOR color1, ALLEGRO_COLOR color2) { al_set_target_backbuffer(display1); al_clear_to_color(color1); al_flip_display(); al_set_target_backbuffer(display2); al_clear_to_color(color2); al_flip_display(); } int main(void) { ALLEGRO_COLOR black; ALLEGRO_COLOR red; ALLEGRO_MOUSE_STATE mst0; ALLEGRO_MOUSE_STATE mst; ALLEGRO_KEYBOARD_STATE kst; if (!al_init()) { abort_example("Couldn't initialise Allegro.\n"); } if (!al_install_mouse()) { abort_example("Couldn't install mouse.\n"); } if (!al_install_keyboard()) { abort_example("Couldn't install keyboard.\n"); } display1 = al_create_display(300, 300); display2 = al_create_display(300, 300); if (!display1 || !display2) { al_destroy_display(display1); al_destroy_display(display2); abort_example("Couldn't open displays.\n"); } open_log(); log_printf("Move the mouse cursor over the displays\n"); black = al_map_rgb(0, 0, 0); red = al_map_rgb(255, 0, 0); memset(&mst0, 0, sizeof(mst0)); while (1) { al_get_mouse_state(&mst); if (mst.display != mst0.display || mst.x != mst0.x || mst.y != mst0.y) { if (mst.display == NULL) log_printf("Outside either display\n"); else if (mst.display == display1) log_printf("In display 1, x = %d, y = %d\n", mst.x, mst.y); else if (mst.display == display2) log_printf("In display 2, x = %d, y = %d\n", mst.x, mst.y); else { log_printf("Unknown display = %p, x = %d, y = %d\n", mst.display, mst.x, mst.y); } mst0 = mst; } if (mst.display == display1) { redraw(red, black); } else if (mst.display == display2) { redraw(black, red); } else { redraw(black, black); } al_rest(0.1); al_get_keyboard_state(&kst); if (al_key_down(&kst, ALLEGRO_KEY_ESCAPE)) { break; } } close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_path.c0000644000175000001440000000443312152725670016033 0ustar tjadenusers#include #include #include "common.c" int main(int argc, char **argv) { ALLEGRO_PATH *dyn = NULL; ALLEGRO_PATH *tostring = NULL; ALLEGRO_PATH *cloned = NULL; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 2) { ALLEGRO_PATH *exe = al_create_path(argv[0]); if (exe) { log_printf("This example needs to be run from the command line.\nUsage1: %s \n", al_get_path_filename(exe)); al_destroy_path(exe); } else { log_printf("This example needs to be run from the command line.\nUsage2: %s \n", argv[0]); } goto done; } dyn = al_create_path(argv[1]); if (!dyn) { log_printf("Failed to create path structure for '%s'.\n", argv[1]); } else { log_printf("dyn: drive=\"%s\", file=\"%s\"\n", al_get_path_drive(dyn), al_get_path_filename(dyn)); al_destroy_path(dyn); } tostring = al_create_path(argv[1]); if (!tostring) { log_printf("Failed to create path structure for tostring test\n"); } else { int i; log_printf("tostring: '%s'\n", al_path_cstr(tostring, '/')); log_printf("tostring: drive:'%s'", al_get_path_drive(tostring)); log_printf(" dirs:"); for (i = 0; i < al_get_path_num_components(tostring); i++) { if (i > 0) log_printf(","); log_printf(" '%s'", al_get_path_component(tostring, i)); } log_printf(" filename:'%s'\n", al_get_path_filename(tostring)); al_destroy_path(tostring); } /* FIXME: test out more of the al_path_ functions, ie: insert, remove, * concat, relative */ dyn = al_create_path(argv[1]); if(dyn) { cloned = al_clone_path(dyn); if(cloned) { log_printf("dyn: '%s'\n", al_path_cstr(dyn, '/')); al_make_path_canonical(cloned); log_printf("can: '%s'\n", al_path_cstr(cloned, '/')); al_destroy_path(dyn); al_destroy_path(cloned); } else { log_printf("failed to clone ALLEGRO_PATH :(\n"); al_destroy_path(dyn); } } else { log_printf("failed to create new ALLEGRO_PATH for cloning..."); } done: close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_gldepth.c0000644000175000001440000001415412152725670016527 0ustar tjadenusers/* An example program showing how to set and use a depth buffer with an OpenGL * display. Use arrow keys to rotate, PgUp/PgDown to move closer/farther away. */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_opengl.h" #include "allegro5/allegro_font.h" #include "common.c" struct camera { double xangle, yangle, zangle; double dist; }; struct camera camera = { 0.0, 0.0, 0.0, 20.0 }; double angle_speed = 5.0; double dist_speed = 1.0; GLuint tex; ALLEGRO_BITMAP *bmp; bool key[ALLEGRO_KEY_MAX]; static void set_camera_position(void) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 40.0); glTranslatef(0, 0, -camera.dist); glRotatef(camera.xangle, 1, 0, 0); glRotatef(camera.yangle, 0, 1, 0); glRotatef(camera.zangle, 0, 0, 1); glMatrixMode(GL_MODELVIEW); } static void keyboard(void) { if(key[ALLEGRO_KEY_LEFT]) camera.yangle += angle_speed; if(key[ALLEGRO_KEY_RIGHT]) camera.yangle -= angle_speed; if(key[ALLEGRO_KEY_UP]) camera.xangle += angle_speed; if(key[ALLEGRO_KEY_DOWN]) camera.xangle -= angle_speed; if(key[ALLEGRO_KEY_PGUP]) camera.dist -= dist_speed; if(key[ALLEGRO_KEY_PGDN]) camera.dist += dist_speed; } static void draw(void) { // Clear the RGB buffer and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set the modelview matrix to be the identity matrix glLoadIdentity(); // Translate and rotate the object glTranslatef(-2.5, 0.0, 0.0); glRotatef(-30, 1.0, 0.0, 0.0); glRotatef(30, 0.0, 1.0, 0.0); glRotatef(30, 0.0, 0.0, 1.0); glColor3f(1.0, 0.0, 1.0); // Draw the sides of the three-sided pyramid glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); glVertex3d(0, 4, 0); glTexCoord2f(1, 0); glVertex3d(0, -4, -4); glTexCoord2f(1, 1); glVertex3d(-4, -4, 4); glTexCoord2f(0, 1); glVertex3d(4, -4, 4); glTexCoord2f(1, 0); glVertex3d(0, -4, -4); glEnd(); glColor3f(0.0, 1.0, 1.0); // Draw the base of the pyramid glBegin(GL_TRIANGLES); glTexCoord2f(1, 0); glVertex3d(0, -4, -4); glTexCoord2f(0, 1); glVertex3d(4, -4, 4); glTexCoord2f(1, 1); glVertex3d(-4, -4, 4); glEnd(); glLoadIdentity(); glTranslatef(2.5, 0.0, 0.0); glRotatef(45, 1.0, 0.0, 0.0); glRotatef(45, 0.0, 1.0, 0.0); glRotatef(45, 0.0, 0.0, 1.0); glColor3f(0.0, 1.0, 0.0); glDisable(GL_TEXTURE_2D); // Draw the sides of the cube glBegin(GL_QUAD_STRIP); glVertex3d(3, 3, -3); glVertex3d(3, -3, -3); glVertex3d(-3, 3, -3); glVertex3d(-3, -3, -3); glVertex3d(-3, 3, 3); glVertex3d(-3, -3, 3); glVertex3d(3, 3, 3); glVertex3d(3, -3, 3); glVertex3d(3, 3, -3); glVertex3d(3, -3, -3); glEnd(); glColor3f(0.0, 0.0, 1.0); // Draw the top of the cube glBegin(GL_QUADS); glVertex3d(-3, -3, -3); glVertex3d(3, -3, -3); glVertex3d(3, -3, 3); glVertex3d(-3, -3, 3); glEnd(); /* Bottom is texture-mapped */ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3d(-3, 3, -3); glTexCoord2f(1, 0); glVertex3d(-3, 3, 3); glTexCoord2f(1, 1); glVertex3d(3, 3, 3); glTexCoord2f(0, 1); glVertex3d(3, 3, -3); glEnd(); } static void setup_textures(ALLEGRO_DISPLAY *display) { ALLEGRO_BITMAP *tmp_bmp; ALLEGRO_FONT *font; int w, h, depth; font = al_load_font("data/fixed_font.tga", 0, 0); if(!font) { abort_example("Error loading `data/fixed_font.tga'\n"); } tmp_bmp = al_load_bitmap("data/mysha.pcx"); if(!tmp_bmp) { abort_example("Error loading `data/mysha.pcx'\n"); } w = 128; h = 128; bmp = al_create_bitmap(w, h); al_set_target_bitmap(bmp); al_draw_scaled_bitmap(tmp_bmp, 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), 0, 0, w, h, 0); depth = al_get_display_option(display, ALLEGRO_DEPTH_SIZE); if (!depth) al_draw_textf(font, al_map_rgb(255, 0, 0), 0, 5, 0, "No Z-buffer!"); else al_draw_textf(font, al_map_rgb(255, 0, 0), 0, 5, 0, "Z-buffer: %i bits", depth); al_set_target_backbuffer(display); al_destroy_bitmap(tmp_bmp); al_destroy_font(font); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); tex = al_get_opengl_texture(bmp); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; ALLEGRO_EVENT event; if(!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_install_keyboard(); al_set_new_display_flags(ALLEGRO_OPENGL); al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); display = al_create_display(640, 480); if(!display) { abort_example("Could not create display.\n"); } timer = al_create_timer(1. / 60.); queue = al_create_event_queue(); al_register_event_source(queue,al_get_keyboard_event_source()); al_register_event_source(queue,al_get_display_event_source(display)); al_register_event_source(queue,al_get_timer_event_source(timer)); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); setup_textures(display); al_start_timer(timer); while(true) { al_wait_for_event(queue, &event); switch(event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: goto done; case ALLEGRO_EVENT_KEY_DOWN: if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) goto done; key[event.keyboard.keycode] = true; break; case ALLEGRO_EVENT_KEY_UP: key[event.keyboard.keycode] = false; break; case ALLEGRO_EVENT_TIMER: keyboard(); if(al_is_event_queue_empty(queue)) { set_camera_position(); draw(); al_flip_display(); } break; } } done: al_destroy_bitmap(bmp); return 0; } allegro-5.0.10/examples/ex_lockbitmap.c0000644000175000001440000001023012152725670017214 0ustar tjadenusers/* * Example program for the Allegro library. * * From left to right you should see Red, Green, Blue gradients. */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bitmap; ALLEGRO_LOCKED_REGION *locked; uint8_t *ptr; int i, j; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; int mode = 0; int lock_flags = ALLEGRO_LOCK_WRITEONLY; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); open_log(); /* Create a window. */ display = al_create_display(3*256, 256); if (!display) { abort_example("Error creating display\n"); } events = al_create_event_queue(); al_register_event_source(events, al_get_keyboard_event_source()); log_printf("Press space to change bitmap type\n"); log_printf("Press w to toggle WRITEONLY mode\n"); restart: /* Create the bitmap to lock, or use the display backbuffer. */ if (mode == 0) { log_printf("Locking video bitmap"); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); bitmap = al_create_bitmap(3*256, 256); } else if (mode == 1) { log_printf("Locking memory bitmap"); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); bitmap = al_create_bitmap(3*256, 256); } else { log_printf("Locking display backbuffer"); bitmap = al_get_backbuffer(display); } if (!bitmap) { abort_example("Error creating bitmap"); } if (lock_flags & ALLEGRO_LOCK_WRITEONLY) { log_printf(" in write-only mode\n"); } else { log_printf(" in read/write mode\n"); } al_set_target_bitmap(bitmap); al_clear_to_color(al_map_rgb_f(0.8, 0.8, 0.9)); al_set_target_backbuffer(display); /* Locking the bitmap means, we work directly with pixel data. We can * choose the format we want to work with, which may imply conversions, or * use the bitmap's actual format so we can work directly with the bitmap's * pixel data. * We use a 16-bit format and odd positions and sizes to increase the * chances of uncovering bugs. */ locked = al_lock_bitmap_region(bitmap, 193, 65, 3*127, 127, ALLEGRO_PIXEL_FORMAT_RGB_565, lock_flags); for (j = 0; j < 127; j++) { ptr = (uint8_t *)locked->data + j * locked->pitch; for (i = 0; i < 3*127; i++) { uint8_t red; uint8_t green; uint8_t blue; uint16_t col; uint16_t *cptr = (uint16_t *)ptr; if (j == 0 || j == 126 || i == 0 || i == 3*127-1) { red = green = blue = 0; } else if (i < 127) { red = 255; green = blue = j*2; } else if (i < 2*127) { green = 255; red = blue = j*2; } else { blue = 255; red = green = j*2; } /* The RGB_555 format means, the 16 bits per pixel are laid out like * this, least significant bit right: RRRRR GGGGGG BBBBB * Because the byte order can vary per platform (big endian or * little endian) we encode an integer and store that * directly rather than storing each component separately. */ col = ((red/8) << 11) | ((green/4) << 5) | (blue/8); *cptr = col; ptr += 2; } } al_unlock_bitmap(bitmap); if (mode < 2) { al_draw_bitmap(bitmap, 0, 0, 0); al_destroy_bitmap(bitmap); bitmap = NULL; } al_flip_display(); while (1) { al_wait_for_event(events, &event); if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.unichar == ' ') { if (++mode > 2) mode = 0; goto restart; } if (event.keyboard.unichar == 'w' || event.keyboard.unichar == 'W') { lock_flags ^= ALLEGRO_LOCK_WRITEONLY; goto restart; } } } close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_memfile.c0000644000175000001440000000534612152725670016521 0ustar tjadenusers/* * Example program for the Allegro library. * * Test memfile addon. */ #include #ifdef _MSC_VER #pragma comment ( linker, "/SUBSYSTEM:CONSOLE") #endif #define ALLEGRO_USE_CONSOLE #include #include #include "common.c" int main(void) { ALLEGRO_FILE *memfile; char *data; int i; const int data_size = 1024; char buffer[50]; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); data = calloc(1, data_size); if (!data) abort_example("Out of memory.\n"); log_printf("Creating memfile\n"); memfile = al_open_memfile(data, data_size, "rw"); if (!memfile) { log_printf("Error opening memfile :(\n"); goto Error; } log_printf("Writing data to memfile\n"); for (i = 0; i < data_size/4; i++) { if (al_fwrite32le(memfile, i) < 4) { log_printf("Failed to write %i to memfile\n", i); goto Error; } } al_fseek(memfile, 0, ALLEGRO_SEEK_SET); log_printf("Reading and testing data from memfile\n"); for (i = 0; i < data_size/4; i++) { int32_t ret = al_fread32le(memfile); if (ret != i || al_feof(memfile)) { log_printf("Item %i failed to verify, got %i\n", i, ret); goto Error; } } if (al_feof(memfile)) { log_printf("EOF indicator prematurely set!\n"); goto Error; } /* testing the ungetc buffer */ al_fseek(memfile, 0, ALLEGRO_SEEK_SET); for (i = 0; al_fungetc(memfile, i) != EOF; ++i) { } log_printf("Length of ungetc buffer: %d\n", i); if (al_ftell(memfile) != -i) { log_printf("Current position is not correct. Expected -%d, but got %d\n", i, (int) al_ftell(memfile)); goto Error; } while (i--) { if (i != al_fgetc(memfile)) { log_printf("Failed to verify ungetc data.\n"); goto Error; } } if (al_ftell(memfile) != 0) { log_printf("Current position is not correct after reading back the ungetc buffer\n"); log_printf("Expected 0, but got %d\n", (int) al_ftell(memfile)); goto Error; } al_fputs(memfile, "legro rocks!"); al_fseek(memfile, 0, ALLEGRO_SEEK_SET); al_fungetc(memfile, 'l'); al_fungetc(memfile, 'A'); al_fgets(memfile, buffer, 15); if (strcmp(buffer, "Allegro rocks!")) { log_printf("Expected to see 'Allegro rocks!' but got '%s' instead.\n", buffer); log_printf("(Maybe the ungetc buffer isn't big enough.)\n"); goto Error; } log_printf("Done.\n"); al_fclose(memfile); free(data); close_log(true); return 0; Error: al_fclose(memfile); free(data); close_log(true); return 1; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_dir.c0000644000175000001440000000407311476660160015655 0ustar tjadenusers#include #include #include "common.c" static void print_file(ALLEGRO_FS_ENTRY *entry) { int mode = al_get_fs_entry_mode(entry); time_t now = time(NULL); time_t atime = al_get_fs_entry_atime(entry); time_t ctime = al_get_fs_entry_ctime(entry); time_t mtime = al_get_fs_entry_mtime(entry); off_t size = al_get_fs_entry_size(entry); const char *name = al_get_fs_entry_name(entry); log_printf("%-36s %s%s%s%s%s%s %8u %8u %8u %8u\n", name, mode & ALLEGRO_FILEMODE_READ ? "r" : ".", mode & ALLEGRO_FILEMODE_WRITE ? "w" : ".", mode & ALLEGRO_FILEMODE_EXECUTE ? "x" : ".", mode & ALLEGRO_FILEMODE_HIDDEN ? "h" : ".", mode & ALLEGRO_FILEMODE_ISFILE ? "f" : ".", mode & ALLEGRO_FILEMODE_ISDIR ? "d" : ".", (unsigned)(now - ctime), (unsigned)(now - mtime), (unsigned)(now - atime), (unsigned)size); } static void print_entry(ALLEGRO_FS_ENTRY *entry) { print_file(entry); if (al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR) { ALLEGRO_FS_ENTRY *next; al_open_directory(entry); while (1) { next = al_read_directory(entry); if (!next) break; print_entry(next); al_destroy_fs_entry(next); } al_close_directory(entry); } } int main(int argc, char **argv) { int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log_monospace(); log_printf("%-36s %-6s %8s %8s %8s %8s\n", "name", "flags", "ctime", "mtime", "atime", "size"); log_printf( "------------------------------------ " "------ " "-------- " "-------- " "-------- " "--------\n"); if (argc == 1) { ALLEGRO_FS_ENTRY *entry = al_create_fs_entry("data"); print_entry(entry); al_destroy_fs_entry(entry); } for (i = 1; i < argc; i++) { ALLEGRO_FS_ENTRY *entry = al_create_fs_entry(argv[i]); print_entry(entry); al_destroy_fs_entry(entry); } close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_nodisplay.c0000644000175000001440000000274212152725670017102 0ustar tjadenusers/* Test that bitmap manipulation without a display works. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "common.c" int main(void) { ALLEGRO_BITMAP *bmp; ALLEGRO_BITMAP *sprite; ALLEGRO_COLOR c1, c2, c3; bool rc; if (!al_init()) { abort_example("Error initialising Allegro\n"); } al_init_image_addon(); sprite = al_load_bitmap("data/cursor.tga"); if (!sprite) { abort_example("Error loading data/cursor.tga\n"); } bmp = al_create_bitmap(256, 256); if (!bmp) { abort_example("Error creating bitmap\n"); } al_set_target_bitmap(bmp); c1 = al_map_rgb(255, 0, 0); c2 = al_map_rgb(0, 255, 0); c3 = al_map_rgb(0, 255, 255); al_draw_bitmap(sprite, 0, 0, 0); al_draw_tinted_bitmap(sprite, c1, 64, 0, ALLEGRO_FLIP_HORIZONTAL); al_draw_tinted_bitmap(sprite, c2, 0, 64, ALLEGRO_FLIP_VERTICAL); al_draw_tinted_bitmap(sprite, c3, 64, 64, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL); al_set_target_bitmap(NULL); rc = al_save_bitmap("ex_nodisplay_out.tga", bmp); if (rc) { #ifdef ALLEGRO_POPUP_EXAMPLES al_show_native_message_box(NULL, "ex_nodisplay_out", "", "Saved ex_nodisplay_out.tga", NULL, 0); #else printf("Saved ex_nodisplay_out.tga\n"); #endif } else { abort_example("Error saving ex_nodisplay_out.tga\n"); } al_destroy_bitmap(sprite); al_destroy_bitmap(bmp); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_ttf.c0000644000175000001440000001314412152725670015673 0ustar tjadenusers#include #include #include #include #include "common.c" struct Example { double fps; ALLEGRO_FONT *f1, *f2, *f3, *f4, *f5; ALLEGRO_CONFIG *config; } ex; static const char *get_string(const char *key) { const char *v = al_get_config_value(ex.config, "", key); return (v) ? v : key; } static void render(void) { ALLEGRO_COLOR white = al_map_rgba_f(1, 1, 1, 1); ALLEGRO_COLOR black = al_map_rgba_f(0, 0, 0, 1); ALLEGRO_COLOR red = al_map_rgba_f(1, 0, 0, 1); ALLEGRO_COLOR green = al_map_rgba_f(0, 0.5, 0, 1); ALLEGRO_COLOR blue = al_map_rgba_f(0.1, 0.2, 1, 1); int x, y, w, h, as, de, xpos, ypos; int target_w, target_h; ALLEGRO_USTR_INFO info, sub_info; const ALLEGRO_USTR *u; al_clear_to_color(white); al_hold_bitmap_drawing(true); al_draw_textf(ex.f1, black, 50, 50, 0, "Tulip (kerning)"); al_draw_textf(ex.f2, black, 50, 100, 0, "Tulip (no kerning)"); al_draw_textf(ex.f3, black, 50, 200, 0, "This font has a size of 12 pixels, " "the one above has 48 pixels."); al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); al_draw_textf(ex.f3, red, 50, 220, 0, "The color can simply be changed."); al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); al_draw_textf(ex.f3, green, 50, 240, 0, "Some unicode symbols:"); al_draw_textf(ex.f3, green, 50, 260, 0, "%s", get_string("symbols1")); al_draw_textf(ex.f3, green, 50, 280, 0, "%s", get_string("symbols2")); al_draw_textf(ex.f3, green, 50, 300, 0, "%s", get_string("symbols3")); #define OFF(x) al_ustr_offset(u, x) #define SUB(x, y) al_ref_ustr(&sub_info, u, OFF(x), OFF(y)) u = al_ref_cstr(&info, get_string("substr1")); al_draw_ustr(ex.f3, green, 50, 320, 0, SUB(0, 6)); u = al_ref_cstr(&info, get_string("substr2")); al_draw_ustr(ex.f3, green, 50, 340, 0, SUB(7, 11)); u = al_ref_cstr(&info, get_string("substr3")); al_draw_ustr(ex.f3, green, 50, 360, 0, SUB(4, 11)); u = al_ref_cstr(&info, get_string("substr4")); al_draw_ustr(ex.f3, green, 50, 380, 0, SUB(0, 11)); al_draw_textf(ex.f5, black, 50, 420, 0, "forced monochrome"); al_hold_bitmap_drawing(false); target_w = al_get_bitmap_width(al_get_target_bitmap()); target_h = al_get_bitmap_height(al_get_target_bitmap()); xpos = target_w - 10; ypos = target_h - 10; al_get_text_dimensions(ex.f4, "Allegro", &x, &y, &w, &h); as = al_get_font_ascent(ex.f4); de = al_get_font_descent(ex.f4); xpos -= w; ypos -= h; x += xpos; y += ypos; al_draw_rectangle(x, y, x + w, y + h, black, 0); al_draw_line(x, y + as, x + w, y + as, black, 0); al_draw_line(x, y + as + de, x + w, y + as + de, black, 0); al_hold_bitmap_drawing(true); al_draw_textf(ex.f4, blue, xpos, ypos, 0, "Allegro"); al_hold_bitmap_drawing(false); al_hold_bitmap_drawing(true); al_draw_textf(ex.f3, black, target_w, 0, ALLEGRO_ALIGN_RIGHT, "%.1f FPS", ex.fps); al_hold_bitmap_drawing(false); } int main(int argc, const char *argv[]) { const char *font_file = "data/DejaVuSans.ttf"; ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; int redraw = 0; double t = 0; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_init_font_addon(); al_init_ttf_addon(); #ifdef ALLEGRO_IPHONE al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); #endif display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } al_install_keyboard(); if (argc >= 2) { font_file = argv[1]; } ex.f1 = al_load_font(font_file, 48, 0); ex.f2 = al_load_font(font_file, 48, ALLEGRO_TTF_NO_KERNING); ex.f3 = al_load_font(font_file, 12, 0); /* Specifying negative values means we specify the glyph height * in pixels, not the usual font size. */ ex.f4 = al_load_font(font_file, -140, 0); ex.f5 = al_load_font(font_file, 12, ALLEGRO_TTF_MONOCHROME); if (!ex.f1 || !ex.f2 || !ex.f3 || !ex.f4) { abort_example("Could not load font: %s\n", font_file); } ex.config = al_load_config_file("data/ex_ttf.ini"); if (!ex.config) { abort_example("Could not data/ex_ttf.ini\n"); } timer = al_create_timer(1.0 / 60); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (true) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_TIMER) redraw++; while (redraw > 0 && al_is_event_queue_empty(queue)) { double dt; redraw--; dt = al_get_time(); render(); dt = al_get_time() - dt; t = 0.99 * t + 0.01 * dt; ex.fps = 1.0 / t; al_flip_display(); } } al_destroy_font(ex.f1); al_destroy_font(ex.f2); al_destroy_font(ex.f3); al_destroy_font(ex.f4); al_destroy_font(ex.f5); al_destroy_config(ex.config); return 0; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/examples/ex_multiwin.c0000644000175000001440000000713312152727422016744 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "common.c" const int W = 640; const int H = 400; int main(void) { ALLEGRO_DISPLAY *display[2]; ALLEGRO_EVENT event; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_BITMAP *pictures[2]; ALLEGRO_BITMAP *target; int width, height; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); events = al_create_event_queue(); al_set_new_display_flags(ALLEGRO_WINDOWED|ALLEGRO_RESIZABLE); /* Create two windows. */ display[0] = al_create_display(W, H); if (!display[0]) { abort_example("Error creating display\n"); } pictures[0] = al_load_bitmap("data/mysha.pcx"); if (!pictures[0]) { abort_example("failed to load mysha.pcx\n"); } display[1] = al_create_display(W, H); if (!display[1]) { abort_example("Error creating display\n"); } pictures[1] = al_load_bitmap("data/allegro.pcx"); if (!pictures[1]) { abort_example("failed to load allegro.pcx\n"); } /* This is only needed since we want to receive resize events. */ al_register_event_source(events, al_get_display_event_source(display[0])); al_register_event_source(events, al_get_display_event_source(display[1])); al_register_event_source(events, al_get_keyboard_event_source()); while (1) { /* read input */ while (!al_is_event_queue_empty(events)) { al_get_next_event(events, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN) { ALLEGRO_KEYBOARD_EVENT *key = &event.keyboard; if (key->keycode == ALLEGRO_KEY_ESCAPE) { goto done; } } if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { ALLEGRO_DISPLAY_EVENT *de = &event.display; al_acknowledge_resize(de->source); } if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { log_printf("%p switching in\n", event.display.source); } if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { log_printf("%p switching out\n", event.display.source); } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { int i; for (i = 0; i < 2; i++) { if (display[i] == event.display.source) display[i] = 0; } al_destroy_display(event.display.source); for (i = 0; i < 2; i++) { if (display[i]) goto not_done; } goto done; not_done: ; } } for (i = 0; i < 2; i++) { if (!display[i]) continue; target = al_get_backbuffer(display[i]); width = al_get_bitmap_width(target); height = al_get_bitmap_height(target); al_set_target_bitmap(target); al_draw_scaled_bitmap(pictures[0], 0, 0, al_get_bitmap_width(pictures[0]), al_get_bitmap_height(pictures[0]), 0, 0, width / 2, height, 0); al_draw_scaled_bitmap(pictures[1], 0, 0, al_get_bitmap_width(pictures[1]), al_get_bitmap_height(pictures[1]), width / 2, 0, width / 2, height, 0); al_flip_display(); } al_rest(0.001); } done: al_destroy_bitmap(pictures[0]); al_destroy_bitmap(pictures[1]); al_destroy_display(display[0]); al_destroy_display(display[1]); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_d3d.cpp0000644000175000001440000000623312152732720016103 0ustar tjadenusers/* * Example of using D3D calls * by Jacob Dawid & Trent Gamblin */ #include #include #include #include #include #include "common.c" #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) struct D3DVERTEX { float fX, fY, fZ; DWORD dwColor; }; int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; (void)argc; (void)argv; if (!al_init()) { abort_example("Error initialising Allegro.\n"); } open_log(); al_install_keyboard(); al_set_new_display_flags(ALLEGRO_DIRECT3D); al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); display = al_create_display(640, 480); if (!display) { abort_example("Unable to create display.\n"); } ALLEGRO_KEYBOARD_STATE state; IDirect3DDevice9 *d3dd = al_get_d3d_device(display); d3dd->SetRenderState(D3DRS_AMBIENT, 0x11111111); d3dd->SetRenderState(D3DRS_LIGHTING,false); d3dd->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); d3dd->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE); d3dd->SetFVF(D3DFVF_CUSTOMVERTEX); D3DXMATRIX m_matProjection; float m_fAspectRatio = 1.0f; float m_fFieldOfView = D3DX_PI / 4.0f; float m_fNearPlane = 1.0f; float m_fFarPlane = 1000.0f; D3DXMatrixPerspectiveFovLH( &m_matProjection, m_fFieldOfView, m_fAspectRatio, m_fNearPlane, m_fFarPlane); d3dd->SetTransform(D3DTS_PROJECTION, &m_matProjection); LPDIRECT3DVERTEXBUFFER9 pTriangleVB = NULL; VOID *pData; D3DVERTEX aTriangle[] = { { -0.5, -0.5f, 0.0f, 0xffff0000 }, { 0.5f, -0.5f, 0.0f, 0xff00ff00 }, { 0.0f, 0.5f, 0.0f, 0xff0000ff } }; d3dd->CreateVertexBuffer(sizeof(aTriangle), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pTriangleVB, NULL); pTriangleVB->Lock(0, sizeof(pData), (void **)&pData, 0); memcpy(pData, aTriangle, sizeof(aTriangle)); pTriangleVB->Unlock(); float angle = 0.0f; D3DXMATRIX mat; double start = al_get_time(); double start_secs = al_get_time(); long frames = 0; do { d3dd->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); /* * The X and Y translation here is to offset * a translation Allegro does internally so * that its coordinate space matches OpenGL's. * Normally you don't have to worry about this * but if you're using D3D directly you do. */ D3DXMatrixTranslation(&mat, 0.5, 0.5, 2.0f); d3dd->SetTransform(D3DTS_WORLDMATRIX(0), &mat); angle += 50 * (al_get_time() - start); D3DXMatrixRotationY(&mat, angle); d3dd->MultiplyTransform(D3DTS_WORLDMATRIX(0), &mat); d3dd->SetFVF(D3DFVF_CUSTOMVERTEX); d3dd->SetStreamSource(0, pTriangleVB, 0, sizeof(D3DVERTEX)); d3dd->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); al_flip_display(); al_get_keyboard_state(&state); start = al_get_time(); frames++; } while (!al_key_down(&state, ALLEGRO_KEY_ESCAPE)); double elapsed = al_get_time() - start_secs; log_printf("%g fps\n", frames/elapsed); al_destroy_display(display); close_log(true); return 0; } allegro-5.0.10/examples/ex_resize2.c0000644000175000001440000000376512152725670016471 0ustar tjadenusers/* * Test program for Allegro. * * Resizing the window currently shows broken behaviour. */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bmp; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; bool redraw; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); al_set_new_display_flags(ALLEGRO_RESIZABLE | ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(640, 480); if (!display) { abort_example("Unable to set any graphic mode\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); bmp = al_load_bitmap("data/mysha.pcx"); if (!bmp) { abort_example("Unable to load image\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_keyboard_event_source()); redraw = true; while (true) { if (redraw && al_is_event_queue_empty(queue)) { al_clear_to_color(al_map_rgb(255, 0, 0)); al_draw_scaled_bitmap(bmp, 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), 0, 0, al_get_display_width(display), al_get_display_height(display), 0); al_flip_display(); redraw = false; } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { al_acknowledge_resize(event.display.source); redraw = true; } if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { redraw = true; } if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } } al_destroy_bitmap(bmp); al_destroy_display(display); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_lines.c0000644000175000001440000001006612152725670016210 0ustar tjadenusers/* * This example exercises line drawing, and single buffer mode. */ #include #include "allegro5/allegro.h" #include #include "common.c" /* XXX the software line drawer currently doesn't perform clipping properly */ const int W = 640; const int H = 480; ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_COLOR black; ALLEGRO_COLOR white; ALLEGRO_COLOR background; ALLEGRO_BITMAP *dbuf; int last_x = -1; int last_y = -1; static void fade(void) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_filled_rectangle(0, 0, W, H, al_map_rgba_f(0.5, 0.5, 0.6, 0.2)); } static void red_dot(int x, int y) { al_draw_filled_rectangle(x - 2, y - 2, x + 2, y + 2, al_map_rgb_f(1, 0, 0)); } static void draw_clip_rect(void) { al_draw_rectangle(100.5, 100.5, W - 100.5, H - 100.5, black, 0); } static void my_set_clip_rect(void) { al_set_clipping_rectangle(100, 100, W - 200, H - 200); } static void reset_clip_rect(void) { al_set_clipping_rectangle(0, 0, W, H); } static void flip(void) { al_set_target_backbuffer(display); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(dbuf, 0.0, 0.0, 0); al_flip_display(); } static void plonk(const int x, const int y, bool blend) { al_set_target_bitmap(dbuf); fade(); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO); draw_clip_rect(); red_dot(x, y); if (last_x == -1 && last_y == -1) { last_x = x; last_y = y; } else { my_set_clip_rect(); if (blend) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); } al_draw_line(last_x, last_y, x, y, white, 0); last_x = last_y = -1; reset_clip_rect(); } flip(); } static void splat(const int x, const int y, bool blend) { double theta; al_set_target_bitmap(dbuf); fade(); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO); draw_clip_rect(); red_dot(x, y); my_set_clip_rect(); if (blend) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); } for (theta = 0.0; theta < 2.0 * ALLEGRO_PI; theta += ALLEGRO_PI/16.0) { al_draw_line(x, y, x + 40.0 * cos(theta), y + 40.0 * sin(theta), white, 0); } reset_clip_rect(); flip(); } int main(int argc, const char *argv[]) { ALLEGRO_EVENT event; ALLEGRO_KEYBOARD_STATE kst; bool blend; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); display = al_create_display(W, H); if (!display) { abort_example("Error creating display\n"); } black = al_map_rgb_f(0.0, 0.0, 0.0); white = al_map_rgb_f(1.0, 1.0, 1.0); background = al_map_rgb_f(0.5, 0.5, 0.6); if (argc > 1 && 0 == strcmp(argv[1], "--memory-bitmap")) { al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); } dbuf = al_create_bitmap(W, H); if (!dbuf) { abort_example("Error creating double buffer\n"); } al_set_target_bitmap(dbuf); al_clear_to_color(background); draw_clip_rect(); flip(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); while (true) { al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { al_get_keyboard_state(&kst); blend = al_key_down(&kst, ALLEGRO_KEY_LSHIFT) || al_key_down(&kst, ALLEGRO_KEY_RSHIFT); if (event.mouse.button == 1) { plonk(event.mouse.x, event.mouse.y, blend); } else { splat(event.mouse.x, event.mouse.y, blend); } } else if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { last_x = last_y = -1; } else if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } al_destroy_event_queue(queue); al_destroy_bitmap(dbuf); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_transform.c0000644000175000001440000001514212152725670017111 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include #include "common.c" int main(int argc, const char *argv[]) { const char *filename; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *buffer, *bitmap, *subbitmap, *buffer_subbitmap; ALLEGRO_BITMAP *overlay; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TRANSFORM transform; bool software = false; bool redraw = false; bool blend = false; bool use_subbitmap = true; int w, h; ALLEGRO_FONT* font; ALLEGRO_FONT* soft_font; if (argc > 1) { filename = argv[1]; } else { filename = "data/mysha.pcx"; } if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } subbitmap = al_create_sub_bitmap(al_get_backbuffer(display), 50, 50, 640 - 50, 480 - 50); overlay = al_create_sub_bitmap(al_get_backbuffer(display), 100, 100, 300, 50); al_set_window_title(display, filename); bitmap = al_load_bitmap(filename); if (!bitmap) { abort_example("%s not found or failed to load\n", filename); } font = al_load_font("data/bmpfont.tga", 0, 0); if (!font) { abort_example("data/bmpfont.tga not found or failed to load\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); buffer = al_create_bitmap(640, 480); buffer_subbitmap = al_create_sub_bitmap(buffer, 50, 50, 640 - 50, 480 - 50); soft_font = al_load_font("data/bmpfont.tga", 0, 0); if (!soft_font) { abort_example("data/bmpfont.tga not found or failed to load\n"); } timer = al_create_timer(1.0 / 60); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); w = al_get_bitmap_width(bitmap); h = al_get_bitmap_height(bitmap); al_set_target_bitmap(overlay); al_identity_transform(&transform); al_rotate_transform(&transform, -0.06); al_use_transform(&transform); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_S) { software = !software; if (software) { /* Restore identity transform on display bitmap. */ ALLEGRO_TRANSFORM identity; al_identity_transform(&identity); al_use_transform(&identity); } } else if (event.keyboard.keycode == ALLEGRO_KEY_L) { blend = !blend; } else if (event.keyboard.keycode == ALLEGRO_KEY_B) { use_subbitmap = !use_subbitmap; } else if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } if (event.type == ALLEGRO_EVENT_TIMER) redraw = true; if (redraw && al_is_event_queue_empty(queue)) { double t = 3.0 + al_get_time(); ALLEGRO_COLOR tint; redraw = false; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); if(blend) tint = al_map_rgba_f(0.5, 0.5, 0.5, 0.5); else tint = al_map_rgba_f(1, 1, 1, 1); if(software) { if(use_subbitmap) { al_set_target_bitmap(buffer); al_clear_to_color(al_map_rgb_f(1, 0, 0)); al_set_target_bitmap(buffer_subbitmap); } else { al_set_target_bitmap(buffer); } } else { if(use_subbitmap) { al_set_target_backbuffer(display); al_clear_to_color(al_map_rgb_f(1, 0, 0)); al_set_target_bitmap(subbitmap); } else { al_set_target_backbuffer(display); } } /* Set the transformation on the target bitmap. */ al_identity_transform(&transform); al_translate_transform(&transform, -640 / 2, -480 / 2); al_scale_transform(&transform, 0.15 + sin(t / 5), 0.15 + cos(t / 5)); al_rotate_transform(&transform, t / 50); al_translate_transform(&transform, 640 / 2, 480 / 2); al_use_transform(&transform); /* Draw some stuff */ al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_draw_tinted_bitmap(bitmap, tint, 0, 0, 0); al_draw_tinted_scaled_bitmap(bitmap, tint, w / 4, h / 4, w / 2, h / 2, w, 0, w / 2, h / 4, 0);//ALLEGRO_FLIP_HORIZONTAL); al_draw_tinted_bitmap_region(bitmap, tint, w / 4, h / 4, w / 2, h / 2, 0, h, ALLEGRO_FLIP_VERTICAL); al_draw_tinted_scaled_rotated_bitmap(bitmap, tint, w / 2, h / 2, w + w / 2, h + h / 2, 0.7, 0.7, 0.3, 0); al_draw_pixel(w + w / 2, h + h / 2, al_map_rgb_f(0, 1, 0)); al_put_pixel(w + w / 2 + 2, h + h / 2 + 2, al_map_rgb_f(0, 1, 1)); al_draw_circle(w, h, 50, al_map_rgb_f(1, 0.5, 0), 3); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); if(software) { al_draw_text(soft_font, al_map_rgba_f(1, 1, 1, 1), 640 / 2, 430, ALLEGRO_ALIGN_CENTRE, "Software Rendering"); al_set_target_backbuffer(display); al_draw_bitmap(buffer, 0, 0, 0); } else { al_draw_text(font, al_map_rgba_f(1, 1, 1, 1), 640 / 2, 430, ALLEGRO_ALIGN_CENTRE, "Hardware Rendering"); } /* Each target bitmap has its own transformation matrix, so this * overlay is unaffected by the transformations set earlier. */ al_set_target_bitmap(overlay); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); al_draw_text(font, al_map_rgba_f(1, 1, 0, 1), 0, 10, ALLEGRO_ALIGN_LEFT, "hello!"); al_set_target_backbuffer(display); al_flip_display(); } } al_destroy_bitmap(bitmap); return 0; } /* vim: set sts=4 sw=4 et: */ allegro-5.0.10/examples/ex_fs_resize.c0000644000175000001440000000715312152725670017072 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include #include "common.c" #define NUM_RESOLUTIONS 4 static struct { int w, h; } res[NUM_RESOLUTIONS] = { { 640, 480 }, { 800, 600 }, { 1024, 768 }, { 1280, 1024 } }; static int cur_res = 0; static void redraw(ALLEGRO_BITMAP *picture) { ALLEGRO_COLOR color; ALLEGRO_BITMAP *target = al_get_target_bitmap(); int w = al_get_bitmap_width(target); int h = al_get_bitmap_height(target); color = al_map_rgb( 128 + rand() % 128, 128 + rand() % 128, 128 + rand() % 128); al_clear_to_color(color); color = al_map_rgb(255, 0, 0); al_draw_line(0, 0, w, h, color, 0); al_draw_line(0, h, w, 0, color, 0); al_draw_bitmap(picture, 0, 0, 0); al_flip_display(); } static void main_loop(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *picture) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; bool can_draw; int new_res; queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); can_draw = true; while (1) { if (al_is_event_queue_empty(queue) && can_draw) { redraw(picture); } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_LOST) { log_printf("Display lost\n"); can_draw = false; continue; } if (event.type == ALLEGRO_EVENT_DISPLAY_FOUND) { log_printf("Display found\n"); can_draw = true; continue; } if (event.type != ALLEGRO_EVENT_KEY_CHAR) { continue; } if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } new_res = cur_res; if (event.keyboard.unichar == '+' || event.keyboard.unichar == ' ' || event.keyboard.keycode == ALLEGRO_KEY_ENTER) { new_res++; if (new_res >= NUM_RESOLUTIONS) new_res = 0; } else if (event.keyboard.unichar == '-') { new_res--; if (new_res < 0) new_res = NUM_RESOLUTIONS - 1; } if (new_res != cur_res) { cur_res = new_res; log_printf("Switching to %dx%d... ", res[cur_res].w, res[cur_res].h); if (al_resize_display(display, res[cur_res].w, res[cur_res].h)) { log_printf("Succeeded.\n"); } else { log_printf("Failed. current resolution: %dx%d\n", al_get_display_width(display), al_get_display_height(display)); } } } al_destroy_event_queue(queue); } int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *picture; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_init_image_addon(); open_log_monospace(); if (argc == 2) { al_set_new_display_adapter(atoi(argv[1])); } al_set_new_display_flags(ALLEGRO_FULLSCREEN | ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(res[cur_res].w, res[cur_res].h); if (!display) { abort_example("Error creating display\n"); } picture = al_load_bitmap("data/mysha.pcx"); if (!picture) { abort_example("mysha.pcx not found\n"); } main_loop(display, picture); al_destroy_bitmap(picture); /* Destroying the fullscreen display restores the original screen * resolution. Shutting down Allegro would automatically destroy the * display, too. */ al_destroy_display(display); return 0; } allegro-5.0.10/examples/ex_timedwait.c0000644000175000001440000000424312152725670017065 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Test timed version of al_wait_for_event(). */ #include #include "common.c" static void test_relative_timeout(ALLEGRO_EVENT_QUEUE *queue); static void test_absolute_timeout(ALLEGRO_EVENT_QUEUE *queue); int main(void) { ALLEGRO_DISPLAY *dpy; ALLEGRO_EVENT_QUEUE *queue; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); dpy = al_create_display(640, 480); if (!dpy) { abort_example("Unable to set any graphic mode\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); test_relative_timeout(queue); test_absolute_timeout(queue); return 0; } static void test_relative_timeout(ALLEGRO_EVENT_QUEUE *queue) { ALLEGRO_EVENT event; float shade = 0.1; while (true) { if (al_wait_for_event_timed(queue, &event, 0.1)) { if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { return; } else { shade = 0.1; } } } else { /* timed out */ shade += 0.1; if (shade > 1.0) shade = 1.0; } al_clear_to_color(al_map_rgba_f(0.5 * shade, 0.25 * shade, shade, 0)); al_flip_display(); } } static void test_absolute_timeout(ALLEGRO_EVENT_QUEUE *queue) { ALLEGRO_TIMEOUT timeout; ALLEGRO_EVENT event; float shade = 0.1; bool ret; while (true) { al_init_timeout(&timeout, 0.1); while ((ret = al_wait_for_event_until(queue, &event, &timeout))) { if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { return; } else { shade = 0.1; } } } if (!ret) { /* timed out */ shade += 0.1; if (shade > 1.0) shade = 1.0; } al_clear_to_color(al_map_rgba_f(shade, 0.5 * shade, 0.25 * shade, 0)); al_flip_display(); } } /* vi: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_blend.c0000644000175000001440000002277512152725670016174 0ustar tjadenusers/* An example demonstrating different blending modes. */ #include #include #include #include #include #include #include #include "common.c" /* A structure holding all variables of our example program. */ struct Example { ALLEGRO_BITMAP *example; /* Our example bitmap. */ ALLEGRO_BITMAP *offscreen; /* An offscreen buffer, for testing. */ ALLEGRO_BITMAP *memory; /* A memory buffer, for testing. */ ALLEGRO_FONT *myfont; /* Our font. */ ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */ int image; /* Which test image to use. */ int mode; /* How to draw it. */ int BUTTONS_X; /* Where to draw buttons. */ int FPS; double last_second; int frames_accum; double fps; } ex; /* Print some text with a shadow. */ static void print(int x, int y, bool vertical, char const *format, ...) { va_list list; char message[1024]; ALLEGRO_COLOR color; int h; int j; va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); h = al_get_font_line_height(ex.myfont); for (j = 0; j < 2; j++) { if (j == 0) color = al_map_rgb(0, 0, 0); else color = al_map_rgb(255, 255, 255); if (vertical) { int i; ALLEGRO_USTR_INFO ui; const ALLEGRO_USTR *us = al_ref_cstr(&ui, message); for (i = 0; i < (int)al_ustr_length(us); i++) { ALLEGRO_USTR_INFO letter; al_draw_ustr(ex.myfont, color, x + 1 - j, y + 1 - j + h * i, 0, al_ref_ustr(&letter, us, al_ustr_offset(us, i), al_ustr_offset(us, i + 1))); } } else { al_draw_text(ex.myfont, color, x + 1 - j, y + 1 - j, 0, message); } } } /* Create an example bitmap. */ static ALLEGRO_BITMAP *create_example_bitmap(void) { ALLEGRO_BITMAP *bitmap; int i, j; ALLEGRO_LOCKED_REGION *locked; unsigned char *data; bitmap = al_create_bitmap(100, 100); locked = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_WRITEONLY); data = locked->data; for (j = 0; j < 100; j++) { for (i = 0; i < 100; i++) { int x = i - 50, y = j - 50; int r = sqrt(x * x + y * y); float rc = 1 - r / 50.0; if (rc < 0) rc = 0; data[i * 4 + 0] = i * 255 / 100; data[i * 4 + 1] = j * 255 / 100; data[i * 4 + 2] = rc * 255; data[i * 4 + 3] = rc * 255; } data += locked->pitch; } al_unlock_bitmap(bitmap); return bitmap; } /* Draw our example scene. */ static void draw(void) { ALLEGRO_COLOR test[5]; ALLEGRO_BITMAP *target = al_get_target_bitmap(); char const *blend_names[] = {"ZERO", "ONE", "ALPHA", "INVERSE"}; char const *blend_vnames[] = {"ZERO", "ONE", "ALPHA", "INVER"}; int blend_modes[] = {ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA}; float x = 40, y = 40; int i, j; al_clear_to_color(al_map_rgb_f(0.5, 0.5, 0.5)); test[0] = al_map_rgba_f(1, 1, 1, 1); test[1] = al_map_rgba_f(1, 1, 1, 0.5); test[2] = al_map_rgba_f(1, 1, 1, 0.25); test[3] = al_map_rgba_f(1, 0, 0, 0.75); test[4] = al_map_rgba_f(0, 0, 0, 0); print(x, 0, false, "D E S T I N A T I O N (%0.2f fps)", ex.fps); print(0, y, true, "S O U R C E"); for (i = 0; i < 4; i++) { print(x + i * 110, 20, false, blend_names[i]); print(20, y + i * 110, true, blend_vnames[i]); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); if (ex.mode >= 1 && ex.mode <= 5) { al_set_target_bitmap(ex.offscreen); al_clear_to_color(test[ex.mode - 1]); } if (ex.mode >= 6 && ex.mode <= 10) { al_set_target_bitmap(ex.memory); al_clear_to_color(test[ex.mode - 6]); } for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { al_set_blender(ALLEGRO_ADD, blend_modes[j], blend_modes[i]); if (ex.image == 0) al_draw_bitmap(ex.example, x + i * 110, y + j * 110, 0); else if (ex.image >= 1 && ex.image <= 6) { al_draw_filled_rectangle(x + i * 110, y + j * 110, x + i * 110 + 100, y + j * 110 + 100, test[ex.image - 1]); } } } if (ex.mode >= 1 && ex.mode <= 5) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_set_target_bitmap(target); al_draw_bitmap_region(ex.offscreen, x, y, 430, 430, x, y, 0); } if (ex.mode >= 6 && ex.mode <= 10) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_set_target_bitmap(target); al_draw_bitmap_region(ex.memory, x, y, 430, 430, x, y, 0); } #define IS(x) ((ex.image == x) ? "*" : " ") print(ex.BUTTONS_X, 20 * 1, false, "What to draw"); print(ex.BUTTONS_X, 20 * 2, false, "%s Picture", IS(0)); print(ex.BUTTONS_X, 20 * 3, false, "%s Rec1 (1/1/1/1)", IS(1)); print(ex.BUTTONS_X, 20 * 4, false, "%s Rec2 (1/1/1/.5)", IS(2)); print(ex.BUTTONS_X, 20 * 5, false, "%s Rec3 (1/1/1/.25)", IS(3)); print(ex.BUTTONS_X, 20 * 6, false, "%s Rec4 (1/0/0/.75)", IS(4)); print(ex.BUTTONS_X, 20 * 7, false, "%s Rec5 (0/0/0/0)", IS(5)); #undef IS #define IS(x) ((ex.mode == x) ? "*" : " ") print(ex.BUTTONS_X, 20 * 9, false, "Where to draw"); print(ex.BUTTONS_X, 20 * 10, false, "%s screen", IS(0)); print(ex.BUTTONS_X, 20 * 11, false, "%s offscreen1", IS(1)); print(ex.BUTTONS_X, 20 * 12, false, "%s offscreen2", IS(2)); print(ex.BUTTONS_X, 20 * 13, false, "%s offscreen3", IS(3)); print(ex.BUTTONS_X, 20 * 14, false, "%s offscreen4", IS(4)); print(ex.BUTTONS_X, 20 * 15, false, "%s offscreen5", IS(5)); print(ex.BUTTONS_X, 20 * 16, false, "%s memory1", IS(6)); print(ex.BUTTONS_X, 20 * 17, false, "%s memory2", IS(7)); print(ex.BUTTONS_X, 20 * 18, false, "%s memory3", IS(8)); print(ex.BUTTONS_X, 20 * 19, false, "%s memory4", IS(9)); print(ex.BUTTONS_X, 20 * 20, false, "%s memory5", IS(10)); #undef IS } /* Called a fixed amount of times per second. */ static void tick(void) { /* Count frames during the last second or so. */ double t = al_get_time(); if (t >= ex.last_second + 1) { ex.fps = ex.frames_accum / (t - ex.last_second); ex.frames_accum = 0; ex.last_second = t; } draw(); al_flip_display(); ex.frames_accum++; } /* Run our test. */ static void run(void) { ALLEGRO_EVENT event; float x, y; bool need_draw = true; while (1) { /* Perform frame skipping so we don't fall behind the timer events. */ if (need_draw && al_is_event_queue_empty(ex.queue)) { tick(); need_draw = false; } al_wait_for_event(ex.queue, &event); switch (event.type) { /* Was the X button on the window pressed? */ case ALLEGRO_EVENT_DISPLAY_CLOSE: return; /* Was a key pressed? */ case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; /* Is it time for the next timer tick? */ case ALLEGRO_EVENT_TIMER: need_draw = true; break; /* Mouse click? */ case ALLEGRO_EVENT_MOUSE_BUTTON_UP: x = event.mouse.x; y = event.mouse.y; if (x >= ex.BUTTONS_X) { int button = y / 20; if (button == 2) ex.image = 0; if (button == 3) ex.image = 1; if (button == 4) ex.image = 2; if (button == 5) ex.image = 3; if (button == 6) ex.image = 4; if (button == 7) ex.image = 5; if (button == 10) ex.mode = 0; if (button == 11) ex.mode = 1; if (button == 12) ex.mode = 2; if (button == 13) ex.mode = 3; if (button == 14) ex.mode = 4; if (button == 15) ex.mode = 5; if (button == 16) ex.mode = 6; if (button == 17) ex.mode = 7; if (button == 18) ex.mode = 8; if (button == 19) ex.mode = 9; if (button == 20) ex.mode = 10; } break; } } } /* Initialize the example. */ static void init(void) { ex.BUTTONS_X = 40 + 110 * 4; ex.FPS = 60; ex.myfont = al_load_font("data/font.tga", 0, 0); if (!ex.myfont) { abort_example("data/font.tga not found\n"); } ex.example = create_example_bitmap(); ex.offscreen = al_create_bitmap(640, 480); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); ex.memory = al_create_bitmap(640, 480); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } init(); timer = al_create_timer(1.0 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); return 0; } allegro-5.0.10/examples/ex_convert.c0000644000175000001440000000217712152725670016562 0ustar tjadenusers/* Image conversion example */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "common.c" int main(int argc, char **argv) { ALLEGRO_BITMAP *bitmap; double t0; double t1; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 3) { log_printf("This example needs to be run from the command line.\n"); log_printf("Usage: %s \n", argv[0]); log_printf("\tPossible file types: BMP PCX PNG TGA\n"); goto done; } al_init_image_addon(); al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_NO_PREMULTIPLIED_ALPHA); bitmap = al_load_bitmap(argv[1]); if (!bitmap) { log_printf("Error loading input file\n"); goto done; } t0 = al_get_time(); if (!al_save_bitmap(argv[2], bitmap)) { log_printf("Error saving bitmap\n"); goto done; } t1 = al_get_time(); log_printf("Saving took %.4f seconds\n", t1 - t0); al_destroy_bitmap(bitmap); done: close_log(true); return 0; } allegro-5.0.10/examples/ex_mixer_pp.c0000644000175000001440000001164512152725670016725 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * This program demonstrates a simple use of mixer postprocessing callbacks. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_primitives.h" #include "common.c" #define FPS 60 static volatile float rms_l = 0.0; static volatile float rms_r = 0.0; static ALLEGRO_DISPLAY *display; static ALLEGRO_BITMAP *dbuf; static ALLEGRO_BITMAP *bmp; static float theta; static void update_meter(void *buf, unsigned int samples, void *data) { float *fbuf = (float *)buf; float sum_l = 0.0; float sum_r = 0.0; unsigned int i; (void)data; for (i = samples; i > 0; i--) { sum_l += fbuf[0] * fbuf[0]; sum_r += fbuf[1] * fbuf[1]; fbuf += 2; } rms_l = sqrt(sum_l / samples); rms_r = sqrt(sum_r / samples); } static void draw(void) { const float sw = al_get_bitmap_width(bmp); const float sh = al_get_bitmap_height(bmp); const float dw = al_get_bitmap_width(dbuf); const float dh = al_get_bitmap_height(dbuf); const float dx = dw / 2.0; const float dy = dh / 2.0; float db_l; float db_r; float db; float scale; float disp; /* Whatever looks okay. */ if (rms_l > 0.0 && rms_r > 0.0) { db_l = 20 * log10(rms_l / 20e-6); db_r = 20 * log10(rms_r / 20e-6); db = (db_l + db_r) / 2.0; scale = db / 20.0; disp = (rms_l + rms_r) * 200.0; } else { db_l = db_r = db = scale = disp = 0.0; } al_set_target_bitmap(dbuf); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_filled_rectangle(0, 0, al_get_bitmap_width(dbuf), al_get_bitmap_height(dbuf), al_map_rgba_f(0.8, 0.3, 0.1, 0.06)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_tinted_scaled_rotated_bitmap(bmp, al_map_rgba_f(0.8, 0.3, 0.1, 0.2), sw/2.0, sh/2.0, dx, dy - disp, scale, scale, theta, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_set_target_backbuffer(display); al_draw_bitmap(dbuf, 0, 0, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_line(10, dh - db_l, 10, dh, al_map_rgb_f(1, 0.6, 0.2), 6); al_draw_line(20, dh - db_r, 20, dh, al_map_rgb_f(1, 0.6, 0.2), 6); al_flip_display(); theta -= (rms_l + rms_r) * 0.1; } static void main_loop(void) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; bool redraw = true; queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); theta = 0.0; for (;;) { if (redraw && al_is_event_queue_empty(queue)) { draw(); redraw = false; } if (!al_wait_for_event_timed(queue, &event, 1.0/FPS)) { redraw = true; continue; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } al_destroy_event_queue(queue); } int main(int argc, char **argv) { const char *filename = "../demos/cosmic_protector/data/sfx/title_music.ogg"; ALLEGRO_VOICE *voice; ALLEGRO_MIXER *mixer; ALLEGRO_AUDIO_STREAM *stream; if (argc > 1) { filename = argv[1]; } if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_init_image_addon(); al_init_acodec_addon(); al_install_keyboard(); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } dbuf = al_create_bitmap(640, 480); bmp = al_load_bitmap("data/mysha.pcx"); if (!bmp) { abort_example("Could not load data/mysha.pcx\n"); } if (!al_install_audio()) { abort_example("Could not init sound.\n"); } voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (!voice) { abort_example("Could not create voice.\n"); } mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); if (!mixer) { abort_example("Could not create mixer.\n"); } if (!al_attach_mixer_to_voice(mixer, voice)) { abort_example("al_attach_mixer_to_voice failed.\n"); } stream = al_load_audio_stream(filename, 4, 2048); if (!stream) { abort_example("Could not load '%s'\n", filename); } al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); al_attach_audio_stream_to_mixer(stream, mixer); al_set_mixer_postprocess_callback(mixer, update_meter, NULL); main_loop(); al_destroy_audio_stream(stream); al_destroy_mixer(mixer); al_destroy_voice(voice); al_uninstall_audio(); al_destroy_bitmap(dbuf); al_destroy_bitmap(bmp); return 0; } allegro-5.0.10/examples/ex_audio_timer.c0000644000175000001440000000750212152725670017400 0ustar tjadenusers/* * Example program for the Allegro library. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_font.h" #include "common.c" #define RESERVED_SAMPLES 16 #define PERIOD 5 static ALLEGRO_DISPLAY *display; static ALLEGRO_FONT *font; static ALLEGRO_SAMPLE *ping; static ALLEGRO_TIMER *timer; static ALLEGRO_EVENT_QUEUE *event_queue; static ALLEGRO_SAMPLE *create_sample_s16(int freq, int len) { char *buf = al_malloc(freq * len * sizeof(int16_t)); return al_create_sample(buf, len, freq, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_1, true); } /* Adapted from SPEED. */ static ALLEGRO_SAMPLE *generate_ping(void) { float osc1, osc2, vol, ramp; int16_t *p; int len; int i; /* ping consists of two sine waves */ len = 8192; ping = create_sample_s16(22050, len); if (!ping) return NULL; p = (int16_t *)al_get_sample_data(ping); osc1 = 0; osc2 = 0; for (i=0; i 1) { bps--; al_set_timer_speed(timer, 1.0 / bps); } } } if (redraw && al_is_event_queue_empty(event_queue)) { ALLEGRO_COLOR c; if (last_timer % PERIOD == 0) c = al_map_rgb_f(1, 1, 1); else c = al_map_rgb_f(0.5, 0.5, 1.0); al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_textf(font, c, 640/32, 480/32 - 4, ALLEGRO_ALIGN_CENTRE, "%u", last_timer); al_flip_display(); } } close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_subbitmap.c0000644000175000001440000002166712152725670017075 0ustar tjadenusers/* * Example program for the Allegro library. * * This program blitting to/from sub-bitmaps. * */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include "common.c" #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) > (y)) ? (x) : (y)) #define CLAMP(x,y,z) MAX((x), MIN((y), (z))) typedef enum { PLAIN_BLIT, SCALED_BLIT } Mode; enum { SRC_WIDTH = 640, SRC_HEIGHT = 480, SRC_X = 160, SRC_Y = 120, DST_WIDTH = 640, DST_HEIGHT = 480 }; ALLEGRO_DISPLAY *src_display; ALLEGRO_DISPLAY *dst_display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_BITMAP *src_bmp; int src_x1 = SRC_X; int src_y1 = SRC_Y; int src_x2 = SRC_X + 319; int src_y2 = SRC_Y + 199; int dst_x1 = 0; int dst_y1 = 0; int dst_x2 = DST_WIDTH-1; int dst_y2 = DST_HEIGHT-1; Mode mode = PLAIN_BLIT; int draw_flags = 0; int main(int argc, const char *argv[]) { ALLEGRO_BITMAP *src_subbmp[2] = {NULL, NULL}; ALLEGRO_BITMAP *dst_subbmp[2] = {NULL, NULL}; ALLEGRO_EVENT event; bool mouse_down; bool recreate_subbitmaps; bool redraw; bool use_memory; const char *image_filename = NULL; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_init_image_addon(); open_log(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); src_display = al_create_display(SRC_WIDTH, SRC_HEIGHT); if (!src_display) { abort_example("Error creating display\n"); } al_set_window_title(src_display, "Source"); dst_display = al_create_display(DST_WIDTH, DST_HEIGHT); if (!dst_display) { abort_example("Error creating display\n"); } al_set_window_title(dst_display, "Destination"); { int i; for (i = 1; i < argc; ++i) { if (!image_filename) image_filename = argv[i]; else abort_example("Unknown argument: %s\n", argv[i]); } if (!image_filename) { image_filename = "data/mysha.pcx"; } } src_bmp = al_load_bitmap(image_filename); if (!src_bmp) { abort_example("Could not load image file\n"); } src_x2 = src_x1 + al_get_bitmap_width(src_bmp); src_y2 = src_y1 + al_get_bitmap_height(src_bmp); al_install_keyboard(); al_install_mouse(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(src_display)); al_register_event_source(queue, al_get_display_event_source(dst_display)); mouse_down = false; recreate_subbitmaps = true; redraw = true; use_memory = false; log_printf("Highlight sub-bitmap regions with left mouse button.\n"); log_printf("Press 'm' to toggle memory bitmaps.\n"); log_printf("Press '1' to perform plain blits.\n"); log_printf("Press 's' to perform scaled blits.\n"); log_printf("Press 'h' to flip horizontally.\n"); log_printf("Press 'v' to flip vertically.\n"); while (true) { if (recreate_subbitmaps) { int l, r, t, b, sw, sh; al_destroy_bitmap(src_subbmp[0]); al_destroy_bitmap(dst_subbmp[0]); al_destroy_bitmap(src_subbmp[1]); al_destroy_bitmap(dst_subbmp[1]); l = MIN(src_x1, src_x2); r = MAX(src_x1, src_x2); t = MIN(src_y1, src_y2); b = MAX(src_y1, src_y2); l -= SRC_X; t -= SRC_Y; r -= SRC_X; b -= SRC_Y; src_subbmp[0] = al_create_sub_bitmap(src_bmp, l, t, r - l + 1, b - t + 1); sw = al_get_bitmap_width(src_subbmp[0]); sh = al_get_bitmap_height(src_subbmp[0]); src_subbmp[1] = al_create_sub_bitmap(src_subbmp[0], 2, 2, sw - 4, sh - 4); l = MIN(dst_x1, dst_x2); r = MAX(dst_x1, dst_x2); t = MIN(dst_y1, dst_y2); b = MAX(dst_y1, dst_y2); al_set_target_backbuffer(dst_display); dst_subbmp[0] = al_create_sub_bitmap(al_get_backbuffer(dst_display), l, t, r - l + 1, b - t + 1); dst_subbmp[1] = al_create_sub_bitmap(dst_subbmp[0], 2, 2, r - l - 3, b - t - 3); recreate_subbitmaps = false; } if (redraw && al_is_event_queue_empty(queue)) { al_set_target_backbuffer(dst_display); al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_target_bitmap(dst_subbmp[1]); switch (mode) { case PLAIN_BLIT: { al_draw_bitmap(src_subbmp[1], 0, 0, draw_flags); break; } case SCALED_BLIT: { al_draw_scaled_bitmap(src_subbmp[1], 0, 0, al_get_bitmap_width(src_subbmp[1]), al_get_bitmap_height(src_subbmp[1]), 0, 0, al_get_bitmap_width(dst_subbmp[1]), al_get_bitmap_height(dst_subbmp[1]), draw_flags); break; } } #define SWAP_GREATER(f1, f2) { \ if (f1 > f2) { \ float tmp = f1; \ f1 = f2; \ f2 = tmp; \ } \ } { /* pixel center is at 0.5/0.5 */ float x = dst_x1 + 0.5; float y = dst_y1 + 0.5; float x_ = dst_x2 + 0.5; float y_ = dst_y2 + 0.5; SWAP_GREATER(x, x_) SWAP_GREATER(y, y_) al_set_target_backbuffer(dst_display); al_draw_rectangle(x, y, x_, y_, al_map_rgb(0, 255, 255), 0); al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, al_map_rgb(255, 255, 0), 0); al_flip_display(); } { /* pixel center is at 0.5/0.5 */ float x = src_x1 + 0.5; float y = src_y1 + 0.5; float x_ = src_x2 + 0.5; float y_ = src_y2 + 0.5; SWAP_GREATER(x, x_) SWAP_GREATER(y, y_) al_set_target_backbuffer(src_display); al_clear_to_color(al_map_rgb(0, 0, 0)); al_draw_bitmap(src_bmp, SRC_X, SRC_Y, 0); al_draw_rectangle(x, y, x_, y_, al_map_rgb(0, 255, 255), 0); al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, al_map_rgb(255, 255, 0), 0); al_flip_display(); } #undef SWAP_GREATER redraw = false; } al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.keyboard.unichar == '1') { mode = PLAIN_BLIT; redraw = true; } else if (event.keyboard.unichar == 's') { mode = SCALED_BLIT; redraw = true; } else if (event.keyboard.unichar == 'h') { draw_flags ^= ALLEGRO_FLIP_HORIZONTAL; redraw = true; } else if (event.keyboard.unichar == 'v') { draw_flags ^= ALLEGRO_FLIP_VERTICAL; redraw = true; } else if (event.keyboard.unichar == 'm') { ALLEGRO_BITMAP *temp = src_bmp; use_memory = !use_memory; log_printf("Using a %s bitmap.\n", use_memory ? "memory" : "video"); al_set_new_bitmap_flags(use_memory ? ALLEGRO_MEMORY_BITMAP : ALLEGRO_VIDEO_BITMAP); src_bmp = al_clone_bitmap(temp); al_destroy_bitmap(temp); redraw = true; recreate_subbitmaps = true; } } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN && event.mouse.button == 1) { if (event.mouse.display == src_display) { src_x1 = src_x2 = event.mouse.x; src_y1 = src_y2 = event.mouse.y; } else if (event.mouse.display == dst_display) { dst_x1 = dst_x2 = event.mouse.x; dst_y1 = dst_y2 = event.mouse.y; } mouse_down = true; redraw = true; } else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { if (mouse_down) { if (event.mouse.display == src_display) { src_x2 = event.mouse.x; src_y2 = event.mouse.y; } else if (event.mouse.display == dst_display) { dst_x2 = event.mouse.x; dst_y2 = event.mouse.y; } redraw = true; } } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP && event.mouse.button == 1) { mouse_down = false; recreate_subbitmaps = true; redraw = true; } else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { redraw = true; } } al_destroy_event_queue(queue); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_drawpixels.c0000644000175000001440000000616012152725670017260 0ustar tjadenusers#include #include #include "common.c" #define WIDTH 640 #define HEIGHT 480 #define NUM_STARS 300 #define TARGET_FPS 9999 typedef struct Point { float x, y; } Point; int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_KEYBOARD_STATE key_state; Point stars[3][NUM_STARS/3]; float speeds[3] = { 0.0001f, 0.05f, 0.15f }; ALLEGRO_COLOR colors[3]; long start, now, elapsed, frame_count; int total_frames = 0; double program_start; double length; int layer, star; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_install_keyboard(); display = al_create_display(WIDTH, HEIGHT); if (!display) { abort_example("Could not create display.\n"); } colors[0] = al_map_rgba(255, 100, 255, 128); colors[1] = al_map_rgba(255, 100, 100, 255); colors[2] = al_map_rgba(100, 100, 255, 255); for (layer = 0; layer < 3; layer++) { for (star = 0; star < NUM_STARS/3; star++) { Point *p = &stars[layer][star]; p->x = rand() % WIDTH; p->y = rand() % HEIGHT; } } start = al_get_time() * 1000; now = start; elapsed = 0; frame_count = 0; program_start = al_get_time(); while (1) { if (frame_count < (1000/TARGET_FPS)) { frame_count += elapsed; } else { int X, Y; frame_count -= (1000/TARGET_FPS); al_clear_to_color(al_map_rgb(0, 0, 0)); for (star = 0; star < NUM_STARS/3; star++) { Point *p = &stars[0][star]; al_draw_pixel(p->x, p->y, colors[0]); } al_lock_bitmap(al_get_backbuffer(display), ALLEGRO_PIXEL_FORMAT_ANY, 0); for (layer = 1; layer < 3; layer++) { for (star = 0; star < NUM_STARS/3; star++) { Point *p = &stars[layer][star]; // put_pixel ignores blending al_put_pixel(p->x, p->y, colors[layer]); } } /* Check that dots appear at the window extremes. */ X = WIDTH - 1; Y = HEIGHT - 1; al_put_pixel(0, 0, al_map_rgb_f(1, 1, 1)); al_put_pixel(X, 0, al_map_rgb_f(1, 1, 1)); al_put_pixel(0, Y, al_map_rgb_f(1, 1, 1)); al_put_pixel(X, Y, al_map_rgb_f(1, 1, 1)); al_unlock_bitmap(al_get_backbuffer(display)); al_flip_display(); total_frames++; } now = al_get_time() * 1000; elapsed = now - start; start = now; for (layer = 0; layer < 3; layer++) { for (star = 0; star < NUM_STARS/3; star++) { Point *p = &stars[layer][star]; p->y -= speeds[layer] * elapsed; if (p->y < 0) { p->x = rand() % WIDTH; p->y = HEIGHT; } } } al_rest(0.001); al_get_keyboard_state(&key_state); if (al_key_down(&key_state, ALLEGRO_KEY_ESCAPE)) break; } length = al_get_time() - program_start; if (length != 0) { log_printf("%d FPS\n", (int)(total_frames / length)); } al_destroy_display(display); close_log(true); return 0; } allegro-5.0.10/examples/ex_fs_window.c0000644000175000001440000000647412152725670017105 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include #include "common.c" static ALLEGRO_DISPLAY *display; static ALLEGRO_BITMAP *picture; static ALLEGRO_EVENT_QUEUE *queue; static ALLEGRO_FONT *font; static bool big; static void redraw(void) { ALLEGRO_COLOR color; int w = al_get_display_width(display); int h = al_get_display_height(display); int pw = al_get_bitmap_width(picture); int ph = al_get_bitmap_height(picture); int th = al_get_font_line_height(font); float cx = (w - pw) * 0.5; float cy = (h - ph) * 0.5; ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); color = al_map_rgb_f(0.8, 0.7, 0.9); al_clear_to_color(color); color = al_map_rgb(255, 0, 0); al_draw_line(0, 0, w, h, color, 0); al_draw_line(0, h, w, 0, color, 0); al_draw_bitmap(picture, cx, cy, 0); al_draw_textf(font, white, w / 2, cy + ph, ALLEGRO_ALIGN_CENTRE, "Press Space to toggle fullscreen"); al_draw_textf(font, white, w / 2, cy + ph + th, ALLEGRO_ALIGN_CENTRE, "Press Enter to toggle window size"); al_draw_textf(font, white, w / 2, cy + ph + th * 2, ALLEGRO_ALIGN_CENTRE, "Window: %dx%d (%s)", al_get_display_width(display), al_get_display_height(display), (al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW) ? "fullscreen" : "not fullscreen"); al_flip_display(); } static void run(void) { ALLEGRO_EVENT event; bool quit = false; while (!quit) { while (al_get_next_event(queue, &event)) { if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) quit = true; else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) quit = true; else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { bool opp = !(al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW); al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, opp); redraw(); } else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { big = !big; if (big) al_resize_display(display, 800, 600); else al_resize_display(display, 640, 480); redraw(); } } } /* FIXME: Lazy timing */ al_rest(0.02); redraw(); } } int main(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); picture = al_load_bitmap("data/mysha.pcx"); if (!picture) { abort_example("mysha.pcx not found\n"); } font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { abort_example("data/fixed_font.tga not found.\n"); } redraw(); run(); al_destroy_display(display); al_destroy_event_queue(queue); return 0; } allegro-5.0.10/examples/ex_synth.cpp0000644000175000001440000003060612152725670016605 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Something like the start of a synthesizer. */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "allegro5/allegro_ttf.h" #include "nihgui.hpp" #include "common.c" #define PI (ALLEGRO_PI) #define TWOPI (2.0 * PI) #define SAMPLES_PER_BUFFER (1024) #define STREAM_FREQUENCY (44100) const double dt = 1.0 / STREAM_FREQUENCY; enum Waveform { WAVEFORM_NONE, WAVEFORM_SINE, WAVEFORM_SQUARE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH }; /* forward declarations */ static void generate_wave(Waveform type, float *buf, size_t samples, double t, float frequency, float phase); static void sine(float *buf, size_t samples, double t, float frequency, float phase); static void square(float *buf, size_t samples, double t, float frequency, float phase); static void triangle(float *buf, size_t samples, double t, float frequency, float phase); static void sawtooth(float *buf, size_t samples, double t, float frequency, float phase); /* globals */ ALLEGRO_FONT *font_gui; ALLEGRO_AUDIO_STREAM *stream1; ALLEGRO_AUDIO_STREAM *stream2; ALLEGRO_AUDIO_STREAM *stream3; ALLEGRO_AUDIO_STREAM *stream4; ALLEGRO_AUDIO_STREAM *stream5; bool saving = false; ALLEGRO_FILE *save_fp = NULL; static void generate_wave(Waveform type, float *buf, size_t samples, double t, float frequency, float phase) { switch (type) { case WAVEFORM_NONE: for (unsigned i = 0; i < samples; i++) { buf[i] = 0.0; } break; case WAVEFORM_SINE: sine(buf, samples, t, frequency, phase); break; case WAVEFORM_SQUARE: square(buf, samples, t, frequency, phase); break; case WAVEFORM_TRIANGLE: triangle(buf, samples, t, frequency, phase); break; case WAVEFORM_SAWTOOTH: sawtooth(buf, samples, t, frequency, phase); break; } } static void sine(float *buf, size_t samples, double t, float frequency, float phase) { const double w = TWOPI * frequency; unsigned i; for (i = 0; i < samples; i++) { double ti = t + i * dt; buf[i] = sin(w * ti + phase); } } static void square(float *buf, size_t samples, double t, float frequency, float phase) { const double w = TWOPI * frequency; unsigned i; for (i = 0; i < samples; i++) { double ti = t + i * dt; double x = sin(w * ti + phase); buf[i] = (x >= 0.0) ? 1.0 : -1.0; } } static void triangle(float *buf, size_t samples, double t, float frequency, float phase) { const double w = TWOPI * frequency; unsigned i; for (i = 0; i < samples; i++) { double tx = w * (t + i * dt) + PI/2.0 + phase; double tu = fmod(tx/PI, 2.0); if (tu <= 1.0) buf[i] = (1.0 - 2.0 * tu); else buf[i] = (-1.0 + 2.0 * (tu - 1.0)); } } static void sawtooth(float *buf, size_t samples, double t, float frequency, float phase) { const double w = TWOPI * frequency; unsigned i; for (i = 0; i < samples; i++) { double tx = w * (t + i * dt) + PI + phase; double tu = fmod(tx/PI, 2.0); buf[i] = (-1.0 + tu); } } static void mixer_pp_callback(void *buf, unsigned int samples, void *userdata) { ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)userdata; int nch; int sample_size; if (!saving) return; switch (al_get_mixer_channels(mixer)) { case ALLEGRO_CHANNEL_CONF_1: nch = 1; break; case ALLEGRO_CHANNEL_CONF_2: nch = 2; break; default: /* Not supported. */ return; } sample_size = al_get_audio_depth_size(al_get_mixer_depth(mixer)); al_fwrite(save_fp, buf, nch * samples * sample_size); } class Group { private: List list; Label freq_label; HSlider freq_slider; Label freq_val_label; Label phase_label; HSlider phase_slider; Label phase_val_label; Label gain_label; HSlider gain_slider; Label pan_label; HSlider pan_slider; double t; float last_gain; float last_pan; public: Group(); void add_to_dialog(Dialog & d, int x, int y); void update_labels(); void generate(float *buf, size_t samples); bool get_gain_if_changed(float *gain); bool get_pan_if_changed(float *pan); private: float get_frequency() const; float get_phase() const; }; Group::Group() : freq_label(Label("f")), freq_slider(220, 1000), phase_label(Label("φ")), phase_slider((int)(100 * PI), (int)(2 * 100 * PI)), /* -π .. π */ gain_label(Label("Gain")), gain_slider(33, 100), /* 0.0 .. 1.0 */ pan_label(Label("Pan")), pan_slider(100, 200), /* -1.0 .. 1.0 */ t(0.0), last_gain(-10000), last_pan(-10000) { /* Order must correspond with Waveform. */ list.append_item("Off"); list.append_item("Sine"); list.append_item("Square"); list.append_item("Triangle"); list.append_item("Sawtooth"); } void Group::add_to_dialog(Dialog & d, int x, int y) { d.add(list, x, y, 4, 4); d.add(freq_label, x+4, y, 2, 1); d.add(freq_slider, x+6, y, 20, 1); d.add(freq_val_label, x+26, y, 4, 1); d.add(phase_label, x+4, y+1, 2, 1); d.add(phase_slider, x+6, y+1, 20, 1); d.add(phase_val_label, x+26, y+1, 4, 1); d.add(gain_label, x+4, y+2, 2, 1); d.add(gain_slider, x+6, y+2, 20, 1); d.add(pan_label, x+4, y+3, 2, 1); d.add(pan_slider, x+6, y+3, 20, 1); } void Group::update_labels() { char buf[32]; float frequency = get_frequency(); float phase = get_phase(); sprintf(buf, "%4.0f Hz", frequency); freq_val_label.set_text(buf); sprintf(buf, "%.2f π", phase/PI); phase_val_label.set_text(buf); } void Group::generate(float *buf, size_t samples) { Waveform type = (Waveform) list.get_cur_value(); float frequency = get_frequency(); float phase = get_phase(); generate_wave(type, buf, samples, t, frequency, phase); t += dt * samples; } float Group::get_frequency() const { return freq_slider.get_cur_value(); } float Group::get_phase() const { return phase_slider.get_cur_value() / 100.0 - PI; } bool Group::get_gain_if_changed(float *gain) { *gain = gain_slider.get_cur_value() / 100.0; bool changed = (last_gain != *gain); last_gain = *gain; return changed; } bool Group::get_pan_if_changed(float *pan) { *pan = pan_slider.get_cur_value() / 100.0 - 1.0; bool changed = (last_pan != *pan); last_pan = *pan; return changed; } class SaveButton : public ToggleButton { public: SaveButton() : ToggleButton("Save raw") {} void on_click(int mx, int my); }; void SaveButton::on_click(int, int) { if (saving) { log_printf("Stopped saving waveform.\n"); saving = false; return; } if (!save_fp) { save_fp = al_fopen("ex_synth.raw", "wb"); } if (save_fp) { log_printf("Started saving waveform.\n"); saving = true; } } class Prog : public EventHandler { private: Dialog d; Group group1; Group group2; Group group3; Group group4; Group group5; SaveButton save_button; double t; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); virtual ~Prog() {} void run(); void handle_event(const ALLEGRO_EVENT & event); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 30, 26)), save_button(SaveButton()), t(0.0) { group1.add_to_dialog(d, 1, 1); group2.add_to_dialog(d, 1, 6); group3.add_to_dialog(d, 1, 11); group4.add_to_dialog(d, 1, 16); group5.add_to_dialog(d, 1, 21); d.add(save_button, 27, 25, 3, 1); } void Prog::run() { d.prepare(); d.register_event_source(al_get_audio_stream_event_source(stream1)); d.register_event_source(al_get_audio_stream_event_source(stream2)); d.register_event_source(al_get_audio_stream_event_source(stream3)); d.register_event_source(al_get_audio_stream_event_source(stream4)); d.register_event_source(al_get_audio_stream_event_source(stream5)); d.set_event_handler(this); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { group1.update_labels(); group2.update_labels(); group3.update_labels(); group4.update_labels(); group5.update_labels(); al_clear_to_color(al_map_rgb(128, 128, 128)); d.draw(); al_flip_display(); } d.run_step(true); } } void Prog::handle_event(const ALLEGRO_EVENT & event) { if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { ALLEGRO_AUDIO_STREAM *stream; Group *group; void *buf; float gain; float pan; stream = (ALLEGRO_AUDIO_STREAM *) event.any.source; buf = al_get_audio_stream_fragment(stream); if (!buf) { /* This is a normal condition that you must deal with. */ return; } if (stream == stream1) group = &group1; else if (stream == stream2) group = &group2; else if (stream == stream3) group = &group3; else if (stream == stream4) group = &group4; else if (stream == stream5) group = &group5; else group = NULL; ALLEGRO_ASSERT(group); if (group) { group->generate((float *) buf, SAMPLES_PER_BUFFER); if (group->get_gain_if_changed(&gain)) { al_set_audio_stream_gain(stream, gain); } if (group->get_pan_if_changed(&pan)) { al_set_audio_stream_pan(stream, pan); } } if (!al_set_audio_stream_fragment(stream, buf)) { log_printf("Error setting stream fragment.\n"); } } } int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_install_keyboard(); al_install_mouse(); al_init_primitives_addon(); al_init_font_addon(); al_init_ttf_addon(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(800, 600); if (!display) { abort_example("Unable to create display\n"); } al_set_window_title(display, "Synthesiser of sorts"); font_gui = al_load_ttf_font("data/DejaVuSans.ttf", 12, 0); if (!font_gui) { abort_example("Failed to load data/fixed_font.tga\n"); } if (!al_install_audio()) { abort_example("Could not init sound!\n"); } if (!al_reserve_samples(0)) { abort_example("Could not set up voice and mixer.\n"); } size_t buffers = 8; unsigned samples = SAMPLES_PER_BUFFER; unsigned freq = STREAM_FREQUENCY; ALLEGRO_AUDIO_DEPTH depth = ALLEGRO_AUDIO_DEPTH_FLOAT32; ALLEGRO_CHANNEL_CONF ch = ALLEGRO_CHANNEL_CONF_1; stream1 = al_create_audio_stream(buffers, samples, freq, depth, ch); stream2 = al_create_audio_stream(buffers, samples, freq, depth, ch); stream3 = al_create_audio_stream(buffers, samples, freq, depth, ch); stream4 = al_create_audio_stream(buffers, samples, freq, depth, ch); stream5 = al_create_audio_stream(buffers, samples, freq, depth, ch); if (!stream1 || !stream2 || !stream3 || !stream4 || !stream5) { abort_example("Could not create stream.\n"); } ALLEGRO_MIXER *mixer = al_get_default_mixer(); if ( !al_attach_audio_stream_to_mixer(stream1, mixer) || !al_attach_audio_stream_to_mixer(stream2, mixer) || !al_attach_audio_stream_to_mixer(stream3, mixer) || !al_attach_audio_stream_to_mixer(stream4, mixer) || !al_attach_audio_stream_to_mixer(stream5, mixer) ) { abort_example("Could not attach stream to mixer.\n"); } al_set_mixer_postprocess_callback(mixer, mixer_pp_callback, mixer); /* Prog is destroyed at the end of this scope. */ { Theme theme(font_gui); Prog prog(theme, display); prog.run(); } al_destroy_audio_stream(stream1); al_destroy_audio_stream(stream2); al_destroy_audio_stream(stream3); al_destroy_audio_stream(stream4); al_destroy_audio_stream(stream5); al_uninstall_audio(); al_destroy_font(font_gui); al_fclose(save_fp); close_log(false); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_winfull.c0000644000175000001440000000313212152725670016552 0ustar tjadenusers#include "allegro5/allegro.h" #include "common.c" int main(void) { ALLEGRO_DISPLAY *win, *full; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); if (al_get_num_video_adapters() < 2) { abort_example("This example requires multiple video adapters.\n"); } al_set_new_display_adapter(1); al_set_new_display_flags(ALLEGRO_WINDOWED); win = al_create_display(640, 480); if (!win) { abort_example("Error creating windowed display on adapter 1 " "(do you have multiple adapters?)\n"); } al_set_new_display_adapter(0); al_set_new_display_flags(ALLEGRO_FULLSCREEN); full = al_create_display(640, 480); if (!full) { abort_example("Error creating fullscreen display on adapter 0\n"); } events = al_create_event_queue(); al_register_event_source(events, al_get_keyboard_event_source()); while (1) { while (!al_is_event_queue_empty(events)) { al_get_next_event(events, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) goto done; } al_set_target_backbuffer(full); al_clear_to_color(al_map_rgb(rand()%255, rand()%255, rand()%255)); al_flip_display(); al_set_target_backbuffer(win); al_clear_to_color(al_map_rgb(rand()%255, rand()%255, rand()%255)); al_flip_display(); al_rest(0.5); } done: al_destroy_event_queue(events); al_destroy_display(win); al_destroy_display(full); return 0; } allegro-5.0.10/examples/ex_display_options.c0000644000175000001440000002751712152725670020327 0ustar tjadenusers/* Test retrieving and settings possible modes. */ #include #include #include #include #include #include "common.c" ALLEGRO_FONT *font; ALLEGRO_COLOR white; int font_h; int modes_count; int options_count; char status[256]; int flags, old_flags; int visible_rows; int first_visible_row; int selected_column; int selected_mode; int selected_option; #define X(x, m) {#x, ALLEGRO_##x, 0, m, 0} struct { char const *name; int option; int value, max_value; int required; } options[] = { X(COLOR_SIZE, 32), X(RED_SIZE, 8), X(GREEN_SIZE, 8), X(BLUE_SIZE, 8), X(ALPHA_SIZE, 8), X(RED_SHIFT, 32), X(GREEN_SHIFT, 32), X(BLUE_SHIFT, 32), X(ALPHA_SHIFT, 32), X(DEPTH_SIZE, 32), X(FLOAT_COLOR, 1), X(FLOAT_DEPTH, 1), X(STENCIL_SIZE, 32), X(SAMPLE_BUFFERS, 1), X(SAMPLES, 8), X(RENDER_METHOD, 2), X(SINGLE_BUFFER, 1), X(SWAP_METHOD, 1), X(VSYNC, 2), X(COMPATIBLE_DISPLAY, 1), X(MAX_BITMAP_SIZE, 65536), X(SUPPORT_NPOT_BITMAP, 1), X(CAN_DRAW_INTO_BITMAP, 1), X(SUPPORT_SEPARATE_ALPHA, 1), }; #undef X static char const *flag_names[32]; static void init_flags(void) { int i; #define X(f) if (1 << i == ALLEGRO_##f) flag_names[i] = #f; for (i = 0; i < 32; i++) { X(WINDOWED) X(FULLSCREEN) X(OPENGL) X(RESIZABLE) X(FRAMELESS) X(GENERATE_EXPOSE_EVENTS) X(FULLSCREEN_WINDOW) X(MINIMIZED) } #undef X } static void load_font(void) { font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { abort_example("data/fixed_font.tga not found\n"); } font_h = al_get_font_line_height(font); } static void display_options(ALLEGRO_DISPLAY *display) { int i, y = 10; int x = 10; int n = options_count; int dw = al_get_display_width(display); int dh = al_get_display_height(display); ALLEGRO_COLOR c; modes_count = al_get_num_display_modes(); c = al_map_rgb_f(0.8, 0.8, 1); al_draw_textf(font, c, x, y, 0, "Create new display"); y += font_h; for (i = first_visible_row; i < modes_count + 2 && i < first_visible_row + visible_rows; i++) { ALLEGRO_DISPLAY_MODE mode; if (i > 1) { al_get_display_mode(i - 2, &mode); } else if (i == 1) { mode.width = 800; mode.height = 600; mode.format = 0; mode.refresh_rate = 0; } else { mode.width = 800; mode.height = 600; mode.format = 0; mode.refresh_rate = 0; } if (selected_column == 0 && selected_mode == i) { c = al_map_rgb_f(1, 1, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_filled_rectangle(x, y, x + 300, y + font_h, c); } c = al_map_rgb_f(0, 0, 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if ((i == first_visible_row && i > 0) || (i == first_visible_row + visible_rows - 1 && i < modes_count + 1)) { al_draw_textf(font, c, x, y, 0, "..."); } else { al_draw_textf(font, c, x, y, 0, "%s %d x %d (fmt: %x, %d Hz)", i > 1 ? "Fullscreen" : i == 0 ? "Windowed" : "FS Window", mode.width, mode.height, mode.format, mode.refresh_rate); } y += font_h; } x = dw / 2 + 10; y = 10; c = al_map_rgb_f(0.8, 0.8, 1); al_draw_textf(font, c, x, y, 0, "Options for new display"); al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "(current display)"); y += font_h; for (i = 0; i < n; i++) { if (selected_column == 1 && selected_option == i) { c = al_map_rgb_f(1, 1, 0); al_draw_filled_rectangle(x, y, x + 300, y + font_h, c); } switch (options[i].required) { case ALLEGRO_REQUIRE: c = al_map_rgb_f(0.5, 0, 0); break; case ALLEGRO_SUGGEST: c = al_map_rgb_f(0, 0, 0); break; case ALLEGRO_DONTCARE: c = al_map_rgb_f(0.5, 0.5, 0.5); break; } al_draw_textf(font, c, x, y, 0, "%s: %d (%s)", options[i].name, options[i].value, options[i].required == ALLEGRO_REQUIRE ? "required" : options[i].required == ALLEGRO_SUGGEST ? "suggested" : "ignored"); c = al_map_rgb_f(0.9, 0.5, 0.3); al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "%d", al_get_display_option(display, options[i].option)); y += font_h; } c = al_map_rgb_f(0, 0, 0.8); x = 10; y = dh - font_h - 10; y -= font_h; al_draw_textf(font, c, x, y, 0, "PageUp/Down: modify values"); y -= font_h; al_draw_textf(font, c, x, y, 0, "Return: set mode or require option"); y -= font_h; al_draw_textf(font, c, x, y, 0, "Cursor keys: change selection"); y -= font_h * 2; for (i = 0; i < 32; i++) { if (flag_names[i]) { if (flags & (1 << i)) c = al_map_rgb_f(0.5, 0, 0); else if (old_flags & (1 << i)) c = al_map_rgb_f(0.5, 0.4, 0.4); else continue; al_draw_text(font, c, x, y, 0, flag_names[i]); x += al_get_text_width(font, flag_names[i]) + 10; } } c = al_map_rgb_f(1, 0, 0); al_draw_text(font, c, dw / 2, dh - font_h, ALLEGRO_ALIGN_CENTRE, status); } static void update_ui(void) { int h = al_get_display_height(al_get_current_display()); visible_rows = h / font_h - 10; } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; bool redraw = false; if (!al_init()) { abort_example("Could not init Allegro.\n"); } init_flags(); al_init_primitives_addon(); white = al_map_rgba_f(1, 1, 1, 1); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(800, 600); if (!display) { abort_example("Could not create display.\n"); } load_font(); timer = al_create_timer(1.0 / 60); modes_count = al_get_num_display_modes(); options_count = sizeof(options) / sizeof(options[0]); update_ui(); al_clear_to_color(al_map_rgb_f(1, 1, 1)); display_options(display); al_flip_display(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { if (event.mouse.button == 1) { int dw = al_get_display_width(display); int y = 10; int row = (event.mouse.y - y) / font_h - 1; int column = event.mouse.x / (dw / 2); if (column == 0) { if (row >= 0 && row <= modes_count) { selected_column = column; selected_mode = row; redraw = true; } } if (column == 1) { if (row >= 0 && row < options_count) { selected_column = column; selected_option = row; redraw = true; } } } } if (event.type == ALLEGRO_EVENT_TIMER) { int f = al_get_display_flags(display); if (f != flags) { redraw = true; flags = f; old_flags |= f; } } if (event.type == ALLEGRO_EVENT_KEY_CHAR) { int change; if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.keycode == ALLEGRO_KEY_LEFT) { selected_column = 0; redraw = true; } if (event.keyboard.keycode == ALLEGRO_KEY_RIGHT) { selected_column = 1; redraw = true; } if (event.keyboard.keycode == ALLEGRO_KEY_UP) { if (selected_column == 0) selected_mode -= 1; if (selected_column == 1) selected_option -= 1; redraw = true; } if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { if (selected_column == 0) selected_mode += 1; if (selected_column == 1) selected_option += 1; redraw = true; } if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { if (selected_column == 0) { ALLEGRO_DISPLAY_MODE mode; ALLEGRO_DISPLAY *new_display; if (selected_mode > 1) { al_get_display_mode(selected_mode - 2, &mode); al_set_new_display_flags(ALLEGRO_FULLSCREEN); } else if (selected_mode == 1) { mode.width = 800; mode.height = 600; al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); } else { mode.width = 800; mode.height = 600; al_set_new_display_flags(ALLEGRO_WINDOWED); } al_destroy_font(font); font = NULL; new_display = al_create_display( mode.width, mode.height); if (new_display) { al_destroy_display(display); display = new_display; al_set_target_backbuffer(display); al_register_event_source(queue, al_get_display_event_source(display)); update_ui(); sprintf(status, "Display creation succeeded."); } else { sprintf(status, "Display creation failed."); } load_font(); } if (selected_column == 1) { options[selected_option].required += 1; options[selected_option].required %= 3; al_set_new_display_option( options[selected_option].option, options[selected_option].value, options[selected_option].required); } redraw = true; } change = 0; if (event.keyboard.keycode == ALLEGRO_KEY_PGUP) change = 1; if (event.keyboard.keycode == ALLEGRO_KEY_PGDN) change = -1; if (change && selected_column == 1) { options[selected_option].value += change; if (options[selected_option].value < 0) options[selected_option].value = 0; if (options[selected_option].value > options[selected_option].max_value) options[selected_option].value = options[selected_option].max_value; al_set_new_display_option(options[selected_option].option, options[selected_option].value, options[selected_option].required); redraw = true; } } if (selected_mode < 0) selected_mode = 0; if (selected_mode > modes_count + 1) selected_mode = modes_count + 1; if (selected_option < 0) selected_option = 0; if (selected_option >= options_count) selected_option = options_count - 1; if (selected_mode < first_visible_row) first_visible_row = selected_mode; if (selected_mode > first_visible_row + visible_rows - 1) first_visible_row = selected_mode - visible_rows + 1; if (redraw && al_is_event_queue_empty(queue)) { redraw = false; al_clear_to_color(al_map_rgb_f(1, 1, 1)); display_options(display); al_flip_display(); } } al_destroy_font(font); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_resample_test.c0000644000175000001440000001122312152725670017741 0ustar tjadenusers/* Resamping test. Probably should integreate into test_driver somehow */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "common.c" #define SAMPLES_PER_BUFFER 1024 #define N 2 int frequency[N]; double samplepos[N]; ALLEGRO_AUDIO_STREAM *stream[N]; ALLEGRO_DISPLAY *display; float waveform[640], waveform_buffer[640]; static void mainloop(void) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; float *buf; double pitch = 440; int i, si; int n = 0; bool redraw = false; for (i = 0; i < N; i++) { frequency[i] = 22050 * pow(2, i / (double)N); stream[i] = al_create_audio_stream(4, SAMPLES_PER_BUFFER, frequency[i], ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_1); if (!stream[i]) { abort_example("Could not create stream.\n"); } if (!al_attach_audio_stream_to_mixer(stream[i], al_get_default_mixer())) { abort_example("Could not attach stream to mixer.\n"); } } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); for (i = 0; i < N; i++) { al_register_event_source(queue, al_get_audio_stream_event_source(stream[i])); } #ifdef ALLEGRO_POPUP_EXAMPLES if (textlog) { al_register_event_source(queue, al_get_native_text_log_event_source(textlog)); } #endif log_printf("Generating %d sine waves of different sampling quality\n", N); log_printf("If Allegro's resampling is correct there should be little variation\n", N); timer = al_create_timer(1.0 / 60); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(display)); al_start_timer(timer); while (n < 60 * frequency[0] / SAMPLES_PER_BUFFER * N) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { for (si = 0; si < N; si++) { buf = al_get_audio_stream_fragment(stream[si]); if (!buf) { continue; } for (i = 0; i < SAMPLES_PER_BUFFER; i++) { double t = samplepos[si]++ / (double)frequency[si]; buf[i] = sin(t * pitch * ALLEGRO_PI * 2) / N; } if (!al_set_audio_stream_fragment(stream[si], buf)) { log_printf("Error setting stream fragment.\n"); } n++; log_printf("%d", si); if ((n % 60) == 0) log_printf("\n"); } } if (event.type == ALLEGRO_EVENT_TIMER) { redraw = true; } if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } #ifdef ALLEGRO_POPUP_EXAMPLES if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { break; } #endif if (redraw &&al_is_event_queue_empty(queue)) { ALLEGRO_COLOR c = al_map_rgb(0, 0, 0); int i; al_clear_to_color(al_map_rgb_f(1, 1, 1)); for (i = 0; i < 640; i++) { al_draw_pixel(i, 50 + waveform[i] * 50, c); } al_flip_display(); redraw = false; } } for (si = 0; si < N; si++) { al_drain_audio_stream(stream[si]); } log_printf("\n"); al_destroy_event_queue(queue); } static void update_waveform(void *buf, unsigned int samples, void *data) { static int pos; float *fbuf = (float *)buf; int i; int n = samples; (void)data; /* Yes, we could do something more advanced, but an oscilloscope of the * first 640 samples of each buffer is enough for our purpose here. */ if (n > 640) n = 640; for (i = 0; i < n; i++) { waveform_buffer[pos++] = fbuf[i * 2]; if (pos == 640) { memcpy(waveform, waveform_buffer, 640 * sizeof(float)); pos = 0; break; } } } int main(void) { int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); open_log(); display = al_create_display(640, 100); if (!display) { abort_example("Could not create display.\n"); } if (!al_install_audio()) { abort_example("Could not init sound.\n"); } al_reserve_samples(N); al_set_mixer_postprocess_callback(al_get_default_mixer(), update_waveform, NULL); mainloop(); close_log(false); for (i = 0; i < N; i++) { al_destroy_audio_stream(stream[i]); } al_uninstall_audio(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_icon2.c0000644000175000001440000000355712152733060016107 0ustar tjadenusers/* * Example program for the Allegro library. * * Set multiple window icons, a big one and a small one. * The small would would be used for the task bar, * and the big one for the alt-tab popup, for example. */ #include #include "allegro5/allegro_image.h" #include "common.c" #define NUM_ICONS 2 int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *icons[NUM_ICONS]; ALLEGRO_EVENT_QUEUE *queue; int u, v; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); display = al_create_display(320, 200); if (!display) { abort_example("Error creating display\n"); } al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_flip_display(); /* First icon 16x16: Read from file. */ icons[0] = al_load_bitmap("data/cursor.tga"); if (!icons[0]) { abort_example("icons.tga not found\n"); } /* Second icon 32x32: Create it. */ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); icons[1] = al_create_bitmap(32, 32); al_set_target_bitmap(icons[1]); for (v = 0; v < 32; v++) { for (u = 0; u < 32; u++) { al_put_pixel(u, v, al_map_rgb_f(u / 31.0, v / 31.0, 1)); } } al_set_target_backbuffer(display); al_set_display_icons(display, NUM_ICONS, icons); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); for (;;) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } } al_uninstall_system(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_stream_file.c0000644000175000001440000000603312152725670017367 0ustar tjadenusers/* * An example program that plays a file from the disk using Allegro5 * streaming API. The file is being read in small chunks and played on the * sound device instead of being loaded at once. * * usage: ./ex_stream_file file.[wav,ogg...] ... * * by Milan Mimica */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" /* Attaches the stream directly to a voice. Streamed file's and voice's sample * rate, channels and depth must match. */ //#define BYPASS_MIXER int main(int argc, char **argv) { int i; ALLEGRO_VOICE* voice; ALLEGRO_MIXER* mixer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 2) { log_printf("This example needs to be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); goto done; } al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (!voice) { abort_example("Could not create ALLEGRO_VOICE.\n"); } log_printf("Voice created.\n"); #ifndef BYPASS_MIXER mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); if (!mixer) { abort_example("Could not create ALLEGRO_MIXER.\n"); } log_printf("Mixer created.\n"); if (!al_attach_mixer_to_voice(mixer, voice)) { abort_example("al_attach_mixer_to_voice failed.\n"); } #endif for (i = 1; i < argc; ++i) { ALLEGRO_AUDIO_STREAM* stream; const char* filename = argv[i]; bool playing = true; ALLEGRO_EVENT event; ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); stream = al_load_audio_stream(filename, 4, 2048); if (!stream) { log_printf("Could not create an ALLEGRO_AUDIO_STREAM from '%s'!\n", filename); continue; } log_printf("Stream created from '%s'.\n", filename); al_register_event_source(queue, al_get_audio_stream_event_source(stream)); #ifndef BYPASS_MIXER if (!al_attach_audio_stream_to_mixer(stream, mixer)) { log_printf("al_attach_audio_stream_to_mixer failed.\n"); continue; } #else if (!al_attach_audio_stream_to_voice(stream, voice)) { abort_example("al_attach_audio_stream_to_voice failed.\n"); } #endif log_printf("Playing %s ... Waiting for stream to finish ", filename); do { al_wait_for_event(queue, &event); if(event.type == ALLEGRO_EVENT_AUDIO_STREAM_FINISHED) playing = false; } while (playing); log_printf("\n"); al_destroy_event_queue(queue); al_destroy_audio_stream(stream); } log_printf("Done\n"); #ifndef BYPASS_MIXER al_destroy_mixer(mixer); #endif al_destroy_voice(voice); al_uninstall_audio(); done: close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_acodec.c0000644000175000001440000000624712152725670016322 0ustar tjadenusers/* * Ryan Dickie * Audio example that loads a series of files and puts them through the mixer. * Originlly derived from the audio example on the wiki. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" int main(int argc, char **argv) { ALLEGRO_VOICE *voice; ALLEGRO_MIXER *mixer; ALLEGRO_SAMPLE_INSTANCE *sample; int i; char const **filenames; int n; if (argc < 2) { n = 1; filenames = malloc(sizeof *filenames); filenames[0] = "data/testing.ogg"; } else { n = argc - 1; filenames = malloc(sizeof *filenames * n); for (i = 1; i < argc; ++i) { filenames[i - 1] = argv[i]; } } if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (!voice) { abort_example("Could not create ALLEGRO_VOICE.\n"); } mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); if (!mixer) { abort_example("al_create_mixer failed.\n"); } if (!al_attach_mixer_to_voice(mixer, voice)) { abort_example("al_attach_mixer_to_voice failed.\n"); } sample = al_create_sample_instance(NULL); if (!sample) { abort_example("al_create_sample failed.\n"); } for (i = 0; i < n; ++i) { ALLEGRO_SAMPLE *sample_data = NULL; const char *filename = filenames[i]; float sample_time = 0; /* Load the entire sound file from disk. */ sample_data = al_load_sample(filename); if (!sample_data) { abort_example("Could not load sample from '%s'!\n", filename); continue; } if (!al_set_sample(sample, sample_data)) { abort_example("al_set_sample_instance_ptr failed.\n"); continue; } if (!al_attach_sample_instance_to_mixer(sample, mixer)) { abort_example("al_attach_sample_instance_to_mixer failed.\n"); goto done; } /* Play sample in looping mode. */ al_set_sample_instance_playmode(sample, ALLEGRO_PLAYMODE_LOOP); al_play_sample_instance(sample); sample_time = al_get_sample_instance_time(sample); log_printf("Playing '%s' (%.3f seconds) 3 times", filename, sample_time); al_rest(sample_time); if (!al_set_sample_instance_gain(sample, 0.5)) { abort_example("Failed to set gain.\n"); } al_rest(sample_time); if (!al_set_sample_instance_gain(sample, 0.25)) { abort_example("Failed to set gain.\n"); } al_rest(sample_time); al_stop_sample_instance(sample); log_printf("\nDone playing '%s'\n", filename); /* Free the memory allocated. */ al_set_sample(sample, NULL); al_destroy_sample(sample_data); } al_destroy_sample_instance(sample); al_destroy_mixer(mixer); al_destroy_voice(voice); al_uninstall_audio(); done: close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_audio_simple.c0000644000175000001440000000563212152725670017553 0ustar tjadenusers/* * Example program for the Allegro library. * * Demonstrate 'simple' audio interface. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" #define RESERVED_SAMPLES 16 #define MAX_SAMPLE_DATA 10 int main(int argc, const char *argv[]) { ALLEGRO_SAMPLE *sample_data[MAX_SAMPLE_DATA] = {NULL}; ALLEGRO_DISPLAY *display = NULL; ALLEGRO_EVENT_QUEUE *event_queue; ALLEGRO_EVENT event; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 2) { log_printf("This example needs to be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); goto done; } argc--; argv++; al_install_keyboard(); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display\n"); } event_queue = al_create_event_queue(); al_register_event_source(event_queue, al_get_keyboard_event_source()); al_init_acodec_addon(); Restart: if (!al_install_audio()) { abort_example("Could not init sound!\n"); } if (!al_reserve_samples(RESERVED_SAMPLES)) { abort_example("Could not set up voice and mixer.\n"); } memset(sample_data, 0, sizeof(sample_data)); for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) { const char *filename = argv[i]; /* Load the entire sound file from disk. */ sample_data[i] = al_load_sample(argv[i]); if (!sample_data[i]) { log_printf("Could not load sample from '%s'!\n", filename); continue; } } log_printf("Press digits to play sounds, space to stop sounds, " "Escape to quit.\n"); while (true) { al_wait_for_event(event_queue, &event); if (event.type == ALLEGRO_EVENT_KEY_CHAR) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.keyboard.unichar == ' ') { al_stop_samples(); } if (event.keyboard.unichar >= '0' && event.keyboard.unichar <= '9') { i = (event.keyboard.unichar - '0' + 9) % 10; if (sample_data[i]) { log_printf("Playing %d\n",i); if (!al_play_sample(sample_data[i], 1.0, 0.5, 1.0, ALLEGRO_PLAYMODE_LOOP, NULL)) { log_printf( "al_play_sample_data failed, perhaps too many sounds\n"); } } } /* Hidden feature: restart audio subsystem. * For debugging race conditions on shutting down the audio. */ if (event.keyboard.unichar == 'r') { al_uninstall_audio(); goto Restart; } } } /* Sample data and other objects will be automatically freed. */ al_uninstall_audio(); done: al_destroy_display(display); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_config.c0000644000175000001440000000540212152725670016341 0ustar tjadenusers/* * Example program for the Allegro library. * * Test config file reading and writing. */ #include #include "allegro5/allegro.h" #include "common.c" static int passed = true; #define TEST(name, expr) \ do { \ if (expr) \ log_printf(" PASS - %s\n", name); \ else { \ log_printf("!FAIL - %s\n", name); \ passed = false; \ } \ } while (0) int main(void) { ALLEGRO_CONFIG *cfg; const char *value; ALLEGRO_CONFIG_SECTION *iterator; ALLEGRO_CONFIG_ENTRY *iterator2; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); cfg = al_load_config_file("data/sample.cfg"); if (!cfg) { abort_example("Couldn't load data/sample.cfg\n"); } value = al_get_config_value(cfg, NULL, "old_var"); TEST("global var", value && !strcmp(value, "old global value")); value = al_get_config_value(cfg, "section", "old_var"); TEST("section var", value && !strcmp(value, "old section value")); value = al_get_config_value(cfg, "", "mysha.xpm"); TEST("long value", value && strlen(value) == 1394); /* Test whether iterating through our whole sample.cfg returns all * sections and entries, in order. */ value = al_get_first_config_section(cfg, &iterator); TEST("section1", value && !strcmp(value, "")); value = al_get_first_config_entry(cfg, value, &iterator2); TEST("entry1", value && !strcmp(value, "old_var")); value = al_get_next_config_entry(&iterator2); TEST("entry2", value && !strcmp(value, "mysha.xpm")); value = al_get_next_config_entry(&iterator2); TEST("entry3", value == NULL); value = al_get_next_config_section(&iterator); TEST("section2", value && !strcmp(value, "section")); value = al_get_first_config_entry(cfg, value, &iterator2); TEST("entry4", value && !strcmp(value, "old_var")); value = al_get_next_config_entry(&iterator2); TEST("entry5", value == NULL); value = al_get_next_config_section(&iterator); TEST("section3", value); value = al_get_first_config_entry(cfg, value, &iterator2); TEST("entry6", value); value = al_get_next_config_entry(&iterator2); TEST("entry7", value == NULL); value = al_get_next_config_section(&iterator); TEST("section4", value == NULL); al_set_config_value(cfg, "", "new_var", "new value"); al_set_config_value(cfg, "section", "old_var", "new value"); TEST("save_config", al_save_config_file("test.cfg", cfg)); log_printf("Done\n"); al_destroy_config(cfg); close_log(true); return passed ? 0 : 1; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_icon.c0000644000175000001440000000354612152733060016023 0ustar tjadenusers#include #include "allegro5/allegro_image.h" #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *icon1; ALLEGRO_BITMAP *icon2; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_TIMER *timer; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); display = al_create_display(320, 200); if (!display) { abort_example("Error creating display\n"); } al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_flip_display(); /* First icon: Read from file. */ icon1 = al_load_bitmap("data/icon.tga"); if (!icon1) { abort_example("icon.tga not found\n"); } /* Second icon: Create it. */ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); icon2 = al_create_bitmap(16, 16); al_set_target_bitmap(icon2); for (i = 0; i < 256; i++) { int u = i % 16; int v = i / 16; al_put_pixel(u, v, al_map_rgb_f(u / 15.0, v / 15.0, 1)); } al_set_target_backbuffer(display); al_set_window_title(display, "Changing icon example"); timer = al_create_timer(0.5); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); for (;;) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_TIMER) { al_set_display_icon(display, (event.timer.count & 1) ? icon2 : icon1); } } al_uninstall_system(); return 0; } allegro-5.0.10/examples/ex_draw.c0000644000175000001440000002071212152725670016032 0ustar tjadenusers/* Tests some drawing primitives. */ #include #include #include #include #include #include #include #include "common.c" struct Example { ALLEGRO_FONT *font; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_COLOR background, text, white, foreground; ALLEGRO_COLOR outline; ALLEGRO_BITMAP *pattern; ALLEGRO_BITMAP *zoom; double timer[4], counter[4]; int FPS; float text_x, text_y; bool software; int samples; int what; int thickness; } ex; char const *names[] = { "filled rectangles", "rectangles", "filled circles", "circles", "lines" }; static void draw_pattern(ALLEGRO_BITMAP *b) { int w = al_get_bitmap_width(b); int h = al_get_bitmap_height(b); int x, y; int format = ALLEGRO_PIXEL_FORMAT_BGR_888; ALLEGRO_COLOR light = al_map_rgb_f(1, 1, 1); ALLEGRO_COLOR dark = al_map_rgb_f(1, 0.9, 0.8); ALLEGRO_LOCKED_REGION *lock; lock = al_lock_bitmap(b, format, ALLEGRO_LOCK_WRITEONLY); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { ALLEGRO_COLOR c = (x + y) & 1 ? light : dark; unsigned char r, g, b; unsigned char *data = lock->data; al_unmap_rgb(c, &r, &g, &b); data += y * lock->pitch; data += x * 3; data[0] = r; data[1] = g; data[2] = b; } } al_unlock_bitmap(b); } static void set_xy(float x, float y) { ex.text_x = x; ex.text_y = y; } static void print(char const *format, ...) { va_list list; char message[1024]; ALLEGRO_STATE state; int th = al_get_font_line_height(ex.font); al_store_state(&state, ALLEGRO_STATE_BLENDER); va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); al_restore_state(&state); ex.text_y += th; } static void primitive(float l, float t, float r, float b, ALLEGRO_COLOR color, bool never_fill) { float cx = (l + r) / 2; float cy = (t + b) / 2; float rx = (r - l) / 2; float ry = (b - t) / 2; int tk = never_fill ? 0 : ex.thickness; int w = ex.what; if (w == 0 && never_fill) w = 1; if (w == 2 && never_fill) w = 3; if (w == 0) al_draw_filled_rectangle(l, t, r, b, color); if (w == 1) al_draw_rectangle(l, t, r, b, color, tk); if (w == 2) al_draw_filled_ellipse(cx, cy, rx, ry, color); if (w == 3) al_draw_ellipse(cx, cy, rx, ry, color, tk); if (w == 4) al_draw_line(l, t, r, b, color, tk); } static void draw(void) { float x, y; int cx, cy, cw, ch; int w = al_get_bitmap_width(ex.zoom); int h = al_get_bitmap_height(ex.zoom); ALLEGRO_BITMAP *screen = al_get_target_bitmap(); ALLEGRO_BITMAP *mem; int rects_num = 16, i, j; float rects[16 * 4]; for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { rects[(j * 4 + i) * 4 + 0] = 2 + i * 0.25 + i * 7; rects[(j * 4 + i) * 4 + 1] = 2 + j * 0.25 + j * 7; rects[(j * 4 + i) * 4 + 2] = 2 + i * 0.25 + i * 7 + 5; rects[(j * 4 + i) * 4 + 3] = 2 + j * 0.25 + j * 7 + 5; } } al_get_clipping_rectangle(&cx, &cy, &cw, &ch); al_clear_to_color(ex.background); set_xy(8, 0); print("Drawing %s (press SPACE to change)", names[ex.what]); set_xy(8, 16); print("Original"); set_xy(80, 16); print("Enlarged x 16"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); if (ex.software) { al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_new_bitmap_format(al_get_bitmap_format(al_get_target_bitmap())); mem = al_create_bitmap(w, h); al_set_target_bitmap(mem); x = 0; y = 0; } else { mem = NULL; x = 8; y = 40; } al_draw_bitmap(ex.pattern, x, y, 0); /* Draw the test scene. */ al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); for (i = 0; i < rects_num; i++) { ALLEGRO_COLOR rgba = ex.foreground; rgba.a *= 0.5; primitive( x + rects[i * 4 + 0], y + rects[i * 4 + 1], x + rects[i * 4 + 2], y + rects[i * 4 + 3], rgba, false); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); if (ex.software) { al_set_target_bitmap(screen); x = 8; y = 40; al_draw_bitmap(mem, x, y, 0); al_destroy_bitmap(mem); } /* Grab screen contents into our bitmap. */ al_set_target_bitmap(ex.zoom); al_draw_bitmap_region(screen, x, y, w, h, 0, 0, 0); al_set_target_bitmap(screen); /* Draw it enlarged. */ x = 80; y = 40; al_draw_scaled_bitmap(ex.zoom, 0, 0, w, h, x, y, w * 16, h * 16, 0); /* Draw outlines. */ for (i = 0; i < rects_num; i++) { primitive( x + rects[i * 4 + 0] * 16, y + rects[i * 4 + 1] * 16, x + rects[i * 4 + 2] * 16, y + rects[i * 4 + 3] * 16, ex.outline, true); } set_xy(8, 640 - 48); print("Thickness: %d (press T to change)", ex.thickness); print("Drawing with: %s (press S to change)", ex.software ? "software" : "hardware"); print("Supersampling: %dx (edit ex_draw.ini to change)", ex.samples); // FIXME: doesn't work // al_get_display_option(ALLEGRO_SAMPLE_BUFFERS)); } static void tick(void) { draw(); al_flip_display(); } static void run(void) { ALLEGRO_EVENT event; bool need_draw = true; while (1) { if (need_draw && al_is_event_queue_empty(ex.queue)) { tick(); need_draw = false; } al_wait_for_event(ex.queue, &event); switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { ex.what++; if (ex.what == 5) ex.what = 0; } if (event.keyboard.keycode == ALLEGRO_KEY_S) { ex.software = !ex.software; } if (event.keyboard.keycode == ALLEGRO_KEY_T) { ex.thickness++; if (ex.thickness == 2) ex.thickness = 0; } break; case ALLEGRO_EVENT_TIMER: need_draw = true; break; } } } static void init(void) { ex.FPS = 60; ex.font = al_load_font("data/fixed_font.tga", 0, 0); if (!ex.font) { abort_example("data/fixed_font.tga not found.\n"); } ex.background = al_color_name("beige"); ex.foreground = al_color_name("black"); ex.outline = al_color_name("red"); ex.text = al_color_name("blue"); ex.white = al_color_name("white"); ex.pattern = al_create_bitmap(32, 32); ex.zoom = al_create_bitmap(32, 32); draw_pattern(ex.pattern); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_CONFIG *config; char const *value; char str[256]; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); /* Read supersampling info from ex_draw.ini. */ ex.samples = 0; config = al_load_config_file("ex_draw.ini"); if (!config) config = al_create_config(); value = al_get_config_value(config, "settings", "samples"); if (value) ex.samples = strtol(value, NULL, 0); sprintf(str, "%d", ex.samples); al_set_config_value(config, "settings", "samples", str); al_save_config_file("ex_draw.ini", config); al_destroy_config(config); if (ex.samples) { al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE); al_set_new_display_option(ALLEGRO_SAMPLES, ex.samples, ALLEGRO_SUGGEST); } display = al_create_display(640, 640); if (!display) { abort_example("Unable to create display.\n"); } init(); timer = al_create_timer(1.0 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_mouse_cursor.c0000644000175000001440000001334112152725670017622 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. */ #include #include #include "allegro5/allegro_image.h" #include "common.c" typedef struct { int system_cursor; const char *label; } CursorList; #define MARGIN_LEFT 20 #define MARGIN_TOP 20 #define NUM_CURSORS 20 CursorList cursor_list[NUM_CURSORS] = { { ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT, "DEFAULT" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW, "ARROW" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY, "BUSY" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION, "QUESTION" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT, "EDIT" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE, "MOVE" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N, "RESIZE_N" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W, "RESIZE_W" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S, "RESIZE_S" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E, "RESIZE_E" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW, "RESIZE_NW" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW, "RESIZE_SW" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE, "RESIZE_SE" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE, "RESIZE_NE" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS, "PROGRESS" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION, "PRECISION" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK, "LINK" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT, "ALT_SELECT" }, { ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE, "UNAVAILABLE" }, { -1, "CUSTOM" } }; int current_cursor[2] = { 0, 0 }; static void draw_display(ALLEGRO_FONT *font) { int th; int i; al_clear_to_color(al_map_rgb(128, 128, 128)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); th = al_get_font_line_height(font); for (i = 0; i < NUM_CURSORS; i++) { al_draw_text(font, al_map_rgba_f(0, 0, 0, 1), MARGIN_LEFT, MARGIN_TOP + i * th, 0, cursor_list[i].label); } i++; al_draw_text(font, al_map_rgba_f(0, 0, 0, 1), MARGIN_LEFT, MARGIN_TOP + i * th, 0, "Press S/H to show/hide cursor"); al_flip_display(); } static int hover(ALLEGRO_FONT *font, int y) { int th; int i; if (y < MARGIN_TOP) return -1; th = al_get_font_line_height(font); i = (y - MARGIN_TOP) / th; if (i < NUM_CURSORS) return i; return -1; } int main(void) { ALLEGRO_DISPLAY *display1; ALLEGRO_DISPLAY *display2; ALLEGRO_BITMAP *bmp; ALLEGRO_BITMAP *shrunk_bmp; ALLEGRO_MOUSE_CURSOR *custom_cursor; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_FONT *font; ALLEGRO_EVENT event; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); if (!al_install_mouse()) { abort_example("Error installing mouse\n"); } if (!al_install_keyboard()) { abort_example("Error installing keyboard\n"); } al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display1 = al_create_display(400, 400); if (!display1) { abort_example("Error creating display1\n"); } display2 = al_create_display(400, 400); if (!display2) { abort_example("Error creating display2\n"); } bmp = al_load_bitmap("data/allegro.pcx"); if (!bmp) { abort_example("Error loading data/allegro.pcx\n"); } font = al_load_bitmap_font("data/fixed_font.tga"); if (!font) { abort_example("Error loading data/fixed_font.tga\n"); } shrunk_bmp = al_create_bitmap(32, 32); if (!shrunk_bmp) { abort_example("Error creating shrunk_bmp\n"); } al_set_target_bitmap(shrunk_bmp); al_draw_scaled_bitmap(bmp, 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), 0, 0, 32, 32, 0); custom_cursor = al_create_mouse_cursor(shrunk_bmp, 0, 0); if (!custom_cursor) { abort_example("Error creating mouse cursor\n"); } al_set_target_bitmap(NULL); al_destroy_bitmap(shrunk_bmp); al_destroy_bitmap(bmp); shrunk_bmp = NULL; bmp = NULL; queue = al_create_event_queue(); if (!queue) { abort_example("Error creating event queue\n"); } al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display1)); al_register_event_source(queue, al_get_display_event_source(display2)); al_set_target_backbuffer(display1); draw_display(font); al_set_target_backbuffer(display2); draw_display(font); while (1) { al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { al_set_target_backbuffer(event.display.source); draw_display(font); continue; } if (event.type == ALLEGRO_EVENT_KEY_CHAR) { switch (event.keyboard.unichar) { case 27: /* escape */ goto Quit; case 'h': al_hide_mouse_cursor(event.keyboard.display); break; case 's': al_show_mouse_cursor(event.keyboard.display); break; default: break; } } if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { int dpy = (event.mouse.display == display1) ? 0 : 1; int i = hover(font, event.mouse.y); if (i >= 0 && current_cursor[dpy] != i) { if (cursor_list[i].system_cursor != -1) { al_set_system_mouse_cursor(event.mouse.display, cursor_list[i].system_cursor); } else { al_set_mouse_cursor(event.mouse.display, custom_cursor); } current_cursor[dpy] = i; } } } Quit: al_destroy_mouse_cursor(custom_cursor); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_blend2.cpp0000644000175000001440000002375412152725670016614 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Compare software blending routines with hardware blending. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include #include "common.c" #include "nihgui.hpp" ALLEGRO_BITMAP *allegro; ALLEGRO_BITMAP *mysha; ALLEGRO_BITMAP *allegro_bmp; ALLEGRO_BITMAP *mysha_bmp; ALLEGRO_BITMAP *target; ALLEGRO_BITMAP *target_bmp; class Prog { private: Dialog d; Label memory_label; Label texture_label; Label source_label; Label destination_label; List source_image; List destination_image; List draw_mode; Label operation_label[6]; List operations[6]; Label rgba_label[2]; HSlider r[2]; HSlider g[2]; HSlider b[2]; HSlider a[2]; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); void run(); private: void blending_test(bool memory); void draw_samples(); void draw_bitmap(const std::string &, const std::string &, bool, bool); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 20, 40)), memory_label(Label("Memory")), texture_label(Label("Texture")), source_label(Label("Source", false)), destination_label(Label("Destination", false)), source_image(List(0)), destination_image(List(1)), draw_mode(List(0)) { d.add(memory_label, 9, 0, 10, 2); d.add(texture_label, 0, 0, 10, 2); d.add(source_label, 1, 15, 6, 2); d.add(destination_label, 7, 15, 6, 2); List *images[] = {&source_image, &destination_image, &draw_mode}; for (int i = 0; i < 3; i++) { List & image = *images[i]; if (i < 2) { image.append_item("Mysha"); image.append_item("Allegro"); image.append_item("Mysha (tinted)"); image.append_item("Allegro (tinted)"); image.append_item("Color"); } else { image.append_item("original"); image.append_item("scaled"); image.append_item("rotated"); } d.add(image, 1 + i * 6, 17, 4, 6); } for (int i = 0; i < 4; i++) { operation_label[i] = Label(i % 2 == 0 ? "Color" : "Alpha", false); d.add(operation_label[i], 1 + i * 3, 24, 3, 2); List &l = operations[i]; l.append_item("ONE"); l.append_item("ZERO"); l.append_item("ALPHA"); l.append_item("INVERSE"); l.append_item("SRC_COLOR"); l.append_item("DEST_COLOR"); l.append_item("INV_SRC_COLOR"); l.append_item("INV_DEST_COLOR"); d.add(l, 1 + i * 3, 25, 3, 9); } for (int i = 4; i < 6; i++) { operation_label[i] = Label(i == 4 ? "Blend op" : "Alpha op", false); d.add(operation_label[i], 1 + i * 3, 24, 3, 2); List &l = operations[i]; l.append_item("ADD"); l.append_item("SRC_MINUS_DEST"); l.append_item("DEST_MINUS_SRC"); d.add(l, 1 + i * 3, 25, 3, 6); } rgba_label[0] = Label("Source tint/color RGBA"); rgba_label[1] = Label("Dest tint/color RGBA"); d.add(rgba_label[0], 1, 34, 5, 1); d.add(rgba_label[1], 7, 34, 5, 1); for (int i = 0; i < 2; i++) { r[i] = HSlider(255, 255); g[i] = HSlider(255, 255); b[i] = HSlider(255, 255); a[i] = HSlider(255, 255); d.add(r[i], 1 + i * 6, 35, 5, 1); d.add(g[i], 1 + i * 6, 36, 5, 1); d.add(b[i], 1 + i * 6, 37, 5, 1); d.add(a[i], 1 + i * 6, 38, 5, 1); } } void Prog::run() { d.prepare(); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { al_clear_to_color(al_map_rgb(128, 128, 128)); draw_samples(); d.draw(); al_flip_display(); } d.run_step(true); } } int str_to_blend_mode(const std::string & str) { if (str == "ZERO") return ALLEGRO_ZERO; if (str == "ONE") return ALLEGRO_ONE; if (str == "SRC_COLOR") return ALLEGRO_SRC_COLOR; if (str == "DEST_COLOR") return ALLEGRO_DEST_COLOR; if (str == "INV_SRC_COLOR") return ALLEGRO_INVERSE_SRC_COLOR; if (str == "INV_DEST_COLOR") return ALLEGRO_INVERSE_DEST_COLOR; if (str == "ALPHA") return ALLEGRO_ALPHA; if (str == "INVERSE") return ALLEGRO_INVERSE_ALPHA; if (str == "ADD") return ALLEGRO_ADD; if (str == "SRC_MINUS_DEST") return ALLEGRO_SRC_MINUS_DEST; if (str == "DEST_MINUS_SRC") return ALLEGRO_DEST_MINUS_SRC; ALLEGRO_ASSERT(false); return ALLEGRO_ONE; } void draw_background(int x, int y) { ALLEGRO_COLOR c[] = { al_map_rgba(0x66, 0x66, 0x66, 0xff), al_map_rgba(0x99, 0x99, 0x99, 0xff) }; for (int i = 0; i < 320 / 16; i++) { for (int j = 0; j < 200 / 16; j++) { al_draw_filled_rectangle(x + i * 16, y + j * 16, x + i * 16 + 16, y + j * 16 + 16, c[(i + j) & 1]); } } } static ALLEGRO_COLOR makecol(int r, int g, int b, int a) { /* Premultiply alpha. */ float rf = (float)r / 255.0f; float gf = (float)g / 255.0f; float bf = (float)b / 255.0f; float af = (float)a / 255.0f; return al_map_rgba_f(rf*af, gf*af, bf*af, af); } static bool contains(const std::string & haystack, const std::string & needle) { return haystack.find(needle) != std::string::npos; } void Prog::draw_bitmap(const std::string & str, const std::string &how, bool memory, bool destination) { int i = destination ? 1 : 0; int rv = r[i].get_cur_value(); int gv = g[i].get_cur_value(); int bv = b[i].get_cur_value(); int av = a[i].get_cur_value(); ALLEGRO_COLOR color = makecol(rv, gv, bv, av); ALLEGRO_BITMAP *bmp; if (contains(str, "Mysha")) bmp = (memory ? mysha_bmp : mysha); else bmp = (memory ? allegro_bmp : allegro); if (how == "original") { if (str == "Color") al_draw_filled_rectangle(0, 0, 320, 200, color); else if (contains(str, "tint")) al_draw_tinted_bitmap(bmp, color, 0, 0, 0); else al_draw_bitmap(bmp, 0, 0, 0); } else if (how == "scaled") { int w = al_get_bitmap_width(bmp); int h = al_get_bitmap_height(bmp); float s = 200.0 / h * 0.9; if (str == "Color") { al_draw_filled_rectangle(10, 10, 300, 180, color); } else if (contains(str, "tint")) { al_draw_tinted_scaled_bitmap(bmp, color, 0, 0, w, h, 160 - w * s / 2, 100 - h * s / 2, w * s, h * s, 0); } else { al_draw_scaled_bitmap(bmp, 0, 0, w, h, 160 - w * s / 2, 100 - h * s / 2, w * s, h * s, 0); } } else if (how == "rotated") { if (str == "Color") { al_draw_filled_circle(160, 100, 100, color); } else if (contains(str, "tint")) { al_draw_tinted_rotated_bitmap(bmp, color, 160, 100, 160, 100, ALLEGRO_PI / 8, 0); } else { al_draw_rotated_bitmap(bmp, 160, 100, 160, 100, ALLEGRO_PI / 8, 0); } } } void Prog::blending_test(bool memory) { ALLEGRO_COLOR transparency = al_map_rgba_f(0, 0, 0, 0); int op = str_to_blend_mode(operations[4].get_selected_item_text()); int aop = str_to_blend_mode(operations[5].get_selected_item_text()); int src = str_to_blend_mode(operations[0].get_selected_item_text()); int asrc = str_to_blend_mode(operations[1].get_selected_item_text()); int dst = str_to_blend_mode(operations[2].get_selected_item_text()); int adst = str_to_blend_mode(operations[3].get_selected_item_text()); /* Initialize with destination. */ al_clear_to_color(transparency); // Just in case. al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); draw_bitmap(destination_image.get_selected_item_text(), "original", memory, true); /* Now draw the blended source over it. */ al_set_separate_blender(op, src, dst, aop, asrc, adst); draw_bitmap(source_image.get_selected_item_text(), draw_mode.get_selected_item_text(), memory, false); } void Prog::draw_samples() { ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); /* Draw a background, in case our target bitmap will end up with * alpha in it. */ draw_background(40, 20); draw_background(400, 20); /* Test standard blending. */ al_set_target_bitmap(target); blending_test(false); /* Test memory blending. */ al_set_target_bitmap(target_bmp); blending_test(true); /* Display results. */ al_restore_state(&state); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_bitmap(target, 40, 20, 0); al_draw_bitmap(target_bmp, 400, 20, 0); al_restore_state(&state); } int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_font_addon(); al_init_image_addon(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(800, 600); if (!display) { abort_example("Unable to create display\n"); } font = al_load_font("data/fixed_font.tga", 0, 0); if (!font) { abort_example("Failed to load data/fixed_font.tga\n"); } allegro = al_load_bitmap("data/allegro.pcx"); if (!allegro) { abort_example("Failed to load data/allegro.pcx\n"); } mysha = al_load_bitmap("data/mysha256x256.png"); if (!mysha) { abort_example("Failed to load data/mysha256x256.png\n"); } target = al_create_bitmap(320, 200); al_add_new_bitmap_flag(ALLEGRO_MEMORY_BITMAP); allegro_bmp = al_clone_bitmap(allegro); mysha_bmp = al_clone_bitmap(mysha); target_bmp = al_clone_bitmap(target); /* Don't remove these braces. */ { Theme theme(font); Prog prog(theme, display); prog.run(); } al_destroy_bitmap(allegro); al_destroy_bitmap(allegro_bmp); al_destroy_bitmap(mysha); al_destroy_bitmap(mysha_bmp); al_destroy_bitmap(target); al_destroy_bitmap(target_bmp); al_destroy_font(font); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_path_test.c0000644000175000001440000004110212152725670017064 0ustar tjadenusers/* * Example program for the Allegro library. * * Stress test path routines. */ #include #include #include "common.c" #ifdef ALLEGRO_MSVC #pragma warning (disable: 4066) #endif typedef void (*test_t)(void); int error = 0; #define CHECK(x) \ do { \ bool ok = (bool)(x); \ if (!ok) { \ log_printf("FAIL %s\n", #x); \ error++; \ } else { \ log_printf("OK %s\n", #x); \ } \ } while (0) #define CHECK_EQ(x,y) CHECK(0 == strcmp(x, y)) /*---------------------------------------------------------------------------*/ /* Test al_create_path, al_get_path_num_components, al_get_path_component, * al_get_path_drive, al_get_path_filename, al_destroy_path. */ static void t1(void) { ALLEGRO_PATH *path; CHECK(path = al_create_path(NULL)); al_destroy_path(path); CHECK(path = al_create_path("")); CHECK(al_get_path_num_components(path) == 0); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* . is a directory component. */ CHECK(path = al_create_path(".")); CHECK(al_get_path_num_components(path) == 1); CHECK_EQ(al_get_path_component(path, 0), "."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* .. is a directory component. */ CHECK(path = al_create_path("..")); CHECK(al_get_path_num_components(path) == 1); CHECK_EQ(al_get_path_component(path, 0), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Relative path. */ CHECK(path = al_create_path("abc/def/..")); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Absolute path. */ CHECK(path = al_create_path("/abc/def/..")); CHECK(al_get_path_num_components(path) == 4); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Directories + filename. */ CHECK(path = al_create_path("/abc/def/ghi")); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), "ghi"); al_destroy_path(path); } /* Test parsing UNC paths. */ static void t2(void) { #ifdef ALLEGRO_WINDOWS ALLEGRO_PATH *path; /* The mixed slashes are deliberate. */ /* Good paths. */ CHECK(path = al_create_path("//server\\share name/dir/filename")); CHECK_EQ(al_get_path_drive(path), "//server"); CHECK(al_get_path_num_components(path) == 2); CHECK_EQ(al_get_path_component(path, 0), "share name"); CHECK_EQ(al_get_path_component(path, 1), "dir"); CHECK_EQ(al_get_path_filename(path), "filename"); al_destroy_path(path); /* Bad paths. */ CHECK(! al_create_path("//")); CHECK(! al_create_path("//filename")); CHECK(! al_create_path("///share/name/filename")); #else log_printf("Skipping Windows-only test...\n"); #endif } /* Test parsing drive letter paths. */ static void t3(void) { #ifdef ALLEGRO_WINDOWS ALLEGRO_PATH *path; /* The mixed slashes are deliberate. */ CHECK(path = al_create_path("c:abc\\def/ghi")); CHECK_EQ(al_get_path_drive(path), "c:"); CHECK(al_get_path_num_components(path) == 2); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_filename(path), "ghi"); CHECK_EQ(al_path_cstr(path, '\\'), "c:abc\\def\\ghi"); al_destroy_path(path); CHECK(path = al_create_path("c:\\abc/def\\ghi")); CHECK_EQ(al_get_path_drive(path), "c:"); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_filename(path), "ghi"); CHECK_EQ(al_path_cstr(path, '\\'), "c:\\abc\\def\\ghi"); al_destroy_path(path); #else log_printf("Skipping Windows-only test...\n"); #endif } /* Test al_append_path_component. */ static void t4(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK(al_get_path_num_components(path) == 0); al_append_path_component(path, "abc"); al_append_path_component(path, "def"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), "ghi"); CHECK_EQ(al_get_path_component(path, -1), "ghi"); CHECK_EQ(al_get_path_component(path, -2), "def"); CHECK_EQ(al_get_path_component(path, -3), "abc"); al_destroy_path(path); } /* Test al_replace_path_component. */ static void t5(void) { ALLEGRO_PATH *path = al_create_path(NULL); al_append_path_component(path, "abc"); al_append_path_component(path, "INKY"); al_append_path_component(path, "def"); al_append_path_component(path, "BLINKY"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 5); al_replace_path_component(path, 1, "PINKY"); al_replace_path_component(path, -2, "CLYDE"); CHECK(al_get_path_num_components(path) == 5); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "PINKY"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), "CLYDE"); CHECK_EQ(al_get_path_component(path, 4), "ghi"); al_destroy_path(path); } /* Test al_remove_path_component. */ static void t6(void) { ALLEGRO_PATH *path = al_create_path(NULL); al_append_path_component(path, "abc"); al_append_path_component(path, "INKY"); al_append_path_component(path, "def"); al_append_path_component(path, "BLINKY"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 5); al_remove_path_component(path, 1); CHECK(al_get_path_num_components(path) == 4); al_remove_path_component(path, -2); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), "ghi"); al_destroy_path(path); } /* Test al_insert_path_component. */ static void t7(void) { ALLEGRO_PATH *path = al_create_path("INKY/BLINKY/"); al_insert_path_component(path, 0, "abc"); al_insert_path_component(path, 2, "def"); al_insert_path_component(path, 4, "ghi"); CHECK(al_get_path_num_components(path) == 5); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "INKY"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), "BLINKY"); CHECK_EQ(al_get_path_component(path, 4), "ghi"); al_destroy_path(path); } /* Test al_get_path_tail, al_drop_path_tail. */ static void t8(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK(! al_get_path_tail(path)); al_append_path_component(path, "abc"); al_append_path_component(path, "def"); al_append_path_component(path, "ghi"); CHECK_EQ(al_get_path_tail(path), "ghi"); al_drop_path_tail(path); CHECK_EQ(al_get_path_tail(path), "def"); al_drop_path_tail(path); al_drop_path_tail(path); CHECK(! al_get_path_tail(path)); /* Drop tail from already empty path. */ al_drop_path_tail(path); CHECK(! al_get_path_tail(path)); al_destroy_path(path); } /* Test al_set_path_drive, al_set_path_filename, al_path_cstr. */ static void t9(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK_EQ(al_path_cstr(path, '/'), ""); /* Drive letters. */ al_set_path_drive(path, "c:"); CHECK_EQ(al_path_cstr(path, '/'), "c:"); CHECK_EQ(al_get_path_drive(path), "c:"); al_set_path_drive(path, "d:"); CHECK_EQ(al_path_cstr(path, '/'), "d:"); /* Plus directory components. */ al_append_path_component(path, "abc"); al_append_path_component(path, "def"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/"); /* Plus filename. */ al_set_path_filename(path, "uvw"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/uvw"); CHECK_EQ(al_get_path_filename(path), "uvw"); /* Replace filename. */ al_set_path_filename(path, "xyz"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/xyz"); /* Remove drive. */ al_set_path_drive(path, NULL); CHECK_EQ(al_path_cstr(path, '/'), "abc/def/xyz"); /* Remove filename. */ al_set_path_filename(path, NULL); CHECK_EQ(al_path_cstr(path, '/'), "abc/def/"); al_destroy_path(path); } /* Test al_join_paths. */ static void t10(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; /* Both empty. */ path1 = al_create_path(NULL); path2 = al_create_path(NULL); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), ""); al_destroy_path(path1); al_destroy_path(path2); /* Both just filenames. */ path1 = al_create_path("file1"); path2 = al_create_path("file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both relative paths. */ path1 = al_create_path("dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #ifdef ALLEGRO_WINDOWS /* Both relative paths with drive letters. */ path1 = al_create_path("d:dir1a/dir1b/file1"); path2 = al_create_path("e:dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #endif /* Path1 absolute, path2 relative. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both paths absolute. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("/dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/file1"); al_destroy_path(path1); al_destroy_path(path2); } /* Test al_rebase_path. */ static void t11(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; /* Both empty. */ path1 = al_create_path(NULL); path2 = al_create_path(NULL); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), ""); al_destroy_path(path1); al_destroy_path(path2); /* Both just filenames. */ path1 = al_create_path("file1"); path2 = al_create_path("file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both relative paths. */ path1 = al_create_path("dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #ifdef ALLEGRO_WINDOWS /* Both relative paths with drive letters. */ path1 = al_create_path("d:dir1a/dir1b/file1"); path2 = al_create_path("e:dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #endif /* Path1 absolute, path2 relative. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both paths absolute. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("/dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); } /* Test al_set_path_extension, al_get_path_extension. */ static void t12(void) { ALLEGRO_PATH *path = al_create_path(NULL); /* Get null extension. */ CHECK_EQ(al_get_path_extension(path), ""); /* Set extension on null filename. */ CHECK(! al_set_path_extension(path, "ext")); CHECK_EQ(al_get_path_filename(path), ""); /* Set extension on extension-less filename. */ al_set_path_filename(path, "abc"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.ext"); /* Replacing extension. */ al_set_path_filename(path, "abc.def"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.ext"); CHECK_EQ(al_get_path_extension(path), ".ext"); /* Filename with multiple dots. */ al_set_path_filename(path, "abc.def.ghi"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.def.ext"); CHECK_EQ(al_get_path_extension(path), ".ext"); al_destroy_path(path); } /* Test al_get_path_basename. */ static void t13(void) { ALLEGRO_PATH *path = al_create_path(NULL); /* No filename. */ al_set_path_filename(path, NULL); CHECK_EQ(al_get_path_basename(path), ""); /* No extension. */ al_set_path_filename(path, "abc"); CHECK_EQ(al_get_path_basename(path), "abc"); /* Filename with a single dot. */ al_set_path_filename(path, "abc.ext"); CHECK_EQ(al_get_path_basename(path), "abc"); /* Filename with multiple dots. */ al_set_path_filename(path, "abc.def.ghi"); CHECK_EQ(al_get_path_basename(path), "abc.def"); al_destroy_path(path); } /* Test al_clone_path. */ static void t14(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; path1 = al_create_path("/abc/def/ghi"); path2 = al_clone_path(path1); CHECK_EQ(al_path_cstr(path1, '/'), al_path_cstr(path2, '/')); al_replace_path_component(path2, 2, "DEF"); al_set_path_filename(path2, "GHI"); CHECK_EQ(al_path_cstr(path1, '/'), "/abc/def/ghi"); CHECK_EQ(al_path_cstr(path2, '/'), "/abc/DEF/GHI"); al_destroy_path(path1); al_destroy_path(path2); } static void t15(void) { /* nothing */ log_printf("Skipping empty test...\n"); } static void t16(void) { /* nothing */ log_printf("Skipping empty test...\n"); } /* Test al_make_path_canonical. */ static void t17(void) { ALLEGRO_PATH *path; path = al_create_path("/../.././abc/./def/../../ghi/jkl"); CHECK(al_make_path_canonical(path)); CHECK(al_get_path_num_components(path) == 6); CHECK_EQ(al_path_cstr(path, '/'), "/abc/def/../../ghi/jkl"); al_destroy_path(path); path = al_create_path("../.././abc/./def/../../ghi/jkl"); CHECK(al_make_path_canonical(path)); CHECK(al_get_path_num_components(path) == 7); CHECK_EQ(al_path_cstr(path, '/'), "../../abc/def/../../ghi/jkl"); al_destroy_path(path); } /*---------------------------------------------------------------------------*/ const test_t all_tests[] = { NULL, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17 }; #define NUM_TESTS (int)(sizeof(all_tests) / sizeof(all_tests[0])) int main(int argc, const char *argv[]) { int i; if (!al_init()) { abort_example("Could not initialise Allegro.\n"); } open_log(); if (argc < 2) { for (i = 1; i < NUM_TESTS; i++) { log_printf("# t%d\n\n", i); all_tests[i](); log_printf("\n"); } } else { i = atoi(argv[1]); if (i > 0 && i < NUM_TESTS) { all_tests[i](); } } log_printf("Done\n"); close_log(true); if (error) { exit(EXIT_FAILURE); } return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_blend_test.c0000644000175000001440000002037112152725670017221 0ustar tjadenusers#include #include #include #include #include "common.c" int test_only_index = 0; int test_index = 0; bool test_display = false; ALLEGRO_DISPLAY *display; static void print_color(ALLEGRO_COLOR c) { float r, g, b, a; al_unmap_rgba_f(c, &r, &g, &b, &a); log_printf("%.2f, %.2f, %.2f, %.2f", r, g, b, a); } static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, int src_format, int dst_format, int src, int dst, int src_a, int dst_a, int operation, bool verbose) { ALLEGRO_COLOR result; ALLEGRO_BITMAP *dst_bmp; al_set_new_bitmap_format(dst_format); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); dst_bmp = al_create_bitmap(1, 1); al_set_target_bitmap(dst_bmp); al_clear_to_color(dst_col); if (operation == 0) { ALLEGRO_BITMAP *src_bmp; al_set_new_bitmap_format(src_format); src_bmp = al_create_bitmap(1, 1); al_set_target_bitmap(src_bmp); al_clear_to_color(src_col); al_set_target_bitmap(dst_bmp); al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); al_draw_bitmap(src_bmp, 0, 0, 0); al_destroy_bitmap(src_bmp); } else if (operation == 1) { al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); al_draw_pixel(0, 0, src_col); } else if (operation == 2) { al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); al_draw_line(0, 0, 1, 1, src_col, 0); } result = al_get_pixel(dst_bmp, 0, 0); al_set_target_backbuffer(display); if (test_display) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(dst_bmp, 0, 0, 0); } al_destroy_bitmap(dst_bmp); if (!verbose) return result; log_printf("---\n"); log_printf("test id: %d\n", test_index); log_printf("source : "); print_color(src_col); log_printf(" %s format=%d mode=%d alpha=%d\n", operation == 0 ? "bitmap" : operation == 1 ? "pixel" : "prim", src_format, src, src_a); log_printf("destination: "); print_color(dst_col); log_printf(" format=%d mode=%d alpha=%d\n", dst_format, dst, dst_a); log_printf("result : "); print_color(result); log_printf("\n"); return result; } static bool same_color(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2) { float r1, g1, b1, a1; float r2, g2, b2, a2; float dr, dg, db, da; float d; al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1); al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2); dr = r1 - r2; dg = g1 - g2; db = b1 - b2; da = a1 - a2; d = sqrt(dr * dr + dg * dg + db * db + da * da); if (d < 0.01) return true; else return false; } static float get_factor(int operation, float alpha) { switch(operation) { case ALLEGRO_ZERO: return 0; case ALLEGRO_ONE: return 1; case ALLEGRO_ALPHA: return alpha; case ALLEGRO_INVERSE_ALPHA: return 1 - alpha; } return 0; } static bool has_alpha(int format) { if (format == ALLEGRO_PIXEL_FORMAT_RGB_888) return false; if (format == ALLEGRO_PIXEL_FORMAT_BGR_888) return false; return true; } #define CLAMP(x) (x > 1 ? 1 : x) static ALLEGRO_COLOR reference_implementation( ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, int src_format, int dst_format, int src_mode, int dst_mode, int src_alpha, int dst_alpha, int operation) { float sr, sg, sb, sa; float dr, dg, db, da; float r, g, b, a; float src, dst, asrc, adst; al_unmap_rgba_f(src_col, &sr, &sg, &sb, &sa); al_unmap_rgba_f(dst_col, &dr, &dg, &db, &da); /* Do we even have source alpha? */ if (operation == 0) { if (!has_alpha(src_format)) { sa = 1; } } r = sr; g = sg; b = sb; a = sa; src = get_factor(src_mode, a); dst = get_factor(dst_mode, a); asrc = get_factor(src_alpha, a); adst = get_factor(dst_alpha, a); r = r * src + dr * dst; g = g * src + dg * dst; b = b * src + db * dst; a = a * asrc + da * adst; r = CLAMP(r); g = CLAMP(g); b = CLAMP(b); a = CLAMP(a); /* Do we even have destination alpha? */ if (!has_alpha(dst_format)) { a = 1; } return al_map_rgba_f(r, g, b, a); } static void do_test2(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, int src_format, int dst_format, int src_mode, int dst_mode, int src_alpha, int dst_alpha, int operation) { ALLEGRO_COLOR reference, result, from_display; test_index++; if (test_only_index && test_index != test_only_index) return; reference = reference_implementation( src_col, dst_col, src_format, dst_format, src_mode, dst_mode, src_alpha, dst_alpha, operation); result = test(src_col, dst_col, src_format, dst_format, src_mode, dst_mode, src_alpha, dst_alpha, operation, false); if (!same_color(reference, result)) { test(src_col, dst_col, src_format, dst_format, src_mode, dst_mode, src_alpha, dst_alpha, operation, true); log_printf("expected : "); print_color(reference); log_printf("\n"); log_printf("FAILED\n"); } else { log_printf(" OK"); } if (test_display) { dst_format = al_get_display_format(display); from_display = al_get_pixel(al_get_backbuffer(display), 0, 0); reference = reference_implementation( src_col, dst_col, src_format, dst_format, src_mode, dst_mode, src_alpha, dst_alpha, operation); if (!same_color(reference, from_display)) { test(src_col, dst_col, src_format, dst_format, src_mode, dst_mode, src_alpha, dst_alpha, operation, true); log_printf("displayed : "); print_color(from_display); log_printf("\n"); log_printf("expected : "); print_color(reference); log_printf("\n"); log_printf("(FAILED on display)\n"); } } } static void do_test1(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, int src_format, int dst_format) { int i, j, k, l, m; int smodes[4] = {ALLEGRO_ALPHA, ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA}; int dmodes[4] = {ALLEGRO_INVERSE_ALPHA, ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_ALPHA}; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { for (l = 0; l < 4; l++) { for (m = 0; m < 3; m++) { do_test2(src_col, dst_col, src_format, dst_format, smodes[i], dmodes[j], smodes[k], dmodes[l], m); } } } } } } #define C al_map_rgba_f int main(int argc, char **argv) { int i, j, l, m; ALLEGRO_COLOR src_colors[2]; ALLEGRO_COLOR dst_colors[2]; int src_formats[2] = { ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_PIXEL_FORMAT_BGR_888 }; int dst_formats[2] = { ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_PIXEL_FORMAT_BGR_888 }; src_colors[0] = C(0, 0, 0, 1); src_colors[1] = C(1, 1, 1, 1); dst_colors[0] = C(1, 1, 1, 1); dst_colors[1] = C(0, 0, 0, 0); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) test_display = 1; else test_only_index = strtol(argv[i], NULL, 10); } if (!al_init()) { abort_example("Could not initialise Allegro\n"); } open_log(); al_init_primitives_addon(); if (test_display) { display = al_create_display(100, 100); if (!display) { abort_example("Unable to create display\n"); } } for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { for (l = 0; l < 2; l++) { for (m = 0; m < 2; m++) { do_test1( src_colors[i], dst_colors[j], src_formats[l], dst_formats[m]); } } } } log_printf("\nDone\n"); if (test_only_index && test_display) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; al_flip_display(); al_install_keyboard(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_wait_for_event(queue, &event); } close_log(true); return 0; } allegro-5.0.10/examples/ex_membmp.c0000644000175000001440000000621112152725670016350 0ustar tjadenusers#include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "common.c" static void print(ALLEGRO_FONT *myfont, char *message, int x, int y) { al_draw_text(myfont, al_map_rgb(0, 0, 0), x+2, y+2, 0, message); al_draw_text(myfont, al_map_rgb(255, 255, 255), x, y, 0, message); } static bool test(ALLEGRO_BITMAP *bitmap, ALLEGRO_FONT *font, char *message) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; double start_time; long frames = 0; double fps = 0; char second_line[100]; bool quit = false; queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); start_time = al_get_time(); for (;;) { if (al_get_next_event(queue, &event)) { if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { break; } if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { quit = true; break; } } } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); /* Clear the backbuffer with red so we can tell if the bitmap does not * cover the entire backbuffer. */ al_clear_to_color(al_map_rgb(255, 0, 0)); al_draw_scaled_bitmap(bitmap, 0, 0, al_get_bitmap_width(bitmap), al_get_bitmap_height(bitmap), 0, 0, al_get_bitmap_width(al_get_target_bitmap()), al_get_bitmap_height(al_get_target_bitmap()), 0); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); /* Note this makes the memory buffer case much slower due to repeated * locking of the backbuffer. Officially you can't use al_lock_bitmap * to solve the problem either. */ print(font, message, 0, 0); sprintf(second_line, "%.1f FPS", fps); print(font, second_line, 0, al_get_font_line_height(font)+5); al_flip_display(); frames++; fps = (double)frames / (al_get_time() - start_time); } al_destroy_event_queue(queue); return quit; } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *accelfont; ALLEGRO_FONT *memfont; ALLEGRO_BITMAP *accelbmp; ALLEGRO_BITMAP *membmp; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 400); if (!display) { abort_example("Error creating display\n"); } accelfont = al_load_font("data/font.tga", 0, 0); if (!accelfont) { abort_example("font.tga not found\n"); } accelbmp = al_load_bitmap("data/mysha.pcx"); if (!accelbmp) { abort_example("mysha.pcx not found\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); memfont = al_load_font("data/font.tga", 0, 0); membmp = al_load_bitmap("data/mysha.pcx"); for (;;) { if (test(membmp, memfont, "Memory bitmap (press SPACE key)")) break; if (test(accelbmp, accelfont, "Accelerated bitmap (press SPACE key)")) break; } return 0; } allegro-5.0.10/examples/ex_audio_props.cpp0000644000175000001440000001113212152725670017755 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Test audio properties (gain and panning, for now). */ #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "nihgui.hpp" #include #include "common.c" ALLEGRO_FONT *font_gui; ALLEGRO_SAMPLE *sample; ALLEGRO_SAMPLE_INSTANCE *sample_inst; class Prog { private: Dialog d; ToggleButton pan_button; HSlider pan_slider; Label speed_label; HSlider speed_slider; ToggleButton bidir_button; Label gain_label; VSlider gain_slider; Label mixer_gain_label; VSlider mixer_gain_slider; Label two_label; Label one_label; Label zero_label; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); void run(); void update_properties(); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 40, 20)), pan_button(ToggleButton("Pan")), pan_slider(HSlider(1000, 2000)), speed_label(Label("Speed")), speed_slider(HSlider(1000, 5000)), bidir_button(ToggleButton("Bidir")), gain_label(Label("Gain")), gain_slider(VSlider(1000, 2000)), mixer_gain_label(Label("Mixer gain")), mixer_gain_slider(VSlider(1000, 2000)), two_label(Label("2.0")), one_label(Label("1.0")), zero_label(Label("0.0")) { pan_button.set_pushed(true); d.add(pan_button, 2, 10, 4, 1); d.add(pan_slider, 6, 10, 22, 1); d.add(speed_label, 2, 12, 4, 1); d.add(speed_slider, 6, 12, 22, 1); d.add(bidir_button, 2, 14, 4, 1); d.add(gain_label, 29, 1, 2, 1); d.add(gain_slider, 29, 2, 2, 17); d.add(mixer_gain_label, 33, 1, 6, 1); d.add(mixer_gain_slider, 35, 2, 2, 17); d.add(two_label, 32, 2, 2, 1); d.add(one_label, 32, 10, 2, 1); d.add(zero_label, 32, 18, 2, 1); } void Prog::run() { d.prepare(); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { update_properties(); al_clear_to_color(al_map_rgb(128, 128, 128)); d.draw(); al_flip_display(); } d.run_step(true); } } void Prog::update_properties() { float pan; float speed; float gain; float mixer_gain; if (pan_button.get_pushed()) pan = pan_slider.get_cur_value() / 1000.0f - 1.0f; else pan = ALLEGRO_AUDIO_PAN_NONE; al_set_sample_instance_pan(sample_inst, pan); speed = speed_slider.get_cur_value() / 1000.0f; al_set_sample_instance_speed(sample_inst, speed); if (bidir_button.get_pushed()) al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_BIDIR); else al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_LOOP); gain = gain_slider.get_cur_value() / 1000.0f; al_set_sample_instance_gain(sample_inst, gain); mixer_gain = mixer_gain_slider.get_cur_value() / 1000.0f; al_set_mixer_gain(al_get_default_mixer(), mixer_gain); } int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; const char *filename; if (argc >= 2) { filename = argv[1]; } else { filename = "data/testing.ogg"; } if (!al_init()) { abort_example("Could not init Allegro\n"); } al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); al_init_primitives_addon(); al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } if (!al_reserve_samples(1)) { abort_example("Could not set up voice and mixer.\n"); } sample = al_load_sample(filename); if (!sample) { abort_example("Could not load sample from '%s'!\n", filename); } al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(640, 480); if (!display) { abort_example("Unable to create display\n"); } font_gui = al_load_font("data/fixed_font.tga", 0, 0); if (!font_gui) { abort_example("Failed to load data/fixed_font.tga\n"); } /* Loop the sample. */ sample_inst = al_create_sample_instance(sample); al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_LOOP); al_attach_sample_instance_to_mixer(sample_inst, al_get_default_mixer()); al_play_sample_instance(sample_inst); /* Don't remove these braces. */ { Theme theme(font_gui); Prog prog(theme, display); prog.run(); } al_destroy_sample_instance(sample_inst); al_destroy_sample(sample); al_uninstall_audio(); al_destroy_font(font_gui); return 0; (void)argc; (void)argv; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_keyboard_events.c0000644000175000001440000000742012152733060020252 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * Updated by Ryan Dickie. * * This program tests keyboard events. */ #include #include #include "common.c" #define WIDTH 640 #define HEIGHT 480 #define SIZE_LOG 50 /* globals */ ALLEGRO_EVENT_QUEUE *event_queue; ALLEGRO_DISPLAY *display; static void log_key(char const *how, int keycode, int unichar, int modifiers) { char multibyte[5] = {0, 0, 0, 0, 0}; const char* key_name; al_utf8_encode(multibyte, unichar <= 32 ? ' ' : unichar); key_name = al_keycode_to_name(keycode); log_printf("%-8s code=%03d, char='%s' (%4d), modifiers=%08x, [%s]\n", how, keycode, multibyte, unichar, modifiers, key_name); } /* main_loop: * The main loop of the program. Here we wait for events to come in from * any one of the event sources and react to each one accordingly. While * there are no events to react to the program sleeps and consumes very * little CPU time. See main() to see how the event sources and event queue * are set up. */ static void main_loop(void) { ALLEGRO_EVENT event; log_printf("Focus on the main window (black) and press keys to see events. "); log_printf("Escape quits.\n\n"); while (true) { /* Take the next event out of the event queue, and store it in `event'. */ al_wait_for_event(event_queue, &event); /* Check what type of event we got and act accordingly. ALLEGRO_EVENT * is a union type and interpretation of its contents is dependent on * the event type, which is given by the 'type' field. * * Each event also comes from an event source and has a timestamp. * These are accessible through the 'any.source' and 'any.timestamp' * fields respectively, e.g. 'event.any.timestamp' */ switch (event.type) { /* ALLEGRO_EVENT_KEY_DOWN - a keyboard key was pressed. */ case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { return; } log_key("KEY_DOWN", event.keyboard.keycode, 0, 0); break; /* ALLEGRO_EVENT_KEY_UP - a keyboard key was released. */ case ALLEGRO_EVENT_KEY_UP: log_key("KEY_UP", event.keyboard.keycode, 0, 0); break; /* ALLEGRO_EVENT_KEY_CHAR - a character was typed or repeated. */ case ALLEGRO_EVENT_KEY_CHAR: { char const *label = (event.keyboard.repeat ? "repeat" : "KEY_CHAR"); log_key(label, event.keyboard.keycode, event.keyboard.unichar, event.keyboard.modifiers); break; } /* ALLEGRO_EVENT_DISPLAY_CLOSE - the window close button was pressed. */ case ALLEGRO_EVENT_DISPLAY_CLOSE: return; /* We received an event of some type we don't know about. * Just ignore it. */ default: break; } } } int main(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log_monospace(); display = al_create_display(WIDTH, HEIGHT); if (!display) { abort_example("al_create_display failed\n"); } al_clear_to_color(al_map_rgb_f(0, 0, 0)); al_flip_display(); if (!al_install_keyboard()) { abort_example("al_install_keyboard failed\n"); } event_queue = al_create_event_queue(); if (!event_queue) { abort_example("al_create_event_queue failed\n"); } al_register_event_source(event_queue, al_get_keyboard_event_source()); al_register_event_source(event_queue, al_get_display_event_source(display)); main_loop(); close_log(false); return 0; } /* vim: set ts=8 sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_font_justify.cpp0000644000175000001440000000646112152725670020165 0ustar tjadenusers/* * Example program for the Allegro library, by Peter Wang. * * Test text justification routines. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_ttf.h" #include #include "nihgui.hpp" #include "common.c" ALLEGRO_FONT *font; ALLEGRO_FONT *font_gui; class Prog { private: Dialog d; Label text_label; Label width_label; Label diff_label; TextEntry text_entry; HSlider width_slider; HSlider diff_slider; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); void run(); void draw_text(); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 10, 20)), text_label(Label("Text")), width_label(Label("Width")), diff_label(Label("Diff")), text_entry(TextEntry("Lorem ipsum dolor sit amet")), width_slider(HSlider(400, al_get_display_width(display))), diff_slider(HSlider(100, al_get_display_width(display))) { d.add(text_label, 0, 10, 1, 1); d.add(text_entry, 1, 10, 8, 1); d.add(width_label, 0, 12, 1, 1); d.add(width_slider, 1, 12, 8, 1); d.add(diff_label, 0, 14, 1, 1); d.add(diff_slider, 1, 14, 8, 1); } void Prog::run() { d.prepare(); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { al_clear_to_color(al_map_rgb(128, 128, 128)); draw_text(); d.draw(); al_flip_display(); } d.run_step(true); } } void Prog::draw_text() { ALLEGRO_BITMAP *target = al_get_target_bitmap(); const int cx = al_get_bitmap_width(target) / 2; const int x1 = cx - width_slider.get_cur_value() / 2; const int x2 = cx + width_slider.get_cur_value() / 2; const int diff = diff_slider.get_cur_value(); const int th = al_get_font_line_height(font); al_draw_justified_text(font, al_map_rgb_f(1, 1, 1), x1, x2, 50, diff, ALLEGRO_ALIGN_INTEGER, text_entry.get_text()); al_draw_rectangle(x1, 50, x2, 50 + th, al_map_rgb(0, 0, 255), 0); al_draw_line(cx - diff / 2, 53 + th, cx + diff / 2, 53 + th, al_map_rgb(0, 255, 0), 0); } int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); al_init_ttf_addon(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(640, 480); if (!display) { abort_example("Unable to create display\n"); } /* Test TTF fonts or bitmap fonts. */ #if 1 font = al_load_font("data/DejaVuSans.ttf", 24, 0); if (!font) { abort_example("Failed to load data/DejaVuSans.ttf\n"); } #else font = al_load_font("data/font.tga", 0, 0); if (!font) { abort_example("Failed to load data/font.tga\n"); } #endif font_gui = al_load_font("data/DejaVuSans.ttf", 14, 0); if (!font_gui) { abort_example("Failed to load data/DejaVuSans.ttf\n"); } /* Don't remove these braces. */ { Theme theme(font_gui); Prog prog(theme, display); prog.run(); } al_destroy_font(font); al_destroy_font(font_gui); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_haiku.c0000644000175000001440000006335011476662264016212 0ustar tjadenusers/* * Haiku - A Musical Instrument, by Mark Oates. * * Allegro example version by Peter Wang. * * It demonstrates use of the audio functions, and other things besides. */ /* This version leaves out some things from Mark's original version: * the nice title sequence, text labels and mouse cursors. */ #include #include #include #include #include "common.c" const float PI = ALLEGRO_PI; const float TWOPI = ALLEGRO_PI * 2.0; enum { TYPE_EARTH, TYPE_WIND, TYPE_WATER, TYPE_FIRE, NUM_TYPES, TYPE_NONE = NUM_TYPES }; enum { IMG_EARTH = TYPE_EARTH, IMG_WIND = TYPE_WIND, IMG_WATER = TYPE_WATER, IMG_FIRE = TYPE_FIRE, IMG_BLACK, IMG_DROPSHADOW, IMG_GLOW, IMG_GLOW_OVERLAY, IMG_AIR_EFFECT, IMG_WATER_DROPS, IMG_FLAME, IMG_MAIN_FLAME, IMG_MAX }; typedef enum { INTERP_LINEAR, INTERP_FAST, INTERP_DOUBLE_FAST, INTERP_SLOW, INTERP_DOUBLE_SLOW, INTERP_SLOW_IN_OUT, INTERP_BOUNCE } Interp; typedef struct Anim Anim; typedef struct Token Token; typedef struct Flair Flair; typedef struct Sprite Sprite; #define MAX_ANIMS 10 struct Anim { float *lval; /* NULL if unused */ float start_val; float end_val; Interp func; float start_time; float end_time; }; struct Sprite { unsigned image; /* IMG_ */ float x, scale_x, align_x; float y, scale_y, align_y; float angle; float r, g, b; float opacity; Anim anims[MAX_ANIMS]; /* keep it simple */ }; struct Token { unsigned type; /* TYPE_ */ float x; float y; int pitch; /* [0, NUM_PITCH) */ Sprite bot; Sprite top; }; struct Flair { Flair *next; float end_time; Sprite sprite; }; /****************************************************************************/ /* Globals */ /****************************************************************************/ enum { NUM_PITCH = 8, TOKENS_X = 16, TOKENS_Y = NUM_PITCH, NUM_TOKENS = TOKENS_X * TOKENS_Y, }; ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *refresh_timer; ALLEGRO_TIMER *playback_timer; ALLEGRO_BITMAP *images[IMG_MAX]; ALLEGRO_SAMPLE *element_samples[NUM_TYPES][NUM_PITCH]; ALLEGRO_SAMPLE *select_sample; Token tokens[NUM_TOKENS]; Token buttons[NUM_TYPES]; Sprite glow; Sprite glow_overlay; ALLEGRO_COLOR glow_color[NUM_TYPES]; Flair *flairs = NULL; Token *hover_token = NULL; Token *selected_button = NULL; int playback_column = 0; const int screen_w = 1024; const int screen_h = 600; const float game_board_x = 100.0; const float token_size = 64; const float token_scale = 0.8; const float button_size = 64; const float button_unsel_scale = 0.8; const float button_sel_scale = 1.1; const float dropshadow_unsel_scale = 0.6; const float dropshadow_sel_scale = 0.9; const float refresh_rate = 60.0; const float playback_period = 2.7333; #define HAIKU_DATA "data/haiku/" /****************************************************************************/ /* Init */ /****************************************************************************/ static void load_images(void) { int i; images[IMG_EARTH] = al_load_bitmap(HAIKU_DATA "earth4.png"); images[IMG_WIND] = al_load_bitmap(HAIKU_DATA "wind3.png"); images[IMG_WATER] = al_load_bitmap(HAIKU_DATA "water.png"); images[IMG_FIRE] = al_load_bitmap(HAIKU_DATA "fire.png"); images[IMG_BLACK] = al_load_bitmap(HAIKU_DATA "black_bead_opaque_A.png"); images[IMG_DROPSHADOW] = al_load_bitmap(HAIKU_DATA "dropshadow.png"); images[IMG_AIR_EFFECT] = al_load_bitmap(HAIKU_DATA "air_effect.png"); images[IMG_WATER_DROPS] = al_load_bitmap(HAIKU_DATA "water_droplets.png"); images[IMG_FLAME] = al_load_bitmap(HAIKU_DATA "flame2.png"); images[IMG_MAIN_FLAME] = al_load_bitmap(HAIKU_DATA "main_flame2.png"); images[IMG_GLOW] = al_load_bitmap(HAIKU_DATA "healthy_glow.png"); images[IMG_GLOW_OVERLAY]= al_load_bitmap(HAIKU_DATA "overlay_pretty.png"); for (i = 0; i < IMG_MAX; i++) { if (images[i] == NULL) abort_example("Error loading image.\n"); } } static void load_samples(void) { const char *base[NUM_TYPES] = {"earth", "air", "water", "fire"}; char name[128]; int t, p; for (t = 0; t < NUM_TYPES; t++) { for (p = 0; p < NUM_PITCH; p++) { sprintf(name, HAIKU_DATA "%s_%d.ogg", base[t], p); element_samples[t][p] = al_load_sample(name); if (!element_samples[t][p]) abort_example("Error loading %s.\n", name); } } select_sample = al_load_sample(HAIKU_DATA "select.ogg"); if (!select_sample) abort_example("Error loading select.ogg.\n"); } static void init_sprite(Sprite *spr, int image, float x, float y, float scale, float opacity) { int i; spr->image = image; spr->x = x; spr->y = y; spr->scale_x = spr->scale_y = scale; spr->align_x = spr->align_y = 0.5; spr->angle = 0.0; spr->r = spr->g = spr->b = 1.0; spr->opacity = opacity; for (i = 0; i < MAX_ANIMS; i++) spr->anims[i].lval = NULL; } static void init_tokens(void) { const float token_w = token_size * token_scale; const float token_x = game_board_x + token_w/2.0; const float token_y = 80; int i; for (i = 0; i < NUM_TOKENS; i++) { int tx = i % TOKENS_X; int ty = i / TOKENS_X; float px = token_x + tx * token_w; float py = token_y + ty * token_w; tokens[i].type = TYPE_NONE; tokens[i].x = px; tokens[i].y = py; tokens[i].pitch = NUM_PITCH - 1 - ty; assert(tokens[i].pitch >= 0 && tokens[i].pitch < NUM_PITCH); init_sprite(&tokens[i].bot, IMG_BLACK, px, py, token_scale, 0.4); init_sprite(&tokens[i].top, IMG_BLACK, px, py, token_scale, 0.0); } } static void init_buttons(void) { const float dist[NUM_TYPES] = {-1.5, -0.5, 0.5, 1.5}; int i; for (i = 0; i < NUM_TYPES; i++) { float x = screen_w/2 + 150 * dist[i]; float y = screen_h - 80; buttons[i].type = i; buttons[i].x = x; buttons[i].y = y; init_sprite(&buttons[i].bot, IMG_DROPSHADOW, x, y, dropshadow_unsel_scale, 0.4); buttons[i].bot.align_y = 0.0; init_sprite(&buttons[i].top, i, x, y, button_unsel_scale, 1.0); } } static void init_glow(void) { init_sprite(&glow, IMG_GLOW, screen_w/2, screen_h, 1.0, 1.0); glow.align_y = 1.0; glow.r = glow.g = glow.b = 0.0; init_sprite(&glow_overlay, IMG_GLOW_OVERLAY, 0.0, 0.0, 1.0, 1.0); glow_overlay.align_x = 0.0; glow_overlay.align_y = 0.0; glow_overlay.r = glow_overlay.g = glow_overlay.b = 0.0; glow_color[TYPE_EARTH] = al_map_rgb(0x6b, 0x8e, 0x23); /* olivedrab */ glow_color[TYPE_WIND] = al_map_rgb(0xad, 0xd8, 0xe6); /* lightblue */ glow_color[TYPE_WATER] = al_map_rgb(0x41, 0x69, 0xe1); /* royalblue */ glow_color[TYPE_FIRE] = al_map_rgb(0xff, 0x00, 0x00); /* red */ } /****************************************************************************/ /* Flairs */ /****************************************************************************/ static Sprite *make_flair(int image, float x, float y, float end_time) { Flair *fl = malloc(sizeof *fl); init_sprite(&fl->sprite, image, x, y, 1.0, 1.0); fl->end_time = end_time; fl->next = flairs; flairs = fl; return &fl->sprite; } static void free_old_flairs(float now) { Flair *prev, *fl, *next; prev = NULL; for (fl = flairs; fl != NULL; fl = next) { next = fl->next; if (fl->end_time > now) prev = fl; else { if (prev) prev->next = next; else flairs = next; free(fl); } } } static void free_all_flairs(void) { Flair *next; for (; flairs != NULL; flairs = next) { next = flairs->next; free(flairs); } } /****************************************************************************/ /* Animations */ /****************************************************************************/ static Anim *get_next_anim(Sprite *spr) { static Anim dummy_anim; unsigned i; for (i = 0; i < MAX_ANIMS; i++) { if (spr->anims[i].lval == NULL) return &spr->anims[i]; } assert(false); return &dummy_anim; } static void fix_conflicting_anims(Sprite *grp, float *lval, float start_time, float start_val) { unsigned i; for (i = 0; i < MAX_ANIMS; i++) { Anim *anim = &grp->anims[i]; if (anim->lval != lval) continue; /* If an old animation would overlap with the new one, truncate it * and make it converge to the new animation's starting value. */ if (anim->end_time > start_time) { anim->end_time = start_time; anim->end_val = start_val; } /* Cancel any old animations which are scheduled to start after the * new one, or which have been reduced to nothing. */ if (anim->start_time >= start_time || anim->start_time >= anim->end_time) { grp->anims[i].lval = NULL; } } } static void anim_full(Sprite *spr, float *lval, float start_val, float end_val, Interp func, float delay, float duration) { float start_time; Anim *anim; start_time = al_get_time() + delay; fix_conflicting_anims(spr, lval, start_time, start_val); anim = get_next_anim(spr); anim->lval = lval; anim->start_val = start_val; anim->end_val = end_val; anim->func = func; anim->start_time = start_time; anim->end_time = start_time + duration; } static void anim(Sprite *spr, float *lval, float start_val, float end_val, Interp func, float duration) { anim_full(spr, lval, start_val, end_val, func, 0.0, duration); } static void anim_to(Sprite *spr, float *lval, float end_val, Interp func, float duration) { anim_full(spr, lval, *lval, end_val, func, 0.0, duration); } static void anim_delta(Sprite *spr, float *lval, float delta, Interp func, float duration) { anim_full(spr, lval, *lval, *lval + delta, func, 0.0, duration); } static void anim_tint(Sprite *spr, const ALLEGRO_COLOR color, Interp func, float duration) { float r, g, b; al_unmap_rgb_f(color, &r, &g, &b); anim_to(spr, &spr->r, r, func, duration); anim_to(spr, &spr->g, g, func, duration); anim_to(spr, &spr->b, b, func, duration); } static float interpolate(Interp func, float t) { switch (func) { case INTERP_LINEAR: return t; case INTERP_FAST: return -t*(t-2); case INTERP_DOUBLE_FAST: t--; return t*t*t + 1; case INTERP_SLOW: return t*t; case INTERP_DOUBLE_SLOW: return t*t*t; case INTERP_SLOW_IN_OUT: { // Quadratic easing in/out - acceleration until halfway, then deceleration float b = 0; float c = 1; float d = 1; t /= d/2; if (t < 1) { return c/2 * t * t + b; } else { t--; return -c/2 * (t*(t-2) - 1) + b; } } case INTERP_BOUNCE: { // BOUNCE EASING: exponentially decaying parabolic bounce // t: current time, b: beginning value, c: change in position, d: duration // bounce easing out if (t < (1/2.75)) return (7.5625*t*t); if (t < (2/2.75)) { t -= (1.5/2.75); return (7.5625*t*t + 0.75); } if (t < (2.5/2.75)) { t -= (2.25/2.75); return (7.5625*t*t + 0.9375); } t -= (2.625/2.75); return (7.5625*t*t + 0.984375); } default: assert(false); return 0.0; } } static void update_anim(Anim *anim, float now) { float dt, t, range; if (!anim->lval) return; if (now < anim->start_time) return; dt = now - anim->start_time; t = dt / (anim->end_time - anim->start_time); if (t >= 1.0) { /* animation has run to completion */ *anim->lval = anim->end_val; anim->lval = NULL; return; } range = anim->end_val - anim->start_val; *anim->lval = anim->start_val + interpolate(anim->func, t) * range; } static void update_sprite_anims(Sprite *spr, float now) { int i; for (i = 0; i < MAX_ANIMS; i++) update_anim(&spr->anims[i], now); } static void update_token_anims(Token *token, float now) { update_sprite_anims(&token->bot, now); update_sprite_anims(&token->top, now); } static void update_anims(float now) { Flair *fl; int i; for (i = 0; i < NUM_TOKENS; i++) update_token_anims(&tokens[i], now); for (i = 0; i < NUM_TYPES; i++) update_token_anims(&buttons[i], now); update_sprite_anims(&glow, now); update_sprite_anims(&glow_overlay, now); for (fl = flairs; fl != NULL; fl = fl->next) update_sprite_anims(&fl->sprite, now); } /****************************************************************************/ /* Drawing */ /****************************************************************************/ static void draw_sprite(const Sprite *spr) { ALLEGRO_BITMAP *bmp; ALLEGRO_COLOR tint; float cx, cy; bmp = images[spr->image]; cx = spr->align_x * al_get_bitmap_width(bmp); cy = spr->align_y * al_get_bitmap_height(bmp); tint = al_map_rgba_f(spr->r, spr->g, spr->b, spr->opacity); al_draw_tinted_scaled_rotated_bitmap(bmp, tint, cx, cy, spr->x, spr->y, spr->scale_x, spr->scale_y, spr->angle, 0); } static void draw_token(const Token *token) { draw_sprite(&token->bot); draw_sprite(&token->top); } static void draw_screen(void) { Flair *fl; int i; al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); draw_sprite(&glow); draw_sprite(&glow_overlay); for (i = 0; i < NUM_TOKENS; i++) draw_token(&tokens[i]); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); for (i = 0; i < NUM_TYPES; i++) draw_token(&buttons[i]); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); for (fl = flairs; fl != NULL; fl = fl->next) draw_sprite(&fl->sprite); al_flip_display(); } /****************************************************************************/ /* Playback */ /****************************************************************************/ static void spawn_wind_effects(float x, float y) { const float now = al_get_time(); Sprite *spr; spr = make_flair(IMG_AIR_EFFECT, x, y, now + 1.0); anim(spr, &spr->scale_x, 0.9, 1.3, INTERP_FAST, 1.0); anim(spr, &spr->scale_y, 0.9, 1.3, INTERP_FAST, 1.0); anim(spr, &spr->opacity, 1.0, 0.0, INTERP_FAST, 1.0); spr = make_flair(IMG_AIR_EFFECT, x, y, now + 1.2); anim(spr, &spr->opacity, 1.0, 0.0, INTERP_LINEAR, 1.2); anim(spr, &spr->scale_x, 1.1, 1.5, INTERP_FAST, 1.2); anim(spr, &spr->scale_y, 1.1, 0.5, INTERP_FAST, 1.2); anim_delta(spr, &spr->x, 10.0, INTERP_FAST, 1.2); } static void spawn_fire_effects(float x, float y) { const float now = al_get_time(); Sprite *spr; int i; spr = make_flair(IMG_MAIN_FLAME, x, y, now + 0.8); spr->align_y = 0.75; anim_full(spr, &spr->scale_x, 0.2, 1.3, INTERP_BOUNCE, 0.0, 0.4); anim_full(spr, &spr->scale_y, 0.2, 1.3, INTERP_BOUNCE, 0.0, 0.4); anim_full(spr, &spr->scale_x, 1.3, 1.4, INTERP_BOUNCE, 0.4, 0.5); anim_full(spr, &spr->scale_y, 1.3, 1.4, INTERP_BOUNCE, 0.4, 0.5); anim_full(spr, &spr->opacity, 1.0, 0.0, INTERP_FAST, 0.3, 0.5); for (i = 0; i < 3; i++) { spr = make_flair(IMG_FLAME, x, y, now + 0.7); spr->align_x = 1.3; spr->angle = TWOPI / 3 * i; anim_delta(spr, &spr->angle, -PI, INTERP_DOUBLE_FAST, 0.7); anim(spr, &spr->opacity, 1.0, 0.0, INTERP_SLOW, 0.7); anim(spr, &spr->scale_x, 0.2, 1.0, INTERP_FAST, 0.7); anim(spr, &spr->scale_y, 0.2, 1.0, INTERP_FAST, 0.7); } } static float random_sign(void) { return (rand() % 2) ? -1.0 : 1.0; } static float random_float(float min, float max) { return ((float) rand()/RAND_MAX)*(max-min) + min; } static void spawn_water_effects(float x, float y) { #define RAND(a, b) (random_float((a), (b))) #define MRAND(a, b) (random_float((a), (b)) * max_duration) #define SIGN (random_sign()) float now = al_get_time(); float max_duration = 1.0; Sprite *spr; int i; spr = make_flair(IMG_WATER, x, y, now + max_duration); anim(spr, &spr->scale_x, 1.0, 2.0, INTERP_FAST, 0.5); anim(spr, &spr->scale_y, 1.0, 2.0, INTERP_FAST, 0.5); anim(spr, &spr->opacity, 0.5, 0.0, INTERP_FAST, 0.5); for (i = 0; i < 9; i++) { spr = make_flair(IMG_WATER_DROPS, x, y, now + max_duration); spr->scale_x = RAND(0.3, 1.2) * SIGN; spr->scale_y = RAND(0.3, 1.2) * SIGN; spr->angle = RAND(0.0, TWOPI); spr->r = RAND(0.0, 0.6); spr->g = RAND(0.4, 0.6); spr->b = 1.0; if (i == 0) { anim_to(spr, &spr->opacity, 0.0, INTERP_LINEAR, max_duration); } else { anim_to(spr, &spr->opacity, 0.0, INTERP_DOUBLE_SLOW, MRAND(0.7, 1.0)); } anim_to(spr, &spr->scale_x, RAND(0.8, 3.0), INTERP_FAST, MRAND(0.7, 1.0)); anim_to(spr, &spr->scale_y, RAND(0.8, 3.0), INTERP_FAST, MRAND(0.7, 1.0)); anim_delta(spr, &spr->x, MRAND(0, 20.0)*SIGN, INTERP_FAST, MRAND(0.7, 1.0)); anim_delta(spr, &spr->y, MRAND(0, 20.0)*SIGN, INTERP_FAST, MRAND(0.7, 1.0)); } #undef RAND #undef MRAND #undef SIGN } static void play_element(int type, int pitch, float vol, float pan) { al_play_sample(element_samples[type][pitch], vol, pan, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); } static void activate_token(Token *token) { const float sc = token_scale; Sprite *spr = &token->top; switch (token->type) { case TYPE_EARTH: play_element(TYPE_EARTH, token->pitch, 0.8, 0.0); anim(spr, &spr->scale_x, spr->scale_x+0.4, spr->scale_x, INTERP_FAST, 0.3); anim(spr, &spr->scale_y, spr->scale_y+0.4, spr->scale_y, INTERP_FAST, 0.3); break; case TYPE_WIND: play_element(TYPE_WIND, token->pitch, 0.8, 0.0); anim_full(spr, &spr->scale_x, sc*1.0, sc*0.8, INTERP_SLOW_IN_OUT, 0.0, 0.5); anim_full(spr, &spr->scale_x, sc*0.8, sc*1.0, INTERP_SLOW_IN_OUT, 0.5, 0.8); anim_full(spr, &spr->scale_y, sc*1.0, sc*0.8, INTERP_SLOW_IN_OUT, 0.0, 0.5); anim_full(spr, &spr->scale_y, sc*0.8, sc*1.0, INTERP_SLOW_IN_OUT, 0.5, 0.8); spawn_wind_effects(spr->x, spr->y); break; case TYPE_WATER: play_element(TYPE_WATER, token->pitch, 0.7, 0.5); anim_full(spr, &spr->scale_x, sc*1.3, sc*0.8, INTERP_BOUNCE, 0.0, 0.5); anim_full(spr, &spr->scale_x, sc*0.8, sc*1.0, INTERP_BOUNCE, 0.5, 0.5); anim_full(spr, &spr->scale_y, sc*0.8, sc*1.3, INTERP_BOUNCE, 0.0, 0.5); anim_full(spr, &spr->scale_y, sc*1.3, sc*1.0, INTERP_BOUNCE, 0.5, 0.5); spawn_water_effects(spr->x, spr->y); break; case TYPE_FIRE: play_element(TYPE_FIRE, token->pitch, 0.8, 0.0); anim(spr, &spr->scale_x, sc*1.3, sc, INTERP_SLOW_IN_OUT, 1.0); anim(spr, &spr->scale_y, sc*1.3, sc, INTERP_SLOW_IN_OUT, 1.0); spawn_fire_effects(spr->x, spr->y); break; } } static void update_playback(void) { int y; for (y = 0; y < TOKENS_Y; y++) activate_token(&tokens[y * TOKENS_X + playback_column]); if (++playback_column >= TOKENS_X) playback_column = 0; } /****************************************************************************/ /* Control */ /****************************************************************************/ static bool is_touched(Token *token, float size, float x, float y) { float half = size/2.0; return (token->x - half <= x && x < token->x + half && token->y - half <= y && y < token->y + half); } static Token *get_touched_token(float x, float y) { int i; for (i = 0; i < NUM_TOKENS; i++) { if (is_touched(&tokens[i], token_size, x, y)) return &tokens[i]; } return NULL; } static Token *get_touched_button(float x, float y) { int i; for (i = 0; i < NUM_TYPES; i++) { if (is_touched(&buttons[i], button_size, x, y)) return &buttons[i]; } return NULL; } static void select_token(Token *token) { if (token->type == TYPE_NONE && selected_button) { Sprite *spr = &token->top; spr->image = selected_button->type; anim_to(spr, &spr->opacity, 1.0, INTERP_FAST, 0.15); token->type = selected_button->type; } } static void unselect_token(Token *token) { if (token->type != TYPE_NONE) { Sprite *spr = &token->top; anim_full(spr, &spr->opacity, spr->opacity, 0.0, INTERP_SLOW, 0.15, 0.15); token->type = TYPE_NONE; } } static void unselect_all_tokens(void) { int i; for (i = 0; i < NUM_TOKENS; i++) unselect_token(&tokens[i]); } static void change_healthy_glow(int type, float x) { anim_tint(&glow, glow_color[type], INTERP_SLOW_IN_OUT, 3.0); anim_to(&glow, &glow.x, x, INTERP_SLOW_IN_OUT, 3.0); anim_tint(&glow_overlay, glow_color[type], INTERP_SLOW_IN_OUT, 4.0); anim_to(&glow_overlay, &glow_overlay.opacity, 1.0, INTERP_SLOW_IN_OUT, 4.0); } static void select_button(Token *button) { Sprite *spr; if (button == selected_button) return; if (selected_button) { spr = &selected_button->top; anim_to(spr, &spr->scale_x, button_unsel_scale, INTERP_SLOW, 0.3); anim_to(spr, &spr->scale_y, button_unsel_scale, INTERP_SLOW, 0.3); anim_to(spr, &spr->opacity, 0.5, INTERP_DOUBLE_SLOW, 0.2); spr = &selected_button->bot; anim_to(spr, &spr->scale_x, dropshadow_unsel_scale, INTERP_SLOW, 0.3); anim_to(spr, &spr->scale_y, dropshadow_unsel_scale, INTERP_SLOW, 0.3); } selected_button = button; spr = &button->top; anim_to(spr, &spr->scale_x, button_sel_scale, INTERP_FAST, 0.3); anim_to(spr, &spr->scale_y, button_sel_scale, INTERP_FAST, 0.3); anim_to(spr, &spr->opacity, 1.0, INTERP_FAST, 0.3); spr = &button->bot; anim_to(spr, &spr->scale_x, dropshadow_sel_scale, INTERP_FAST, 0.3); anim_to(spr, &spr->scale_y, dropshadow_sel_scale, INTERP_FAST, 0.3); change_healthy_glow(button->type, button->x); al_play_sample(select_sample, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); } static void on_mouse_down(float x, float y, int mbut) { Token *token; Token *button; if (mbut == 1) { if ((token = get_touched_token(x, y))) select_token(token); else if ((button = get_touched_button(x, y))) select_button(button); } else if (mbut == 2) { if ((token = get_touched_token(x, y))) unselect_token(token); } } static void on_mouse_axes(float x, float y) { Token *token = get_touched_token(x, y); if (token == hover_token) return; if (hover_token) { Sprite *spr = &hover_token->bot; anim_to(spr, &spr->opacity, 0.4, INTERP_DOUBLE_SLOW, 0.2); } hover_token = token; if (hover_token) { Sprite *spr = &hover_token->bot; anim_to(spr, &spr->opacity, 0.7, INTERP_FAST, 0.2); } } static void main_loop(ALLEGRO_EVENT_QUEUE *queue) { ALLEGRO_EVENT event; bool redraw = true; for (;;) { if (redraw && al_is_event_queue_empty(queue)) { float now = al_get_time(); free_old_flairs(now); update_anims(now); draw_screen(); redraw = false; } al_wait_for_event(queue, &event); if (event.timer.source == refresh_timer) { redraw = true; continue; } if (event.timer.source == playback_timer) { update_playback(); continue; } if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { on_mouse_axes(event.mouse.x, event.mouse.y); continue; } if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { on_mouse_down(event.mouse.x, event.mouse.y, event.mouse.button); continue; } if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; if (event.keyboard.keycode == ALLEGRO_KEY_C) unselect_all_tokens(); } } } int main(void) { ALLEGRO_EVENT_QUEUE *queue; if (!al_init()) { abort_example("Error initialising Allegro.\n"); } if (!al_install_audio() || !al_reserve_samples(128)) { abort_example("Error initialising audio.\n"); } al_init_acodec_addon(); al_init_image_addon(); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); display = al_create_display(screen_w, screen_h); if (!display) { abort_example("Error creating display.\n"); } al_set_window_title(display, "Haiku - A Musical Instrument"); load_images(); load_samples(); init_tokens(); init_buttons(); init_glow(); select_button(&buttons[TYPE_EARTH]); al_install_keyboard(); al_install_mouse(); refresh_timer = al_create_timer(1.0 / refresh_rate); playback_timer = al_create_timer(playback_period / TOKENS_X); queue = al_create_event_queue(); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_timer_event_source(refresh_timer)); al_register_event_source(queue, al_get_timer_event_source(playback_timer)); al_start_timer(refresh_timer); al_start_timer(playback_timer); main_loop(queue); free_all_flairs(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_glext.c0000644000175000001440000002263412152725670016225 0ustar tjadenusers/* This examples demonstrates how to use the extension mechanism. * Taken from AllegroGL. */ #include #include #include #include #include #include "common.c" #ifdef ALLEGRO_MACOSX #include #else #include #endif #define WINDOW_W 640 #define WINDOW_H 480 #define MESH_SIZE 64 GLfloat mesh[MESH_SIZE][MESH_SIZE][3]; GLfloat wave_movement = 0.0f; /* Define our vertex program. * It basically does: * pos = vertex.position; * pos.y = (sin(wave.x + pos.x / 5) + sin(wave.x + pos.z / 4)) * 2.5; * result.position = modelview * projection * pos; */ /* Plain ARBvp doesn't have a SIN opcode, so we provide one, built on a taylor * expansion, with some fugding. * * First, we convert the operand to the [-pi..+pi] period by: * - Dividing by 2pi, adding 1/2 * - Taking the fraction of the result * - Multiplying by 2pi, then subtracting pi. * x' = frac((x / 2pi) + 0.5) * 2pi - pi * * Then, we compute the sine using a 7th order Taylor series centered at 0: * x' = x - x^3/3! + x^5/5! - x^7/7! * * Note that we begin by multiplying x by 0.98 as a fugding factor to * compensate for the fact that our Taylor series is just an approximation. * The error is then reduced to < 0.5% from the ideal sine function. */ #define SIN(d, s, t) \ /* Convert to [-pi..+pi] period */ \ "MAD "d", "s", one_over_pi, 0.5;\n" \ "FRC "d","d";\n" \ "MAD "d","d", two_pi, -pi;\n" \ "MUL "d","d", 0.98;\n" /* Scale input to compensate for prec error */\ /* Compute SIN(d), using a Taylor series */ \ "MUL "t".x, "d", "d";\n" /* x^2 */ \ "MUL "t".y, "t".x, "d";\n" /* x^3 */ \ "MUL "t".z, "t".y, "t".x;\n" /* x^5 */ \ "MUL "t".w, "t".z, "t".x;\n" /* x^7 */ \ "MAD "d", "t".y,-inv_3_fact, "d";\n" /* x - x^3/3! */ \ "MAD "d", "t".z, inv_5_fact, "d";\n" /* x - x^3/3! + x^5/5! */ \ "MAD "d", "t".w,-inv_7_fact, "d";\n" /* x - x^3/3! + x^5/5! - x^7/7!*/ /* This is the actual vertex program. * It computes sin(wave.x + pos.x / 5) and sin(wave.x + pos.z), adds them up, * scales the result by 2.5 and stores that as the vertex's y component. * * Then, it does the modelview-projection transform on the vertex. * * XXX Broken ATI drivers need a \n after each "line" */ const char *program = "!!ARBvp1.0\n" "ATTRIB pos = vertex.position;\n" "ATTRIB wave = vertex.attrib[1];\n" "PARAM modelview[4] = { state.matrix.mvp };\n" "PARAM one_over_pi = 0.1591549;\n" "PARAM pi = 3.1415926;\n" "PARAM two_pi = 6.2831853;\n" "PARAM inv_3_fact = 0.1666666;\n" "PARAM inv_5_fact = 0.00833333333;\n" "PARAM inv_7_fact = 0.00019841269841269;\n" "TEMP temp, temp2;\n" /* temp.y = sin(wave.x + pos.x / 5) */ "MAD temp.y, pos.x, 0.2, wave.x;\n" SIN("temp.y", "temp.y", "temp2") /* temp.y += sin(wave.x + pos.z / 4) */ "MAD temp.x, pos.z, 0.25, wave.x;\n" SIN("temp.x", "temp.x", "temp2") "ADD temp.y, temp.x, temp.y;\n" /* pos.y = temp.y * 2.5 */ "MOV temp2, pos;\n" "MUL temp2.y, temp.y, 2.5;\n" /* Transform the position by the modelview matrix */ "DP4 result.position.w, temp2, modelview[3];\n" "DP4 result.position.x, temp2, modelview[0];\n" "DP4 result.position.y, temp2, modelview[1];\n" "DP4 result.position.z, temp2, modelview[2];\n" "MOV result.color, vertex.color;\n" "END"; /* NVIDIA drivers do a better job; let's use a simpler program if we can. */ const char *program_nv = "!!ARBvp1.0" "OPTION NV_vertex_program2;" "ATTRIB wave = vertex.attrib[1];" "PARAM modelview[4] = { state.matrix.mvp };" "TEMP temp;" "TEMP pos;" "MOV pos, vertex.position;" /* temp.x = sin(wave.x + pos.x / 5) */ /* temp.z = sin(wave.x + pos.z / 4) */ "MAD temp.xz, pos, {0.2, 1.0, 0.25, 1.0}, wave.x;" "SIN temp.x, temp.x;" "SIN temp.z, temp.z;" /* temp.y = temp.x + temp.z */ "ADD temp.y, temp.x, temp.z;" /* pos.y = temp.y * 2.5 */ "MUL pos.y, temp.y, 2.5;" /* Transform the position by the modelview matrix */ "DP4 result.position.w, pos, modelview[3];" "DP4 result.position.x, pos, modelview[0];" "DP4 result.position.y, pos, modelview[1];" "DP4 result.position.z, pos, modelview[2];" "MOV result.color, vertex.color;" "END"; static void create_mesh(void) { int x, z; /* Create our mesh */ for (x = 0; x < MESH_SIZE; x++) { for (z = 0; z < MESH_SIZE; z++) { mesh[x][z][0] = (float) (MESH_SIZE / 2) - x; mesh[x][z][1] = 0.0f; mesh[x][z][2] = (float) (MESH_SIZE / 2) - z; } } } static void draw_mesh(void) { int x, z; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor4f(0.5f, 1.0f, 0.5f, 1.0f); for (x = 0; x < MESH_SIZE - 1; x++) { glBegin(GL_TRIANGLE_STRIP); for (z = 0; z < MESH_SIZE - 1; z++) { glVertexAttrib1fARB(1, wave_movement); glVertex3fv(&mesh[x][z][0]); glVertex3fv(&mesh[x+1][z][0]); wave_movement += 0.00001f; if (wave_movement > 2 * ALLEGRO_PI) { wave_movement = 0.0f; } } glEnd(); } glFlush(); } int main(int argc, const char *argv[]) { GLuint pid; ALLEGRO_DISPLAY *d; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; ALLEGRO_TIMER *timer; int frames = 0; double start; bool limited = true; if (argc > 1 && 0 == strcmp(argv[1], "-nolimit")) { limited = false; } if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_set_new_display_flags(ALLEGRO_OPENGL); al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); d = al_create_display(WINDOW_W, WINDOW_H); if (!d) { abort_example("Unable to open a OpenGL display.\n"); } if (al_get_display_option(d, ALLEGRO_SAMPLE_BUFFERS)) { log_printf("With multisampling, level %i\n", al_get_display_option(d, ALLEGRO_SAMPLES)); } else { log_printf("Without multisampling.\n"); } al_install_keyboard(); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(d)); if (limited) { timer = al_create_timer(1/60.0); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); } else { timer = NULL; } if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multisample) { glEnable(GL_MULTISAMPLE_ARB); } if (!al_get_opengl_extension_list()->ALLEGRO_GL_ARB_vertex_program) { abort_example("This example requires a video card that supports " " the ARB_vertex_program extension.\n"); } glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_CULL_FACE); /* Setup projection and modelview matrices */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, WINDOW_W/(float)WINDOW_H, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* Position the camera to look at our mesh from a distance */ gluLookAt(0.0f, 20.0f, -45.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0); create_mesh(); /* Define the vertex program */ glEnable(GL_VERTEX_PROGRAM_ARB); glGenProgramsARB(1, &pid); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, pid); glGetError(); if (al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option) { glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(program_nv), program_nv); } else { glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(program), program); } /* Check for errors */ if (glGetError()) { const char *pgm = al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option ? program_nv : program; GLint error_pos; const GLubyte *error_str = glGetString(GL_PROGRAM_ERROR_STRING_ARB); glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos); abort_example("Error compiling the vertex program:\n%s\n\nat " "character: %i\n%s\n", error_str, (int)error_pos, pgm + error_pos); } start = al_get_time(); while (1) { if (limited) { al_wait_for_event(queue, NULL); } if (!al_is_event_queue_empty(queue)) { while (al_get_next_event(queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: goto done; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) goto done; break; } } } draw_mesh(); al_flip_display(); frames++; } done: log_printf("%.1f FPS\n", frames / (al_get_time() - start)); glDeleteProgramsARB(1, &pid); al_destroy_event_queue(queue); al_destroy_display(d); close_log(true); return 0; } allegro-5.0.10/examples/ex_opengl.c0000644000175000001440000001145012152725670016360 0ustar tjadenusers#include #include #include #include #include "common.c" /* Simple example showing how to use an extension. It draws a yellow triangle * on red background onto a texture, then draws a quad with that texture. */ GLuint tex, fbo; bool no_fbo = false; static void draw_opengl(void) { double secs = al_get_time(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* Let's create a texture. It will only be visible if we cannot draw over * it with the framebuffer extension. */ if (!tex) { unsigned char *pixels = malloc(256 * 256 * 4); int x, y; for (y = 0; y < 256; y++) { for (x = 0; x < 256; x++) { unsigned char r = x, g = y, b = 0, a = 255; pixels[y * 256 * 4 + x * 4 + 0] = r; pixels[y * 256 * 4 + x * 4 + 1] = g; pixels[y * 256 * 4 + x * 4 + 2] = b; pixels[y * 256 * 4 + x * 4 + 3] = a; } } glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); free(pixels); } /* Let's create a framebuffer object. */ if (!fbo && !no_fbo) { /* Did Allegro discover the OpenGL extension for us? */ if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) { /* If yes, then it also filled in the function pointer. How nice. */ glGenFramebuffersEXT(1, &fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); /* Attach the framebuffer object to our texture. */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { no_fbo = true; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } else { /* We are screwed, the extension is not available. */ no_fbo = true; } } /* Draw a yellow triangle on red background to the framebuffer object. */ if (fbo && !no_fbo) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT); glViewport(0, 0, 256, 256); glClearColor(1, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 256, 256, 0, -1, 1); glDisable(GL_TEXTURE_2D); glColor3f(1, 1, 0); glTranslatef(128, 128 + sin(secs * ALLEGRO_PI * 2 * 2) * 20, 0); glBegin(GL_TRIANGLES); glVertex2f(0, -100); glVertex2f(100, 0); glVertex2f(-100, 0); glEnd(); glPopMatrix(); glPopAttrib(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } /* Draw a quad with our texture. */ glClearColor(0, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(320, 240, 0); glRotatef(secs * 360 / 4, 0, 0, 1); glColor3f(1, 1, 1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-100, -100); glTexCoord2f(1, 0); glVertex2f(+100, -100); glTexCoord2f(1, 1); glVertex2f(+100, +100); glTexCoord2f(0, 1); glVertex2f(-100, +100); glEnd(); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; int frames = 0; double start; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_install_keyboard(); al_set_new_display_flags(ALLEGRO_OPENGL); display = al_create_display(640, 480); if (!display) { abort_example("Could not create display.\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); start = al_get_time(); while (true) { /* Check for ESC key or close button event and quit in either case. */ if (!al_is_event_queue_empty(queue)) { while (al_get_next_event(queue, &event)) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: goto done; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) goto done; break; } } } draw_opengl(); al_flip_display(); frames++; } done: log_printf("%.1f FPS\n", frames / (al_get_time() - start)); al_destroy_event_queue(queue); al_destroy_display(display); close_log(true); return 0; } allegro-5.0.10/examples/ex_saw.c0000644000175000001440000000516012152725670015667 0ustar tjadenusers/* Recreate exstream.c from A4. */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "common.c" #define SAMPLES_PER_BUFFER 1024 static void saw(ALLEGRO_AUDIO_STREAM *stream) { ALLEGRO_EVENT_QUEUE *queue; int8_t *buf; int pitch = 0x10000; int val = 0; int i; int n = 200; queue = al_create_event_queue(); al_register_event_source(queue, al_get_audio_stream_event_source(stream)); #ifdef ALLEGRO_POPUP_EXAMPLES if (textlog) { al_register_event_source(queue, al_get_native_text_log_event_source(textlog)); } #endif log_printf("Generating saw wave...\n"); while (n > 0) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { buf = al_get_audio_stream_fragment(stream); if (!buf) { /* This is a normal condition you must deal with. */ continue; } for (i = 0; i < SAMPLES_PER_BUFFER; i++) { /* Crude saw wave at maximum amplitude. Please keep this compatible * to the A4 example so we know when something has broken for now. * * It would be nice to have a better example with user interface * and some simple synth effects. */ buf[i] = ((val >> 16) & 0xff); val += pitch; pitch++; } if (!al_set_audio_stream_fragment(stream, buf)) { log_printf("Error setting stream fragment.\n"); } n--; if ((n % 10) == 0) { log_printf("."); fflush(stdout); } } #ifdef ALLEGRO_POPUP_EXAMPLES if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { break; } #endif } al_drain_audio_stream(stream); log_printf("\n"); al_destroy_event_queue(queue); } int main(void) { ALLEGRO_AUDIO_STREAM *stream; if (!al_init()) { abort_example("Could not init Allegro.\n"); } if (!al_install_audio()) { abort_example("Could not init sound.\n"); } al_reserve_samples(0); stream = al_create_audio_stream(8, SAMPLES_PER_BUFFER, 22050, ALLEGRO_AUDIO_DEPTH_UINT8, ALLEGRO_CHANNEL_CONF_1); if (!stream) { abort_example("Could not create stream.\n"); } if (!al_attach_audio_stream_to_mixer(stream, al_get_default_mixer())) { abort_example("Could not attach stream to mixer.\n"); } open_log(); saw(stream); close_log(false); al_destroy_audio_stream(stream); al_uninstall_audio(); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_windows.c0000644000175000001440000000543712152725670016576 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include #include #include "common.c" const int W = 100; const int H = 100; int main(void) { ALLEGRO_DISPLAY *displays[2]; ALLEGRO_MONITOR_INFO *info; int adapter_count; int x, y; ALLEGRO_FONT *myfont; ALLEGRO_EVENT_QUEUE *events; ALLEGRO_EVENT event; int i; srand(time(NULL)); if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_mouse(); al_init_font_addon(); al_init_image_addon(); adapter_count = al_get_num_video_adapters(); info = malloc(adapter_count * sizeof(ALLEGRO_MONITOR_INFO)); for (i = 0; i < adapter_count; i++) { al_get_monitor_info(i, &info[i]); } x = ((info[0].x2 - info[0].x1) / 3) - (W / 2); y = ((info[0].y2 - info[0].y1) / 2) - (H / 2); al_set_new_window_position(x, y); displays[0] = al_create_display(W, H); x *= 2; al_set_new_window_position(x, y); displays[1] = al_create_display(W, H); if (!displays[0] || !displays[1]) { abort_example("Could not create displays.\n"); } al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); myfont = al_load_font("data/fixed_font.tga", 0, 0); if (!myfont) { abort_example("Could not load font.\n"); } events = al_create_event_queue(); al_register_event_source(events, al_get_mouse_event_source()); al_register_event_source(events, al_get_display_event_source(displays[0])); al_register_event_source(events, al_get_display_event_source(displays[1])); for (;;) { for (i = 0; i < 2; i++) { al_set_target_backbuffer(displays[i]); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (i == 0) al_clear_to_color(al_map_rgb(255, 0, 255)); else al_clear_to_color(al_map_rgb(155, 255, 0)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(myfont, al_map_rgb(0, 0, 0), 50, 50, ALLEGRO_ALIGN_CENTRE, "Click me.."); al_flip_display(); } if (al_wait_for_event_timed(events, &event, 1)) { if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { break; } else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { int a = rand() % adapter_count; int w = info[a].x2 - info[a].x1; int h = info[a].y2 - info[a].y1; int margin = 20; x = margin + info[a].x1 + (rand() % (w - W - margin)); y = margin + info[a].y1 + (rand() % (h - H - margin)); al_set_window_position(event.mouse.display, x, y); } } } al_destroy_event_queue(events); al_destroy_display(displays[0]); al_destroy_display(displays[1]); free(info); return 0; } allegro-5.0.10/examples/ex_acodec_multi.c0000644000175000001440000000626012152725670017527 0ustar tjadenusers/* * Milan Mimica * Audio example that plays multiple files at the same time * Originlly derived from the ex_acodec example. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" int main(int argc, char **argv) { int i; ALLEGRO_SAMPLE **sample_data; ALLEGRO_SAMPLE_INSTANCE **sample; ALLEGRO_MIXER *mixer; ALLEGRO_VOICE *voice; float longest_sample; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 2) { log_printf("This example needs to be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); goto done; } al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } sample = malloc(argc * sizeof(*sample)); if (!sample) { abort_example("Out of memory!\n"); } sample_data = malloc(argc * sizeof(*sample_data)); if (!sample_data) { abort_example("Out of memory!\n"); } /* a voice is used for playback */ voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (!voice) { abort_example("Could not create ALLEGRO_VOICE from sample\n"); } mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); if (!mixer) { abort_example("al_create_mixer failed.\n"); } if (!al_attach_mixer_to_voice(mixer, voice)) { abort_example("al_attach_mixer_to_voice failed.\n"); } for (i = 1; i < argc; ++i) { const char *filename = argv[i]; sample[i] = NULL; /* loads the entire sound file from disk into sample data */ sample_data[i] = al_load_sample(filename); if (!sample_data[i]) { abort_example("Could not load sample from '%s'!\n", filename); } sample[i] = al_create_sample_instance(sample_data[i]); if (!sample[i]) { log_printf("Could not create sample!\n"); al_destroy_sample(sample_data[i]); sample_data[i] = NULL; continue; } if (!al_attach_sample_instance_to_mixer(sample[i], mixer)) { log_printf("al_attach_sample_instance_to_mixer failed.\n"); continue; } } longest_sample = 0; for (i = 1; i < argc; ++i) { const char *filename = argv[i]; float sample_time; if (!sample[i]) continue; /* play each sample once */ al_play_sample_instance(sample[i]); sample_time = al_get_sample_instance_time(sample[i]); log_printf("Playing '%s' (%.3f seconds)\n", filename, sample_time); if (sample_time > longest_sample) longest_sample = sample_time; } al_rest(longest_sample); log_printf("Done\n"); for (i = 1; i < argc; ++i) { /* free the memory allocated when creating the sample + voice */ if (sample[i]) { al_stop_sample_instance(sample[i]); al_destroy_sample_instance(sample[i]); al_destroy_sample(sample_data[i]); } } al_destroy_mixer(mixer); al_destroy_voice(voice); free(sample); free(sample_data); al_uninstall_audio(); done: close_log(true); return 0; } allegro-5.0.10/examples/ex_iphone.c0000644000175000001440000000502312152725670016355 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_primitives.h" #include "common.c" const int MAX_TOUCHES = 5; int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *cursor; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; ALLEGRO_FONT *font; ALLEGRO_TIMER *timer; ALLEGRO_EVENT touch_events[MAX_TOUCHES]; int touch = 0; bool in = true; bool down = false; int i; memset(touch_events, 0, sizeof(touch_events)); if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(480, 320); if (!display) { abort_example("Error creating display\n"); } al_hide_mouse_cursor(); cursor = al_load_bitmap("data/cursor.tga"); if (!cursor) { abort_example("Error loading cursor.tga\n"); } font = al_load_font("data/fixed_font.tga", 1, 0); if (!font) { abort_example("data/fixed_font.tga not found\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); timer = al_create_timer(1/10.0); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (1) { al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_MOUSE_AXES: touch_events[touch] = event; touch++; touch %= MAX_TOUCHES; break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: down = true; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: down = false; break; case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: in = true; break; case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: in = false; break; case ALLEGRO_EVENT_TIMER: al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); if (down) { for (i = 0; i < MAX_TOUCHES; i++) { al_draw_bitmap(cursor, touch_events[i].mouse.x, touch_events[i].mouse.y, 0); } } al_flip_display(); break; case ALLEGRO_EVENT_DISPLAY_CLOSE: goto done; } } done: al_destroy_event_queue(queue); return 0; } /* vim: set sw=3 sts=3 et: */ allegro-5.0.10/examples/ex_premulalpha.c0000644000175000001440000001066012152730747017411 0ustar tjadenusers#include #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_font.h" #include "common.c" int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *tex1, *tex2; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; bool redraw = true; ALLEGRO_LOCKED_REGION *lock; ALLEGRO_FONT *font; unsigned char *p; int x, y; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_install_mouse(); al_install_keyboard(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } font = al_load_font("data/fixed_font.tga", 0, 0); tex1 = al_create_bitmap(8, 8); lock = al_lock_bitmap(tex1, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); p = lock->data; for (y = 0; y < 8; y++) { unsigned char *lp = p; for (x = 0; x < 8; x++) { if (x == 0 || y == 0 || x == 7 || y == 7) { p[0] = 0; p[1] = 0; p[2] = 0; p[3] = 0; } else { p[0] = 0; p[1] = 255; p[2] = 0; p[3] = 255; } p += 4; } p = lp + lock->pitch; } al_unlock_bitmap(tex1); al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR); tex2 = al_clone_bitmap(tex1); timer = al_create_timer(1.0 / 30); queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) break; if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; } if (event.type == ALLEGRO_EVENT_TIMER) redraw = true; if (redraw && al_is_event_queue_empty(queue)) { float x = 8, y = 60; float a, t = al_get_time(); float th = al_get_font_line_height(font); ALLEGRO_COLOR color = al_map_rgb_f(0, 0, 0); ALLEGRO_COLOR color2 = al_map_rgb_f(1, 0, 0); ALLEGRO_COLOR color3 = al_map_rgb_f(0, 0.5, 0); t /= 10; a = t - floor(t); a *= 2 * ALLEGRO_PI; redraw = false; al_clear_to_color(al_map_rgb_f(0.5, 0.6, 1)); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, color, x, y, 0, "not premultiplied"); al_draw_textf(font, color, x, y + th, 0, "no filtering"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_scaled_rotated_bitmap(tex1, 4, 4, x + 320, y, 8, 8, a, 0); y += 120; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, color, x, y, 0, "not premultiplied"); al_draw_textf(font, color, x, y + th, 0, "mag linear filtering"); al_draw_textf(font, color2, x + 400, y, 0, "wrong dark border"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); al_draw_scaled_rotated_bitmap(tex2, 4, 4, x + 320, y, 8, 8, a, 0); y += 120; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, color, x, y, 0, "premultiplied alpha"); al_draw_textf(font, color, x, y + th, 0, "no filtering"); al_draw_textf(font, color, x + 400, y, 0, "no difference"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_scaled_rotated_bitmap(tex1, 4, 4, x + 320, y, 8, 8, a, 0); y += 120; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(font, color, x, y, 0, "premultiplied alpha"); al_draw_textf(font, color, x, y + th, 0, "mag linear filtering"); al_draw_textf(font, color3, x + 400, y, 0, "correct color"); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_scaled_rotated_bitmap(tex2, 4, 4, x + 320, y, 8, 8, a, 0); al_flip_display(); } } al_destroy_font(font); al_destroy_bitmap(tex1); al_destroy_bitmap(tex2); return 0; } allegro-5.0.10/examples/ex_blend_bench.c0000644000175000001440000000753112152725670017324 0ustar tjadenusers/* * Benchmark for memory blenders. */ #include #include #include #include #include #include "common.c" /* Do a few un-timed runs to switch CPU to performance mode and cache * data and so on - seems to make the results more stable here. * Also used to guess the number of timed iterations. */ #define WARMUP 100 /* How many seconds the timing should approximately take - a fixed * number of iterations is not enough on very fast systems but takes * too long on slow systems. */ #define TEST_TIME 5.0 enum Mode { ALL, PLAIN_BLIT, SCALED_BLIT, ROTATE_BLIT }; static char const *names[] = { "", "Plain blit", "Scaled blit", "Rotated blit" }; ALLEGRO_DISPLAY *display; static void step(enum Mode mode, ALLEGRO_BITMAP *b2) { switch (mode) { case ALL: break; case PLAIN_BLIT: al_draw_bitmap(b2, 0, 0, 0); break; case SCALED_BLIT: al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); break; case ROTATE_BLIT: al_draw_scaled_rotated_bitmap(b2, 10, 10, 10, 10, 2.0, 2.0, ALLEGRO_PI/30, 0); break; } } /* al_get_current_time() measures wallclock time - but for the benchmark * result we prefer CPU time so clock() is better. */ static double current_clock(void) { clock_t c = clock(); return (double)c / CLOCKS_PER_SEC; } static bool do_test(enum Mode mode) { ALLEGRO_STATE state; ALLEGRO_BITMAP *b1; ALLEGRO_BITMAP *b2; int REPEAT; double t0, t1; int i; al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); b1 = al_load_bitmap("data/mysha.pcx"); if (!b1) { abort_example("Error loading data/mysha.pcx\n"); return false; } b2 = al_load_bitmap("data/allegro.pcx"); if (!b2) { abort_example("Error loading data/mysha.pcx\n"); return false; } al_set_target_bitmap(b1); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); step(mode, b2); /* Display the blended bitmap to the screen so we can see something. */ al_store_state(&state, ALLEGRO_STATE_ALL); al_set_target_backbuffer(display); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(b1, 0, 0, 0); al_flip_display(); al_restore_state(&state); log_printf("Benchmark: %s\n", names[mode]); log_printf("Please wait...\n"); /* Do warmup run and estimate required runs for real test. */ t0 = current_clock(); for (i = 0; i < WARMUP; i++) { step(mode, b2); } t1 = current_clock(); REPEAT = TEST_TIME * 100 / (t1 - t0); /* Do the real test. */ t0 = current_clock(); for (i = 0; i < REPEAT; i++) { step(mode, b2); } t1 = current_clock(); log_printf("Time = %g s, %d steps\n", t1 - t0, REPEAT); log_printf("%s: %g FPS\n", names[mode], REPEAT / (t1 - t0)); log_printf("Done\n"); al_destroy_bitmap(b1); al_destroy_bitmap(b2); return true; } int main(int argc, const char *argv[]) { enum Mode mode = ALL; int i; if (argc > 1) { i = strtol(argv[1], NULL, 10); switch (i) { case 0: mode = PLAIN_BLIT; break; case 1: mode = SCALED_BLIT; break; case 2: mode = ROTATE_BLIT; break; } } if (!al_init()) { abort_example("Could not init Allegro\n"); } open_log(); al_init_image_addon(); al_init_primitives_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } if (mode == ALL) { for (mode = PLAIN_BLIT; mode <= ROTATE_BLIT; mode++) { do_test(mode); } } else { do_test(mode); } al_destroy_display(display); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_color.cpp0000644000175000001440000001327512152725670016561 0ustar tjadenusers/* * Example program for the Allegro library, by Elias Pschernig. * * Demonstrates some of the conversion functions in the color addon. */ #include #include #include "allegro5/allegro.h" #include "allegro5/allegro_ttf.h" #include "allegro5/allegro_color.h" #include #include "nihgui.hpp" #include "common.c" #define SLIDERS_COUNT 16 char const *names[] = {"R", "G", "B", "H", "S", "V", "H", "S", "L", "Y", "U", "V", "C", "M", "Y", "K"}; class Prog { private: Dialog d; VSlider sliders[SLIDERS_COUNT]; Label labels[SLIDERS_COUNT]; Label labels2[SLIDERS_COUNT]; int previous[SLIDERS_COUNT]; public: Prog(const Theme & theme, ALLEGRO_DISPLAY *display); void run(); }; Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : d(Dialog(theme, display, 640, 480)) { for (int i = 0; i < SLIDERS_COUNT; i++) { int j = i < 12 ? i / 3 : 4; sliders[i] = VSlider(1000, 1000); d.add(sliders[i], 8 + i * 32 + j * 16, 8, 15, 256); labels[i].set_text(names[i]); d.add(labels[i], i * 32 + j * 16, 8 + 256, 32, 20); d.add(labels2[i], i * 32 + j * 16, 8 + 276, 32, 20); previous[i] = 0; } } namespace { float clamp(float x) { if (x < 0) return 0; if (x > 1) return 1; return x; } }; void Prog::run() { d.prepare(); while (!d.is_quit_requested()) { if (d.is_draw_requested()) { al_clear_to_color(al_map_rgb(128, 128, 128)); float v[SLIDERS_COUNT]; int keep = -1; for (int i = 0; i < SLIDERS_COUNT; i++) { int x = sliders[i].get_cur_value(); v[i] = x / 1000.0; if (previous[i] != x) { keep = i; } } if (keep != -1) { int space = keep < 12 ? keep / 3 : 4; switch (space) { case 0: al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); v[3] /= 360; v[6] /= 360; break; case 1: al_color_hsv_to_rgb(v[3] * 360, v[4], v[5], v + 0, v + 1, v + 2); al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); v[6] /= 360; break; case 2: al_color_hsl_to_rgb(v[6] * 360, v[7], v[8], v + 0, v + 1, v + 2); al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); v[3] /= 360; break; case 3: al_color_yuv_to_rgb(v[9], v[10], v[11], v + 0, v + 1, v + 2); v[0] = clamp(v[0]); v[1] = clamp(v[1]); v[2] = clamp(v[2]); al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); v[3] /= 360; v[6] /= 360; break; case 4: al_color_cmyk_to_rgb(v[12], v[13], v[14], v[15], v + 0, v + 1, v + 2); al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); v[3] /= 360; v[6] /= 360; break; } } for (int i = 0; i < SLIDERS_COUNT; i++) { sliders[i].set_cur_value((int)(v[i] * 1000)); previous[i] = sliders[i].get_cur_value(); char c[100]; sprintf(c, "%d", (int)(v[i] * 100)); labels2[i].set_text(c); } d.draw(); al_draw_filled_rectangle(0, 400, 640, 480, al_map_rgb_f(v[0], v[1], v[2])); char const *name = al_color_rgb_to_name(v[0], v[1], v[2]); char html[8]; al_color_rgb_to_html(v[0], v[1], v[2], html); al_draw_text(d.get_theme().font, al_map_rgb(0, 0, 0), 0, 380, 0, name); al_draw_text(d.get_theme().font, al_map_rgb(0, 0, 0), 0, 360, 0, html); al_flip_display(); } d.run_step(true); } } int main(int argc, char *argv[]) { ALLEGRO_DISPLAY *display; ALLEGRO_FONT *font; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro\n"); } al_init_primitives_addon(); al_install_keyboard(); al_install_mouse(); al_init_font_addon(); al_init_ttf_addon(); al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); display = al_create_display(640, 480); if (!display) { abort_example("Unable to create display\n"); } font = al_load_font("data/DejaVuSans.ttf", 12, 0); if (!font) { abort_example("Failed to load data/DejaVuSans.ttf\n"); } Theme theme(font); Prog prog(theme, display); prog.run(); al_destroy_font(font); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_gp2xwiz.c0000644000175000001440000000253012152727422016502 0ustar tjadenusers#include #include #include #include "common.c" const int W = 320, H = 240; const int R = 240; const int POINTS = 200; int main(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); ALLEGRO_DISPLAY *d = al_create_display(W, H); if (!d) { abort_example("Error creating display\n"); } ALLEGRO_VERTEX v[POINTS]; ALLEGRO_COLOR c; v[0].x = 0; v[0].y = 0; c = al_map_rgb(rand()%256, rand()%256, rand()%256); v[0].color = al_get_prim_color(c); v[1].x = 0+R; v[1].y = 0; c = al_map_rgb(rand()%256, rand()%256, rand()%256); v[1].color = al_get_prim_color(c); float a = 0; float r = R; int i; for (i = 2; i < POINTS; i++) { v[i].x = 0+cos(a)*r; v[i].y = 0+sin(a)*r; a += 0.3f; r -= 1.5f; c = al_map_rgb(rand()%256, rand()%256, rand()%256); v[i].color = al_get_prim_color(c); } int frames = 0; ALLEGRO_TRANSFORM t; while (true) { al_clear_to_color(al_map_rgb(0, 0, 0)); al_identity_transform(&t); al_rotate_transform(&t, frames*0.1f); al_translate_transform(&t, W/2, H/2); al_use_transform(&t); al_draw_prim(v, NULL, 0, POINTS, ALLEGRO_PRIM_TRIANGLE_FAN); al_flip_display(); /* GP2X Wiz is locked to 60FPS using OpenGL */ frames++; if (frames > 400) break; } al_uninstall_system(); return 0; } allegro-5.0.10/examples/ex_kcm_direct.c0000644000175000001440000000530412152725670017201 0ustar tjadenusers/* Shows the ability to play a sample without a mixer. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" int main(int argc, char **argv) { ALLEGRO_VOICE *voice; ALLEGRO_SAMPLE_INSTANCE *sample; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 2) { log_printf("This example needs to be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); goto done; } al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } for (i = 1; i < argc; ++i) { ALLEGRO_SAMPLE *sample_data = NULL; const char *filename = argv[i]; ALLEGRO_CHANNEL_CONF chan; ALLEGRO_AUDIO_DEPTH depth; unsigned long freq; float sample_time = 0; /* Load the entire sound file from disk. */ sample_data = al_load_sample(filename); if (!sample_data) { log_printf("Could not load sample from '%s'!\n", filename); continue; } sample = al_create_sample_instance(NULL); if (!sample) { abort_example("al_create_sample failed.\n"); } if (!al_set_sample(sample, sample_data)) { log_printf("al_set_sample failed.\n"); continue; } depth = al_get_sample_instance_depth(sample); chan = al_get_sample_instance_channels(sample); freq = al_get_sample_instance_frequency(sample); log_printf("Loaded sample: %i-bit depth, %i channels, %li Hz\n", (depth < 8) ? (8+depth*8) : 0, (chan>>4)+(chan%0xF), freq); log_printf("Trying to create a voice with the same specs... "); voice = al_create_voice(freq, depth, chan); if (!voice) { abort_example("Could not create ALLEGRO_VOICE.\n"); } log_printf("done.\n"); if (!al_attach_sample_instance_to_voice(sample, voice)) { abort_example("al_attach_sample_instance_to_voice failed.\n"); } /* Play sample in looping mode. */ al_set_sample_instance_playmode(sample, ALLEGRO_PLAYMODE_LOOP); al_play_sample_instance(sample); sample_time = al_get_sample_instance_time(sample); log_printf("Playing '%s' (%.3f seconds) 3 times", filename, sample_time); al_rest(sample_time * 3); al_stop_sample_instance(sample); log_printf("\n"); /* Free the memory allocated. */ al_set_sample(sample, NULL); al_destroy_sample(sample_data); al_destroy_sample_instance(sample); al_destroy_voice(voice); } al_uninstall_audio(); done: close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_mouse.c0000644000175000001440000000324712152725670016231 0ustar tjadenusers#include #include "allegro5/allegro_image.h" #include #include "common.c" #define NUM_BUTTONS 3 static void draw_mouse_button(int but, bool down) { const int offset[NUM_BUTTONS] = {0, 70, 35}; ALLEGRO_COLOR grey; ALLEGRO_COLOR black; int x; int y; x = 400 + offset[but-1]; y = 130; grey = al_map_rgb(0xe0, 0xe0, 0xe0); black = al_map_rgb(0, 0, 0); al_draw_filled_rectangle(x, y, x + 27, y + 42, grey); al_draw_rectangle(x + 0.5, y + 0.5, x + 26.5, y + 41.5, black, 0); if (down) { al_draw_filled_rectangle(x + 2, y + 2, x + 25, y + 40, black); } } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *cursor; ALLEGRO_MOUSE_STATE msestate; ALLEGRO_KEYBOARD_STATE kbdstate; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_primitives_addon(); al_install_mouse(); al_install_keyboard(); al_init_image_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } al_hide_mouse_cursor(display); cursor = al_load_bitmap("data/cursor.tga"); if (!cursor) { abort_example("Error loading cursor.tga\n"); } do { al_get_mouse_state(&msestate); al_get_keyboard_state(&kbdstate); al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); for (i = 1; i <= NUM_BUTTONS; i++) { draw_mouse_button(i, al_mouse_button_down(&msestate, i)); } al_draw_bitmap(cursor, msestate.x, msestate.y, 0); al_flip_display(); al_rest(0.005); } while (!al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)); return 0; } allegro-5.0.10/examples/ex_mixer_chain.c0000644000175000001440000000647712152725670017377 0ustar tjadenusers/* * Example program for the Allegro library. * * Test chaining mixers to mixers. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "common.c" int main(int argc, char **argv) { ALLEGRO_VOICE *voice; ALLEGRO_MIXER *mixer; ALLEGRO_MIXER *submixer[2]; ALLEGRO_SAMPLE_INSTANCE *sample[2]; ALLEGRO_SAMPLE *sample_data[2]; float sample_time; float max_sample_time; int i; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); if (argc < 3) { log_printf("This example needs to be run from the command line.\nUsage: %s file1 file2\n", argv[0]); goto done; } al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (!voice) { abort_example("Could not create ALLEGRO_VOICE.\n"); } mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); submixer[0] = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); submixer[1] = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); if (!mixer || !submixer[0] || !submixer[1]) { abort_example("al_create_mixer failed.\n"); } if (!al_attach_mixer_to_voice(mixer, voice)) { abort_example("al_attach_mixer_to_voice failed.\n"); } for (i = 0; i < 2; i++) { const char *filename = argv[i + 1]; sample_data[i] = al_load_sample(filename); if (!sample_data[i]) { abort_example("Could not load sample from '%s'!\n", filename); } sample[i] = al_create_sample_instance(NULL); if (!sample[i]) { abort_example("al_create_sample failed.\n"); } if (!al_set_sample(sample[i], sample_data[i])) { abort_example("al_set_sample_ptr failed.\n"); } if (!al_attach_sample_instance_to_mixer(sample[i], submixer[i])) { abort_example("al_attach_sample_instance_to_mixer failed.\n"); } if (!al_attach_mixer_to_mixer(submixer[i], mixer)) { abort_example("al_attach_mixer_to_mixer failed.\n"); } } /* Play sample in looping mode. */ for (i = 0; i < 2; i++) { al_set_sample_instance_playmode(sample[i], ALLEGRO_PLAYMODE_LOOP); al_play_sample_instance(sample[i]); } max_sample_time = al_get_sample_instance_time(sample[0]); sample_time = al_get_sample_instance_time(sample[1]); if (sample_time > max_sample_time) max_sample_time = sample_time; log_printf("Playing..."); al_rest(max_sample_time); al_set_sample_instance_gain(sample[0], 0.5); al_rest(max_sample_time); al_set_sample_instance_gain(sample[1], 0.25); al_rest(max_sample_time); al_stop_sample_instance(sample[0]); al_stop_sample_instance(sample[1]); log_printf("Done\n"); /* Free the memory allocated. */ for (i = 0; i < 2; i++) { al_set_sample(sample[i], NULL); al_destroy_sample(sample_data[i]); al_destroy_sample_instance(sample[i]); al_destroy_mixer(submixer[i]); } al_destroy_mixer(mixer); al_destroy_voice(voice); al_uninstall_audio(); done: close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_curl.c0000644000175000001440000002261412152725670016045 0ustar tjadenusers/* * Example program for Allegro library. * * Custom file stream using cURL library. */ /* * Adapted from libcurl example fopen.c; licensed as follows: *--- * Coyright (c)2003 Simtec Electronics * * Re-implemented by Vincent Sanders with extensive * reference to original curl example code * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #ifndef WIN32 # include #endif #include #include #include #include #include #include "common.c" typedef struct CURL_FILE CURL_FILE; struct CURL_FILE { CURL *curl; char *buffer; /* buffer to store cached data */ size_t buffer_len; /* currently allocated buffers length */ size_t buffer_pos; /* end of data in buffer*/ int still_running; /* Is background url fetch still in progress */ }; /* forward declaration */ static ALLEGRO_FILE_INTERFACE curl_file_vtable; /* we use a global one for convenience */ static CURLM *multi_handle; /* curl calls this routine to get more data. */ static size_t write_callback(char *buffer, size_t size, size_t nitems, void *userp) { CURL_FILE *cf = userp; char *newbuff; size_t rembuff; size *= nitems; rembuff = cf->buffer_len - cf->buffer_pos; if (size > rembuff) { /* Not enough space in buffer. */ newbuff = realloc(cf->buffer, cf->buffer_len + size - rembuff); if (!newbuff) { log_printf("callback buffer grow failed\n"); size = rembuff; } else { /* realloc increase buffer size. */ cf->buffer_len += size - rembuff; cf->buffer = newbuff; } } memcpy(cf->buffer + cf->buffer_pos, buffer, size); cf->buffer_pos += size; return size; } static void *curl_file_fopen(const char *path, const char *mode) { CURL_FILE *cf; /* Only support reading. */ if (strcmp(mode, "r") != 0 && strcmp(mode, "rb") != 0) return NULL; cf = calloc(1, sizeof(*cf)); if (!cf) return NULL; cf->curl = curl_easy_init(); curl_easy_setopt(cf->curl, CURLOPT_URL, path); curl_easy_setopt(cf->curl, CURLOPT_WRITEDATA, cf); curl_easy_setopt(cf->curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(cf->curl, CURLOPT_WRITEFUNCTION, write_callback); if (!multi_handle) multi_handle = curl_multi_init(); curl_multi_add_handle(multi_handle, cf->curl); /* Let's start the fetch. */ while (curl_multi_perform(multi_handle, &cf->still_running) == CURLM_CALL_MULTI_PERFORM); if ((cf->buffer_pos == 0) && (!cf->still_running)) { /* If still_running is 0 now, we should return NULL. */ curl_multi_remove_handle(multi_handle, cf->curl); curl_easy_cleanup(cf->curl); free(cf); cf = NULL; } return cf; } static void curl_file_fclose(ALLEGRO_FILE *f) { CURL_FILE *cf = al_get_file_userdata(f); curl_multi_remove_handle(multi_handle, cf->curl); curl_easy_cleanup(cf->curl); if (cf->buffer) free(cf->buffer); free(cf); } static bool fill_buffer(CURL_FILE *cf, size_t size) { fd_set fdread; fd_set fdwrite; fd_set fdexcep; int maxfd; struct timeval timeout; int rc; /* Only attempt to fill buffer if transactions still running and buffer * doesn't exceed required size already. */ if (!cf->still_running || cf->buffer_pos > size) return false; /* Attempt to fill buffer. */ do { FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* Set a suitable timeout to fail on. */ timeout.tv_sec = 10; timeout.tv_usec = 0; /* Get file descriptors from the transfers. */ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); /* In a real-world program you OF COURSE check the return code of the * function calls, *and* you make sure that maxfd is bigger than -1 * so that the call to select() below makes sense! */ rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); switch (rc) { case -1: /* select error */ break; case 0: break; default: /* Timeout or readable/writable sockets. */ /* Note we *could* be more efficient and not wait for * CURLM_CALL_MULTI_PERFORM to clear here and check it on * re-entry but that gets messy. */ while (curl_multi_perform(multi_handle, &cf->still_running) == CURLM_CALL_MULTI_PERFORM); break; } } while (cf->still_running && cf->buffer_pos < size); return true; } static void use_buffer(CURL_FILE *cf, size_t size) { if (cf->buffer_pos - size <= 0) { cf->buffer_pos = 0; } else { /* Move rest down make it available for later. */ memmove(cf->buffer, cf->buffer + size, cf->buffer_pos - size); cf->buffer_pos -= size; } } static size_t curl_file_fread(ALLEGRO_FILE *f, void *ptr, size_t size) { CURL_FILE *cf = al_get_file_userdata(f); fill_buffer(cf, size); if (!cf->buffer_pos) return 0; if (cf->buffer_pos < size) size = cf->buffer_pos; memcpy(ptr, cf->buffer, size); use_buffer(cf, size); return size; } static size_t curl_file_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) { (void)f; (void)ptr; (void)size; al_set_errno(EBADF); return 0; } static bool curl_file_fflush(ALLEGRO_FILE *f) { (void)f; return true; } static int64_t curl_file_ftell(ALLEGRO_FILE *f) { /* Not implemented. */ (void)f; al_set_errno(ENOSYS); return -1; } static bool curl_file_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) { if (whence != ALLEGRO_SEEK_CUR || offset < 0) { /* Not implemented. */ al_set_errno(ENOSYS); return false; } while (offset > 0) { if (al_fgetc(f) == EOF) break; offset--; } return offset == 0; } static bool curl_file_feof(ALLEGRO_FILE *f) { CURL_FILE *cf = al_get_file_userdata(f); return (cf->buffer_pos == 0 && !cf->still_running); } static bool curl_file_ferror(ALLEGRO_FILE *f) { /* Not implemented. */ (void)f; return false; } static void curl_file_fclearerr(ALLEGRO_FILE *f) { /* Not implemented. */ (void)f; } static int curl_file_fungetc(ALLEGRO_FILE *f, int c) { /* Not implemented. */ (void)f; (void)c; al_set_errno(ENOSYS); return -1; } static off_t curl_file_fsize(ALLEGRO_FILE *f) { /* Not implemented. */ (void)f; al_set_errno(ENOSYS); return -1; } static ALLEGRO_FILE_INTERFACE curl_file_vtable = { curl_file_fopen, curl_file_fclose, curl_file_fread, curl_file_fwrite, curl_file_fflush, curl_file_ftell, curl_file_fseek, curl_file_feof, curl_file_ferror, curl_file_fclearerr, curl_file_fungetc, curl_file_fsize }; static void show_image(ALLEGRO_BITMAP *bmp) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); while (true) { al_draw_bitmap(bmp, 0, 0, 0); al_flip_display(); al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } al_destroy_event_queue(queue); } int main(int argc, const char *argv[]) { const char *url; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *bmp; if (argc > 1) url = argv[1]; else url = "http://liballeg.org/images/logo.png"; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_init_image_addon(); al_install_keyboard(); display = al_create_display(640, 480); if (!display) { abort_example("Unable to create display.\n"); } curl_global_init(CURL_GLOBAL_ALL); al_set_new_file_interface(&curl_file_vtable); bmp = al_load_bitmap(url); if (bmp) { show_image(bmp); al_destroy_bitmap(bmp); } curl_global_cleanup(); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/examples/ex_dualies.c0000644000175000001440000000350112152725670016520 0ustar tjadenusers#include "allegro5/allegro.h" #include "allegro5/allegro_image.h" #include #include "common.c" static void go(void) { ALLEGRO_DISPLAY *d1, *d2; ALLEGRO_BITMAP *b1, *b2; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; al_set_new_display_flags(ALLEGRO_FULLSCREEN); al_set_new_display_adapter(0); d1 = al_create_display(640, 480); if (!d1) { abort_example("Error creating first display\n"); } b1 = al_load_bitmap("data/mysha.pcx"); if (!b1) { abort_example("Error loading mysha.pcx\n"); } al_set_new_display_adapter(1); d2 = al_create_display(640, 480); if (!d2) { abort_example("Error creating second display\n"); } b2 = al_load_bitmap("data/allegro.pcx"); if (!b2) { abort_example("Error loading allegro.pcx\n"); } queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); while (1) { if (!al_is_event_queue_empty(queue)) { al_get_next_event(queue, &event); if (event.type == ALLEGRO_EVENT_KEY_DOWN) { if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { break; } } } al_set_target_backbuffer(d1); al_draw_scaled_bitmap(b1, 0, 0, 320, 200, 0, 0, 640, 480, 0); al_flip_display(); al_set_target_backbuffer(d2); al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); al_flip_display(); al_rest(0.1); } al_destroy_bitmap(b1); al_destroy_bitmap(b2); al_destroy_display(d1); al_destroy_display(d2); } int main(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_init_image_addon(); if (al_get_num_video_adapters() < 2) { abort_example("You need 2 or more adapters/monitors for this example.\n"); } go(); return 0; } allegro-5.0.10/examples/ex_blit.c0000644000175000001440000001476312152725670016040 0ustar tjadenusers/* An example demonstrating different blending modes. */ #include #include #include #include #include #include #include #include "common.c" struct Example { ALLEGRO_BITMAP *pattern; ALLEGRO_FONT *font; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_COLOR background, text, white; double timer[4], counter[4]; int FPS; float text_x, text_y; } ex; static ALLEGRO_BITMAP *example_bitmap(int w, int h) { int i, j; float mx = w * 0.5; float my = h * 0.5; ALLEGRO_STATE state; ALLEGRO_BITMAP *pattern = al_create_bitmap(w, h); al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(pattern); al_lock_bitmap(pattern, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); for (i = 0; i < w; i++) { for (j = 0; j < h; j++) { float a = atan2(i - mx, j - my); float d = sqrt(pow(i - mx, 2) + pow(j - my, 2)); float sat = pow(1.0 - 1 / (1 + d * 0.1), 5); float hue = 3 * a * 180 / ALLEGRO_PI; hue = (hue / 360 - floorf(hue / 360)) * 360; al_put_pixel(i, j, al_color_hsv(hue, sat, 1)); } } al_put_pixel(0, 0, al_map_rgb(0, 0, 0)); al_unlock_bitmap(pattern); al_restore_state(&state); return pattern; } static void set_xy(float x, float y) { ex.text_x = x; ex.text_y = y; } static void get_xy(float *x, float *y) { *x = ex.text_x; *y = ex.text_y; } static void print(char const *format, ...) { va_list list; char message[1024]; int th = al_get_font_line_height(ex.font); va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); ex.text_y += th; } static void start_timer(int i) { ex.timer[i] -= al_get_time(); ex.counter[i]++; } static void stop_timer(int i) { ex.timer[i] += al_get_time(); } static double get_fps(int i) { if (ex.timer[i] == 0) return 0; return ex.counter[i] / ex.timer[i]; } static void draw(void) { float x, y; int iw = al_get_bitmap_width(ex.pattern); int ih = al_get_bitmap_height(ex.pattern); ALLEGRO_BITMAP *screen, *temp; ALLEGRO_LOCKED_REGION *lock; void *data; int size, i, format; al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_clear_to_color(ex.background); screen = al_get_target_bitmap(); set_xy(8, 8); /* Test 1. */ /* Disabled: drawing to same bitmap is not supported. */ /* print("Screen -> Screen (%.1f fps)", get_fps(0)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(0); al_draw_bitmap_region(screen, x, y, iw, ih, x + 8 + iw, y, 0); stop_timer(0); set_xy(x, y + ih); */ /* Test 2. */ print("Screen -> Bitmap -> Screen (%.1f fps)", get_fps(1)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); temp = al_create_bitmap(iw, ih); al_set_target_bitmap(temp); al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); start_timer(1); al_draw_bitmap_region(screen, x, y, iw, ih, 0, 0, 0); al_set_target_bitmap(screen); al_draw_bitmap(temp, x + 8 + iw, y, 0); stop_timer(1); set_xy(x, y + ih); al_destroy_bitmap(temp); /* Test 3. */ print("Screen -> Memory -> Screen (%.1f fps)", get_fps(2)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); temp = al_create_bitmap(iw, ih); al_set_target_bitmap(temp); al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); start_timer(2); al_draw_bitmap_region(screen, x, y, iw, ih, 0, 0, 0); al_set_target_bitmap(screen); al_draw_bitmap(temp, x + 8 + iw, y, 0); stop_timer(2); set_xy(x, y + ih); al_destroy_bitmap(temp); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); /* Test 4. */ print("Screen -> Locked -> Screen (%.1f fps)", get_fps(3)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(3); lock = al_lock_bitmap_region(screen, x, y, iw, ih, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); format = lock->format; size = lock->pixel_size; data = malloc(size * iw * ih); for (i = 0; i < ih; i++) memcpy((char*)data + i * size * iw, (char*)lock->data + i * lock->pitch, size * iw); al_unlock_bitmap(screen); lock = al_lock_bitmap_region(screen, x + 8 + iw, y, iw, ih, format, ALLEGRO_LOCK_WRITEONLY); for (i = 0; i < ih; i++) memcpy((char*)lock->data + i * lock->pitch, (char*)data + i * size * iw, size * iw); al_unlock_bitmap(screen); free(data); stop_timer(3); set_xy(x, y + ih); } static void tick(void) { draw(); al_flip_display(); } static void run(void) { ALLEGRO_EVENT event; bool need_draw = true; while (1) { if (need_draw && al_is_event_queue_empty(ex.queue)) { tick(); need_draw = false; } al_wait_for_event(ex.queue, &event); switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; case ALLEGRO_EVENT_TIMER: need_draw = true; break; } } } static void init(void) { ex.FPS = 60; ex.font = al_load_font("data/fixed_font.tga", 0, 0); if (!ex.font) { abort_example("data/fixed_font.tga not found\n"); } ex.background = al_color_name("beige"); ex.text = al_color_name("black"); ex.white = al_color_name("white"); ex.pattern = example_bitmap(100, 100); } int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); al_init_image_addon(); al_init_font_addon(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display\n"); } init(); timer = al_create_timer(1.0 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); return 0; } allegro-5.0.10/examples/common.c0000644000175000001440000000405612066454720015673 0ustar tjadenusers#include #include void abort_example(char const *format, ...); void open_log(void); void open_log_monospace(void); void close_log(bool wait_for_user); void log_printf(char const *format, ...); #ifdef ALLEGRO_POPUP_EXAMPLES #include "allegro5/allegro_native_dialog.h" ALLEGRO_TEXTLOG *textlog = NULL; void abort_example(char const *format, ...) { char str[1024]; va_list args; ALLEGRO_DISPLAY *display; va_start(args, format); vsnprintf(str, sizeof str, format, args); va_end(args); if (al_init_native_dialog_addon()) { display = al_is_system_installed() ? al_get_current_display() : NULL; al_show_native_message_box(display, "Error", "Cannot run example", str, NULL, 0); } else { fprintf(stderr, "%s", str); } exit(1); } void open_log(void) { if (al_init_native_dialog_addon()) { textlog = al_open_native_text_log("Log", 0); } } void open_log_monospace(void) { if (al_init_native_dialog_addon()) { textlog = al_open_native_text_log("Log", ALLEGRO_TEXTLOG_MONOSPACE); } } void close_log(bool wait_for_user) { if (textlog && wait_for_user) { ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); al_register_event_source(queue, al_get_native_text_log_event_source( textlog)); al_wait_for_event(queue, NULL); al_destroy_event_queue(queue); } al_close_native_text_log(textlog); textlog = NULL; } void log_printf(char const *format, ...) { char str[1024]; va_list args; va_start(args, format); vsnprintf(str, sizeof str, format, args); va_end(args); al_append_native_text_log(textlog, "%s", str); } #else void abort_example(char const *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); exit(1); } void open_log(void) { } void open_log_monospace(void) { } void close_log(bool wait_for_user) { (void)wait_for_user; } void log_printf(char const *format, ...) { va_list args; va_start(args, format); vprintf(format, args); va_end(args); } #endif allegro-5.0.10/examples/ex_stream_seek.c0000644000175000001440000002023512152733432017372 0ustar tjadenusers/* * Example program for the Allegro library, by Todd Cope. * * Stream seeking. */ #include #include "allegro5/allegro.h" #include "allegro5/allegro_font.h" #include "allegro5/allegro_image.h" #include "allegro5/allegro_audio.h" #include "allegro5/allegro_acodec.h" #include "allegro5/allegro_primitives.h" #include "common.c" ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_FONT *basic_font = NULL; ALLEGRO_AUDIO_STREAM *music_stream = NULL; char *stream_filename = NULL; float slider_pos = 0.0; float loop_start, loop_end; int mouse_button[16] = {0}; bool exiting = false; static void initialize(void) { if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); al_init_primitives_addon(); al_init_image_addon(); al_init_font_addon(); if (!al_install_keyboard()) { abort_example("Could not init keyboard!\n"); } if (!al_install_mouse()) { abort_example("Could not init mouse!\n"); } al_init_acodec_addon(); if (!al_install_audio()) { abort_example("Could not init sound!\n"); } if (!al_reserve_samples(16)) { abort_example("Could not set up voice and mixer.\n"); } display = al_create_display(640, 228); if (!display) { abort_example("Could not create display!\n"); } basic_font = al_load_font("data/font.tga", 0, 0); if (!basic_font) { abort_example("Could not load font!\n"); } timer = al_create_timer(1.000 / 30); if (!timer) { abort_example("Could not init timer!\n"); } queue = al_create_event_queue(); if (!queue) { abort_example("Could not create event queue!\n"); } al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_timer_event_source(timer)); } static void logic(void) { /* calculate the position of the slider */ double w = al_get_display_width(display) - 20; double pos = al_get_audio_stream_position_secs(music_stream); double len = al_get_audio_stream_length_secs(music_stream); slider_pos = w * (pos / len); } static void print_time(int x, int y, float t) { int hours, minutes; hours = (int)t / 3600; t -= hours * 3600; minutes = (int)t / 60; t -= minutes * 60; al_draw_textf(basic_font, al_map_rgb(255, 255, 255), x, y, 0, "%02d:%02d:%05.2f", hours, minutes, t); } static void render(void) { double pos = al_get_audio_stream_position_secs(music_stream); double length = al_get_audio_stream_length_secs(music_stream); double w = al_get_display_width(display) - 20; double loop_start_pos = w * (loop_start / length); double loop_end_pos = w * (loop_end / length); ALLEGRO_COLOR c = al_map_rgb(255, 255, 255); al_clear_to_color(al_map_rgb(64, 64, 128)); /* render "music player" */ al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(basic_font, c, 0, 0, 0, "Playing %s", stream_filename); print_time(8, 24, pos); al_draw_textf(basic_font, c, 100, 24, 0, "/"); print_time(110, 24, length); al_draw_filled_rectangle(10.0, 48.0 + 7.0, 10.0 + w, 48.0 + 9.0, al_map_rgb(0, 0, 0)); al_draw_line(10.0 + loop_start_pos, 46.0, 10.0 + loop_start_pos, 66.0, al_map_rgb(0, 168, 128), 0); al_draw_line(10.0 + loop_end_pos, 46.0, 10.0 + loop_end_pos, 66.0, al_map_rgb(255, 0, 0), 0); al_draw_filled_rectangle(10.0 + slider_pos - 2.0, 48.0, 10.0 + slider_pos + 2.0, 64.0, al_map_rgb(224, 224, 224)); /* show help */ al_draw_textf(basic_font, c, 0, 96, 0, "Drag the slider to seek."); al_draw_textf(basic_font, c, 0, 120, 0, "Middle-click to set loop start."); al_draw_textf(basic_font, c, 0, 144, 0, "Right-click to set loop end."); al_draw_textf(basic_font, c, 0, 168, 0, "Left/right arrows to seek."); al_draw_textf(basic_font, c, 0, 192, 0, "Space to pause."); al_flip_display(); } static void myexit(void) { bool playing; playing = al_get_mixer_playing(al_get_default_mixer()); if (playing && music_stream) al_drain_audio_stream(music_stream); al_destroy_audio_stream(music_stream); } static void maybe_fiddle_sliders(int mx, int my) { double seek_pos; double w = al_get_display_width(display) - 20; if (!(mx >= 10 && mx < 10 + w && my >= 48 && my < 64)) { return; } seek_pos = al_get_audio_stream_length_secs(music_stream) * ((mx - 10) / w); if (mouse_button[1]) { al_seek_audio_stream_secs(music_stream, seek_pos); } else if (mouse_button[2]) { loop_end = seek_pos; al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); } else if (mouse_button[3]) { loop_start = seek_pos; al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); } } static void event_handler(const ALLEGRO_EVENT * event) { int i; switch (event->type) { /* Was the X button on the window pressed? */ case ALLEGRO_EVENT_DISPLAY_CLOSE: exiting = true; break; /* Was a key pressed? */ case ALLEGRO_EVENT_KEY_CHAR: if (event->keyboard.keycode == ALLEGRO_KEY_LEFT) { double pos = al_get_audio_stream_position_secs(music_stream); pos -= 5.0; if (pos < 0.0) pos = 0.0; al_seek_audio_stream_secs(music_stream, pos); } else if (event->keyboard.keycode == ALLEGRO_KEY_RIGHT) { double pos = al_get_audio_stream_position_secs(music_stream); pos += 5.0; if (!al_seek_audio_stream_secs(music_stream, pos)) log_printf("seek error!\n"); } else if (event->keyboard.keycode == ALLEGRO_KEY_SPACE) { bool playing; playing = al_get_mixer_playing(al_get_default_mixer()); playing = !playing; al_set_mixer_playing(al_get_default_mixer(), playing); } else if (event->keyboard.keycode == ALLEGRO_KEY_ESCAPE) { exiting = true; } break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: mouse_button[event->mouse.button] = 1; maybe_fiddle_sliders(event->mouse.x, event->mouse.y); break; case ALLEGRO_EVENT_MOUSE_AXES: maybe_fiddle_sliders(event->mouse.x, event->mouse.y); break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: mouse_button[event->mouse.button] = 0; break; case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: for (i = 0; i < 16; i++) mouse_button[i] = 0; break; /* Is it time for the next timer tick? */ case ALLEGRO_EVENT_TIMER: logic(); render(); break; } } int main(int argc, char * argv[]) { ALLEGRO_CONFIG *config; ALLEGRO_EVENT event; unsigned buffer_count; unsigned samples; const char *s; initialize(); if (argc < 2) { log_printf("This example needs to be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); goto done; } buffer_count = 0; samples = 0; config = al_load_config_file("ex_stream_seek.cfg"); if (config) { if ((s = al_get_config_value(config, "", "buffer_count"))) { buffer_count = atoi(s); } if ((s = al_get_config_value(config, "", "samples"))) { samples = atoi(s); } al_destroy_config(config); } if (buffer_count == 0) { buffer_count = 4; } if (samples == 0) { samples = 1024; } stream_filename = argv[1]; music_stream = al_load_audio_stream(stream_filename, buffer_count, samples); if (!music_stream) { abort_example("Stream error!\n"); } loop_start = 0.0; loop_end = al_get_audio_stream_length_secs(music_stream); al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); al_set_audio_stream_playmode(music_stream, ALLEGRO_PLAYMODE_LOOP); al_attach_audio_stream_to_mixer(music_stream, al_get_default_mixer()); al_start_timer(timer); while (!exiting) { al_wait_for_event(queue, &event); event_handler(&event); } done: myexit(); al_destroy_display(display); close_log(true); return 0; } /* vim: set sts=3 sw=3 et: */ allegro-5.0.10/allegro5.cfg0000644000175000001440000000673312137071470014614 0ustar tjadenusers# # Configuration file for the Allegro 5 library. # # This file should be either in the same directory as your program. # # On Unix, this file may also be stored as ~/.allegro5rc or /etc/allegro5rc. # If multiple files exist, they will be merged, with values from more specific # files overriding the less specific files. [graphics] # Graphics driver. # Can be 'default', 'opengl' or 'direct3d' (Windows only). driver=default # Display configuration selection mode. # # Under Linux, it can be used to force the old GLX 1.2 way of choosing # display settings or the new FBConfig method introduced with GLX 1.3. # # Under Windows, when using the OpenGL driver, setting it to old will # use DescribePixelFormat and new will use wglGetPixelFormatAttribivARB # (provided by WGL_ARB_pixel_format extension). # # Can be 'old' and 'new'. Default is 'new'. config_selection=new [audio] # Driver can be 'default', 'openal', 'alsa', 'oss', 'pulseaudio' or 'directsound' # depending on platform. driver=default # Mixer quality can be 'linear' (default), 'cubic' (best), or 'point' (bad). # default_mixer_quality=linear # The frequency to use for the default voice/mixer. Default: 44100. # primary_voice_frequency=44100 # primary_mixer_frequency=44100 # Can be 'int16', otherwise defaults to float32. # primary_voice_depth=float32 # primary_mixer_depth=float32 [oss] # You can skip probing for OSS4 driver by setting this option to 'yes'. # Default is 'no'. force_ver3=no # When OSS3 is used, you can choose a sound device here. # Default is '/dev/dsp'. device=/dev/dsp [alsa] # Set the ALSA sound device. # Default is 'default'. device=default [pulseaudio] # Set the buffer size (in samples) buffer_size=1024 [directsound] # Set the DirectSound buffer size (in samples) buffer_size = 8192 [opengl] # If you want to support old OpenGL versions, you can make Allegro # believe an older version than what you actually have is used with # this key. This is only for testing/debugging purposes. # force_opengl_version = 1.2 [opengl_disabled_extensions] # Any OpenGL extensions can be listed here to make Allegro report them # as not available. The extensions used by Allegro itself if available # are shown below - uncommenting them would disable them: # GL_ARB_texture_non_power_of_two=0 # GL_EXT_framebuffer_object=0 [joystick] # Linux: Allegro normally searches for joystick device N at /dev/input/jsN. # You can override the device file path on a per-device basis, like this. # device0=/dev/input/by-id/usb-blahblah-joystick [keyboard] # You can trap/untrap the mouse cursor within a window with a key combination # of your choice, e.g. "Ctrl-G", "Shift-Ctrl-G", "Ctrl-LShift", "RWin". # This feature currently only works on X11 and Windows. # toggle_mouse_grab_key = ScrollLock [trace] # Comma-separated list of channels to log. Default is "all" which # disables channel filtering. Some possible channels are: # system,display,keyboard,opengl # Channel names can be prefixed with - to exclude only those channels. # Each addon and source-file can define additional channels though so # there are more. channels=all # Log-level. Can be one of debug, info, warn, error. level=debug # Set to 0 to disable line numbers in log files. lines=1 # Set to 0 to disable timestamps in log files. timestamps=1 # Set to 0 to disable function names in log files. functions=1 [xkeymap] # Override X11 keycode. The below example maps X11 code 52 (Y) to Allegro # code 26 (Z) and X11 code 29 (Z) to Allegro code 25 (Y). # 52=26 # 29=25